tge/example/creator/editor/particleEditor.cs
2025-02-17 23:17:30 -06:00

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);
}