Skip to content

Commit

Permalink
Update for KSP 1.4 use of Shuriken
Browse files Browse the repository at this point in the history
  • Loading branch information
sarbian committed Mar 10, 2018
1 parent 9e4f01a commit 96816d2
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 89 deletions.
84 changes: 19 additions & 65 deletions ModelMultiShurikenPersistFX.cs
Expand Up @@ -255,10 +255,11 @@ public override void OnEvent(float power)
UpdateEmitters(power);
for (int i = 0; i < persistentEmitters.Count; i++)
{
persistentEmitters[i].fixedEmit = true;
if (persistentEmitters[i].pe != null)
PersistentKSPShurikenEmitter pkse = persistentEmitters[i];
pkse.fixedEmit = true;
if (pkse.pe != null)
{
ParticleSystem.EmissionModule em = persistentEmitters[i].pe.emission;
ParticleSystem.EmissionModule em = pkse.pe.emission;
em.enabled = false;
}
}
Expand All @@ -267,16 +268,18 @@ public override void OnEvent(float power)
{
for (int j = 0; j < persistentEmitters.Count; j++)
{
persistentEmitters[j].fixedEmit = false;
if (persistentEmitters[j].pe != null)
PersistentKSPShurikenEmitter pkse = persistentEmitters[j];
pkse.fixedEmit = false;
if (pkse.pe != null)
{
ParticleSystem.EmissionModule em = persistentEmitters[j].pe.emission;
ParticleSystem.EmissionModule em = pkse.pe.emission;
em.enabled = false;
}
}
}
}


public void FixedUpdate()
{
//Print("FixedUpdate");
Expand Down Expand Up @@ -557,75 +560,28 @@ public override void OnInitialize()

for (int i = 0; i < transforms.Count; i++)
{
GameObject emitterGameObject = Instantiate(model) as GameObject;
GameObject emitterGameObject = i==0 ? model : Instantiate(model);
KSPParticleEmitter childKSPParticleEmitter = emitterGameObject.GetComponentInChildren<KSPParticleEmitter>();

//if (shader != null)
//{
// childKSPParticleEmitter.material.shader = shader;
// childKSPParticleEmitter.pr.material.shader = shader;
//}


if (childKSPParticleEmitter != null)
{
// Destroy them ?
childKSPParticleEmitter.pr.enabled = false;
childKSPParticleEmitter.pe.enabled = false;
childKSPParticleEmitter.enabled = false;

ParticleSystem particleSystem = childKSPParticleEmitter.gameObject.AddComponent<ParticleSystem>();
ParticleSystem particleSystem = childKSPParticleEmitter.gameObject.GetComponent<ParticleSystem>();
ParticleSystemRenderer particleSystemRenderer = childKSPParticleEmitter.gameObject.GetComponent<ParticleSystemRenderer>();

PersistentKSPShurikenEmitter pkpe = new PersistentKSPShurikenEmitter(
emitterGameObject,
particleSystem,
particleSystemRenderer,
templateKspParticleEmitter);

particleSystem.simulationSpace = childKSPParticleEmitter.pe.useWorldSpace
? ParticleSystemSimulationSpace.World
: ParticleSystemSimulationSpace.Local;

particleSystem.maxParticles = particleCountLimit;
childKSPParticleEmitter);

particleSystemRenderer.material = childKSPParticleEmitter.pr.material;

// TODO Actually copy the mode from childKSPParticleEmitter.particleRenderMode?
particleSystemRenderer.renderMode = ParticleSystemRenderMode.Billboard;

try
{
childKSPParticleEmitter.particleRenderMode =
(ParticleRenderMode)Enum.Parse(typeof(ParticleRenderMode), renderMode);
}
catch (ArgumentException)
{
Print("ModelMultiParticleFXExt: " + renderMode + " is not a valid ParticleRenderMode");
}
// We do the emission and animation ourselves so we disable the KSP code
childKSPParticleEmitter.emit = false;
childKSPParticleEmitter.SetupProperties();
childKSPParticleEmitter.enabled = false;

switch (childKSPParticleEmitter.particleRenderMode)
{
case ParticleRenderMode.Billboard:
particleSystemRenderer.renderMode = ParticleSystemRenderMode.Billboard;
break;
case ParticleRenderMode.Stretch:
particleSystemRenderer.renderMode = ParticleSystemRenderMode.Stretch;
break;
case ParticleRenderMode.SortedBillboard:
particleSystemRenderer.renderMode = ParticleSystemRenderMode.Billboard;
particleSystemRenderer.sortMode = ParticleSystemSortMode.Distance;
break;
case ParticleRenderMode.HorizontalBillboard:
particleSystemRenderer.renderMode = ParticleSystemRenderMode.HorizontalBillboard;
break;
case ParticleRenderMode.VerticalBillboard:
particleSystemRenderer.renderMode = ParticleSystemRenderMode.VerticalBillboard;
break;
default:
particleSystemRenderer.renderMode = ParticleSystemRenderMode.Billboard;
break;
}
ParticleSystem.MainModule main = particleSystem.main;
main.maxParticles = particleCountLimit;

//particleSystemRenderer.alignment = ParticleSystemRenderSpace.View;

Expand Down Expand Up @@ -668,12 +624,10 @@ public override void OnInitialize()
}
}

