2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 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.
14 Doom 3 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.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 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 Source Code. If not, please request a copy in writing from id Software at the address below.
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.
26 ===========================================================================
33 ===============================================================================
37 A surface is tesselated to a triangle mesh with each edge shared by
38 at most two triangles.
40 ===============================================================================
43 typedef struct surfaceEdge_s {
44 int verts[2]; // edge vertices always with ( verts[0] < verts[1] )
45 int tris[2]; // edge triangles
52 explicit idSurface( const idSurface &surf );
53 explicit idSurface( const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes );
56 const idDrawVert & operator[]( const int index ) const;
57 idDrawVert & operator[]( const int index );
58 idSurface & operator+=( const idSurface &surf );
60 int GetNumIndexes( void ) const { return indexes.Num(); }
61 const int * GetIndexes( void ) const { return indexes.Ptr(); }
62 int GetNumVertices( void ) const { return verts.Num(); }
63 const idDrawVert * GetVertices( void ) const { return verts.Ptr(); }
64 const int * GetEdgeIndexes( void ) const { return edgeIndexes.Ptr(); }
65 const surfaceEdge_t * GetEdges( void ) const { return edges.Ptr(); }
68 void SwapTriangles( idSurface &surf );
69 void TranslateSelf( const idVec3 &translation );
70 void RotateSelf( const idMat3 &rotation );
72 // splits the surface into a front and back surface, the surface itself stays unchanged
73 // frontOnPlaneEdges and backOnPlaneEdges optionally store the indexes to the edges that lay on the split plane
75 int Split( const idPlane &plane, const float epsilon, idSurface **front, idSurface **back, int *frontOnPlaneEdges = NULL, int *backOnPlaneEdges = NULL ) const;
76 // cuts off the part at the back side of the plane, returns true if some part was at the front
77 // if there is nothing at the front the number of points is set to zero
78 bool ClipInPlace( const idPlane &plane, const float epsilon = ON_EPSILON, const bool keepOn = false );
80 // returns true if each triangle can be reached from any other triangle by a traversal
81 bool IsConnected( void ) const;
82 // returns true if the surface is closed
83 bool IsClosed( void ) const;
84 // returns true if the surface is a convex hull
85 bool IsPolytope( const float epsilon = 0.1f ) const;
87 float PlaneDistance( const idPlane &plane ) const;
88 int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const;
90 // returns true if the line intersects one of the surface triangles
91 bool LineIntersection( const idVec3 &start, const idVec3 &end, bool backFaceCull = false ) const;
92 // intersection point is start + dir * scale
93 bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull = false ) const;
96 idList<idDrawVert> verts; // vertices
97 idList<int> indexes; // 3 references to vertices for each triangle
98 idList<surfaceEdge_t> edges; // edges
99 idList<int> edgeIndexes; // 3 references to edges for each triangle, may be negative for reversed edge
102 void GenerateEdgeIndexes( void );
103 int FindEdge( int v1, int v2 ) const;
111 ID_INLINE idSurface::idSurface( void ) {
119 ID_INLINE idSurface::idSurface( const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) {
120 assert( verts != NULL && indexes != NULL && numVerts > 0 && numIndexes > 0 );
121 this->verts.SetNum( numVerts );
122 memcpy( this->verts.Ptr(), verts, numVerts * sizeof( verts[0] ) );
123 this->indexes.SetNum( numIndexes );
124 memcpy( this->indexes.Ptr(), indexes, numIndexes * sizeof( indexes[0] ) );
125 GenerateEdgeIndexes();
133 ID_INLINE idSurface::idSurface( const idSurface &surf ) {
134 this->verts = surf.verts;
135 this->indexes = surf.indexes;
136 this->edges = surf.edges;
137 this->edgeIndexes = surf.edgeIndexes;
142 idSurface::~idSurface
145 ID_INLINE idSurface::~idSurface( void ) {
150 idSurface::operator[]
153 ID_INLINE const idDrawVert &idSurface::operator[]( const int index ) const {
154 return verts[ index ];
159 idSurface::operator[]
162 ID_INLINE idDrawVert &idSurface::operator[]( const int index ) {
163 return verts[ index ];
168 idSurface::operator+=
171 ID_INLINE idSurface &idSurface::operator+=( const idSurface &surf ) {
175 verts.Append( surf.verts ); // merge verts where possible ?
176 indexes.Append( surf.indexes );
177 for ( i = m; i < indexes.Num(); i++ ) {
180 GenerateEdgeIndexes();
189 ID_INLINE void idSurface::Clear( void ) {
198 idSurface::SwapTriangles
201 ID_INLINE void idSurface::SwapTriangles( idSurface &surf ) {
202 verts.Swap( surf.verts );
203 indexes.Swap( surf.indexes );
204 edges.Swap( surf.edges );
205 edgeIndexes.Swap( surf.edgeIndexes );
210 idSurface::TranslateSelf
213 ID_INLINE void idSurface::TranslateSelf( const idVec3 &translation ) {
214 for ( int i = 0; i < verts.Num(); i++ ) {
215 verts[i].xyz += translation;
221 idSurface::RotateSelf
224 ID_INLINE void idSurface::RotateSelf( const idMat3 &rotation ) {
225 for ( int i = 0; i < verts.Num(); i++ ) {
226 verts[i].xyz *= rotation;
227 verts[i].normal *= rotation;
228 verts[i].tangents[0] *= rotation;
229 verts[i].tangents[1] *= rotation;
233 #endif /* !__SURFACE_H__ */