doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Model_prt.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 "../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "tr_local.h"
33 #include "Model_local.h"
34 
35 static const char *parametricParticle_SnapshotName = "_ParametricParticle_Snapshot_";
36 
37 /*
38 ====================
39 idRenderModelPrt::idRenderModelPrt
40 ====================
41 */
44 }
45 
46 /*
47 ====================
48 idRenderModelPrt::InitFromFile
49 ====================
50 */
51 void idRenderModelPrt::InitFromFile( const char *fileName ) {
52  name = fileName;
53  particleSystem = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, fileName ) );
54 }
55 
56 /*
57 =================
58 idRenderModelPrt::TouchData
59 =================
60 */
62  // Ensure our particle system is added to the list of referenced decls
63  particleSystem = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, name ) );
64 }
65 
66 /*
67 ====================
68 idRenderModelPrt::InstantiateDynamicModel
69 ====================
70 */
71 idRenderModel *idRenderModelPrt::InstantiateDynamicModel( const struct renderEntity_s *renderEntity, const struct viewDef_s *viewDef, idRenderModel *cachedModel ) {
72  idRenderModelStatic *staticModel;
73 
74  if ( cachedModel && !r_useCachedDynamicModels.GetBool() ) {
75  delete cachedModel;
76  cachedModel = NULL;
77  }
78 
79  // this may be triggered by a model trace or other non-view related source, to which we should look like an empty model
80  if ( renderEntity == NULL || viewDef == NULL ) {
81  delete cachedModel;
82  return NULL;
83  }
84 
85  if ( r_skipParticles.GetBool() ) {
86  delete cachedModel;
87  return NULL;
88  }
89 
90  /*
91  // if the entire system has faded out
92  if ( renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] && viewDef->renderView.time * 0.001f >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] ) {
93  delete cachedModel;
94  return NULL;
95  }
96  */
97 
98  if ( cachedModel != NULL ) {
99 
100  assert( dynamic_cast<idRenderModelStatic *>(cachedModel) != NULL );
101  assert( idStr::Icmp( cachedModel->Name(), parametricParticle_SnapshotName ) == 0 );
102 
103  staticModel = static_cast<idRenderModelStatic *>(cachedModel);
104 
105  } else {
106 
107  staticModel = new idRenderModelStatic;
108  staticModel->InitEmpty( parametricParticle_SnapshotName );
109  }
110 
112 
113  g.renderEnt = renderEntity;
114  g.renderView = &viewDef->renderView;
115  g.origin.Zero();
116  g.axis.Identity();
117 
118  for ( int stageNum = 0; stageNum < particleSystem->stages.Num(); stageNum++ ) {
119  idParticleStage *stage = particleSystem->stages[stageNum];
120 
121  if ( !stage->material ) {
122  continue;
123  }
124  if ( !stage->cycleMsec ) {
125  continue;
126  }
127  if ( stage->hidden ) { // just for gui particle editor use
128  staticModel->DeleteSurfaceWithId( stageNum );
129  continue;
130  }
131 
132  idRandom steppingRandom, steppingRandom2;
133 
134  int stageAge = g.renderView->time + renderEntity->shaderParms[SHADERPARM_TIMEOFFSET] * 1000 - stage->timeOffset * 1000;
135  int stageCycle = stageAge / stage->cycleMsec;
136  int inCycleTime = stageAge - stageCycle * stage->cycleMsec;
137 
138  // some particles will be in this cycle, some will be in the previous cycle
139  steppingRandom.SetSeed( (( stageCycle << 10 ) & idRandom::MAX_RAND) ^ (int)( renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND ) );
140  steppingRandom2.SetSeed( (( (stageCycle-1) << 10 ) & idRandom::MAX_RAND) ^ (int)( renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND ) );
141 
142  int count = stage->totalParticles * stage->NumQuadsPerParticle();
143 
144  int surfaceNum;
145  modelSurface_t *surf;
146 
147  if ( staticModel->FindSurfaceWithId( stageNum, surfaceNum ) ) {
148  surf = &staticModel->surfaces[surfaceNum];
150  } else {
151  surf = &staticModel->surfaces.Alloc();
152  surf->id = stageNum;
153  surf->shader = stage->material;
154  surf->geometry = R_AllocStaticTriSurf();
155  R_AllocStaticTriSurfVerts( surf->geometry, 4 * count );
156  R_AllocStaticTriSurfIndexes( surf->geometry, 6 * count );
157  R_AllocStaticTriSurfPlanes( surf->geometry, 6 * count );
158  }
159 
160  int numVerts = 0;
161  idDrawVert *verts = surf->geometry->verts;
162 
163  for ( int index = 0; index < stage->totalParticles; index++ ) {
164  g.index = index;
165 
166  // bump the random
167  steppingRandom.RandomInt();
168  steppingRandom2.RandomInt();
169 
170  // calculate local age for this index
171  int bunchOffset = stage->particleLife * 1000 * stage->spawnBunching * index / stage->totalParticles;
172 
173  int particleAge = stageAge - bunchOffset;
174  int particleCycle = particleAge / stage->cycleMsec;
175  if ( particleCycle < 0 ) {
176  // before the particleSystem spawned
177  continue;
178  }
179  if ( stage->cycles && particleCycle >= stage->cycles ) {
180  // cycled systems will only run cycle times
181  continue;
182  }
183 
184  if ( particleCycle == stageCycle ) {
185  g.random = steppingRandom;
186  } else {
187  g.random = steppingRandom2;
188  }
189 
190  int inCycleTime = particleAge - particleCycle * stage->cycleMsec;
191 
192  if ( renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] &&
193  g.renderView->time - inCycleTime >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME]*1000 ) {
194  // don't fire any more particles
195  continue;
196  }
197 
198  // supress particles before or after the age clamp
199  g.frac = (float)inCycleTime / ( stage->particleLife * 1000 );
200  if ( g.frac < 0.0f ) {
201  // yet to be spawned
202  continue;
203  }
204  if ( g.frac > 1.0f ) {
205  // this particle is in the deadTime band
206  continue;
207  }
208 
209  // this is needed so aimed particles can calculate origins at different times
210  g.originalRandom = g.random;
211 
212  g.age = g.frac * stage->particleLife;
213 
214  // if the particle doesn't get drawn because it is faded out or beyond a kill region, don't increment the verts
215  numVerts += stage->CreateParticle( &g, verts + numVerts );
216  }
217 
218  // numVerts must be a multiple of 4
219  assert( ( numVerts & 3 ) == 0 && numVerts <= 4 * count );
220 
221  // build the indexes
222  int numIndexes = 0;
223  glIndex_t *indexes = surf->geometry->indexes;
224  for ( int i = 0; i < numVerts; i += 4 ) {
225  indexes[numIndexes+0] = i;
226  indexes[numIndexes+1] = i+2;
227  indexes[numIndexes+2] = i+3;
228  indexes[numIndexes+3] = i;
229  indexes[numIndexes+4] = i+3;
230  indexes[numIndexes+5] = i+1;
231  numIndexes += 6;
232  }
233 
234  surf->geometry->tangentsCalculated = false;
235  surf->geometry->facePlanesCalculated = false;
236  surf->geometry->numVerts = numVerts;
237  surf->geometry->numIndexes = numIndexes;
238  surf->geometry->bounds = stage->bounds; // just always draw the particles
239  }
240 
241  return staticModel;
242 }
243 
244 /*
245 ====================
246 idRenderModelPrt::IsDynamicModel
247 ====================
248 */
250  return DM_CONTINUOUS;
251 }
252 
253 /*
254 ====================
255 idRenderModelPrt::Bounds
256 ====================
257 */
259  return particleSystem->bounds;
260 }
261 
262 /*
263 ====================
264 idRenderModelPrt::DepthHack
265 ====================
266 */
268  return particleSystem->depthHack;
269 }
270 
271 /*
272 ====================
273 idRenderModelPrt::Memory
274 ====================
275 */
277  int total = 0;
278 
279  total += idRenderModelStatic::Memory();
280 
281  if ( particleSystem ) {
282  total += sizeof( *particleSystem );
283 
284  for ( int i = 0; i < particleSystem->stages.Num(); i++ ) {
285  total += sizeof( particleSystem->stages[i] );
286  }
287  }
288 
289  return total;
290 }
GLubyte g
Definition: glext.h:4662
idCVar r_skipParticles("r_skipParticles","0", CVAR_RENDERER|CVAR_INTEGER,"1 = skip all particle systems", 0, 1, idCmdSystem::ArgCompletion_Integer< 0, 1 >)
virtual float DepthHack() const
Definition: Model_prt.cpp:267
bool FindSurfaceWithId(int id, int &surfaceNum)
Definition: Model.cpp:2318
idList< modelSurface_t > surfaces
Definition: Model_local.h:106
assert(prefInfo.fullscreenBtn)
const int SHADERPARM_DIVERSITY
Definition: RenderWorld.h:52
virtual int Memory() const
Definition: Model.cpp:111
int numVerts
Definition: Model.h:98
const idMaterial * shader
Definition: Model.h:146
case const float
Definition: Callbacks.cpp:62
bool facePlanesCalculated
Definition: Model.h:93
const renderEntity_t * renderEnt
Definition: DeclParticle.h:86
virtual const char * Name() const =0
static const int MAX_RAND
Definition: Random.h:52
bool tangentsCalculated
Definition: Model.h:92
srfTriangles_t * R_AllocStaticTriSurf(void)
Definition: tr_trisurf.cpp:523
void Identity(void)
Definition: Matrix.h:591
bool DeleteSurfaceWithId(int id)
Definition: Model.cpp:2283
int i
Definition: process.py:33
int Icmp(const char *text) const
Definition: Str.h:667
virtual idRenderModel * InstantiateDynamicModel(const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel)
Definition: Model_prt.cpp:71
idRandom originalRandom
Definition: DeclParticle.h:96
int RandomInt(void)
Definition: Random.h:70
GLuint GLuint GLsizei count
Definition: glext.h:2845
virtual void InitEmpty(const char *name)
Definition: Model.cpp:332
void SetSeed(int seed)
Definition: Random.h:62
GLuint index
Definition: glext.h:3476
void R_AllocStaticTriSurfPlanes(srfTriangles_t *tri, int numIndexes)
Definition: tr_trisurf.cpp:585
idBounds bounds
Definition: Model.h:87
renderView_t renderView
Definition: tr_local.h:370
#define NULL
Definition: Lib.h:88
srfTriangles_t * geometry
Definition: Model.h:147
virtual int CreateParticle(particleGen_t *g, idDrawVert *verts) const
int glIndex_t
Definition: Model.h:52
virtual const idDecl * FindType(declType_t type, const char *name, bool makeDefault=true)=0
const renderView_t * renderView
Definition: DeclParticle.h:87
virtual dynamicModel_t IsDynamicModel() const
Definition: Model_prt.cpp:249
const idMaterial * material
Definition: DeclParticle.h:128
virtual idBounds Bounds(const struct renderEntity_s *ent) const
Definition: Model_prt.cpp:258
const int SHADERPARM_TIMEOFFSET
Definition: RenderWorld.h:51
idList< idParticleStage * > stages
Definition: DeclParticle.h:204
idBounds bounds
Definition: DeclParticle.h:205
idDeclManager * declManager
idRandom random
Definition: DeclParticle.h:90
virtual void InitFromFile(const char *fileName)
Definition: Model_prt.cpp:51
idCVar r_useCachedDynamicModels("r_useCachedDynamicModels","1", CVAR_RENDERER|CVAR_BOOL,"cache snapshots of dynamic models")
bool GetBool(void) const
Definition: CVarSystem.h:142
int Num(void) const
Definition: List.h:265
dynamicModel_t
Definition: Model.h:150
const GLcharARB * name
Definition: glext.h:3629
glIndex_t * indexes
Definition: Model.h:102
void R_AllocStaticTriSurfIndexes(srfTriangles_t *tri, int numIndexes)
Definition: tr_trisurf.cpp:565
int numIndexes
Definition: Model.h:101
virtual void TouchData()
Definition: Model_prt.cpp:61
void R_AllocStaticTriSurfVerts(srfTriangles_t *tri, int numVerts)
Definition: tr_trisurf.cpp:555
void Zero(void)
Definition: Vector.h:415
float shaderParms[MAX_ENTITY_SHADER_PARMS]
Definition: RenderWorld.h:127
void R_FreeStaticTriSurfVertexCaches(srfTriangles_t *tri)
Definition: tr_trisurf.cpp:343
virtual int NumQuadsPerParticle() const
idDrawVert * verts
Definition: Model.h:99
virtual int Memory() const
Definition: Model_prt.cpp:276
const idDeclParticle * particleSystem
Definition: Model_local.h:300
const int SHADERPARM_PARTICLE_STOPTIME
Definition: RenderWorld.h:71