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 /* TetraBuilding:
14  *  Encapsulates a tetrahederon in the game environment.
15  */
16 
17 #ifndef BZF_MESH_FACE_OBSTACLE_H
18 #define BZF_MESH_FACE_OBSTACLE_H
19 
20 #include "common.h"
21 #include <string>
22 #include <iostream>
23 #include "vectors.h"
24 #include "Ray.h"
25 #include "Obstacle.h"
26 #include "global.h"
27 #include "BzMaterial.h"
28 //#include "PhysicsDrive.h"
29 
30 
31 class MeshFace : public Obstacle
32 {
33 
34     friend class MeshObstacle;
35     friend class ObstacleModifier;
36 
37 public:
38     MeshFace(class MeshObstacle* mesh);
39     MeshFace(MeshObstacle* mesh, int vertexCount,
40              float** vertices, float** normals, float** texcoords,
41              const BzMaterial* material, int physics,
42              bool noclusters, bool smoothBounce, bool drive, bool shoot, bool ricochet);
43     ~MeshFace();
44 
45     const char* getType() const;
46     static const char* getClassName(); // const
47     bool isValid() const;
48     bool isFlatTop() const;
49 
50     float intersect(const Ray&) const;
51     void getNormal(const float* p, float* n) const;
52     void get3DNormal(const float* p, float* n) const;
53 
54     bool inCylinder(const float* p, float radius, float height) const;
55     bool inBox(const float* p, float angle,
56                float halfWidth, float halfBreadth, float height) const;
57     bool inMovingBox(const float* oldP, float oldAngle,
58                      const float *newP, float newAngle,
59                      float halfWidth, float halfBreadth, float height) const;
60     bool isCrossing(const float* p, float angle,
61                     float halfWidth, float halfBreadth, float height,
62                     float* plane) const;
63 
64     bool getHitNormal(const float* pos1, float azimuth1,
65                       const float* pos2, float azimuth2,
66                       float halfWidth, float halfBreadth,
67                       float height, float* normal) const;
68 
69     MeshObstacle* getMesh() const;
70     int getVertexCount() const;
71     bool useNormals() const;
72     bool useTexcoords() const;
73     const float* getVertex(int index) const;
74     const float* getNormal(int index) const;
75     const float* getTexcoord(int index) const;
76     const float* getPlane() const;
77     const BzMaterial* getMaterial() const;
78     int getPhysicsDriver() const;
79     bool noClusters() const;
80     bool isSmoothBounce() const;
81 
82     bool isSpecial() const;
83     bool isBaseFace() const;
84     bool isLinkToFace() const;
85     bool isLinkFromFace() const;
86     bool isZPlane() const;
87     bool isUpPlane() const;
88     bool isDownPlane() const;
89 
90     void setLink(const MeshFace* link);
91     const MeshFace* getLink() const;
92 
93     int packSize() const;
94     void *pack(void*) const;
95     const void *unpack(const void*);
96 
97     void print(std::ostream& out, const std::string& indent) const;
98 
99 public:
100     mutable float scratchPad;
101 
102 private:
103     void finalize();
104 
105 private:
106     static const char* typeName;
107 
108     class MeshObstacle* mesh;
109     int vertexCount;
110     float** vertices;
111     float** normals;
112     float** texcoords;
113     const BzMaterial* bzMaterial;
114     bool smoothBounce;
115     bool noclusters;
116     int phydrv;
117 
118     afvec4 plane;
119     afvec4* edgePlanes;
120 
121     MeshFace* edges; // edge 0 is between vertex 0 and 1, etc...
122     // not currently used for anything
123 
124     enum
125     {
126         XPlane    = (1 << 0),
127         YPlane    = (1 << 1),
128         ZPlane    = (1 << 2),
129         UpPlane   = (1 << 3),
130         DownPlane = (1 << 4),
131         WallPlane = (1 << 5)
132     } PlaneBits;
133 
134     char planeBits;
135 
136 
137     enum
138     {
139         LinkToFace      = (1 << 0),
140         LinkFromFace    = (1 << 1),
141         BaseFace        = (1 << 2),
142         IcyFace    = (1 << 3),
143         StickyFace      = (1 << 5),
144         DeathFace       = (1 << 6),
145         PortalFace      = (1 << 7)
146     } SpecialBits;
147 
148     // combining all types into one struct, because I'm lazy
149     typedef struct
150     {
151         // linking data
152         const MeshFace* linkFace;
153         bool linkFromFlat;
154         float linkFromSide[3]; // sideways vector
155         float linkFromDown[3]; // downwards vector
156         float linkFromCenter[3];
157         bool linkToFlat;
158         float linkToSide[3]; // sideways vector
159         float linkToDown[3]; // downwards vector
160         float linkToCenter[3];
161         // base data
162         TeamColor teamColor;
163     } SpecialData;
164 
165     uint16_t specialState;
166     SpecialData* specialData;
167 };
168 
getMesh()169 inline MeshObstacle* MeshFace::getMesh() const
170 {
171     return mesh;
172 }
173 
getMaterial()174 inline const BzMaterial* MeshFace::getMaterial() const
175 {
176     return bzMaterial;
177 }
178 
getPhysicsDriver()179 inline int MeshFace::getPhysicsDriver() const
180 {
181     return phydrv;
182 }
183 
getPlane()184 inline const float* MeshFace::getPlane() const
185 {
186     return plane;
187 }
188 
getVertexCount()189 inline int MeshFace::getVertexCount() const
190 {
191     return vertexCount;
192 }
193 
getVertex(int index)194 inline const float* MeshFace::getVertex(int index) const
195 {
196     return (const float*)vertices[index];
197 }
198 
getNormal(int index)199 inline const float* MeshFace::getNormal(int index) const
200 {
201     return (const float*)normals[index];
202 }
203 
getTexcoord(int index)204 inline const float* MeshFace::getTexcoord(int index) const
205 {
206     return (const float*)texcoords[index];
207 }
208 
useNormals()209 inline bool MeshFace::useNormals() const
210 {
211     return (normals != NULL);
212 }
213 
useTexcoords()214 inline bool MeshFace::useTexcoords() const
215 {
216     return (texcoords != NULL);
217 }
218 
noClusters()219 inline bool MeshFace::noClusters() const
220 {
221     return noclusters;
222 }
223 
isSmoothBounce()224 inline bool MeshFace::isSmoothBounce() const
225 {
226     return smoothBounce;
227 }
228 
isSpecial()229 inline bool MeshFace::isSpecial() const
230 {
231     return (specialState != 0);
232 }
233 
isBaseFace()234 inline bool MeshFace::isBaseFace() const
235 {
236     return (specialState & BaseFace) != 0;
237 }
238 
isLinkToFace()239 inline bool MeshFace::isLinkToFace() const
240 {
241     return (specialState & LinkToFace) != 0;
242 }
243 
isLinkFromFace()244 inline bool MeshFace::isLinkFromFace() const
245 {
246     return (specialState & LinkFromFace) != 0;
247 }
248 
getLink()249 inline const MeshFace* MeshFace::getLink() const
250 {
251     return specialData->linkFace;
252 }
253 
isZPlane()254 inline bool MeshFace::isZPlane() const
255 {
256     return ((planeBits & ZPlane) != 0);
257 }
258 
isUpPlane()259 inline bool MeshFace::isUpPlane() const
260 {
261     return ((planeBits & UpPlane) != 0);
262 }
263 
isDownPlane()264 inline bool MeshFace::isDownPlane() const
265 {
266     return ((planeBits & DownPlane) != 0);
267 }
268 
269 
270 #endif // BZF_MESH_FACE_OBSTACLE_H
271 
272 // Local Variables: ***
273 // mode: C++ ***
274 // tab-width: 4 ***
275 // c-basic-offset: 4 ***
276 // indent-tabs-mode: nil ***
277 // End: ***
278 // ex: shiftwidth=4 tabstop=4
279