Destroy(model);

list.Add(this);

// 1.0 don't seems to properly do this for engines.
OnEvent(0f);
//OnEvent(0f);
}

private static void DisableCollider(GameObject go)
Expand Down
64 changes: 40 additions & 24 deletions PersistentKSPShurikenEmitter.cs
Expand Up @@ -28,6 +28,7 @@
using System;
using SmokeScreen;
using UnityEngine;
using UnityEngine.Profiling;
using Random = UnityEngine.Random;

// TODO : handle the relation with PersistentEmitterManager inside the class
Expand Down Expand Up @@ -272,7 +273,7 @@ private void Emit()
}

Vector3 vel;
if (pe.simulationSpace == ParticleSystemSimulationSpace.Local)
if (pe.main.simulationSpace == ParticleSystemSimulationSpace.Local)
{
vel = localVelocity + new Vector3(
Random.Range(-rndVelocity.x, rndVelocity.x),
Expand Down Expand Up @@ -338,10 +339,9 @@ public void EmitterOnUpdate(Vector3 emitterWorldVelocity)
}
Profiler.EndSample();

if (particles == null || pe.maxParticles > particles.Length)
particles = new ParticleSystem.Particle[pe.maxParticles];
if (particles == null || pe.main.maxParticles > particles.Length)
particles = new ParticleSystem.Particle[pe.main.maxParticles];

// This line (and the one that does the oposite at the end) is actally the slowest part of the whole function
Profiler.BeginSample("GetParticles");
int numParticlesAlive = pe.GetParticles(particles);
Profiler.EndSample();
Expand All @@ -362,7 +362,7 @@ public void EmitterOnUpdate(Vector3 emitterWorldVelocity)

Vector3d frameVel = Krakensbane.GetFrameVelocity();

bool useWorldSpace = pe.simulationSpace == ParticleSystemSimulationSpace.World;
bool useWorldSpace = pe.main.simulationSpace == ParticleSystemSimulationSpace.World;

Profiler.BeginSample("Loop");

Expand All @@ -371,7 +371,7 @@ public void EmitterOnUpdate(Vector3 emitterWorldVelocity)
{
ParticleSystem.Particle particle = particles[j];

//Profiler.BeginSample("Cull");
Profiler.BeginSample("Cull");
// Check if we need to cull the number of particles
if (SmokeScreenConfig.particleDecimate != 0 && numParticlesAlive > SmokeScreenConfig.decimateFloor)
{
Expand All @@ -381,22 +381,23 @@ public void EmitterOnUpdate(Vector3 emitterWorldVelocity)
|| (SmokeScreenConfig.particleDecimate < 0
&& (SmokeScreenConfig.particleCounter % SmokeScreenConfig.particleDecimate) != 0))
{
particle.lifetime = 0; // energy set to 0 remove the particle, as per Unity doc
particle.remainingLifetime = 0; // energy set to 0 remove the particle, as per Unity doc
}
}
//Profiler.EndSample();
Profiler.EndSample();

if (particle.lifetime > 0)
if (particle.remainingLifetime > 0)
{
//Slight methodology change to avoid duplicating if statements:
Vector3d pVel;
Vector3d pPos;
Profiler.BeginSample("lifetime");
if (useWorldSpace)
{
pVel = particle.velocity + frameVel;
pPos = particle.position;
}
else if (!useWorldSpace && particle.lifetime == particle.startLifetime)
else if (!useWorldSpace && particle.remainingLifetime == particle.startLifetime)
{
Vector3 lVel = new Vector3(0, 0, 1);
Vector3 lPos = particle.position;
Expand Down Expand Up @@ -432,7 +433,7 @@ public void EmitterOnUpdate(Vector3 emitterWorldVelocity)
pVel = peTransform.TransformDirection(lVel)
+ frameVel;
}
else if (!useWorldSpace && particle.lifetime != particle.startLifetime)
else if (!useWorldSpace && particle.remainingLifetime != particle.startLifetime)
{
pPos = peTransform.TransformPoint(particle.position);
pVel = peTransform.TransformDirection(particle.velocity.x * xyForce,
Expand All @@ -445,14 +446,15 @@ public void EmitterOnUpdate(Vector3 emitterWorldVelocity)
pPos = peTransform.TransformPoint(particle.position);
pVel = peTransform.TransformDirection(particle.velocity) + frameVel;
}

Profiler.EndSample();
// try-finally block to ensure we set the particle velocities correctly in the end.
try
{
// Fixed update is not the best place to update the size but the particles array copy is
// slow so doing each frame would be worse


Profiler.BeginSample("Grow");

if (sizeGrow != 0.0)
{
particle.startSize = particle.startSize * growConst;
Expand All @@ -463,16 +465,17 @@ public void EmitterOnUpdate(Vector3 emitterWorldVelocity)
// Euler integration of the derivative of Log(logarithmicGrowth * t + 1) + 1.
// This might look weird.

particle.startSize += (float) ((logGrowConst / (1 + (particle.startLifetime - particle.lifetime) * logarithmicGrow)) * averageSize);
particle.startSize += (float) ((logGrowConst / (1 + (particle.startLifetime - particle.remainingLifetime) * logarithmicGrow)) * averageSize);
}
if (linearGrow != 0.0)
{
particle.startSize += linGrowConst;
}

particle.startSize = Mathf.Min(particle.startSize, sizeClamp);

if (particle.lifetime == particle.startLifetime)
Profiler.EndSample();
Profiler.BeginSample("Velocity");
if (particle.remainingLifetime == particle.startLifetime)
{

if (useWorldSpace)
Expand Down Expand Up @@ -519,36 +522,44 @@ public void EmitterOnUpdate(Vector3 emitterWorldVelocity)

}
}

Profiler.EndSample();
Profiler.BeginSample("ParticlePhysics");
if (physical && (j % physicsPass == activePhysicsPass))
{
// There must be a way to keep the actual initial volume,
// but I'm lazy.
pVel = ParticlePhysics(particle.size, averageSize, pPos, pVel);
pVel = ParticlePhysics(particle.startSize, averageSize, pPos, pVel);

}

if (collide && particle.lifetime != particle.startLifetime
Profiler.EndSample();
Profiler.BeginSample("ParticleCollision");
if (collide && particle.remainingLifetime != particle.startLifetime

// Do not collide newly created particles (they collide with the emitter and things look bad).
&& (j % physicsPass == activePhysicsPass))
{
pVel = ParticleCollision(pPos, pVel, mask);

}

Profiler.EndSample();
}
finally
{
particle.velocity = pe.simulationSpace == ParticleSystemSimulationSpace.World
Profiler.BeginSample("SetVelPos");
particle.velocity = pe.main.simulationSpace == ParticleSystemSimulationSpace.World
? (Vector3)(pVel - frameVel)
: peTransform.InverseTransformDirection(pVel - frameVel);
particle.position = pe.simulationSpace == ParticleSystemSimulationSpace.World
particle.position = pe.main.simulationSpace == ParticleSystemSimulationSpace.World
? (Vector3)pPos
: peTransform.InverseTransformPoint(pPos);
Profiler.EndSample();
}


if (doesAnimateColor)
{
float lifePercentage = 1 - (particle.lifetime / particle.startLifetime);
Profiler.BeginSample("AnimateColor");
float lifePercentage = 1 - (particle.remainingLifetime / particle.startLifetime);

float lerp;
Color a;
Expand Down Expand Up @@ -580,9 +591,12 @@ public void EmitterOnUpdate(Vector3 emitterWorldVelocity)

Color c = Color.Lerp(a, b, lerp);
particle.startColor = c;
Profiler.EndSample();
}
}
Profiler.BeginSample("SetParticle");
particles[j] = particle;
Profiler.EndSample();
}
Profiler.EndSample();
activePhysicsPass = ++activePhysicsPass % physicsPass;
Expand All @@ -593,6 +607,7 @@ public void EmitterOnUpdate(Vector3 emitterWorldVelocity)
SmokeScreenConfig.activeParticles += pe.particleCount;
}

//[MethodImpl(MethodImplOptions.AggressiveInlining)]
private Vector3 ParticlePhysics(double radius, double initialRadius, Vector3d pPos, Vector3d pVel)
{
// N.B.: multiplications rather than Pow, Pow is slow,
Expand All @@ -618,6 +633,7 @@ private Vector3 ParticlePhysics(double radius, double initialRadius, Vector3d pP
return pVel + acceleration * TimeWarp.fixedDeltaTime * physicsPass;
}

//[MethodImpl(MethodImplOptions.AggressiveInlining)]
private Vector3 ParticleCollision(Vector3d pPos, Vector3d pVel, int mask)
{
RaycastHit hit;
Expand Down

0 comments on commit 96816d2

Please sign in to comment.