DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

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__ */