diff --git a/Engine/source/T3D/fx/particleEmitter.cpp b/Engine/source/T3D/fx/particleEmitter.cpp index 04429d8fa..e65643bb9 100644 --- a/Engine/source/T3D/fx/particleEmitter.cpp +++ b/Engine/source/T3D/fx/particleEmitter.cpp @@ -118,6 +118,7 @@ ParticleEmitterData::ParticleEmitterData() ejectionVelocity = 2.0f; // From 1.0 - 3.0 meters per sec velocityVariance = 1.0f; ejectionOffset = sgDefaultEjectionOffset; // ejection from the emitter point + ejectionOffsetVariance = 0.0f; thetaMin = 0.0f; // All heights thetaMax = 90.0f; @@ -199,6 +200,9 @@ void ParticleEmitterData::initPersistFields() addFieldV( "ejectionOffset", TYPEID< F32 >(), Offset(ejectionOffset, ParticleEmitterData), &ejectionFValidator, "Distance along ejection Z axis from which to eject particles." ); + + addFieldV( "ejectionOffsetVariance", TYPEID< F32 >(), Offset(ejectionOffsetVariance, ParticleEmitterData), &ejectionFValidator, + "Distance Padding along ejection Z axis from which to eject particles." ); addFieldV( "thetaMin", TYPEID< F32 >(), Offset(thetaMin, ParticleEmitterData), &thetaFValidator, "Minimum angle, from the horizontal plane, to eject from." ); @@ -316,6 +320,8 @@ void ParticleEmitterData::packData(BitStream* stream) stream->writeInt((S32)(velocityVariance * 100), 14); if( stream->writeFlag( ejectionOffset != sgDefaultEjectionOffset ) ) stream->writeInt((S32)(ejectionOffset * 100), 16); + if( stream->writeFlag( ejectionOffsetVariance != 0.0f ) ) + stream->writeInt((S32)(ejectionOffsetVariance * 100), 16); stream->writeRangedU32((U32)thetaMin, 0, 180); stream->writeRangedU32((U32)thetaMax, 0, 180); if( stream->writeFlag( phiReferenceVel != sgDefaultPhiReferenceVel ) ) @@ -368,7 +374,10 @@ void ParticleEmitterData::unpackData(BitStream* stream) ejectionOffset = stream->readInt(16) / 100.0f; else ejectionOffset = sgDefaultEjectionOffset; - + if( stream->readFlag() ) + ejectionOffsetVariance = stream->readInt(16) / 100.0f; + else + ejectionOffsetVariance = 0.0f; thetaMin = (F32)stream->readRangedU32(0, 180); thetaMax = (F32)stream->readRangedU32(0, 180); if( stream->readFlag() ) @@ -1287,7 +1296,7 @@ void ParticleEmitter::addParticle(const Point3F& pos, F32 initialVel = mDataBlock->ejectionVelocity; initialVel += (mDataBlock->velocityVariance * 2.0f * gRandGen.randF()) - mDataBlock->velocityVariance; - pNew->pos = pos + (ejectionAxis * mDataBlock->ejectionOffset); + pNew->pos = pos_start + (ejectionAxis * (mDataBlock->ejectionOffset + mDataBlock->ejectionOffsetVariance* gRandGen.randF()) ); pNew->vel = ejectionAxis * initialVel; pNew->orientDir = ejectionAxis; pNew->acc.set(0, 0, 0); diff --git a/Engine/source/T3D/fx/particleEmitter.h b/Engine/source/T3D/fx/particleEmitter.h index 02aab525a..36d486f47 100644 --- a/Engine/source/T3D/fx/particleEmitter.h +++ b/Engine/source/T3D/fx/particleEmitter.h @@ -73,7 +73,7 @@ class ParticleEmitterData : public GameBaseData F32 ejectionVelocity; ///< Ejection velocity F32 velocityVariance; ///< Variance for velocity between 0 and n F32 ejectionOffset; ///< Z offset from emitter point to eject from - + F32 ejectionOffsetVariance; ///< Z offset Variance from emitter point to eject F32 thetaMin; ///< Minimum angle, from the horizontal plane, to eject from F32 thetaMax; ///< Maximum angle, from the horizontal plane, to eject from diff --git a/Templates/Empty/game/tools/particleEditor/ParticleEditor.ed.gui b/Templates/Empty/game/tools/particleEditor/ParticleEditor.ed.gui index cbc17ca61..865334dbd 100644 --- a/Templates/Empty/game/tools/particleEditor/ParticleEditor.ed.gui +++ b/Templates/Empty/game/tools/particleEditor/ParticleEditor.ed.gui @@ -1069,7 +1069,53 @@ $PE_guielement_ext_colorpicker = "18 18"; position = $PE_guielement_pos_value; Extent = $PE_guielement_ext_value; altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffset\", $ThisControl.getText());"; - }; + }; + }; + new GuiControl(){ // Emitter Offset Variance + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "OffsetVariance"; + }; + new GuiSliderCtrl(PEE_ejectionOffsetVariance) { + internalName = "PEE_ejectionOffsetVariance_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateEmitter( \"ejectionOffsetVariance\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffsetVariance\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 25"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_ejectionOffsetVariance_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffsetVariance\", $ThisControl.getText());"; + }; }; }; // end stack }; // end "spread" rollout diff --git a/Templates/Full/game/tools/particleEditor/ParticleEditor.ed.gui b/Templates/Full/game/tools/particleEditor/ParticleEditor.ed.gui index cbc17ca61..865334dbd 100644 --- a/Templates/Full/game/tools/particleEditor/ParticleEditor.ed.gui +++ b/Templates/Full/game/tools/particleEditor/ParticleEditor.ed.gui @@ -1069,7 +1069,53 @@ $PE_guielement_ext_colorpicker = "18 18"; position = $PE_guielement_pos_value; Extent = $PE_guielement_ext_value; altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffset\", $ThisControl.getText());"; - }; + }; + }; + new GuiControl(){ // Emitter Offset Variance + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "OffsetVariance"; + }; + new GuiSliderCtrl(PEE_ejectionOffsetVariance) { + internalName = "PEE_ejectionOffsetVariance_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateEmitter( \"ejectionOffsetVariance\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffsetVariance\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 25"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_ejectionOffsetVariance_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffsetVariance\", $ThisControl.getText());"; + }; }; }; // end stack }; // end "spread" rollout