Surface.h (7360B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 29 #ifndef __SURFACE_H__ 30 #define __SURFACE_H__ 31 32 /* 33 =============================================================================== 34 35 Surface base class. 36 37 A surface is tesselated to a triangle mesh with each edge shared by 38 at most two triangles. 39 40 =============================================================================== 41 */ 42 43 typedef struct surfaceEdge_s { 44 int verts[2]; // edge vertices always with ( verts[0] < verts[1] ) 45 int tris[2]; // edge triangles 46 } surfaceEdge_t; 47 48 49 class idSurface { 50 public: 51 idSurface(); 52 explicit idSurface( const idSurface &surf ); 53 explicit idSurface( const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); 54 ~idSurface(); 55 56 const idDrawVert & operator[]( const int index ) const; 57 idDrawVert & operator[]( const int index ); 58 idSurface & operator+=( const idSurface &surf ); 59 60 int GetNumIndexes() const { return indexes.Num(); } 61 const int * GetIndexes() const { return indexes.Ptr(); } 62 int GetNumVertices() const { return verts.Num(); } 63 const idDrawVert * GetVertices() const { return verts.Ptr(); } 64 const int * GetEdgeIndexes() const { return edgeIndexes.Ptr(); } 65 const surfaceEdge_t * GetEdges() const { return edges.Ptr(); } 66 67 void Clear(); 68 void TranslateSelf( const idVec3 &translation ); 69 void RotateSelf( const idMat3 &rotation ); 70 71 // splits the surface into a front and back surface, the surface itself stays unchanged 72 // frontOnPlaneEdges and backOnPlaneEdges optionally store the indexes to the edges that lay on the split plane 73 // returns a SIDE_? 74 int Split( const idPlane &plane, const float epsilon, idSurface **front, idSurface **back, int *frontOnPlaneEdges = NULL, int *backOnPlaneEdges = NULL ) const; 75 // cuts off the part at the back side of the plane, returns true if some part was at the front 76 // if there is nothing at the front the number of points is set to zero 77 bool ClipInPlace( const idPlane &plane, const float epsilon = ON_EPSILON, const bool keepOn = false ); 78 79 // returns true if each triangle can be reached from any other triangle by a traversal 80 bool IsConnected() const; 81 // returns true if the surface is closed 82 bool IsClosed() const; 83 // returns true if the surface is a convex hull 84 bool IsPolytope( const float epsilon = 0.1f ) const; 85 86 float PlaneDistance( const idPlane &plane ) const; 87 int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; 88 89 // returns true if the line intersects one of the surface triangles 90 bool LineIntersection( const idVec3 &start, const idVec3 &end, bool backFaceCull = false ) const; 91 // intersection point is start + dir * scale 92 bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull = false ) const; 93 94 protected: 95 idList<idDrawVert, TAG_IDLIB_LIST_SURFACE> verts; // vertices 96 idList<int, TAG_IDLIB_LIST_SURFACE> indexes; // 3 references to vertices for each triangle 97 idList<surfaceEdge_t, TAG_IDLIB_LIST_SURFACE> edges; // edges 98 idList<int, TAG_IDLIB_LIST_SURFACE> edgeIndexes; // 3 references to edges for each triangle, may be negative for reversed edge 99 100 protected: 101 void GenerateEdgeIndexes(); 102 int FindEdge( int v1, int v2 ) const; 103 }; 104 105 /* 106 ==================== 107 idSurface::idSurface 108 ==================== 109 */ 110 ID_INLINE idSurface::idSurface() { 111 } 112 113 /* 114 ================= 115 idSurface::idSurface 116 ================= 117 */ 118 ID_INLINE idSurface::idSurface( const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { 119 assert( verts != NULL && indexes != NULL && numVerts > 0 && numIndexes > 0 ); 120 this->verts.SetNum( numVerts ); 121 memcpy( this->verts.Ptr(), verts, numVerts * sizeof( verts[0] ) ); 122 this->indexes.SetNum( numIndexes ); 123 memcpy( this->indexes.Ptr(), indexes, numIndexes * sizeof( indexes[0] ) ); 124 GenerateEdgeIndexes(); 125 } 126 127 /* 128 ==================== 129 idSurface::idSurface 130 ==================== 131 */ 132 ID_INLINE idSurface::idSurface( const idSurface &surf ) { 133 this->verts = surf.verts; 134 this->indexes = surf.indexes; 135 this->edges = surf.edges; 136 this->edgeIndexes = surf.edgeIndexes; 137 } 138 139 /* 140 ==================== 141 idSurface::~idSurface 142 ==================== 143 */ 144 ID_INLINE idSurface::~idSurface() { 145 } 146 147 /* 148 ================= 149 idSurface::operator[] 150 ================= 151 */ 152 ID_INLINE const idDrawVert &idSurface::operator[]( const int index ) const { 153 return verts[ index ]; 154 }; 155 156 /* 157 ================= 158 idSurface::operator[] 159 ================= 160 */ 161 ID_INLINE idDrawVert &idSurface::operator[]( const int index ) { 162 return verts[ index ]; 163 }; 164 165 /* 166 ================= 167 idSurface::operator+= 168 ================= 169 */ 170 ID_INLINE idSurface &idSurface::operator+=( const idSurface &surf ) { 171 int i, m, n; 172 n = verts.Num(); 173 m = indexes.Num(); 174 verts.Append( surf.verts ); // merge verts where possible ? 175 indexes.Append( surf.indexes ); 176 for ( i = m; i < indexes.Num(); i++ ) { 177 indexes[i] += n; 178 } 179 GenerateEdgeIndexes(); 180 return *this; 181 } 182 183 /* 184 ================= 185 idSurface::Clear 186 ================= 187 */ 188 ID_INLINE void idSurface::Clear() { 189 verts.Clear(); 190 indexes.Clear(); 191 edges.Clear(); 192 edgeIndexes.Clear(); 193 } 194 195 /* 196 ================= 197 idSurface::TranslateSelf 198 ================= 199 */ 200 ID_INLINE void idSurface::TranslateSelf( const idVec3 &translation ) { 201 for ( int i = 0; i < verts.Num(); i++ ) { 202 verts[i].xyz += translation; 203 } 204 } 205 206 /* 207 ================= 208 idSurface::RotateSelf 209 ================= 210 */ 211 ID_INLINE void idSurface::RotateSelf( const idMat3 &rotation ) { 212 for ( int i = 0; i < verts.Num(); i++ ) { 213 verts[i].xyz *= rotation; 214 verts[i].SetNormal( verts[i].GetNormal() * rotation ); 215 verts[i].SetTangent( verts[i].GetTangent() * rotation ); 216 } 217 } 218 219 #endif /* !__SURFACE_H__ */