]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/idlib/geometry/Surface.h
hello world
[icculus/iodoom3.git] / neo / idlib / geometry / Surface.h
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
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.
13
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.
18
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/>.
21
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.
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( void );
52                                                         explicit idSurface( const idSurface &surf );
53                                                         explicit idSurface( const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes );
54                                                         ~idSurface( void );
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( 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(); }
66
67         void                                    Clear( void );
68         void                                    SwapTriangles( idSurface &surf );
69         void                                    TranslateSelf( const idVec3 &translation );
70         void                                    RotateSelf( const idMat3 &rotation );
71
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
74                                                         // returns a SIDE_?
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 );
79
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;
86
87         float                                   PlaneDistance( const idPlane &plane ) const;
88         int                                             PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const;
89
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;
94
95 protected:
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
100
101 protected:
102         void                                    GenerateEdgeIndexes( void );
103         int                                             FindEdge( int v1, int v2 ) const;
104 };
105
106 /*
107 ====================
108 idSurface::idSurface
109 ====================
110 */
111 ID_INLINE idSurface::idSurface( void ) {
112 }
113
114 /*
115 =================
116 idSurface::idSurface
117 =================
118 */
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();
126 }
127
128 /*
129 ====================
130 idSurface::idSurface
131 ====================
132 */
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;
138 }
139
140 /*
141 ====================
142 idSurface::~idSurface
143 ====================
144 */
145 ID_INLINE idSurface::~idSurface( void ) {
146 }
147
148 /*
149 =================
150 idSurface::operator[]
151 =================
152 */
153 ID_INLINE const idDrawVert &idSurface::operator[]( const int index ) const {
154         return verts[ index ];
155 };
156
157 /*
158 =================
159 idSurface::operator[]
160 =================
161 */
162 ID_INLINE idDrawVert &idSurface::operator[]( const int index ) {
163         return verts[ index ];
164 };
165
166 /*
167 =================
168 idSurface::operator+=
169 =================
170 */
171 ID_INLINE idSurface &idSurface::operator+=( const idSurface &surf ) {
172         int i, m, n;
173         n = verts.Num();
174         m = indexes.Num();
175         verts.Append( surf.verts );                     // merge verts where possible ?
176         indexes.Append( surf.indexes );
177         for ( i = m; i < indexes.Num(); i++ ) {
178                 indexes[i] += n;
179         }
180         GenerateEdgeIndexes();
181         return *this;
182 }
183
184 /*
185 =================
186 idSurface::Clear
187 =================
188 */
189 ID_INLINE void idSurface::Clear( void ) {
190         verts.Clear();
191         indexes.Clear();
192         edges.Clear();
193         edgeIndexes.Clear();
194 }
195
196 /*
197 =================
198 idSurface::SwapTriangles
199 =================
200 */
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 );
206 }
207
208 /*
209 =================
210 idSurface::TranslateSelf
211 =================
212 */
213 ID_INLINE void idSurface::TranslateSelf( const idVec3 &translation ) {
214         for ( int i = 0; i < verts.Num(); i++ ) {
215                 verts[i].xyz += translation;
216         }
217 }
218
219 /*
220 =================
221 idSurface::RotateSelf
222 =================
223 */
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;
230         }
231 }
232
233 #endif /* !__SURFACE_H__ */