369 lines
16 KiB
C#
Executable File
369 lines
16 KiB
C#
Executable File
// The Particle Editor!
|
|
// Edits both emitters and their particles in realtime in game.
|
|
//
|
|
// Open the particle editor to spawn a test emitter in front of the player.
|
|
// Edit the sliders, check boxes, and text fields and see the results in
|
|
// realtime. Switch between emitters and particles with the buttons in the
|
|
// top left corner. When in particle mode, the only particles available will
|
|
// be those assigned to the current emitter to avoid confusion. In the top
|
|
// right corner, there is a button marked "Drop Emitter", which will spawn the
|
|
// test emitter in front of the player again, and a button marked "Restart
|
|
// Emitter", which will play the particle animation again.
|
|
|
|
//TODO: animTexName on Particles (max 50)
|
|
|
|
function toggleParticleEditor(%val)
|
|
{
|
|
if (!%val)
|
|
return;
|
|
|
|
if ($ParticleEditor::isOpen)
|
|
{
|
|
Canvas.popDialog(ParticleEditor);
|
|
$ParticleEditor::isOpen = false;
|
|
return;
|
|
}
|
|
|
|
if (!isObject(ParticleEditor))
|
|
{
|
|
exec("common/editor/ParticleEditor.gui");
|
|
ParticleEditor.initEditor();
|
|
}
|
|
ParticleEditor.startup();
|
|
|
|
Canvas.pushDialog(ParticleEditor);
|
|
$ParticleEditor::isOpen = true;
|
|
}
|
|
|
|
|
|
function ParticleEditor::startup(%this)
|
|
{
|
|
$ParticleEditor::activeEditor.updateControls();
|
|
if (!isObject($ParticleEditor::emitterNode))
|
|
%this.resetEmitterNode();
|
|
}
|
|
|
|
function ParticleEditor::initEditor(%this)
|
|
{
|
|
echo("Initializing ParticleEmitterData and ParticleData DataBlocks...");
|
|
|
|
%count = DatablockGroup.getCount();
|
|
%emitterCount = 0;
|
|
%particleCount = 0;
|
|
|
|
PEE_EmitterSelector.clear();
|
|
PEE_EmitterParticleSelector1.clear();
|
|
PEE_EmitterParticleSelector2.clear();
|
|
PEE_EmitterParticleSelector3.clear();
|
|
PEE_EmitterParticleSelector4.clear();
|
|
PEP_ParticleSelector.clear();
|
|
for (%i = 0; %i < %count; %i++)
|
|
{
|
|
%obj = DatablockGroup.getObject(%i);
|
|
if (%obj.getClassName() $= "ParticleEmitterData")
|
|
{
|
|
PEE_EmitterSelector.add(%obj.getName(), %emitterCount);
|
|
%emitterCount++;
|
|
}
|
|
if (%obj.getClassName() $= "ParticleData")
|
|
{
|
|
PEE_EmitterParticleSelector1.add(%obj.getName(), %particleCount);
|
|
PEE_EmitterParticleSelector2.add(%obj.getName(), %particleCount);
|
|
PEE_EmitterParticleSelector3.add(%obj.getName(), %particleCount);
|
|
PEE_EmitterParticleSelector4.add(%obj.getName(), %particleCount);
|
|
%particleCount++;
|
|
}
|
|
}
|
|
PEE_EmitterParticleSelector2.add("", %particleCount); //insert a blank space
|
|
PEE_EmitterParticleSelector3.add("", %particleCount); //insert a blank space
|
|
PEE_EmitterParticleSelector4.add("", %particleCount); //insert a blank space
|
|
|
|
echo("Found" SPC %emitterCount SPC "emitters and" SPC %particleCount SPC "particles.");
|
|
|
|
PEE_EmitterSelector.sort();
|
|
PEE_EmitterParticleSelector1.sort();
|
|
PEE_EmitterParticleSelector2.sort();
|
|
PEE_EmitterParticleSelector3.sort();
|
|
PEE_EmitterParticleSelector4.sort();
|
|
|
|
PEE_EmitterSelector.setSelected(0);
|
|
|
|
%this.openEmitterPane();
|
|
}
|
|
|
|
function PE_EmitterEditor::updateControls(%this)
|
|
{
|
|
%id = PEE_EmitterSelector.getSelected();
|
|
%data = PEE_EmitterSelector.getTextById(%id);
|
|
|
|
PEE_ejectionPeriodMS.setValue( %data.ejectionPeriodMS);
|
|
PEE_periodVarianceMS.setValue( %data.periodVarianceMS);
|
|
PEE_ejectionVelocity.setValue( %data.ejectionVelocity);
|
|
PEE_velocityVariance.setValue( %data.velocityVariance);
|
|
PEE_ejectionOffset.setValue( %data.ejectionOffset);
|
|
PEE_lifetimeMS.setValue( %data.lifetimeMS);
|
|
PEE_lifetimeVarianceMS.setValue( %data.lifetimeVarianceMS);
|
|
PEE_thetaMin.setValue( %data.thetaMin);
|
|
PEE_thetaMax.setValue( %data.thetaMax);
|
|
PEE_phiReferenceVel.setValue( %data.phiReferenceVel);
|
|
PEE_phiVariance.setValue( %data.phiVariance);
|
|
PEE_overrideAdvance.setValue( %data.overrideAdvance);
|
|
PEE_orientParticles.setValue( %data.orientParticles);
|
|
PEE_orientOnVelocity.setValue( %data.orientOnVelocity);
|
|
PEE_useEmitterSizes.setValue( %data.useEmitterSizes);
|
|
PEE_useEmitterColors.setValue( %data.useEmitterColors);
|
|
|
|
PEE_EmitterParticleSelector1.setText(getField(%data.particles, 0));
|
|
PEE_EmitterParticleSelector2.setText(getField(%data.particles, 1));
|
|
PEE_EmitterParticleSelector3.setText(getField(%data.particles, 2));
|
|
PEE_EmitterParticleSelector4.setText(getField(%data.particles, 3));
|
|
|
|
$ParticleEditor::currEmitter = %data;
|
|
}
|
|
|
|
function PE_ParticleEditor::updateControls(%this)
|
|
{
|
|
%id = PEP_ParticleSelector.getSelected();
|
|
%data = PEP_ParticleSelector.getTextById(%id);
|
|
|
|
PEP_dragCoefficient.setValue( %data.dragCoefficient);
|
|
PEP_windCoefficient.setValue( %data.windCoefficient);
|
|
PEP_gravityCoefficient.setValue( %data.gravityCoefficient);
|
|
PEP_inheritedVelFactor.setValue( %data.inheritedVelFactor);
|
|
PEP_constantAcceleration.setValue(%data.constantAcceleration);
|
|
PEP_lifetimeMS.setValue( %data.lifetimeMS);
|
|
PEP_lifetimeVarianceMS.setValue( %data.lifetimeVarianceMS);
|
|
PEP_spinSpeed.setValue( %data.spinSpeed);
|
|
PEP_spinRandomMin.setValue( %data.spinRandomMin);
|
|
PEP_framesPerSec.setValue( %data.framesPerSec);
|
|
PEP_spinRandomMax.setValue( %data.spinRandomMax);
|
|
PEP_useInvAlpha.setValue( %data.useInvAlpha);
|
|
PEP_animateTexture.setValue( %data.animateTexture);
|
|
PEP_times0.setText( %data.times[0]);
|
|
PEP_times1.setText( %data.times[1]);
|
|
PEP_times2.setText( %data.times[2]);
|
|
PEP_times3.setText( %data.times[3]);
|
|
PEP_sizes0.setText( %data.sizes[0]);
|
|
PEP_sizes1.setText( %data.sizes[1]);
|
|
PEP_sizes2.setText( %data.sizes[2]);
|
|
PEP_sizes3.setText( %data.sizes[3]);
|
|
PEP_colors0.setText( %data.colors[0]);
|
|
PEP_colors1.setText( %data.colors[1]);
|
|
PEP_colors2.setText( %data.colors[2]);
|
|
PEP_colors3.setText( %data.colors[3]);
|
|
PEP_textureName.setText( %data.textureName);
|
|
|
|
$ParticleEditor::currParticle = %data;
|
|
}
|
|
|
|
function ParticleEditor::openEmitterPane(%this)
|
|
{
|
|
PE_Window.setText("Particle Editor - Emitters");
|
|
PE_EmitterEditor.setVisible(true);
|
|
PE_EmitterButton.setActive(false);
|
|
PE_ParticleEditor.setVisible(false);
|
|
PE_ParticleButton.setActive(true);
|
|
PE_EmitterEditor.updateControls();
|
|
$ParticleEditor::activeEditor = PE_EmitterEditor;
|
|
}
|
|
|
|
function ParticleEditor::openParticlePane(%this)
|
|
{
|
|
PE_Window.setText("Particle Editor - Particles");
|
|
PE_EmitterEditor.setVisible(false);
|
|
PE_EmitterButton.setActive(true);
|
|
PE_ParticleEditor.setVisible(true);
|
|
PE_ParticleButton.setActive(false);
|
|
|
|
PEP_ParticleSelector.clear();
|
|
PEP_ParticleSelector.add(PEE_EmitterParticleSelector1.getText(), 0);
|
|
%count = 1;
|
|
if (PEE_EmitterParticleSelector2.getText() !$= "")
|
|
{
|
|
PEP_ParticleSelector.add(PEE_EmitterParticleSelector2.getText(), %count);
|
|
%count++;
|
|
}
|
|
if (PEE_EmitterParticleSelector3.getText() !$= "")
|
|
{
|
|
PEP_ParticleSelector.add(PEE_EmitterParticleSelector3.getText(), %count);
|
|
%count++;
|
|
}
|
|
if (PEE_EmitterParticleSelector4.getText() !$= "")
|
|
PEP_ParticleSelector.add(PEE_EmitterParticleSelector4.getText(), %count);
|
|
|
|
PEP_ParticleSelector.sort();
|
|
PEP_ParticleSelector.setSelected(0); //select the PEE_EmitterParticleSelector1 particle
|
|
|
|
PE_ParticleEditor.updateControls();
|
|
$ParticleEditor::activeEditor = PE_ParticleEditor;
|
|
}
|
|
|
|
function PE_EmitterEditor::updateEmitter(%this)
|
|
{
|
|
$ParticleEditor::currEmitter.ejectionPeriodMS = PEE_ejectionPeriodMS.getValue();
|
|
$ParticleEditor::currEmitter.periodVarianceMS = PEE_periodVarianceMS.getValue();
|
|
if ($ParticleEditor::currEmitter.periodVarianceMS >= $ParticleEditor::currEmitter.ejectionPeriodMS)
|
|
{
|
|
$ParticleEditor::currEmitter.periodVarianceMS = $ParticleEditor::currEmitter.ejectionPeriodMS - 1;
|
|
PEE_periodVarianceMS.setValue($ParticleEditor::currEmitter.periodVarianceMS);
|
|
}
|
|
$ParticleEditor::currEmitter.ejectionVelocity = PEE_ejectionVelocity.getValue();
|
|
$ParticleEditor::currEmitter.velocityVariance = PEE_velocityVariance.getValue();
|
|
if ($ParticleEditor::currEmitter.velocityVariance >= $ParticleEditor::currEmitter.ejectionVelocity)
|
|
{
|
|
$ParticleEditor::currEmitter.velocityVariance = $ParticleEditor::currEmitter.ejectionVelocity - 0.01;
|
|
if ($ParticleEditor::currEmitter.velocityVariance < 0)
|
|
$ParticleEditor::currEmitter.velocityVariance = 0;
|
|
PEE_velocityVariance.setValue($ParticleEditor::currEmitter.velocityVariance);
|
|
}
|
|
$ParticleEditor::currEmitter.ejectionOffset = PEE_ejectionOffset.getValue();
|
|
$ParticleEditor::currEmitter.lifetimeMS = PEE_lifetimeMS.getValue();
|
|
$ParticleEditor::currEmitter.lifetimeVarianceMS = PEE_lifetimeVarianceMS.getValue();
|
|
if ($ParticleEditor::currEmitter.lifetimeMS == 0)
|
|
{
|
|
$ParticleEditor::currEmitter.lifetimeVarianceMS = 0;
|
|
PEE_lifetimeVarianceMS.setValue($ParticleEditor::currEmitter.lifetimeVarianceMS);
|
|
}
|
|
else if ($ParticleEditor::currEmitter.lifetimeVarianceMS >= $ParticleEditor::currEmitter.lifetimeMS)
|
|
{
|
|
$ParticleEditor::currEmitter.lifetimeVarianceMS = $ParticleEditor::currEmitter.lifetimeMS - 1;
|
|
PEE_lifetimeVarianceMS.setValue($ParticleEditor::currEmitter.lifetimeVarianceMS);
|
|
}
|
|
$ParticleEditor::currEmitter.thetaMin = PEE_thetaMin.getValue();
|
|
$ParticleEditor::currEmitter.thetaMax = PEE_thetaMax.getValue();
|
|
$ParticleEditor::currEmitter.phiReferenceVel = PEE_phiReferenceVel.getValue();
|
|
$ParticleEditor::currEmitter.phiVariance = PEE_phiVariance.getValue();
|
|
$ParticleEditor::currEmitter.overrideAdvance = PEE_overrideAdvance.getValue();
|
|
$ParticleEditor::currEmitter.orientParticles = PEE_orientParticles.getValue();
|
|
$ParticleEditor::currEmitter.orientOnVelocity = PEE_orientOnVelocity.getValue();
|
|
$ParticleEditor::currEmitter.useEmitterSizes = PEE_useEmitterSizes.getValue();
|
|
$ParticleEditor::currEmitter.useEmitterColors = PEE_useEmitterColors.getValue();
|
|
$ParticleEditor::currEmitter.particles = PEE_EmitterParticleSelector1.getText();
|
|
|
|
if (PEE_EmitterParticleSelector2.getText() !$= "")
|
|
$ParticleEditor::currEmitter.particles = $ParticleEditor::currEmitter.particles TAB PEE_EmitterParticleSelector2.getText();
|
|
if (PEE_EmitterParticleSelector3.getText() !$= "")
|
|
$ParticleEditor::currEmitter.particles = $ParticleEditor::currEmitter.particles TAB PEE_EmitterParticleSelector3.getText();
|
|
if (PEE_EmitterParticleSelector4.getText() !$= "")
|
|
$ParticleEditor::currEmitter.particles = $ParticleEditor::currEmitter.particles TAB PEE_EmitterParticleSelector4.getText();
|
|
|
|
$ParticleEditor::currEmitter.reload();
|
|
}
|
|
|
|
function PE_ParticleEditor::updateParticle(%this)
|
|
{
|
|
$ParticleEditor::currParticle.dragCoefficient = PEP_dragCoefficient.getValue();
|
|
$ParticleEditor::currParticle.windCoefficient = PEP_windCoefficient.getValue();
|
|
$ParticleEditor::currParticle.gravityCoefficient = PEP_gravityCoefficient.getValue();
|
|
$ParticleEditor::currParticle.inheritedVelFactor = PEP_inheritedVelFactor.getValue();
|
|
$ParticleEditor::currParticle.constantAcceleration = PEP_constantAcceleration.getValue();
|
|
$ParticleEditor::currParticle.lifetimeMS = PEP_lifetimeMS.getValue();
|
|
$ParticleEditor::currParticle.lifetimeVarianceMS = PEP_lifetimeVarianceMS.getValue();
|
|
if ($ParticleEditor::currParticle.lifetimeVarianceMS >= $ParticleEditor::currParticle.lifetimeMS)
|
|
{
|
|
$ParticleEditor::currParticle.lifetimeVarianceMS = $ParticleEditor::currParticle.lifetimeMS - 1;
|
|
PEP_lifetimeVarianceMS.setValue($ParticleEditor::currParticle.lifetimeVarianceMS);
|
|
}
|
|
$ParticleEditor::currParticle.spinSpeed = PEP_spinSpeed.getValue();
|
|
$ParticleEditor::currParticle.spinRandomMin = PEP_spinRandomMin.getValue();
|
|
$ParticleEditor::currParticle.spinRandomMax = PEP_spinRandomMax.getValue();
|
|
$ParticleEditor::currParticle.framesPerSec = PEP_framesPerSec.getValue();
|
|
$ParticleEditor::currParticle.useInvAlpha = PEP_useInvAlpha.getValue();
|
|
$ParticleEditor::currParticle.animateTexture = PEP_animateTexture.getValue();
|
|
|
|
$ParticleEditor::currParticle.times[0] = PEP_times0.getValue();
|
|
$ParticleEditor::currParticle.times[1] = PEP_times1.getValue();
|
|
$ParticleEditor::currParticle.times[2] = PEP_times2.getValue();
|
|
$ParticleEditor::currParticle.times[3] = PEP_times3.getValue();
|
|
$ParticleEditor::currParticle.sizes[0] = PEP_sizes0.getValue();
|
|
$ParticleEditor::currParticle.sizes[1] = PEP_sizes1.getValue();
|
|
$ParticleEditor::currParticle.sizes[2] = PEP_sizes2.getValue();
|
|
$ParticleEditor::currParticle.sizes[3] = PEP_sizes3.getValue();
|
|
$ParticleEditor::currParticle.colors[0] = PEP_colors0.getValue();
|
|
$ParticleEditor::currParticle.colors[1] = PEP_colors1.getValue();
|
|
$ParticleEditor::currParticle.colors[2] = PEP_colors2.getValue();
|
|
$ParticleEditor::currParticle.colors[3] = PEP_colors3.getValue();
|
|
|
|
$ParticleEditor::currParticle.textureName = PEP_textureName.getValue();
|
|
|
|
$ParticleEditor::currParticle.reload();
|
|
}
|
|
|
|
function PE_EmitterEditor::onNewEmitter(%this)
|
|
{
|
|
ParticleEditor.updateEmitterNode();
|
|
PE_EmitterEditor.updateControls();
|
|
}
|
|
|
|
function PE_ParticleEditor::onNewParticle(%this)
|
|
{
|
|
PE_ParticleEditor.updateControls();
|
|
}
|
|
|
|
function ParticleEditor::resetEmitterNode(%this)
|
|
{
|
|
%tform = ServerConnection.getControlObject().getEyeTransform();
|
|
%vec = VectorNormalize(ServerConnection.getControlObject().getForwardVector());
|
|
%vec = VectorScale(%vec, 4);
|
|
%tform = setWord(%tform, 0, getWord(%tform, 0) + getWord(%vec, 0));
|
|
%tform = setWord(%tform, 1, getWord(%tform, 1) + getWord(%vec, 1));
|
|
%tform = setWord(%tform, 2, getWord(%tform, 2) + getWord(%vec, 2));
|
|
|
|
if (!isObject($ParticleEditor::emitterNode))
|
|
{
|
|
if (!isObject(TestEmitterNodeData))
|
|
{
|
|
datablock ParticleEmitterNodeData(TestEmitterNodeData)
|
|
{
|
|
timeMultiple = 1;
|
|
};
|
|
}
|
|
|
|
$ParticleEditor::emitterNode = new ParticleEmitterNode()
|
|
{
|
|
emitter = PEE_EmitterSelector.getText();
|
|
velocity = 1;
|
|
position = getWords(%tform, 0, 2);
|
|
rotation = getWords(%tform, 3, 6);
|
|
datablock = TestEmitterNodeData;
|
|
};
|
|
//grab the client-side emitter node so we can reload the emitter datablock
|
|
$ParticleEditor::clientEmitterNode = $ParticleEditor::emitterNode+1;
|
|
}
|
|
else
|
|
{
|
|
$ParticleEditor::clientEmitterNode.setTransform(%tform);
|
|
ParticleEditor.updateEmitterNode();
|
|
}
|
|
}
|
|
|
|
function ParticleEditor::updateEmitterNode()
|
|
{
|
|
$ParticleEditor::clientEmitterNode.setEmitterDataBlock(PEE_EmitterSelector.getText().getId());
|
|
}
|
|
|
|
function PE_EmitterEditor::save(%this)
|
|
{
|
|
%mod = $currentMod;
|
|
if (%mod $= "")
|
|
{
|
|
warn("Warning: No mod detected, saving in common.");
|
|
%mod = "common";
|
|
}
|
|
%filename = %mod @ "/" @ $ParticleEditor::currEmitter @ ".cs";
|
|
$ParticleEditor::currEmitter.save(%filename);
|
|
}
|
|
|
|
function PE_ParticleEditor::save(%this)
|
|
{
|
|
%mod = $currentMod;
|
|
if (%mod $= "")
|
|
{
|
|
warn("Warning: No mod detected, saving in common.");
|
|
%mod = "common";
|
|
}
|
|
%filename = %mod @ "/" @ $ParticleEditor::currParticle @ ".cs";
|
|
$ParticleEditor::currParticle.save(%filename);
|
|
}
|
|
|