Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
part_emt.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***************************************************************************
22 * *
23 * Project Name : G *
24 * *
25 * $Archive:: /Commando/Code/ww3d2/part_emt.cpp $*
26 * *
27 * $Org Author:: Jani_p $*
28 * *
29 * $Author:: Kenny_m $*
30 * *
31 * $Modtime:: 08/05/02 10:44a $*
32 * *
33 * $Revision:: 14 $*
34 * *
35 * 08/05/02 KM Texture class redesign
36 *-------------------------------------------------------------------------*
37 * Functions: *
38 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
39
40#include "part_emt.h"
41#include "wwdebug.h"
42#include "ww3d.h"
43#include "assetmgr.h"
44#include "part_ldr.h"
45#include "w3derr.h"
46#include "scene.h"
47#include "texture.h"
48#include "wwprofile.h"
49#include <limits.h>
50#include <gcd_lcm.h>
51#include "texture.h"
52#include "part_ldr.h"
53
54
55// Global variable which is only used to communicate the worldspace emitter
56// velocity from ParticleEmitterClass::Create_New_Particles() to
57// ParticleEmitterClass::Initialize_Particle(), for velocity inheritance.
59
60// This debug setting disables particles from being generated
61bool ParticleEmitterClass::DebugDisable = false;
62
63// This is used to set the global behavior of emitters...
64// Should they be removed from the scene when they complete their
65// emissions, or should they stay in the scene. (For editing purposes)
66// (gth) 09/17/2000 - particle emitters now have a local RemoveOnComplete flag
67// which is initialized to the state of DefaultRemoveOnComplete.
68bool ParticleEmitterClass::DefaultRemoveOnComplete = true;
69
70
71ParticleEmitterClass::ParticleEmitterClass(float emit_rate, unsigned int burst_size,
72 Vector3Randomizer *pos_rnd, Vector3 base_vel, Vector3Randomizer *vel_rnd, float out_vel,
73 float vel_inherit_factor,
77 ParticlePropertyStruct<float> &rotation, float orient_rnd,
80 Vector3 accel, float max_age, float future_start, TextureClass *tex, ShaderClass shader, int max_particles,
81 int max_buffer_size, bool pingpong,int render_mode,int frame_mode,
82 const W3dEmitterLinePropertiesStruct * line_props
83) :
85 EmitRate(emit_rate > 0.0f ? (unsigned int)(1000.0f / emit_rate) : 1000U),
86 BurstSize(burst_size != 0 ? burst_size : 1),
87 OneTimeBurstSize(1),
88 OneTimeBurst(false),
89 PosRand(pos_rnd),
90 BaseVel(base_vel * 0.001f),
91 VelRand(vel_rnd),
92 OutwardVel(out_vel * 0.001f),
93 VelInheritFactor(vel_inherit_factor),
94 EmitRemain(0U),
95 PrevQ(true),
96 PrevOrig(0.0, 0.0, 0.0),
97 Active(false),
98 FirstTime(true),
99 BufferSceneNeeded(true),
100 ParticlesLeft(max_particles),
101 MaxParticles(max_particles),
102 IsComplete(false),
103 NameString(::_strdup ("ParticleEmitter")),
104 UserString(NULL),
105 RemoveOnComplete(DefaultRemoveOnComplete),
106 IsInScene(false),
107 GroupID(0),
108 Buffer(NULL),
109 IsInvisible(false)
110{
111 max_age = max_age > 0.0f ? max_age : 1.0f;
112 VelRand->Scale(0.001f);
113
114 // The maximum number of particles is determined by the emission rate, burst size and lifetime.
115 // However, it is capped both by the particle cap and by the maximum buffer size, if these are
116 // active.
117 int max_num = BurstSize * emit_rate * (max_age + 1);
118 if (max_particles > 0) max_num = MIN(max_num, max_particles);
119 if (max_buffer_size > 0) max_num = MIN(max_num, max_buffer_size);
120 max_num = MAX(max_num, 2); // max_num of 1 causes problems
121
122 Buffer = W3DNEW ParticleBufferClass(this, max_num, color, opacity, size, rotation, orient_rnd,
123 frames, blur_times, accel/1000000.0f,max_age, future_start, tex, shader, pingpong, render_mode, frame_mode,
124 line_props);
125 SET_REF_OWNER( Buffer );
126}
127
128
130 RenderObjClass(src),
131 EmitRate(src.EmitRate),
132 BurstSize(src.BurstSize),
133 OneTimeBurstSize(src.OneTimeBurstSize),
134 OneTimeBurst(src.OneTimeBurst),
135 PosRand(src.PosRand ? src.PosRand->Clone() : NULL),
136 BaseVel(src.BaseVel),
137 VelRand(src.VelRand ? src.VelRand->Clone() : NULL),
138 OutwardVel(src.OutwardVel),
139 VelInheritFactor(src.VelInheritFactor),
140 EmitRemain(src.EmitRemain),
141 PrevQ(src.PrevQ),
142 PrevOrig(src.PrevOrig),
143 Active(true), // default to on
144 FirstTime(true),
145 BufferSceneNeeded(true),
146 ParticlesLeft(src.ParticlesLeft),
147 MaxParticles(src.MaxParticles),
148 IsComplete(false),
149 NameString(::_strdup (src.NameString)),
150 UserString(::_strdup (src.UserString)),
151 RemoveOnComplete(src.RemoveOnComplete),
152 IsInScene(false),
153 GroupID(0),
154 Buffer(NULL),
155 IsInvisible(src.IsInvisible)
156{
157 Buffer = (ParticleBufferClass *) src.Buffer->Clone();
158 Buffer->Set_Emitter(this);
159 SET_REF_OWNER( Buffer );
160}
161
162
164{
166
167 if (this != &that) {
168 assert(0); // TODO: if you hit this assert, please implement me !!!;-)
169 }
170
171 return * this;
172}
173
174
176{
177 Buffer->Emitter_Is_Dead();
178 Buffer->Release_Ref();
179
180 if (PosRand != NULL) {
181 delete PosRand;
182 PosRand = NULL;
183 }
184
185 if (VelRand != NULL) {
186 delete VelRand;
187 VelRand = NULL;
188 }
189
190 if (NameString != NULL) {
191 ::free (NameString);
192 NameString = NULL;
193 }
194
195 if (UserString != NULL) {
196 ::free (UserString);
197 UserString = NULL;
198 }
199
200 return ;
201}
202
203
206{
207 // Assume failure
208 ParticleEmitterClass *pemitter = NULL;
209
210 // Attempt to load the texture for this emitter
211 const char *ptexture_filename = definition.Get_Texture_Filename ();
212 TextureClass *ptexture = NULL;
213 if (ptexture_filename && ptexture_filename[0]) {
215 (
216 ptexture_filename,
219 );
220// false); // no compression for particle textures!
221 }
222
223 ShaderClass shader;
224 definition.Get_Shader (shader);
225 if (WW3DAssetManager::Get_Instance()->Get_Activate_Fog_On_Load()) {
226 shader.Enable_Fog ("ParticleEmitterClass");
227 }
228 /*if (ptexture) {
229 // If texture has an alpha channel do alpha blending instead of additive
230 // (which is the default for point groups):
231 srTextureIFace::Dimensions dimensions;
232 ptexture->getDimensions(dimensions);
233 if (dimensions.pixelFormat.aBits > 0) {
234 shader = ShaderClass::_PresetAlphaSpriteShader;
235 }
236 }*/
237
238 //
239 // Peek at the definition's keyframes
240 //
244 ParticlePropertyStruct<float> rotation_keys;
246 ParticlePropertyStruct<float> blur_time_keys;
247
248 definition.Get_Color_Keyframes (color_keys);
249 definition.Get_Opacity_Keyframes (opacity_keys);
250 definition.Get_Size_Keyframes (size_keys);
251 definition.Get_Rotation_Keyframes (rotation_keys);
252 definition.Get_Frame_Keyframes (frame_keys);
253 definition.Get_Blur_Time_Keyframes (blur_time_keys);
254
255 //
256 // Create the emitter
257 //
258 pemitter = NEW_REF( ParticleEmitterClass, ( definition.Get_Emission_Rate (),
259 definition.Get_Burst_Size (),
260 definition.Get_Creation_Volume (),
261 definition.Get_Velocity (),
262 definition.Get_Velocity_Random (),
263 definition.Get_Outward_Vel (),
264 definition.Get_Vel_Inherit (),
265 color_keys,
266 opacity_keys,
267 size_keys,
268 rotation_keys,
270 frame_keys,
271 blur_time_keys,
272 definition.Get_Acceleration (),
273 definition.Get_Lifetime (),
274 definition.Get_Future_Start_Time(),
275 ptexture,
276 shader,
277 definition.Get_Max_Emissions (),
278 0,
279 false,
280 definition.Get_Render_Mode (),
281 definition.Get_Frame_Mode (),
282 definition.Get_Line_Properties ()) );
283
284 if (color_keys.KeyTimes != NULL) delete [] color_keys.KeyTimes;
285 if (color_keys.Values != NULL) delete [] color_keys.Values;
286 if (opacity_keys.KeyTimes != NULL) delete [] opacity_keys.KeyTimes;
287 if (opacity_keys.Values != NULL) delete [] opacity_keys.Values;
288 if (size_keys.KeyTimes != NULL) delete [] size_keys.KeyTimes;
289 if (size_keys.Values != NULL) delete [] size_keys.Values;
290 if (rotation_keys.KeyTimes != NULL) delete [] rotation_keys.KeyTimes;
291 if (rotation_keys.Values != NULL) delete [] rotation_keys.Values;
292 if (frame_keys.KeyTimes != NULL) delete [] frame_keys.KeyTimes;
293 if (frame_keys.Values != NULL) delete [] frame_keys.Values;
294 if (blur_time_keys.KeyTimes != NULL) delete [] blur_time_keys.KeyTimes;
295 if (blur_time_keys.Values != NULL) delete [] blur_time_keys.Values;
296
297 // Pass the name along to the emitter
298 pemitter->Set_Name (definition.Get_Name ());
299
300 // release our reference to particle texture.
301 if (ptexture) {
302 REF_PTR_RELEASE(ptexture);
303 ptexture = 0;
304 }
305
306 // Return a pointer to the new emitter
307 return pemitter;
308}
309
314
316{
317 // calling Start will cause all internal counters to reset
318 Start();
319}
320
322{
325 if (FirstTime == false) {
326 Active = true;
327 }
328 IsInScene = true;
329}
330
332{
335 Active = false;
336 IsInScene = false;
337
338 //Buffer->Emitter_Is_Dead();
339}
340
341// Scales the size of all particles and effects positions/velocities of
342// particles emitted after the Scale() call (but not before)
344{
345 // Scale all velosity and position parameters
346 if (PosRand) PosRand->Scale(scale);
347 BaseVel *= scale;
348 if (VelRand) VelRand->Scale(scale);
349 OutwardVel *= scale;
350
351 // Scale sizes of all particles
352 Buffer->Scale(scale);
353}
354
355// Put particle buffer in scene if this is the first time (clunky code
356// - hopefully can be rewritten more cleanly in future)...
358{
359 WWPROFILE("ParticleEmitterClass::On_Frame_Update");
360 if (Active && !IsComplete) {
361 if (FirstTime) {
362
363 // The particle buffer doesn't have a valid Scene yet - the emitter
364 // finds out what scene it belongs to (goes up the container tree
365 // until it finds a non-NULL Scene), and then adds the particle
366 // buffer to it.
367 if ( BufferSceneNeeded ) {
368
369 if (Is_In_Scene()) {
370 Buffer->Add(Scene);
371 BufferSceneNeeded = false;
372 } else {
373 return;
374 }
375
376 }
377 BufferSceneNeeded = false;
378
379 // Initialize previous transform:
381 PrevOrig = Get_Transform().Get_Translation();
382
383 FirstTime = false;
384 }
385 }
386
387 if (Is_Complete()) {
389 Scene->Register(this,SceneClass::RELEASE);
390 }
391 }
392}
393
395{
396 // Note: This flag needs to be set first thing, otherwise
397 // getting the transform will result in an 'update_x' call
398 // which in turn results in a 'Set_Animation_Hidden' call, which
399 // in turn will cause the Update_Visibilty function to call
400 // Start(). This won't cause a stack overflow like in Start
401 // but it would do some extra work.
402 Active = true;
403
404 // Initialize previous transform:
406 PrevOrig = Get_Transform().Get_Translation();
407
408 // Reset the number of particles to emit
409 ParticlesLeft = MaxParticles;
410 EmitRemain = 0;
411 IsComplete = false;
412}
413
415{
416 // Note: This flag needs to be set first thing, otherwise
417 // getting the transform will result in an 'update_x' call
418 // which in turn results in a 'Set_Animation_Hidden' call, which
419 // in turn will cause the Update_Visibilty function to call
420 // this method. And then... Stack Overflow! ;)
421 Active = true;
422
423 // Initialize previous transform:
425 PrevOrig = Get_Transform().Get_Translation();
426
427 // Reset the number of particles to emit (if necessary)
428 if (IsComplete == true) {
429 ParticlesLeft = MaxParticles;
430 IsComplete = false;
431 }
432
433 // This is to keep track of particles so that
434 // the line segments can start and stop properly
435 GroupID++;
436 Buffer->Set_Current_GroupID(GroupID);
437}
438
439
441{
442 Active = false;
443}
444
445
447{
448 return (Active == false);
449}
450
451
453{
454 if (PosRand) {
455 delete PosRand;
456 PosRand =NULL;
457 }
458 PosRand = rand;
459}
460
461
463{
464 if (VelRand) {
465 delete VelRand;
466 VelRand =NULL;
467 }
468 VelRand = rand;
469 if (VelRand) {
470 VelRand->Scale(0.001f); // Convert from seconds to ms
471 }
472}
473
474
476{
477 Vector3Randomizer *randomizer = NULL;
478 if (PosRand != NULL) {
479 randomizer = PosRand->Clone ();
480 //randomizer->Scale (1000.0F);
481 }
482 return randomizer;
483}
484
485
487{
488 Vector3Randomizer *randomizer = NULL;
489 if (VelRand != NULL) {
490 randomizer = VelRand->Clone ();
491 randomizer->Scale (1000.0F);
492 }
493 return randomizer;
494}
495
497{
498 BaseVel = base_vel * 0.001f; // Convert from seconds to ms
499}
500
501
503{
504 OutwardVel = out_vel * 0.001f; // Convert from seconds to ms
505}
506
507
509{
510 VelInheritFactor = inh_factor;
511}
512
513
514// Emit particles (put in particle buffer). This is called by the particle
515// buffer On_Frame_Update() function to avoid order dependence.
517{
518 WWPROFILE("PartlicleEmitter::Emit");
519#ifdef WWDEBUG
520 if (DebugDisable == true) {
521 return;
522 }
523#endif
524
525 if (Active && !IsComplete) {
526 Quaternion curr_quat; // Quaternion form of orientation.
527 Vector3 curr_orig; // Origin.
528
529 // Convert current matrix into quaternion + origin form.
530 curr_quat = Build_Quaternion(Get_Transform());
531 curr_orig = Get_Transform().Get_Translation();
532
533 Create_New_Particles(curr_quat, curr_orig);
534
535 PrevQ = curr_quat;
536 PrevOrig = curr_orig;
537 } else {
538 // These need to be updated each frame no matter what
540 PrevOrig = Get_Transform().Get_Translation();
541 }
542}
543
544
545// Collision sphere is a point - emitter emits also when not visible, so this
546// is only important to avoid affecting the collision spheres of composite
547// objects into which the emitter is inserted.
548void ParticleEmitterClass::Update_Cached_Bounding_Volumes(void) const
549{
554}
555
556
557// Note that creation location and velocity are in local coordinates, so new
558// particles need to be transformed into worldspace. It is important to get
559// the correct transform at the exact time of particle creation (for frame-
560// rate independence), so the current emitter transform is calculated by
561// time-based interpolation between the transforms at the beginning and end
562// of the current frame. This interpolation is performed via quaternion-
563// slerping the orientation and lerping the origin.
564void ParticleEmitterClass::Create_New_Particles(const Quaternion & curr_quat, const Vector3 & curr_orig)
565{
566 Quaternion quat;
567 Vector3 orig;
568
569 // The emit remainder from the previous interval (the time remaining in
570 // the previous interval when the last particle was emitted) is added to
571 // the size of the current frame to yield the time currently available
572 // for emitting particles.
573 unsigned int frametime = WW3D::Get_Frame_Time();
574 // Since the particles are written into a wraparound buffer, we can take the time modulo a time
575 // constant which represents the time it takes to fill up the entire buffer with new particles.
576 // We will do this so we don't run into performance problems with very large frame times.
577 if (frametime > 100 * EmitRate) { // If the loop will run over 100 times
578 unsigned int buf_size = Buffer->Get_Buffer_Size();
579 unsigned int gcd = Greatest_Common_Divisor(buf_size, BurstSize);
580 unsigned int bursts = buf_size / gcd;
581 unsigned int cycle_time = EmitRate * bursts;
582 if (cycle_time > 1) {
583 frametime = frametime % cycle_time;
584 } else {
585 frametime = 1;
586 }
587 }
588
589 EmitRemain += frametime;
590
591 // The interpolation factor (0: start of interval: 1: end of interval).
592 // Possibly negative at this point, but after the delta is added to it, it
593 // will be positive.
594 float fl_frametime = (float)frametime;
595 float alpha = 1 - ((float)EmitRemain / fl_frametime);
596 float d_alpha = (float)EmitRate / fl_frametime;
597
598 // Setup the slerp between the two quaternions.
599 SlerpInfoStruct slerp_info;
600 Slerp_Setup(PrevQ, curr_quat, &slerp_info);
601
602 // Find the velocity of the emitter (for velocity inheritance).
603 // InheritedWorldSpaceEmitterVel is a global variable which is only used
604 // to pass this into the following Initialize_Particle() calls without
605 // having to set it as an argument for each call.
606 if (VelInheritFactor) {
607 InheritedWorldSpaceEmitterVel = (curr_orig - PrevOrig) * (VelInheritFactor / fl_frametime);
608 } else {
609 InheritedWorldSpaceEmitterVel.Set(0.0, 0.0, 0.0);
610 }
611
612 for (; EmitRemain > EmitRate;) {
613
614 // Calculate the new remainder.
615 EmitRemain -= EmitRate;
616
617 // Interpolate the start and end transforms to find the transform at
618 // the moment of particle creation.
619 alpha += d_alpha;
620 quat = Cached_Slerp(PrevQ, curr_quat, alpha, &slerp_info);
621 Vector3::Lerp(PrevOrig, curr_orig, alpha, &orig);
622
623 // Initialize BurstSize new particles with the given age and emitter
624 // transform (expressed as a quaternion and origin vector), and add it
625 // to the particle buffer's new particle vector.
626 unsigned int age = WW3D::Get_Sync_Time() - EmitRemain;
627 unsigned int burst_size = BurstSize;
628 if (OneTimeBurst) {
629 burst_size = OneTimeBurstSize;
630 OneTimeBurst = false;
631 }
632
633 if ( ParticlesLeft > 0 ) { // if we are counting,
634 if (burst_size > (unsigned int)ParticlesLeft) {
635 burst_size = (unsigned int)ParticlesLeft;
636 ParticlesLeft = 0;
637 } else {
638 ParticlesLeft -= burst_size;
639 }
640 if ( ParticlesLeft <= 0 ) { // count and if done
641 IsComplete = true; // stop
642 }
643 }
644
645 for (unsigned int i = 0; i < burst_size; i++) {
646 Initialize_Particle(Buffer->Add_Uninitialized_New_Particle(), age, quat, orig);
647 }
648
649 if (IsComplete) break;
650 }
651}
652
653
654// Initialize one new particle at the given NewParticleStruct address, with
655// the given age and emitter transform (expressed as a quaternion and origin
656// vector). (must check if address is NULL).
657void ParticleEmitterClass::Initialize_Particle(NewParticleStruct * newpart,
658 unsigned int timestamp, const Quaternion & quat, const Vector3 & orig)
659{
660 // Set time stamp.
661 newpart->TimeStamp = timestamp;
662
663 // Set starting (random) local position.
664 Vector3 rand_pos;
665 if (PosRand) {
666 PosRand->Get_Vector(rand_pos);
667 } else {
668 rand_pos.Set(0.0, 0.0, 0.0);
669 }
670
671 // Transform position to worldspace, using the transform at moment of
672 // particle creation.
673 newpart->Position = quat.Rotate_Vector(rand_pos) + orig;
674
675 // Set (random) local velocity.
676 Vector3 rand_vel;
677 if (VelRand) {
678 VelRand->Get_Vector(rand_vel);
679 } else {
680 rand_vel.Set(0.0, 0.0, 0.0);
681 }
682
683 // Add outwards velocity to emitterspace velocity
684 if (OutwardVel) {
685 // Find vector pointing outwards (from origin to creation position)
686 Vector3 outwards;
687 float pos_l2 = rand_pos.Length2();
688 if (pos_l2) {
689 outwards = rand_pos * (OutwardVel * WWMath::Inv_Sqrt(pos_l2));
690 } else {
691 outwards.X = OutwardVel;
692 outwards.Y = 0.0f;
693 outwards.Z = 0.0f;
694 }
695
696 rand_vel += outwards;
697 }
698
699 // Add base velocity to emitterspace velocity
700 rand_vel += BaseVel;
701
702 // Rotate velocity to worldspace and add emitter's inherited velocity.
703 newpart->Velocity = InheritedWorldSpaceEmitterVel + quat.Rotate_Vector(rand_vel);
704
705 // GroupID
706 newpart->GroupID = GroupID;
707}
708
709
712{
713 // Allocate a new emitter definition object
715 WWASSERT (pdefinition != NULL);
716 if (pdefinition != NULL) {
717
718 // Set the texture's filename
719 TextureClass *ptexture = Get_Texture ();
720 if (ptexture != NULL) {
721 pdefinition->Set_Texture_Filename (ptexture->Get_Texture_Name());
722 REF_PTR_RELEASE(ptexture);
723 }
724
725 // Now fill the definition with data from this emitter instance
726 pdefinition->Set_Render_Mode (Get_Render_Mode());
727 pdefinition->Set_Frame_Mode (Get_Frame_Mode());
728 pdefinition->Set_Name (Get_Name ());
729 pdefinition->Set_Lifetime (Get_Lifetime ());
731 pdefinition->Set_Emission_Rate (Get_Emission_Rate ());
732 pdefinition->Set_Max_Emissions (Get_Max_Particles ());
733 pdefinition->Set_Fade_Time (Get_Fade_Time ());
734 pdefinition->Set_Gravity (0);
735 pdefinition->Set_Elasticity (0);
736 pdefinition->Set_Velocity (Get_Start_Velocity ());
737 pdefinition->Set_Acceleration (Get_Acceleration ());
738 pdefinition->Set_Burst_Size (Get_Burst_Size ());
739 pdefinition->Set_Outward_Vel (Get_Outwards_Vel ());
740 pdefinition->Set_Vel_Inherit (Get_Velocity_Inherit ());
741 pdefinition->Set_Shader (Get_Shader ());
742
743 //
744 // Pass the creation volume onto the definition
745 //
746 Vector3Randomizer *randomizer = Get_Creation_Volume ();
747 pdefinition->Set_Creation_Volume (randomizer);
748
749 //
750 // Pass the velocity randomizer onto the definition
751 //
752 randomizer = Get_Velocity_Random ();
753 pdefinition->Set_Velocity_Random (randomizer);
754
755 //
756 // Pass the color keyframes onto the definition
757 //
759 Get_Color_Key_Frames (colors);
760 pdefinition->Set_Color_Keyframes (colors);
761 if (colors.KeyTimes != NULL) delete [] colors.KeyTimes;
762 if (colors.Values != NULL) delete [] colors.Values;
763
764 //
765 // Pass the opacity keyframes onto the definition
766 //
768 Get_Opacity_Key_Frames (opacities);
769 pdefinition->Set_Opacity_Keyframes (opacities);
770 if (opacities.KeyTimes != NULL) delete [] opacities.KeyTimes;
771 if (opacities.Values != NULL) delete [] opacities.Values;
772
773 //
774 // Pass the size keyframes onto the definition
775 //
777 Get_Size_Key_Frames (sizes);
778 pdefinition->Set_Size_Keyframes (sizes);
779 if (sizes.KeyTimes != NULL) delete [] sizes.KeyTimes;
780 if (sizes.Values != NULL) delete [] sizes.Values;
781
782 //
783 // Pass the rotation keyframes onto the definition
784 //
786 Get_Rotation_Key_Frames (rotations);
787 pdefinition->Set_Rotation_Keyframes (rotations, Get_Initial_Orientation_Random());
788 if (rotations.KeyTimes != NULL) delete [] rotations.KeyTimes;
789 if (rotations.Values != NULL) delete [] rotations.Values;
790
791 //
792 // Pass the frame keyframes onto the definition
793 //
795 Get_Frame_Key_Frames (frames);
796 pdefinition->Set_Frame_Keyframes (frames);
797 if (frames.KeyTimes != NULL) delete [] frames.KeyTimes;
798 if (frames.Values != NULL) delete [] frames.Values;
799
800 //
801 // Pass the blur time keyframes onto the definition
802 //
804 Get_Blur_Time_Key_Frames (blur_times);
805 pdefinition->Set_Blur_Time_Keyframes (blur_times);
806 if (blur_times.KeyTimes != NULL) delete [] blur_times.KeyTimes;
807 if (blur_times.Values != NULL) delete [] blur_times.Values;
808
809
810 //
811 // Set up the line parameters
812 //
815 pdefinition->Set_Freeze_Random(Is_Freeze_Random());
817 pdefinition->Set_End_Caps(Are_End_Caps_Enabled());
823
824 }
825
826 // Return a pointer to the new definition
827 return pdefinition;
828}
829
830
833{
834 // Assume error
836
837 // Build a definition from this emitter instance, and save it
838 // to the chunk.
840 if (pdefinition != NULL) {
841 ret_val = pdefinition->Save_W3D (chunk_save);
842 }
843
844 // Return the WW3DErrorType return code
845 return ret_val;
846}
847
848
849void
851{
852 // Free the old name if necessary
853 if (NameString != NULL) {
854 ::free (NameString);
855 NameString = NULL;
856 }
857
858 // Copy the provided name
859 NameString = ::_strdup (pname);
860 return ;
861}
862
863
864void
866{
867 // Simply start or stop the emission based on
868 // the visibility state of the emitter.
869 if (Is_Not_Hidden_At_All() && !IsInvisible && Is_Stopped() && IsInScene) {
870 Start ();
871 } else if ((!Is_Not_Hidden_At_All() || IsInvisible) && !Is_Stopped()) {
872 Stop ();
873 }
874
875 return ;
876}
877
878
879void
881(
883 bool textures_only
884)
885{
886 //
887 // Get the texture the emitter is using and add it to our list
888 //
889 TextureClass *texture = Get_Texture ();
890 if (texture != NULL) {
891 file_list.Add (texture->Get_Full_Path ());
892 REF_PTR_RELEASE(texture);
893 }
894
895 // Allow the base class to process this call (extremely important)
896 RenderObjClass::Add_Dependencies_To_List (file_list, textures_only);
897 return ;
898}
#define NULL
Definition BaseType.h:92
Color scale(const Color &a, const Color &b)
Definition GameMtl.cpp:722
#define WWASSERT
#define MIN(a, b)
Definition always.h:189
#define W3DNEW
Definition always.h:109
#define MAX(a, b)
Definition always.h:185
@ true
Definition bool.h:59
@ false
Definition bool.h:59
Vector3 Center
Definition aabox.h:123
Vector3 Extent
Definition aabox.h:124
bool Add(T const &object)
Definition Vector.H:671
WWINLINE Vector3 Get_Translation(void) const
Definition matrix3d.h:217
virtual RenderObjClass * Clone(void) const
Definition part_buf.cpp:798
bool Is_Remove_On_Complete_Enabled(void)
Definition part_emt.h:218
virtual void Notify_Added(SceneClass *scene)
Definition part_emt.cpp:321
int Get_Render_Mode(void) const
Definition part_emt.h:233
void Set_Outwards_Velocity(float out_vel)
Definition part_emt.cpp:502
void Set_Base_Velocity(const Vector3 &base_vel)
Definition part_emt.cpp:496
float Get_Fade_Time(void) const
Definition part_emt.h:243
float Get_Future_Start_Time(void) const
Definition part_emt.h:238
ShaderClass Get_Shader(void) const
Definition part_emt.h:256
void Get_Rotation_Key_Frames(ParticlePropertyStruct< float > &rotations) const
Definition part_emt.h:262
int Get_Line_Texture_Mapping_Mode(void) const
Definition part_emt.h:268
virtual void Add_Dependencies_To_List(DynamicVectorClass< StringClass > &file_list, bool textures_only=false)
Definition part_emt.cpp:881
float Get_Texture_Tile_Factor(void) const
Definition part_emt.h:276
TextureClass * Get_Texture(void) const
Definition part_emt.h:241
Vector3 Get_Acceleration(void) const
Definition part_emt.h:236
virtual void Scale(float scale)
Definition part_emt.cpp:343
WW3DErrorType Save(ChunkSaveClass &chunk_save) const
Definition part_emt.cpp:832
float Get_Velocity_Inherit(void) const
Definition part_emt.h:255
float Get_Noise_Amplitude(void) const
Definition part_emt.h:274
int Is_Sorting_Disabled(void) const
Definition part_emt.h:271
virtual void Set_Name(const char *pname)
Definition part_emt.cpp:850
static ParticleEmitterClass * Create_From_Definition(const ParticleEmitterDefClass &definition)
Definition part_emt.cpp:205
int Are_End_Caps_Enabled(void) const
Definition part_emt.h:272
virtual void Emit(void)
Definition part_emt.cpp:516
float Get_Emission_Rate(void) const
Definition part_emt.h:248
float Get_Lifetime(void) const
Definition part_emt.h:237
int Get_Max_Particles(void) const
Definition part_emt.h:250
void Get_Color_Key_Frames(ParticlePropertyStruct< Vector3 > &colors) const
Definition part_emt.h:259
int Get_Frame_Mode(void) const
Definition part_emt.h:234
void Get_Frame_Key_Frames(ParticlePropertyStruct< float > &frames) const
Definition part_emt.h:263
int Get_Burst_Size(void) const
Definition part_emt.h:249
int Is_Merge_Intersections(void) const
Definition part_emt.h:269
virtual void Update_On_Visibilty(void)
Definition part_emt.cpp:865
void Get_Blur_Time_Key_Frames(ParticlePropertyStruct< float > &blurtimes) const
Definition part_emt.h:264
float Get_Outwards_Vel(void) const
Definition part_emt.h:254
virtual bool Is_Complete(void)
Definition part_emt.h:215
void Get_Opacity_Key_Frames(ParticlePropertyStruct< float > &opacities) const
Definition part_emt.h:260
ParticleEmitterDefClass * Build_Definition(void) const
Definition part_emt.cpp:711
float Get_Merge_Abort_Factor(void) const
Definition part_emt.h:275
void Set_Velocity_Inheritance_Factor(float inh_factor)
Definition part_emt.cpp:508
Vector3Randomizer * Get_Velocity_Random(void) const
Definition part_emt.cpp:486
virtual const char * Get_Name(void) const
Definition part_emt.h:138
virtual RenderObjClass * Clone(void) const
Definition part_emt.cpp:310
void Set_Velocity_Randomizer(Vector3Randomizer *rand)
Definition part_emt.cpp:462
ParticleEmitterClass & operator=(const ParticleEmitterClass &)
Definition part_emt.cpp:163
void Set_Position_Randomizer(Vector3Randomizer *rand)
Definition part_emt.cpp:452
float Get_Initial_Orientation_Random(void) const
Definition part_emt.h:265
Vector3Randomizer * Get_Creation_Volume(void) const
Definition part_emt.cpp:475
void Get_Size_Key_Frames(ParticlePropertyStruct< float > &sizes) const
Definition part_emt.h:261
virtual void Notify_Removed(SceneClass *scene)
Definition part_emt.cpp:331
int Get_Subdivision_Level(void) const
Definition part_emt.h:273
Vector2 Get_UV_Offset_Rate(void) const
Definition part_emt.h:277
int Is_Freeze_Random(void) const
Definition part_emt.h:270
virtual ~ParticleEmitterClass(void)
Definition part_emt.cpp:175
bool Is_Stopped(void)
Definition part_emt.cpp:446
Vector3 Get_Start_Velocity(void) const
Definition part_emt.h:251
virtual void On_Frame_Update(void)
Definition part_emt.cpp:357
ParticleEmitterClass(float emit_rate, unsigned int burst_size, Vector3Randomizer *pos_rnd, Vector3 base_vel, Vector3Randomizer *vel_rnd, float out_vel, float vel_inherit_factor, ParticlePropertyStruct< Vector3 > &color, ParticlePropertyStruct< float > &opacity, ParticlePropertyStruct< float > &size, ParticlePropertyStruct< float > &rotation, float orient_rnd, ParticlePropertyStruct< float > &frames, ParticlePropertyStruct< float > &blur_times, Vector3 accel, float max_age, float future_start, TextureClass *tex, ShaderClass shader=ShaderClass::_PresetAdditiveSpriteShader, int max_particles=0, int max_buffer_size=-1, bool pingpong=false, int render_mode=W3D_EMITTER_RENDER_MODE_TRI_PARTICLES, int frame_mode=W3D_EMITTER_FRAME_MODE_1x1, const W3dEmitterLinePropertiesStruct *line_props=NULL)
Definition part_emt.cpp:71
virtual void Restart(void)
Definition part_emt.cpp:315
virtual WW3DErrorType Save_W3D(ChunkSaveClass &chunk_save)
float Get_Future_Start_Time(void) const
Definition part_ldr.h:147
virtual void Get_Size_Keyframes(ParticlePropertyStruct< float > &keyframes) const
float Get_Max_Emissions(void) const
Definition part_ldr.h:138
int Get_Render_Mode(void) const
Definition part_ldr.h:133
virtual void Set_Texture_Filename(const char *pname)
Definition part_ldr.cpp:314
const char * Get_Name(void) const
Definition part_ldr.h:122
virtual void Set_Velocity(const Vector3 &value)
Definition part_ldr.h:158
virtual void Set_Frame_Keyframes(ParticlePropertyStruct< float > &keyframes)
virtual void Set_Size_Keyframes(ParticlePropertyStruct< float > &keyframes)
virtual void Set_Frame_Mode(int mode)
Definition part_ldr.h:150
float Get_Vel_Inherit(void) const
Definition part_ldr.h:146
virtual void Set_End_Caps(int onoff)
Definition part_ldr.h:223
virtual void Get_Opacity_Keyframes(ParticlePropertyStruct< float > &keyframes) const
virtual void Set_Lifetime(float value)
Definition part_ldr.h:152
virtual void Set_Name(const char *pname)
Definition part_ldr.cpp:301
virtual void Get_Color_Keyframes(ParticlePropertyStruct< Vector3 > &keyframes) const
unsigned int Get_Burst_Size(void) const
Definition part_ldr.h:144
virtual void Set_Velocity_Random(Vector3Randomizer *randomizer)
Definition part_ldr.cpp:246
virtual void Set_Merge_Intersections(int onoff)
Definition part_ldr.h:220
virtual void Set_Disable_Sorting(int onoff)
Definition part_ldr.h:222
virtual void Set_Merge_Abort_Factor(float k)
Definition part_ldr.h:226
virtual void Set_Max_Emissions(float value)
Definition part_ldr.h:154
const char * Get_Texture_Filename(void) const
Definition part_ldr.h:135
virtual void Set_Noise_Amplitude(float k)
Definition part_ldr.h:225
Vector3Randomizer * Get_Creation_Volume(void) const
Definition part_ldr.h:171
virtual float Get_Initial_Orientation_Random(void) const
Definition part_ldr.h:185
virtual void Get_Rotation_Keyframes(ParticlePropertyStruct< float > &rotationframes) const
void Get_Shader(ShaderClass &shader) const
Definition part_ldr.h:165
virtual void Set_Shader(const ShaderClass &shader)
Definition part_ldr.h:166
virtual void Set_Line_Texture_Mapping_Mode(int mode)
Definition part_ldr.h:315
virtual void Set_Color_Keyframes(ParticlePropertyStruct< Vector3 > &keyframes)
virtual void Set_UV_Offset_Rate(const Vector2 &rate)
Definition part_ldr.h:228
virtual void Set_Acceleration(const Vector3 &value)
Definition part_ldr.h:159
int Get_Frame_Mode(void) const
Definition part_ldr.h:134
virtual void Set_Gravity(float value)
Definition part_ldr.h:156
virtual void Set_Subdivision_Level(int lvl)
Definition part_ldr.h:224
float Get_Outward_Vel(void) const
Definition part_ldr.h:145
virtual void Set_Rotation_Keyframes(ParticlePropertyStruct< float > &keyframes, float orient_rnd)
virtual void Set_Render_Mode(int mode)
Definition part_ldr.h:149
virtual void Set_Emission_Rate(float value)
Definition part_ldr.h:153
Vector3 Get_Acceleration(void) const
Definition part_ldr.h:143
Vector3Randomizer * Get_Velocity_Random(void) const
Definition part_ldr.h:172
virtual void Set_Freeze_Random(int onoff)
Definition part_ldr.h:221
virtual void Set_Outward_Vel(float value)
Definition part_ldr.h:161
float Get_Emission_Rate(void) const
Definition part_ldr.h:137
virtual void Set_Blur_Time_Keyframes(ParticlePropertyStruct< float > &keyframes)
virtual void Set_Opacity_Keyframes(ParticlePropertyStruct< float > &keyframes)
virtual void Set_Fade_Time(float value)
Definition part_ldr.h:155
virtual void Set_Future_Start_Time(float value)
Definition part_ldr.h:163
virtual void Get_Frame_Keyframes(ParticlePropertyStruct< float > &frameframes) const
virtual void Set_Creation_Volume(Vector3Randomizer *randomizer)
Definition part_ldr.cpp:267
virtual void Get_Blur_Time_Keyframes(ParticlePropertyStruct< float > &blurtimeframes) const
virtual void Set_Elasticity(float value)
Definition part_ldr.h:157
virtual void Set_Texture_Tile_Factor(float k)
Definition part_ldr.h:227
const W3dEmitterLinePropertiesStruct * Get_Line_Properties(void) const
Definition part_ldr.h:206
Vector3 Get_Velocity(void) const
Definition part_ldr.h:142
float Get_Lifetime(void) const
Definition part_ldr.h:136
virtual void Set_Vel_Inherit(float value)
Definition part_ldr.h:162
virtual void Set_Burst_Size(unsigned int count)
Definition part_ldr.h:160
WWINLINE Vector3 Rotate_Vector(const Vector3 &v) const
Definition quat.h:246
Vector3 Get_Position(void) const
Definition rendobj.cpp:508
void Validate_Cached_Bounding_Volumes(void) const
Definition rendobj.h:524
virtual int Is_Not_Hidden_At_All(void)
Definition rendobj.h:463
RenderObjClass(void)
Definition rendobj.cpp:170
AABoxClass CachedBoundingBox
Definition rendobj.h:553
virtual void Notify_Added(SceneClass *scene)
Definition rendobj.cpp:862
RenderObjClass & operator=(const RenderObjClass &)
Definition rendobj.cpp:232
SceneClass * Scene
Definition rendobj.h:557
virtual bool Is_In_Scene(void)
Definition rendobj.h:487
virtual void Add_Dependencies_To_List(DynamicVectorClass< StringClass > &file_list, bool textures_only=false)
Definition rendobj.cpp:1136
virtual void Notify_Removed(SceneClass *scene)
Definition rendobj.cpp:884
const Matrix3D & Get_Transform(void) const
Definition rendobj.h:617
friend class SceneClass
Definition rendobj.h:563
SphereClass CachedBoundingSphere
Definition rendobj.h:552
virtual void Register(RenderObjClass *obj, RegType for_what)=0
@ ON_FRAME_UPDATE
Definition scene.h:165
@ RELEASE
Definition scene.h:167
virtual void Unregister(RenderObjClass *obj, RegType for_what)=0
void Enable_Fog(const char *source)
Definition shader.cpp:280
void Init(const Vector3 &pos, float radius)
Definition sphere.h:248
const StringClass & Get_Texture_Name(void) const
Definition texture.h:112
const StringClass & Get_Full_Path(void) const
Definition texture.h:113
float X
Definition vector3.h:90
WWINLINE float Length2(void) const
Definition vector3.h:469
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91
WWINLINE void Set(float x, float y, float z)
Definition vector3.h:103
static void Lerp(const Vector3 &a, const Vector3 &b, float alpha, Vector3 *set_result)
Definition vector3.h:535
virtual void Scale(float scale)=0
virtual Vector3Randomizer * Clone(void) const =0
virtual TextureClass * Get_Texture(const char *filename, MipCountType mip_level_count=MIP_LEVELS_ALL, WW3DFormat texture_format=WW3D_FORMAT_UNKNOWN, bool allow_compression=true, TextureBaseClass::TexAssetType type=TextureBaseClass::TEX_REGULAR, bool allow_reduction=true)
static WW3DAssetManager * Get_Instance(void)
Definition assetmgr.h:205
static unsigned int Get_Sync_Time(void)
Definition ww3d.h:172
static unsigned int Get_Frame_Time(void)
Definition ww3d.h:173
static float Inv_Sqrt(float a)
Definition wwmath.h:651
unsigned int Greatest_Common_Divisor(unsigned int a, unsigned int b)
Definition gcd_lcm.cpp:38
Vector3 InheritedWorldSpaceEmitterVel
Definition part_emt.cpp:58
else return(RetVal)
Quaternion Cached_Slerp(const Quaternion &p, const Quaternion &q, float alpha, SlerpInfoStruct *slerpinfo)
Definition quat.cpp:589
void Slerp_Setup(const Quaternion &p, const Quaternion &q, SlerpInfoStruct *slerpinfo)
Definition quat.cpp:545
Quaternion Build_Quaternion(const Matrix3D &mat)
Definition quat.cpp:663
#define SET_REF_OWNER(P)
Definition refcount.h:63
#define REF_PTR_RELEASE(x)
Definition refcount.h:80
#define NEW_REF(C, P)
Definition refcount.h:62
Vector3 Velocity
Definition part_buf.h:63
unsigned int TimeStamp
Definition part_buf.h:64
unsigned char GroupID
Definition part_buf.h:65
Vector3 Position
Definition part_buf.h:62
@ MIP_LEVELS_ALL
WW3DErrorType
Definition w3derr.h:51
@ WW3D_ERROR_SAVE_FAILED
Definition w3derr.h:55
@ WW3D_FORMAT_UNKNOWN
Definition ww3dformat.h:76
#define WWPROFILE(name)
Definition wwprofile.h:270