diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_buf.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_buf.cpp index 7f51891c29f..55caafc76b9 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_buf.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_buf.cpp @@ -87,6 +87,7 @@ ParticleBufferClass::ParticleBufferClass ParticlePropertyStruct &rotation, float orient_rnd, ParticlePropertyStruct &frame, + ParticlePropertyStruct &blurtime, Vector3 accel, float max_age, TextureClass *tex, @@ -135,6 +136,10 @@ ParticleBufferClass::ParticleBufferClass FrameKeyFrameTimes(NULL), FrameKeyFrameValues(NULL), FrameKeyFrameDeltas(NULL), + NumBlurTimeKeyFrames(0), + BlurTimeKeyFrameTimes(NULL), + BlurTimeKeyFrameValues(NULL), + BlurTimeKeyFrameDeltas(NULL), NumRandomColorEntriesMinus1(0), RandomColorEntries(NULL), NumRandomAlphaEntriesMinus1(0), @@ -153,6 +158,8 @@ ParticleBufferClass::ParticleBufferClass RandomOrientationEntries(NULL), NumRandomFrameEntriesMinus1(0), RandomFrameEntries(NULL), + NumRandomBlurTimeEntriesMinus1(0), + RandomBlurTimeEntries(NULL), PointGroup(NULL), LineRenderer(NULL), Diffuse(NULL), @@ -161,6 +168,7 @@ ParticleBufferClass::ParticleBufferClass Size(NULL), Orientation(NULL), Frame(NULL), + TailPosition(NULL), APT(NULL), PingPongPosition(pingpong), Velocity(NULL), @@ -190,6 +198,9 @@ ParticleBufferClass::ParticleBufferClass // Create the frame array, keyframes, and randomizer table (if needed) Reset_Frames(frame); + // Create the blur time array, keyframes, and randomizer table if needed + Reset_Blur_Times(blurtime); + // We do not add a ref for the emitter (see DTor for detailed explanation) // if (Emitter) Emitter->Add_Ref(); @@ -295,6 +306,10 @@ ParticleBufferClass::ParticleBufferClass(const ParticleBufferClass & src) : FrameKeyFrameTimes(NULL), FrameKeyFrameValues(NULL), FrameKeyFrameDeltas(NULL), + NumBlurTimeKeyFrames(src.NumBlurTimeKeyFrames), + BlurTimeKeyFrameTimes(NULL), + BlurTimeKeyFrameValues(NULL), + BlurTimeKeyFrameDeltas(NULL), RandomColorEntries(NULL), RandomAlphaEntries(NULL), RandomSizeEntries(NULL), @@ -310,14 +325,17 @@ ParticleBufferClass::ParticleBufferClass(const ParticleBufferClass & src) : RandomOrientationEntries(NULL), NumRandomFrameEntriesMinus1(0), RandomFrameEntries(NULL), + NumRandomBlurTimeEntriesMinus1(0), + RandomBlurTimeEntries(NULL), PointGroup(NULL), LineRenderer(NULL), - Diffuse(NULL), + Diffuse(NULL), Color(NULL), Alpha(NULL), Size(NULL), Orientation(NULL), Frame(NULL), + TailPosition(NULL), APT(NULL), PingPongPosition(src.PingPongPosition), Velocity(NULL), @@ -488,6 +506,31 @@ ParticleBufferClass::ParticleBufferClass(const ParticleBufferClass & src) : FrameKeyFrameValues[0] = src.FrameKeyFrameValues[0]; } + // Set up the blur times keyframes + NumRandomBlurTimeEntriesMinus1 = src.NumRandomBlurTimeEntriesMinus1; + if (NumBlurTimeKeyFrames > 0) { + // Copy blur time keyframes + BlurTimeKeyFrameTimes = new unsigned int [NumBlurTimeKeyFrames]; + BlurTimeKeyFrameValues = new float [NumBlurTimeKeyFrames]; + BlurTimeKeyFrameDeltas = new float [NumBlurTimeKeyFrames]; + for (i = 0; i < NumBlurTimeKeyFrames; i++) { + BlurTimeKeyFrameTimes[i] = src.BlurTimeKeyFrameTimes[i]; + BlurTimeKeyFrameValues[i] = src.BlurTimeKeyFrameValues[i]; + BlurTimeKeyFrameDeltas[i] = src.BlurTimeKeyFrameDeltas[i]; + } + + // Copy blur time randomizer table + if (src.RandomBlurTimeEntries) { + RandomBlurTimeEntries = new float [NumRandomBlurTimeEntriesMinus1 + 1]; + for (unsigned int j = 0; j <= NumRandomBlurTimeEntriesMinus1; j++) { + RandomBlurTimeEntries[j] = src.RandomBlurTimeEntries[j]; + } + } + } else { + BlurTimeKeyFrameValues = new float [1]; + BlurTimeKeyFrameValues[0] = src.BlurTimeKeyFrameValues[0]; + } + // We do not add a ref for the emitter (see DTor for detailed explanation) // if (Emitter) Emitter->Add_Ref(); @@ -574,12 +617,16 @@ ParticleBufferClass::~ParticleBufferClass(void) if (FrameKeyFrameTimes) delete [] FrameKeyFrameTimes; if (FrameKeyFrameValues) delete [] FrameKeyFrameValues; if (FrameKeyFrameDeltas) delete [] FrameKeyFrameDeltas; + if (BlurTimeKeyFrameTimes) delete [] BlurTimeKeyFrameTimes; + if (BlurTimeKeyFrameValues) delete [] BlurTimeKeyFrameValues; + if (BlurTimeKeyFrameDeltas) delete [] BlurTimeKeyFrameDeltas; if (RandomColorEntries) delete [] RandomColorEntries; if (RandomAlphaEntries) delete [] RandomAlphaEntries; if (RandomSizeEntries) delete [] RandomSizeEntries; if (RandomRotationEntries) delete [] RandomRotationEntries; if (RandomOrientationEntries) delete [] RandomOrientationEntries; if (RandomFrameEntries) delete [] RandomFrameEntries; + if (RandomBlurTimeEntries) delete [] RandomBlurTimeEntries; if (PointGroup) delete PointGroup; @@ -1920,6 +1967,154 @@ void ParticleBufferClass::Reset_Frames(ParticlePropertyStruct &new_props) } +void ParticleBufferClass::Reset_Blur_Times(ParticlePropertyStruct &new_blur_times) +{ + + unsigned int i; // Used in loops + float oo_intmax = 1.0f / (float)INT_MAX; + unsigned int ui_previous_key_time = 0; + unsigned int ui_current_key_time = 0; + + BlurTimeRandom = new_blur_times.Rand; + + // If the randomizer is effectively zero and there are no keyframes, then we just create a + // values array with one entry and store the starting value in it (the keyframes and random + // table will not be used in this case). + static const float eps_blur = 1e-5f; // Epsilon is equivalent to 1e-5 units per second + bool blurtime_rand_zero = (fabs(new_blur_times.Rand) < eps_blur); + if (blurtime_rand_zero && new_blur_times.NumKeyFrames == 0) { + + // Release Arrays, Reuse KeyFrameValues if the right size, + // otherwise release and reallocate. + if (BlurTimeKeyFrameTimes) { + delete [] BlurTimeKeyFrameTimes; + BlurTimeKeyFrameTimes = NULL; + } + if (BlurTimeKeyFrameDeltas) { + delete [] BlurTimeKeyFrameDeltas; + BlurTimeKeyFrameDeltas = NULL; + } + if (BlurTimeKeyFrameValues) { + if (NumBlurTimeKeyFrames > 1) { + delete [] BlurTimeKeyFrameValues; + BlurTimeKeyFrameValues = new float [1]; + } + } else { + BlurTimeKeyFrameValues = new float [1]; + } + + NumBlurTimeKeyFrames = 0; + NumRandomBlurTimeEntriesMinus1 = 0; + BlurTimeKeyFrameValues[0] = new_blur_times.Start; + + } else { + + // Check times of the keyframes (each keytime must be larger than the + // previous one by at least a millisecond, and we stop at the first + // keytime of MaxAge or larger. (If all keyframes below MaxAge, the value is + // constant during the last segment between last keyframe and MaxAge). + ui_previous_key_time = 0; + unsigned int key = 0; + for (; key < new_blur_times.NumKeyFrames; key++) { + ui_current_key_time = (unsigned int)(new_blur_times.KeyTimes[key] * 1000.0f); + WWASSERT(ui_current_key_time > ui_previous_key_time); + if (ui_current_key_time >= MaxAge) break; + ui_previous_key_time = ui_current_key_time; + } + bool blurtime_constant_at_end = (key == new_blur_times.NumKeyFrames); + + // Reuse BlurTimeKeyFrameValues, BlurTimeKeyFrameTimes and BlurTimeKeyFrameDeltas if the right size, + // otherwise release and reallocate. + unsigned int new_num_key_frames = key + 1;// Includes start keyframe (keytime == 0). + if (new_num_key_frames != NumBlurTimeKeyFrames) { + + if (BlurTimeKeyFrameTimes) { + delete [] BlurTimeKeyFrameTimes; + BlurTimeKeyFrameTimes = NULL; + } + if (BlurTimeKeyFrameValues) { + delete [] BlurTimeKeyFrameValues; + BlurTimeKeyFrameValues = NULL; + } + if (BlurTimeKeyFrameDeltas) { + delete [] BlurTimeKeyFrameDeltas; + BlurTimeKeyFrameDeltas = NULL; + } + + NumBlurTimeKeyFrames = new_num_key_frames; + BlurTimeKeyFrameTimes = new unsigned int [NumBlurTimeKeyFrames]; + BlurTimeKeyFrameValues = new float [NumBlurTimeKeyFrames]; + BlurTimeKeyFrameDeltas = new float [NumBlurTimeKeyFrames]; + } + + // Set keyframes (deltas will be set later) + BlurTimeKeyFrameTimes[0] = 0; + BlurTimeKeyFrameValues[0] = new_blur_times.Start; + for (i = 1; i < NumBlurTimeKeyFrames; i++) { + unsigned int im1 = i - 1; + BlurTimeKeyFrameTimes[i] = (unsigned int)(new_blur_times.KeyTimes[im1] * 1000.0f); + BlurTimeKeyFrameValues[i] = new_blur_times.Values[im1]; + } + + // Do deltas for all frame keyframes except last + for (i = 0; i < NumBlurTimeKeyFrames - 1; i++) { + BlurTimeKeyFrameDeltas[i] = (BlurTimeKeyFrameValues[i + 1] - BlurTimeKeyFrameValues[i]) / + (float)(BlurTimeKeyFrameTimes[i + 1] - BlurTimeKeyFrameTimes[i]); + } + + // Do delta for last frame keyframe (i is NumBlurTimeKeyFrames - 1) + if (blurtime_constant_at_end) { + BlurTimeKeyFrameDeltas[i] = 0.0f; + } else { + // This is OK because if frame_constant_at_end is false, NumBlurTimeKeyFrames is equal or + // smaller than new_props.NumKeyFrames so new_props.Values[NumBlurTimeKeyFrames - 1] and + // new_props.KeyTimes[NumBlurTimeKeyFrames - 1] exist. + BlurTimeKeyFrameDeltas[i] = (new_blur_times.Values[i] - BlurTimeKeyFrameValues[i]) / + (new_blur_times.KeyTimes[i] * 1000.0f - (float)BlurTimeKeyFrameTimes[i]); + } + + // Set up frame randomizer table + if (blurtime_rand_zero) { + + if (RandomBlurTimeEntries) { + // Reuse RandomBlurTimeEntries if the right size, otherwise release and reallocate. + if (NumRandomBlurTimeEntriesMinus1 != 0) { + delete [] RandomBlurTimeEntries; + RandomBlurTimeEntries = new float [1]; + } + } else { + RandomBlurTimeEntries = new float [1]; + } + + NumRandomBlurTimeEntriesMinus1 = 0; + RandomBlurTimeEntries[0] = 0.0f; + } else { + + // Default size of randomizer tables (tables for non-zero randomizers will be this size) + unsigned int pot_num = Find_POT(MaxNum); + unsigned int default_randomizer_entries = MIN(pot_num, MAX_RANDOM_ENTRIES); + + if (RandomBlurTimeEntries) { + // Reuse RandomBlurTimeEntries if the right size, otherwise release and reallocate. + if (NumRandomBlurTimeEntriesMinus1 != (default_randomizer_entries - 1)) { + delete [] RandomBlurTimeEntries; + RandomBlurTimeEntries = new float [default_randomizer_entries]; + } + } else { + RandomBlurTimeEntries = new float [default_randomizer_entries]; + } + + NumRandomBlurTimeEntriesMinus1 = default_randomizer_entries - 1; + + float scale = new_blur_times.Rand * oo_intmax; + for (unsigned int j = 0; j <= NumRandomBlurTimeEntriesMinus1; j++) { + RandomBlurTimeEntries[j] = rand_gen * scale; + } + } + } +} + + // This informs the buffer that the emitter is dead, so it can release // its pointer to it and be removed itself after all its particles dies // out. @@ -2046,6 +2241,7 @@ void ParticleBufferClass::Update_Visual_Particle_State(void) unsigned int skey = NumSizeKeyFrames - 1; unsigned int rkey = NumRotationKeyFrames - 1; unsigned int fkey = NumFrameKeyFrames - 1; + unsigned int bkey = NumBlurTimeKeyFrames -1; unsigned int part; Vector3 *color = Color ? Color->Get_Array(): NULL; @@ -2053,6 +2249,16 @@ void ParticleBufferClass::Update_Visual_Particle_State(void) float *size = Size ? Size->Get_Array(): NULL; uint8 *orientation = Orientation ? Orientation->Get_Array(): NULL; uint8 *frame = Frame ? Frame->Get_Array(): NULL; + Vector3 *tailposition = TailPosition ? TailPosition->Get_Array() : NULL; + + Vector3 *position=NULL; + + if (PingPongPosition) { + int pingpong = WW3D::Get_Frame_Count() & 0x1; + position = Position[pingpong]->Get_Array(); + } else { + position = Position[0]->Get_Array(); + } for (part = Start; part < sub1_end; part++) { @@ -2123,6 +2329,19 @@ void ParticleBufferClass::Update_Visual_Particle_State(void) frame[part] = (uint)(((int)(tmp_frame)) & 0xFF); } + + if (tailposition) { + // We go from older to younger particles, so we go backwards from the last keyframe until + // age >= keytime. This loop must terminate because the 0th keytime is 0. + float blur_time = BlurTimeKeyFrameValues[0]; + if (BlurTimeKeyFrameTimes) { + for (; part_age < BlurTimeKeyFrameTimes[bkey]; bkey--); + blur_time = BlurTimeKeyFrameValues[bkey] + + BlurTimeKeyFrameDeltas[bkey] * (float)(part_age - BlurTimeKeyFrameTimes[bkey]) + + RandomBlurTimeEntries[part & NumRandomBlurTimeEntriesMinus1]; + } + tailposition[part]=position[part]-Velocity[part]*blur_time*1000; + } } for (part = sub2_start; part < End; part++) { @@ -2194,6 +2413,19 @@ void ParticleBufferClass::Update_Visual_Particle_State(void) frame[part] = (uint)(((int)(tmp_frame)) & 0xFF); } + + if (tailposition) { + // We go from older to younger particles, so we go backwards from the last keyframe until + // age >= keytime. This loop must terminate because the 0th keytime is 0. + float blur_time = BlurTimeKeyFrameValues[0]; + if (BlurTimeKeyFrameTimes) { + for (; part_age < BlurTimeKeyFrameTimes[bkey]; bkey--); + blur_time = BlurTimeKeyFrameValues[bkey] + + BlurTimeKeyFrameDeltas[bkey] * (float)(part_age - BlurTimeKeyFrameTimes[bkey]) + + RandomBlurTimeEntries[part & NumRandomBlurTimeEntriesMinus1]; + } + tailposition[part]=position[part]-Velocity[part]*blur_time*1000; + } } } @@ -2710,7 +2942,7 @@ void ParticleBufferClass::Get_Frame_Key_Frames (ParticlePropertyStruct &f // // If we have more than just the start rotation, build - // an array of key times and rotation values + // an array of key times and frame values // if (real_keyframe_count > 0) { frames.KeyTimes = W3DNEWARRAY float[real_keyframe_count]; @@ -2744,6 +2976,62 @@ void ParticleBufferClass::Get_Frame_Key_Frames (ParticlePropertyStruct &f return ; } +void ParticleBufferClass::Get_Blur_Time_Key_Frames (ParticlePropertyStruct &blurtimes) const +{ + int real_keyframe_count = (NumBlurTimeKeyFrames > 0) ? (NumBlurTimeKeyFrames - 1) : 0; + bool create_last_keyframe = false; + + // + // Determine if there is a keyframe at the very end of the particle's lifetime + // + if ((BlurTimeKeyFrameDeltas != NULL) && + (BlurTimeKeyFrameDeltas[NumBlurTimeKeyFrames - 1] != 0)) { + real_keyframe_count ++; + create_last_keyframe = true; + } + + blurtimes.Start = BlurTimeKeyFrameValues[0]; + blurtimes.Rand = BlurTimeRandom; + blurtimes.NumKeyFrames = real_keyframe_count; + blurtimes.KeyTimes = NULL; + blurtimes.Values = NULL; + + // + // If we have more than just the start rotation, build + // an array of key times and blur time values + // + if (real_keyframe_count > 0) { + blurtimes.KeyTimes = new float[real_keyframe_count]; + blurtimes.Values = new float[real_keyframe_count]; + + // + // Copy the keytimes and frame values + // + unsigned int index; + for (index = 1; index < NumBlurTimeKeyFrames; index ++) { + blurtimes.KeyTimes[index - 1] = ((float)BlurTimeKeyFrameTimes[index]) / 1000; + blurtimes.Values[index - 1] = BlurTimeKeyFrameValues[index]; + } + + // + // Add a keyframe at the very end of the timeline if necessary + // + if (create_last_keyframe) { + blurtimes.KeyTimes[index - 1] = ((float)MaxAge / 1000); + + // + // Determine what the value of the last keyframe should be + // + float start_blurtime = BlurTimeKeyFrameValues[index - 1]; + float &delta = BlurTimeKeyFrameDeltas[NumBlurTimeKeyFrames - 1]; + float time_delta = MaxAge - BlurTimeKeyFrameTimes[index - 1]; + blurtimes.Values[index - 1] = start_blurtime + (delta * time_delta); + } + } + + return ; +} + void ParticleBufferClass::Set_LOD_Max_Screen_Size(int lod_level,float max_screen_size) { if ((lod_level <0) || (lod_level > 17)) { diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_buf.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_buf.h index 5c9828bd042..ec8e0cebfbd 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_buf.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_buf.h @@ -89,7 +89,8 @@ class ParticleBufferClass : public RenderObjClass ParticleBufferClass(ParticleEmitterClass *emitter, unsigned int buffer_size, ParticlePropertyStruct &color, ParticlePropertyStruct &opacity, ParticlePropertyStruct &size, ParticlePropertyStruct &rotation, - float orient_rnd, ParticlePropertyStruct &frame, Vector3 accel, + float orient_rnd, ParticlePropertyStruct &frame, + ParticlePropertyStruct &blurtime, Vector3 accel, float max_age, TextureClass *tex, ShaderClass shader, bool pingpong, int render_mode, int frame_mode, const W3dEmitterLinePropertiesStruct * line_props); @@ -151,6 +152,7 @@ class ParticleBufferClass : public RenderObjClass void Reset_Size(ParticlePropertyStruct &new_props); void Reset_Rotations(ParticlePropertyStruct &new_rotations, float orient_rnd); void Reset_Frames(ParticlePropertyStruct &new_frames); + void Reset_Blur_Times(ParticlePropertyStruct &new_blur_times); // This informs the buffer that the emitter is dead, so it can release // its pointer to it and be removed itself after all its particles dies @@ -217,6 +219,7 @@ class ParticleBufferClass : public RenderObjClass void Get_Size_Key_Frames (ParticlePropertyStruct &sizes) const; void Get_Rotation_Key_Frames (ParticlePropertyStruct &rotations) const; void Get_Frame_Key_Frames (ParticlePropertyStruct &frames) const; + void Get_Blur_Time_Key_Frames (ParticlePropertyStruct &blurtimes) const; float Get_Initial_Orientation_Random (void) const { return InitialOrientationRandom; } // Total Active Particle Buffer Count @@ -329,6 +332,10 @@ class ParticleBufferClass : public RenderObjClass unsigned int * FrameKeyFrameTimes; // 0th entry is always 0 float * FrameKeyFrameValues; float * FrameKeyFrameDeltas; + unsigned int NumBlurTimeKeyFrames; + unsigned int * BlurTimeKeyFrameTimes; // 0th entry is always 0 + float * BlurTimeKeyFrameValues; + float * BlurTimeKeyFrameDeltas; // These tables are indexed by the array position in the particle buffer. // The table size is either the smallest power of two equal or larger @@ -350,12 +357,15 @@ class ParticleBufferClass : public RenderObjClass float * RandomOrientationEntries; unsigned int NumRandomFrameEntriesMinus1; // 2^n - 1 so can be used as a mask also float * RandomFrameEntries; + unsigned int NumRandomBlurTimeEntriesMinus1; // 2^n - 1 so can be used as a mask also + float * RandomBlurTimeEntries; Vector3 ColorRandom; float OpacityRandom; float SizeRandom; float RotationRandom; float FrameRandom; + float BlurTimeRandom; float InitialOrientationRandom; // This object implements particle rendering @@ -375,6 +385,7 @@ class ParticleBufferClass : public RenderObjClass ShareBufferClass * Alpha; ShareBufferClass * Size; ShareBufferClass * Frame; + ShareBufferClass * TailPosition; // Only used for line groups ShareBufferClass * Orientation; ShareBufferClass * APT; diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_emt.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_emt.cpp index 46d691a97b4..2ed27f6d4ef 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_emt.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_emt.cpp @@ -73,6 +73,7 @@ ParticleEmitterClass::ParticleEmitterClass(float emit_rate, unsigned int burst_s ParticlePropertyStruct &size, ParticlePropertyStruct &rotation, float orient_rnd, ParticlePropertyStruct &frames, + ParticlePropertyStruct &blur_times, Vector3 accel, float max_age, TextureClass *tex, ShaderClass shader, int max_particles, int max_buffer_size, bool pingpong,int render_mode,int frame_mode, const W3dEmitterLinePropertiesStruct * line_props @@ -111,7 +112,7 @@ ParticleEmitterClass::ParticleEmitterClass(float emit_rate, unsigned int burst_s max_num = MAX(max_num, 2); // max_num of 1 causes problems Buffer = W3DNEW ParticleBufferClass(this, max_num, color, opacity, size, rotation, orient_rnd, - frames, accel/1000000.0f,max_age, tex, shader, pingpong, render_mode, frame_mode, + frames, blur_times, accel/1000000.0f,max_age, tex, shader, pingpong, render_mode, frame_mode, line_props); SET_REF_OWNER( Buffer ); BufferSceneNeeded = true; @@ -207,7 +208,8 @@ ParticleEmitterClass::Create_From_Definition (const ParticleEmitterDefClass &def const char *ptexture_filename = definition.Get_Texture_Filename (); TextureClass *ptexture = NULL; if (ptexture_filename && ptexture_filename[0]) { - ptexture = WW3DAssetManager::Get_Instance()->Get_Texture( + ptexture = WW3DAssetManager::Get_Instance()->Get_Texture + ( ptexture_filename, MIP_LEVELS_ALL, WW3D_FORMAT_UNKNOWN, @@ -237,12 +239,14 @@ ParticleEmitterClass::Create_From_Definition (const ParticleEmitterDefClass &def ParticlePropertyStruct size_keys; ParticlePropertyStruct rotation_keys; ParticlePropertyStruct frame_keys; + ParticlePropertyStruct blur_time_keys; definition.Get_Color_Keyframes (color_keys); definition.Get_Opacity_Keyframes (opacity_keys); definition.Get_Size_Keyframes (size_keys); definition.Get_Rotation_Keyframes (rotation_keys); definition.Get_Frame_Keyframes (frame_keys); + definition.Get_Blur_Time_Keyframes (blur_time_keys); // // Create the emitter @@ -260,6 +264,7 @@ ParticleEmitterClass::Create_From_Definition (const ParticleEmitterDefClass &def rotation_keys, definition.Get_Initial_Orientation_Random(), frame_keys, + blur_time_keys, definition.Get_Acceleration (), definition.Get_Lifetime (), ptexture, @@ -281,6 +286,8 @@ ParticleEmitterClass::Create_From_Definition (const ParticleEmitterDefClass &def if (rotation_keys.Values != NULL) delete [] rotation_keys.Values; if (frame_keys.KeyTimes != NULL) delete [] frame_keys.KeyTimes; if (frame_keys.Values != NULL) delete [] frame_keys.Values; + if (blur_time_keys.KeyTimes != NULL) delete [] blur_time_keys.KeyTimes; + if (blur_time_keys.Values != NULL) delete [] blur_time_keys.Values; // Pass the name along to the emitter pemitter->Set_Name (definition.Get_Name ()); @@ -775,6 +782,16 @@ ParticleEmitterClass::Build_Definition (void) const if (frames.KeyTimes != NULL) delete [] frames.KeyTimes; if (frames.Values != NULL) delete [] frames.Values; + // + // Pass the blur time keyframes onto the definition + // + ParticlePropertyStruct blur_times; + Get_Blur_Time_Key_Frames (blur_times); + pdefinition->Set_Blur_Time_Keyframes (blur_times); + if (blur_times.KeyTimes != NULL) delete [] blur_times.KeyTimes; + if (blur_times.Values != NULL) delete [] blur_times.Values; + + // // Set up the line parameters // diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_emt.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_emt.h index f5729f3d84d..485355ced53 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_emt.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_emt.h @@ -115,6 +115,7 @@ class ParticleEmitterClass : public RenderObjClass ParticlePropertyStruct &size, ParticlePropertyStruct &rotation, float orient_rnd, ParticlePropertyStruct &frames, + ParticlePropertyStruct &blur_times, Vector3 accel, float max_age, TextureClass *tex, ShaderClass shader = ShaderClass::_PresetAdditiveSpriteShader, int max_particles = 0, int max_buffer_size = -1, bool pingpong = false, @@ -159,7 +160,7 @@ class ParticleEmitterClass : public RenderObjClass virtual void Set_Animation_Hidden(int onoff) { RenderObjClass::Set_Animation_Hidden (onoff); Update_On_Visibilty (); } virtual void Set_Force_Visible(int onoff) { RenderObjClass::Set_Force_Visible (onoff); Update_On_Visibilty (); } - virtual void Set_LOD_Bias(float bias) { if (Buffer) Buffer->Set_LOD_Bias(bias); } + virtual void Set_LOD_Bias(float bias) { if (Buffer) Buffer->Set_LOD_Bias(bias); } // These are not part of the renderobject interface: @@ -184,6 +185,7 @@ class ParticleEmitterClass : public RenderObjClass void Reset_Size(ParticlePropertyStruct &new_props) { if (Buffer) Buffer->Reset_Size(new_props); } void Reset_Rotations(ParticlePropertyStruct &new_props, float orient_rnd) { if (Buffer) Buffer->Reset_Rotations(new_props, orient_rnd); } void Reset_Frames(ParticlePropertyStruct &new_props) { if (Buffer) Buffer->Reset_Frames(new_props); } + void Reset_Blur_Times(ParticlePropertyStruct &new_props) { if (Buffer) Buffer->Reset_Blur_Times(new_props); } // Change emission/burst rate, or tell the emitter to emit a one-time burst. // NOTE: default buffer size fits the emission/burst rate that the emitter was created with. @@ -252,6 +254,7 @@ class ParticleEmitterClass : public RenderObjClass void Get_Size_Key_Frames (ParticlePropertyStruct &sizes) const { Buffer->Get_Size_Key_Frames (sizes); } void Get_Rotation_Key_Frames (ParticlePropertyStruct &rotations) const { Buffer->Get_Rotation_Key_Frames (rotations); } void Get_Frame_Key_Frames (ParticlePropertyStruct &frames) const { Buffer->Get_Frame_Key_Frames (frames); } + void Get_Blur_Time_Key_Frames (ParticlePropertyStruct &blurtimes) const { Buffer->Get_Blur_Time_Key_Frames (blurtimes); } float Get_Initial_Orientation_Random (void) const { return Buffer->Get_Initial_Orientation_Random(); } // Line rendering accessors