1 /* bzflag
2  * Copyright (c) 1993-2021 Tim Riker
3  *
4  * This package is free software;  you can redistribute it and/or
5  * modify it under the terms of the license found in the file
6  * named COPYING that should have accompanied this file.
7  *
8  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  */
12 
13 #ifndef __COLLISION_GRID__
14 #define __COLLISION_GRID__
15 
16 #include "common.h"
17 
18 // system headers
19 #include <vector>
20 
21 // common headers
22 #include "Extents.h"
23 
24 class Ray;
25 class Obstacle;
26 class MeshObstacle;
27 class BoxBuilding;
28 class PyramidBuilding;
29 class BaseBuilding;
30 class Teleporter;
31 
32 
33 typedef struct
34 {
35     int count;
36     Obstacle** list;
37 } ObsList;
38 
39 typedef union
40 {
41     ObsList array[6];
42     struct
43     {
44         ObsList boxes;
45         ObsList bases;
46         ObsList pyrs;
47         ObsList teles;
48         ObsList faces;
49         ObsList meshes;
50     } named;
51 } SplitObsList;
52 
53 typedef struct
54 {
55     int count;
56     const class ColDetNode** list;
57 } ColDetNodeList;
58 
59 
60 // well you know my name is Simon, and I like to do drawings
61 typedef void (*DrawLinesFunc)
62 (int pointCount, float (*points)[3], int color);
63 
64 
65 class CollisionManager
66 {
67 
68 public:
69 
70     CollisionManager();
71     ~CollisionManager();
72 
73     void load ();
74     void clear ();
75 
76     // some basics
77     bool needReload() const;     // octree parameter has changed
78     int getObstacleCount() const;    // total number of obstacles
79     const Extents& getWorldExtents() const;
80 
81 
82     // test against an axis aligned bounding box
83     const ObsList* axisBoxTest (const Extents& extents);
84 
85     // test against a cylinder
86     const ObsList* cylinderTest (const float *pos,
87                                  float radius, float height) const;
88     // test against a box
89     const ObsList* boxTest (const float* pos, float angle,
90                             float dx, float dy, float dz) const;
91     // test against a moving box
92     const ObsList* movingBoxTest (const float* oldPos, float oldAngle,
93                                   const float* pos, float angle,
94                                   float dx, float dy, float dz) const;
95     // test against a Ray
96     const ObsList* rayTest (const Ray* ray, float timeLeft) const;
97 
98     // test against a Ray (and return a list of ColDetNodes)
99     const ColDetNodeList* rayTestNodes (const Ray* ray, float timeLeft) const;
100 
101     // test against a box and return a split list
102     //const SplitObsList *boxTestSplit (const float* pos, float angle,
103     //                float dx, float dy, float dz) const;
104 
105     // drawing function
106     void draw (DrawLinesFunc drawLinesFunc);
107 
108 private:
109 
110     void setExtents(ObsList* list); // gather the extents
111 
112     class ColDetNode* root;   // the root of the octree
113 
114     float worldSize;
115     Extents gridExtents;
116     Extents worldExtents;
117 };
118 
119 extern CollisionManager COLLISIONMGR;
120 
121 
122 class ColDetNode
123 {
124 public:
125     ColDetNode(unsigned char depth, const Extents& exts, ObsList *fullList);
126     ~ColDetNode();
127 
128     int getCount() const;
129     const ObsList* getList() const;
130     const Extents& getExtents() const;
131     float getInTime() const;
132     float getOutTime() const;
133 
134     // these fill in the FullList return list
135     void axisBoxTest (const Extents& extents) const;
136     void boxTest (const float* pos, float angle, float dx, float dy, float dz) const;
137     void rayTest (const Ray* ray, float timeLeft) const;
138     void rayTestNodes (const Ray* ray, float timeLeft) const;
139 
140     // this fills in the SplitList return list
141     // (FIXME: not yet implemented, boxTestSplit might be useful for radar)
142     //void boxTestSplit (const float* pos, float angle, float dx, float dy, float dz) const;
143 
144     void tallyStats();
145     void draw(DrawLinesFunc drawLinesFunc);
146 
147 private:
148     void makeChildren ();
149     void resizeCell ();
150 
151     unsigned char depth;
152     int count;
153     Extents extents;
154     unsigned char childCount;
155     ColDetNode* children[8];
156     ObsList fullList;
157     mutable float inTime, outTime;
158 };
159 
160 
getCount()161 inline int ColDetNode::getCount() const
162 {
163     return count;
164 }
165 
getList()166 inline const ObsList* ColDetNode::getList() const
167 {
168     return &fullList;
169 }
170 
getExtents()171 inline const Extents& ColDetNode::getExtents() const
172 {
173     return extents;
174 }
175 
getInTime()176 inline float ColDetNode::getInTime() const
177 {
178     return inTime;
179 }
180 
getOutTime()181 inline float ColDetNode::getOutTime() const
182 {
183     return outTime;
184 }
185 
186 
getObstacleCount()187 inline int CollisionManager::getObstacleCount() const
188 {
189     if (root == NULL)
190         return 0;
191     else
192         return root->getCount();
193 }
194 
getWorldExtents()195 inline const Extents& CollisionManager::getWorldExtents() const
196 {
197     return worldExtents;
198 }
199 
200 
201 #endif /* __COLLISION_GRID__ */
202 
203 // Local Variables: ***
204 // mode: C++ ***
205 // tab-width: 4 ***
206 // c-basic-offset: 4 ***
207 // indent-tabs-mode: nil ***
208 // End: ***
209 // ex: shiftwidth=4 tabstop=4
210