doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Surface_SweptSpline.cpp
Go to the documentation of this file.
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 #include "../precompiled.h"
30 #pragma hdrstop
31 
32 
33 /*
34 ====================
35 idSurface_SweptSpline::SetSpline
36 ====================
37 */
39  if ( this->spline ) {
40  delete this->spline;
41  }
42  this->spline = spline;
43 }
44 
45 /*
46 ====================
47 idSurface_SweptSpline::SetSweptSpline
48 ====================
49 */
51  if ( this->sweptSpline ) {
52  delete this->sweptSpline;
53  }
54  this->sweptSpline = sweptSpline;
55 }
56 
57 /*
58 ====================
59 idSurface_SweptSpline::SetSweptCircle
60 
61  Sets the swept spline to a NURBS circle.
62 ====================
63 */
64 void idSurface_SweptSpline::SetSweptCircle( const float radius ) {
66  nurbs->Clear();
67  nurbs->AddValue( 0.0f, idVec4( radius, radius, 0.0f, 0.00f ) );
68  nurbs->AddValue( 100.0f, idVec4( -radius, radius, 0.0f, 0.25f ) );
69  nurbs->AddValue( 200.0f, idVec4( -radius, -radius, 0.0f, 0.50f ) );
70  nurbs->AddValue( 300.0f, idVec4( radius, -radius, 0.0f, 0.75f ) );
72  nurbs->SetCloseTime( 100.0f );
73  if ( sweptSpline ) {
74  delete sweptSpline;
75  }
76  sweptSpline = nurbs;
77 }
78 
79 /*
80 ====================
81 idSurface_SweptSpline::GetFrame
82 ====================
83 */
84 void idSurface_SweptSpline::GetFrame( const idMat3 &previousFrame, const idVec3 dir, idMat3 &newFrame ) {
85  float wx, wy, wz;
86  float xx, yy, yz;
87  float xy, xz, zz;
88  float x2, y2, z2;
89  float a, c, s, x, y, z;
90  idVec3 d, v;
91  idMat3 axis;
92 
93  d = dir;
94  d.Normalize();
95  v = d.Cross( previousFrame[2] );
96  v.Normalize();
97 
98  a = idMath::ACos( previousFrame[2] * d ) * 0.5f;
99  c = idMath::Cos( a );
100  s = idMath::Sqrt( 1.0f - c * c );
101 
102  x = v[0] * s;
103  y = v[1] * s;
104  z = v[2] * s;
105 
106  x2 = x + x;
107  y2 = y + y;
108  z2 = z + z;
109  xx = x * x2;
110  xy = x * y2;
111  xz = x * z2;
112  yy = y * y2;
113  yz = y * z2;
114  zz = z * z2;
115  wx = c * x2;
116  wy = c * y2;
117  wz = c * z2;
118 
119  axis[0][0] = 1.0f - ( yy + zz );
120  axis[0][1] = xy - wz;
121  axis[0][2] = xz + wy;
122  axis[1][0] = xy + wz;
123  axis[1][1] = 1.0f - ( xx + zz );
124  axis[1][2] = yz - wx;
125  axis[2][0] = xz - wy;
126  axis[2][1] = yz + wx;
127  axis[2][2] = 1.0f - ( xx + yy );
128 
129  newFrame = previousFrame * axis;
130 
131  newFrame[2] = dir;
132  newFrame[2].Normalize();
133  newFrame[1].Cross( newFrame[ 2 ], newFrame[ 0 ] );
134  newFrame[1].Normalize();
135  newFrame[0].Cross( newFrame[ 1 ], newFrame[ 2 ] );
136  newFrame[0].Normalize();
137 }
138 
139 /*
140 ====================
141 idSurface_SweptSpline::Tessellate
142 
143  tesselate the surface
144 ====================
145 */
146 void idSurface_SweptSpline::Tessellate( const int splineSubdivisions, const int sweptSplineSubdivisions ) {
147  int i, j, offset, baseOffset, splineDiv, sweptSplineDiv;
148  int i0, i1, j0, j1;
149  float totalTime, t;
150  idVec4 splinePos, splineD1;
151  idMat3 splineMat;
152 
153  if ( !spline || !sweptSpline ) {
155  return;
156  }
157 
158  verts.SetNum( splineSubdivisions * sweptSplineSubdivisions, false );
159 
160  // calculate the points and first derivatives for the swept spline
162  sweptSplineDiv = sweptSpline->GetBoundaryType() == idCurve_Spline<idVec3>::BT_CLOSED ? sweptSplineSubdivisions : sweptSplineSubdivisions - 1;
163  baseOffset = (splineSubdivisions-1) * sweptSplineSubdivisions;
164  for ( i = 0; i < sweptSplineSubdivisions; i++ ) {
165  t = totalTime * i / sweptSplineDiv;
166  splinePos = sweptSpline->GetCurrentValue( t );
167  splineD1 = sweptSpline->GetCurrentFirstDerivative( t );
168  verts[baseOffset+i].xyz = splinePos.ToVec3();
169  verts[baseOffset+i].st[0] = splinePos.w;
170  verts[baseOffset+i].tangents[0] = splineD1.ToVec3();
171  }
172 
173  // sweep the spline
174  totalTime = spline->GetTime( spline->GetNumValues() - 1 ) - spline->GetTime( 0 ) + spline->GetCloseTime();
175  splineDiv = spline->GetBoundaryType() == idCurve_Spline<idVec3>::BT_CLOSED ? splineSubdivisions : splineSubdivisions - 1;
176  splineMat.Identity();
177  for ( i = 0; i < splineSubdivisions; i++ ) {
178  t = totalTime * i / splineDiv;
179 
180  splinePos = spline->GetCurrentValue( t );
181  splineD1 = spline->GetCurrentFirstDerivative( t );
182 
183  GetFrame( splineMat, splineD1.ToVec3(), splineMat );
184 
185  offset = i * sweptSplineSubdivisions;
186  for ( j = 0; j < sweptSplineSubdivisions; j++ ) {
187  idDrawVert *v = &verts[offset+j];
188  v->xyz = splinePos.ToVec3() + verts[baseOffset+j].xyz * splineMat;
189  v->st[0] = verts[baseOffset+j].st[0];
190  v->st[1] = splinePos.w;
191  v->tangents[0] = verts[baseOffset+j].tangents[0] * splineMat;
192  v->tangents[1] = splineD1.ToVec3();
193  v->normal = v->tangents[1].Cross( v->tangents[0] );
194  v->normal.Normalize();
195  v->color[0] = v->color[1] = v->color[2] = v->color[3] = 0;
196  }
197  }
198 
199  indexes.SetNum( splineDiv * sweptSplineDiv * 2 * 3, false );
200 
201  // create indexes for the triangles
202  for ( offset = i = 0; i < splineDiv; i++ ) {
203 
204  i0 = (i+0) * sweptSplineSubdivisions;
205  i1 = (i+1) % splineSubdivisions * sweptSplineSubdivisions;
206 
207  for ( j = 0; j < sweptSplineDiv; j++ ) {
208 
209  j0 = (j+0);
210  j1 = (j+1) % sweptSplineSubdivisions;
211 
212  indexes[offset++] = i0 + j0;
213  indexes[offset++] = i0 + j1;
214  indexes[offset++] = i1 + j1;
215 
216  indexes[offset++] = i1 + j1;
217  indexes[offset++] = i1 + j0;
218  indexes[offset++] = i0 + j0;
219  }
220  }
221 
223 }
void SetSweptSpline(idCurve_Spline< idVec4 > *sweptSpline)
idCurve_Spline< idVec4 > * sweptSpline
virtual boundary_t GetBoundaryType(void) const
Definition: Curve.h:940
float Normalize(void)
Definition: Vector.h:646
idList< idDrawVert > verts
Definition: Surface.h:96
idCurve_Spline< idVec4 > * spline
GLint GLint GLint j1
Definition: qgl.h:262
const GLdouble * v
Definition: glext.h:2936
GLdouble GLdouble x2
Definition: qgl.h:415
void SetNum(int newnum, bool resize=true)
Definition: List.h:289
idVec3 xyz
Definition: DrawVert.h:42
GLenum GLint GLint y
Definition: glext.h:2849
virtual void SetBoundaryType(const boundary_t bt)
Definition: Curve.h:939
idVec3 tangents[2]
Definition: DrawVert.h:45
Definition: Vector.h:316
static float Sqrt(float x)
Definition: Math.h:302
void Clear(void)
Definition: Surface.h:189
GLdouble s
Definition: glext.h:2935
virtual float GetCloseTime(void)
Definition: Curve.h:943
idVec3 Cross(const idVec3 &a) const
Definition: Vector.h:619
void Identity(void)
Definition: Matrix.h:591
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
GLintptr offset
Definition: glext.h:3113
virtual void SetCloseTime(const float t)
Definition: Curve.h:942
idVec2 st
Definition: DrawVert.h:43
idList< int > indexes
Definition: Surface.h:97
const GLubyte * c
Definition: glext.h:4677
Definition: Vector.h:808
void SetSweptCircle(const float radius)
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:134
virtual void Clear(void)
Definition: Curve.h:2338
float w
Definition: Vector.h:813
idVec3 normal
Definition: DrawVert.h:44
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:153
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
GLdouble GLdouble GLdouble y2
Definition: qgl.h:415
float GetTime(const int index) const
Definition: Curve.h:60
void Tessellate(const int splineSubdivisions, const int sweptSplineSubdivisions)
Definition: Matrix.h:333
void GenerateEdgeIndexes(void)
Definition: Surface.cpp:841
virtual int AddValue(const float time, const type &value)
Definition: Curve.h:2368
tuple f
Definition: idal.py:89
byte color[4]
Definition: DrawVert.h:46
GLint i1
Definition: qgl.h:261
void GetFrame(const idMat3 &previousFrame, const idVec3 dir, idMat3 &newFrame)
const idVec3 & ToVec3(void) const
Definition: Vector.h:1043
GLint j
Definition: qgl.h:264
int GetNumValues(void) const
Definition: Curve.h:56
static float ACos(float a)
Definition: Math.h:544
void SetSpline(idCurve_Spline< idVec4 > *spline)
GLdouble GLdouble z
Definition: glext.h:3067
GLdouble GLdouble t
Definition: glext.h:2943
static float Cos(float a)
Definition: Math.h:346