emitter updates
This commit is contained in:
+132
-55
@@ -11,7 +11,7 @@ using namespace wiScene;
|
||||
void EmitterWindow::Create(EditorComponent* editor)
|
||||
{
|
||||
wiWindow::Create("Emitter Window");
|
||||
SetSize(XMFLOAT2(680, 660));
|
||||
SetSize(XMFLOAT2(680, 700));
|
||||
|
||||
float x = 200;
|
||||
float y = 5;
|
||||
@@ -290,6 +290,97 @@ void EmitterWindow::Create(EditorComponent* editor)
|
||||
});
|
||||
AddWidget(&frameStartInput);
|
||||
|
||||
|
||||
|
||||
|
||||
VelocityXInput.Create("");
|
||||
VelocityXInput.SetValue(0);
|
||||
VelocityXInput.SetDescription("Starting Velocity: ");
|
||||
VelocityXInput.SetTooltip("Vector X component");
|
||||
VelocityXInput.SetPos(XMFLOAT2(x, y += step));
|
||||
VelocityXInput.SetSize(XMFLOAT2(38, itemheight));
|
||||
VelocityXInput.OnInputAccepted([&](wiEventArgs args) {
|
||||
auto emitter = GetEmitter();
|
||||
if (emitter != nullptr)
|
||||
{
|
||||
emitter->velocity.x = args.fValue;
|
||||
}
|
||||
});
|
||||
AddWidget(&VelocityXInput);
|
||||
|
||||
VelocityYInput.Create("");
|
||||
VelocityYInput.SetValue(0);
|
||||
VelocityYInput.SetTooltip("Vector Y component");
|
||||
VelocityYInput.SetPos(XMFLOAT2(x + 40, y));
|
||||
VelocityYInput.SetSize(XMFLOAT2(38, itemheight));
|
||||
VelocityYInput.OnInputAccepted([&](wiEventArgs args) {
|
||||
auto emitter = GetEmitter();
|
||||
if (emitter != nullptr)
|
||||
{
|
||||
emitter->velocity.y = args.fValue;
|
||||
}
|
||||
});
|
||||
AddWidget(&VelocityYInput);
|
||||
|
||||
VelocityZInput.Create("");
|
||||
VelocityZInput.SetValue(0);
|
||||
VelocityZInput.SetTooltip("Vector Z component");
|
||||
VelocityZInput.SetPos(XMFLOAT2(x + 80, y));
|
||||
VelocityZInput.SetSize(XMFLOAT2(38, itemheight));
|
||||
VelocityZInput.OnInputAccepted([&](wiEventArgs args) {
|
||||
auto emitter = GetEmitter();
|
||||
if (emitter != nullptr)
|
||||
{
|
||||
emitter->velocity.z = args.fValue;
|
||||
}
|
||||
});
|
||||
AddWidget(&VelocityZInput);
|
||||
|
||||
|
||||
|
||||
GravityXInput.Create("");
|
||||
GravityXInput.SetValue(0);
|
||||
GravityXInput.SetDescription("Gravity: ");
|
||||
GravityXInput.SetTooltip("Vector X component");
|
||||
GravityXInput.SetPos(XMFLOAT2(x + 200, y));
|
||||
GravityXInput.SetSize(XMFLOAT2(38, itemheight));
|
||||
GravityXInput.OnInputAccepted([&](wiEventArgs args) {
|
||||
auto emitter = GetEmitter();
|
||||
if (emitter != nullptr)
|
||||
{
|
||||
emitter->gravity.x = args.fValue;
|
||||
}
|
||||
});
|
||||
AddWidget(&GravityXInput);
|
||||
|
||||
GravityYInput.Create("");
|
||||
GravityYInput.SetValue(0);
|
||||
GravityYInput.SetTooltip("Vector Y component");
|
||||
GravityYInput.SetPos(XMFLOAT2(x + 240, y));
|
||||
GravityYInput.SetSize(XMFLOAT2(38, itemheight));
|
||||
GravityYInput.OnInputAccepted([&](wiEventArgs args) {
|
||||
auto emitter = GetEmitter();
|
||||
if (emitter != nullptr)
|
||||
{
|
||||
emitter->gravity.y = args.fValue;
|
||||
}
|
||||
});
|
||||
AddWidget(&GravityYInput);
|
||||
|
||||
GravityZInput.Create("");
|
||||
GravityZInput.SetValue(0);
|
||||
GravityZInput.SetTooltip("Vector Z component");
|
||||
GravityZInput.SetPos(XMFLOAT2(x + 280, y));
|
||||
GravityZInput.SetSize(XMFLOAT2(38, itemheight));
|
||||
GravityZInput.OnInputAccepted([&](wiEventArgs args) {
|
||||
auto emitter = GetEmitter();
|
||||
if (emitter != nullptr)
|
||||
{
|
||||
emitter->gravity.z = args.fValue;
|
||||
}
|
||||
});
|
||||
AddWidget(&GravityZInput);
|
||||
|
||||
maxParticlesSlider.Create(100.0f, 1000000.0f, 10000, 100000, "Max particle count: ");
|
||||
maxParticlesSlider.SetSize(XMFLOAT2(360, itemheight));
|
||||
maxParticlesSlider.SetPos(XMFLOAT2(x, y += step));
|
||||
@@ -416,6 +507,20 @@ void EmitterWindow::Create(EditorComponent* editor)
|
||||
emitLifeRandomnessSlider.SetTooltip("Set the randomness of lifespans for the emitted particles.");
|
||||
AddWidget(&emitLifeRandomnessSlider);
|
||||
|
||||
emitColorRandomnessSlider.Create(0.0f, 2.0f, 0.0f, 100000, "Color randomness: ");
|
||||
emitColorRandomnessSlider.SetSize(XMFLOAT2(360, itemheight));
|
||||
emitColorRandomnessSlider.SetPos(XMFLOAT2(x, y += step));
|
||||
emitColorRandomnessSlider.OnSlide([&](wiEventArgs args) {
|
||||
auto emitter = GetEmitter();
|
||||
if (emitter != nullptr)
|
||||
{
|
||||
emitter->random_color = args.fValue;
|
||||
}
|
||||
});
|
||||
emitColorRandomnessSlider.SetEnabled(false);
|
||||
emitColorRandomnessSlider.SetTooltip("Set the randomness of color for the emitted particles.");
|
||||
AddWidget(&emitColorRandomnessSlider);
|
||||
|
||||
emitMotionBlurSlider.Create(0.0f, 1.0f, 1.0f, 100000, "Motion blur: ");
|
||||
emitMotionBlurSlider.SetSize(XMFLOAT2(360, itemheight));
|
||||
emitMotionBlurSlider.SetPos(XMFLOAT2(x, y += step));
|
||||
@@ -462,6 +567,20 @@ void EmitterWindow::Create(EditorComponent* editor)
|
||||
|
||||
|
||||
|
||||
dragSlider.Create(-1, 0.016f, -1, 100000, "Drag: ");
|
||||
dragSlider.SetSize(XMFLOAT2(360, itemheight));
|
||||
dragSlider.SetPos(XMFLOAT2(x, y += step));
|
||||
dragSlider.OnSlide([&](wiEventArgs args) {
|
||||
auto emitter = GetEmitter();
|
||||
if (emitter != nullptr)
|
||||
{
|
||||
emitter->drag = args.fValue;
|
||||
}
|
||||
});
|
||||
dragSlider.SetEnabled(false);
|
||||
dragSlider.SetTooltip("The velocity will be multiplied with this value, so lower than 1 will slow decelerate the particles.");
|
||||
AddWidget(&dragSlider);
|
||||
|
||||
|
||||
|
||||
//////////////// SPH ////////////////////////////
|
||||
@@ -541,33 +660,7 @@ void EmitterWindow::SetEntity(Entity entity)
|
||||
|
||||
if (emitter != nullptr)
|
||||
{
|
||||
emitterNameField.SetEnabled(true);
|
||||
restartButton.SetEnabled(true);
|
||||
shaderTypeComboBox.SetEnabled(true);
|
||||
meshComboBox.SetEnabled(true);
|
||||
debugCheckBox.SetEnabled(true);
|
||||
volumeCheckBox.SetEnabled(true);
|
||||
frameBlendingCheckBox.SetEnabled(true);
|
||||
sortCheckBox.SetEnabled(true);
|
||||
depthCollisionsCheckBox.SetEnabled(true);
|
||||
sphCheckBox.SetEnabled(true);
|
||||
pauseCheckBox.SetEnabled(true);
|
||||
maxParticlesSlider.SetEnabled(true);
|
||||
emitCountSlider.SetEnabled(true);
|
||||
emitSizeSlider.SetEnabled(true);
|
||||
emitRotationSlider.SetEnabled(true);
|
||||
emitNormalSlider.SetEnabled(true);
|
||||
emitScalingSlider.SetEnabled(true);
|
||||
emitLifeSlider.SetEnabled(true);
|
||||
emitRandomnessSlider.SetEnabled(true);
|
||||
emitLifeRandomnessSlider.SetEnabled(true);
|
||||
emitMotionBlurSlider.SetEnabled(true);
|
||||
emitMassSlider.SetEnabled(true);
|
||||
timestepSlider.SetEnabled(true);
|
||||
sph_h_Slider.SetEnabled(true);
|
||||
sph_K_Slider.SetEnabled(true);
|
||||
sph_p0_Slider.SetEnabled(true);
|
||||
sph_e_Slider.SetEnabled(true);
|
||||
SetEnabled(true);
|
||||
|
||||
shaderTypeComboBox.SetSelected((int)emitter->shaderType);
|
||||
|
||||
@@ -593,9 +686,17 @@ void EmitterWindow::SetEntity(Entity entity)
|
||||
emitLifeSlider.SetValue(emitter->life);
|
||||
emitRandomnessSlider.SetValue(emitter->random_factor);
|
||||
emitLifeRandomnessSlider.SetValue(emitter->random_life);
|
||||
emitColorRandomnessSlider.SetValue(emitter->random_color);
|
||||
emitMotionBlurSlider.SetValue(emitter->motionBlurAmount);
|
||||
emitMassSlider.SetValue(emitter->mass);
|
||||
timestepSlider.SetValue(emitter->FIXED_TIMESTEP);
|
||||
dragSlider.SetValue(emitter->drag);
|
||||
VelocityXInput.SetValue(emitter->velocity.x);
|
||||
VelocityYInput.SetValue(emitter->velocity.y);
|
||||
VelocityZInput.SetValue(emitter->velocity.z);
|
||||
GravityXInput.SetValue(emitter->gravity.x);
|
||||
GravityYInput.SetValue(emitter->gravity.y);
|
||||
GravityZInput.SetValue(emitter->gravity.z);
|
||||
|
||||
sph_h_Slider.SetValue(emitter->SPH_h);
|
||||
sph_K_Slider.SetValue(emitter->SPH_K);
|
||||
@@ -608,33 +709,9 @@ void EmitterWindow::SetEntity(Entity entity)
|
||||
{
|
||||
infoLabel.SetText("No emitter object selected.");
|
||||
|
||||
emitterNameField.SetEnabled(false);
|
||||
restartButton.SetEnabled(false);
|
||||
shaderTypeComboBox.SetEnabled(false);
|
||||
meshComboBox.SetEnabled(false);
|
||||
debugCheckBox.SetEnabled(false);
|
||||
volumeCheckBox.SetEnabled(false);
|
||||
frameBlendingCheckBox.SetEnabled(false);
|
||||
sortCheckBox.SetEnabled(false);
|
||||
depthCollisionsCheckBox.SetEnabled(false);
|
||||
sphCheckBox.SetEnabled(false);
|
||||
pauseCheckBox.SetEnabled(false);
|
||||
maxParticlesSlider.SetEnabled(false);
|
||||
emitCountSlider.SetEnabled(false);
|
||||
emitSizeSlider.SetEnabled(false);
|
||||
emitRotationSlider.SetEnabled(false);
|
||||
emitNormalSlider.SetEnabled(false);
|
||||
emitScalingSlider.SetEnabled(false);
|
||||
emitLifeSlider.SetEnabled(false);
|
||||
emitRandomnessSlider.SetEnabled(false);
|
||||
emitLifeRandomnessSlider.SetEnabled(false);
|
||||
emitMotionBlurSlider.SetEnabled(false);
|
||||
emitMassSlider.SetEnabled(false);
|
||||
timestepSlider.SetEnabled(false);
|
||||
sph_h_Slider.SetEnabled(false);
|
||||
sph_K_Slider.SetEnabled(false);
|
||||
sph_p0_Slider.SetEnabled(false);
|
||||
sph_e_Slider.SetEnabled(false);
|
||||
SetEnabled(false);
|
||||
|
||||
addButton.SetEnabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,9 +39,18 @@ public:
|
||||
wiSlider emitLifeSlider;
|
||||
wiSlider emitRandomnessSlider;
|
||||
wiSlider emitLifeRandomnessSlider;
|
||||
wiSlider emitColorRandomnessSlider;
|
||||
wiSlider emitMotionBlurSlider;
|
||||
wiSlider emitMassSlider;
|
||||
wiSlider timestepSlider;
|
||||
wiSlider dragSlider;
|
||||
wiTextInputField VelocityXInput;
|
||||
wiTextInputField VelocityYInput;
|
||||
wiTextInputField VelocityZInput;
|
||||
wiTextInputField GravityXInput;
|
||||
wiTextInputField GravityYInput;
|
||||
wiTextInputField GravityZInput;
|
||||
|
||||
wiSlider sph_h_Slider;
|
||||
wiSlider sph_K_Slider;
|
||||
wiSlider sph_p0_Slider;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
This file contains changelog of wiArchive versions
|
||||
|
||||
64: serialized per-emitter gravity, velocity, drag and random_color
|
||||
63: serialized wiResourceManager embedded resources
|
||||
62: serialized WeatherComponent::colorGradingMapName property
|
||||
61: serialized sheen and clearcoat material properties
|
||||
|
||||
@@ -79,6 +79,12 @@ CBUFFER(EmittedParticleCB, CBSLOT_OTHER_EMITTEDPARTICLE)
|
||||
float xEmitterFixedTimestep; // we can force a fixed timestep (>0) onto the simulation to avoid blowing up
|
||||
float xParticleEmissive;
|
||||
|
||||
float3 xParticleGravity;
|
||||
float xParticleDrag;
|
||||
|
||||
float3 xParticleVelocity;
|
||||
float xParticleRandomColorFactor;
|
||||
|
||||
};
|
||||
|
||||
static const uint THREADCOUNT_EMIT = 256;
|
||||
|
||||
@@ -99,7 +99,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
|
||||
particle.position = pos;
|
||||
particle.force = 0;
|
||||
particle.mass = xParticleMass;
|
||||
particle.velocity = (nor + (float3(rand(seed, uv), rand(seed, uv), rand(seed, uv)) - 0.5f) * xParticleRandomFactor) * xParticleNormalFactor;
|
||||
particle.velocity = xParticleVelocity + (nor + (float3(rand(seed, uv), rand(seed, uv), rand(seed, uv)) - 0.5f) * xParticleRandomFactor) * xParticleNormalFactor;
|
||||
particle.rotationalVelocity = xParticleRotation + (rand(seed, uv) - 0.5f) * xParticleRandomFactor;
|
||||
particle.maxLife = xParticleLifeSpan + xParticleLifeSpan * (rand(seed, uv) - 0.5f) * xParticleLifeSpanRandomness;
|
||||
particle.life = particle.maxLife;
|
||||
@@ -109,10 +109,9 @@ void main(uint3 DTid : SV_DispatchThreadID)
|
||||
particle.color_mirror |= ((rand(seed, uv) < 0.5f) << 30) & 0x20000000;
|
||||
|
||||
uint color_modifier = 0;
|
||||
//color_modifier |= (uint)(255.0f * lerp(1, rand(seed, uv), xParticleRandomFactor)) << 0;
|
||||
//color_modifier |= (uint)(255.0f * lerp(1, rand(seed, uv), xParticleRandomFactor)) << 8;
|
||||
//color_modifier |= (uint)(255.0f * lerp(1, rand(seed, uv), xParticleRandomFactor)) << 16;
|
||||
color_modifier = 0x00FFFFFF;
|
||||
color_modifier |= (uint)(255.0 * lerp(1, rand(seed, uv), xParticleRandomColorFactor)) << 0;
|
||||
color_modifier |= (uint)(255.0 * lerp(1, rand(seed, uv), xParticleRandomColorFactor)) << 8;
|
||||
color_modifier |= (uint)(255.0 * lerp(1, rand(seed, uv), xParticleRandomColorFactor)) << 16;
|
||||
particle.color_mirror |= xParticleColor & color_modifier;
|
||||
|
||||
|
||||
|
||||
@@ -120,18 +120,19 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex)
|
||||
#endif // DEPTHCOLLISIONS
|
||||
|
||||
// integrate:
|
||||
particle.force += xParticleGravity;
|
||||
particle.velocity += particle.force * dt;
|
||||
particle.position += particle.velocity * dt;
|
||||
|
||||
// reset force for next frame:
|
||||
particle.force = 0;
|
||||
|
||||
// drag:
|
||||
particle.velocity *= xParticleDrag;
|
||||
|
||||
[branch]
|
||||
if (xEmitterOptions & EMITTER_OPTION_BIT_SPH_ENABLED)
|
||||
{
|
||||
// drag:
|
||||
particle.velocity *= 0.98f;
|
||||
|
||||
// debug collisions:
|
||||
|
||||
float elastic = 0.6;
|
||||
|
||||
@@ -204,11 +204,8 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, ui
|
||||
f_a *= -1;
|
||||
f_av *= e;
|
||||
|
||||
// gravity:
|
||||
const float3 G = float3(0, -9.8f * 2, 0);
|
||||
|
||||
// apply all forces:
|
||||
particleA.force += (f_a + f_av) / densityA + G;
|
||||
particleA.force += (f_a + f_av) / densityA;
|
||||
|
||||
particleBuffer[particleIndexA].force = particleA.force;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
using namespace std;
|
||||
|
||||
// this should always be only INCREMENTED and only if a new serialization is implemeted somewhere!
|
||||
uint64_t __archiveVersion = 63;
|
||||
uint64_t __archiveVersion = 64;
|
||||
// this is the version number of which below the archive is not compatible with the current version
|
||||
uint64_t __archiveVersionBarrier = 22;
|
||||
|
||||
|
||||
@@ -272,6 +272,10 @@ void wiEmittedParticle::UpdateGPU(const TransformComponent& transform, const Mat
|
||||
cb.xEmitterFrameStart = frameStart;
|
||||
cb.xEmitterTexMul = float2(1.0f / (float)cb.xEmitterFramesXY.x, 1.0f / (float)cb.xEmitterFramesXY.y);
|
||||
cb.xEmitterFrameRate = frameRate;
|
||||
cb.xParticleGravity = gravity;
|
||||
cb.xParticleDrag = drag;
|
||||
cb.xParticleVelocity = velocity;
|
||||
cb.xParticleRandomColorFactor = random_color;
|
||||
|
||||
cb.xEmitterOptions = 0;
|
||||
if (IsSPHEnabled())
|
||||
@@ -813,6 +817,22 @@ void wiEmittedParticle::Serialize(wiArchive& archive, wiECS::EntitySerializer& s
|
||||
uint8_t shadingRate;
|
||||
archive >> shadingRate; // no longer needed
|
||||
}
|
||||
|
||||
if (archive.GetVersion() >= 64)
|
||||
{
|
||||
archive >> velocity;
|
||||
archive >> gravity;
|
||||
archive >> drag;
|
||||
archive >> random_color;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsSPHEnabled())
|
||||
{
|
||||
gravity = XMFLOAT3(0, -9.8f * 2, 0);
|
||||
drag = 0.98f;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -845,6 +865,14 @@ void wiEmittedParticle::Serialize(wiArchive& archive, wiECS::EntitySerializer& s
|
||||
archive << frameStart;
|
||||
archive << frameRate;
|
||||
}
|
||||
|
||||
if (archive.GetVersion() >= 64)
|
||||
{
|
||||
archive << velocity;
|
||||
archive << gravity;
|
||||
archive << drag;
|
||||
archive << random_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,11 @@ public:
|
||||
float rotation = 0.0f;
|
||||
float motionBlurAmount = 0.0f;
|
||||
float mass = 1.0f;
|
||||
float random_color = 0;
|
||||
|
||||
XMFLOAT3 velocity = {}; // starting velocity of all new particles
|
||||
XMFLOAT3 gravity = {}; // constant gravity force
|
||||
float drag = 1.0f; // constant drag (per frame velocity multiplier, reducing it will make particles slow down over time)
|
||||
|
||||
float SPH_h = 1.0f; // smoothing radius
|
||||
float SPH_K = 250.0f; // pressure constant
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace wiVersion
|
||||
// minor features, major updates, breaking compatibility changes
|
||||
const int minor = 54;
|
||||
// minor bug fixes, alterations, refactors, updates
|
||||
const int revision = 1;
|
||||
const int revision = 2;
|
||||
|
||||
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user