summaryrefslogtreecommitdiff
path: root/Runtime/Graphics/ParticleSystem/ParticleSystemParticle.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-14 22:50:43 +0800
committerchai <chaifix@163.com>2019-08-14 22:50:43 +0800
commit15740faf9fe9fe4be08965098bbf2947e096aeeb (patch)
treea730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Graphics/ParticleSystem/ParticleSystemParticle.cpp
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/Graphics/ParticleSystem/ParticleSystemParticle.cpp')
-rw-r--r--Runtime/Graphics/ParticleSystem/ParticleSystemParticle.cpp323
1 files changed, 323 insertions, 0 deletions
diff --git a/Runtime/Graphics/ParticleSystem/ParticleSystemParticle.cpp b/Runtime/Graphics/ParticleSystem/ParticleSystemParticle.cpp
new file mode 100644
index 0000000..d10bee0
--- /dev/null
+++ b/Runtime/Graphics/ParticleSystem/ParticleSystemParticle.cpp
@@ -0,0 +1,323 @@
+#include "UnityPrefix.h"
+#include "ParticleSystemParticle.h"
+
+#include "Runtime/Dynamics/Collider.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+#include "Runtime/Threads/Thread.h"
+
+void InitializeEmitAccumulator(dynamic_array<float>& emitAccumulator, const size_t count)
+{
+ emitAccumulator.resize_uninitialized(count);
+ memset(emitAccumulator.begin(), 0, count * sizeof(float));
+}
+
+ParticleCollisionEvent::ParticleCollisionEvent (const Vector3f& intersection, const Vector3f& normal, const Vector3f& velocity, int colliderInstanceID, int rigidBodyOrColliderInstanceID)
+{
+ m_Intersection = intersection;
+ m_Normal = normal;
+ m_Velocity = velocity;
+ m_ColliderInstanceID = colliderInstanceID;
+ m_RigidBodyOrColliderInstanceID = rigidBodyOrColliderInstanceID;
+}
+
+size_t ParticleSystemParticles::GetParticleSize()
+{
+ // @TODO: How do we guard against elements we remove
+ return sizeof(ParticleSystemParticle);
+}
+
+void ParticleSystemParticles::SetUsesAxisOfRotation()
+{
+ usesAxisOfRotation = true;
+ const size_t count = position.size();
+ axisOfRotation.resize_uninitialized(count);
+ for(int i = 0; i < count; i++)
+ axisOfRotation[i] = Vector3f::yAxis;
+}
+
+void ParticleSystemParticles::SetUsesRotationalSpeed()
+{
+ usesRotationalSpeed = true;
+ const size_t count = position.size();
+ rotationalSpeed.resize_uninitialized(count);
+ for(int i = 0; i < count; i++)
+ rotationalSpeed[i] = 0.0f;
+}
+
+void ParticleSystemParticles::SetUsesCollisionEvents (bool wantUsesCollisionEvents)
+{
+ if (usesCollisionEvents == wantUsesCollisionEvents) return;
+ usesCollisionEvents = wantUsesCollisionEvents;
+ if (!usesCollisionEvents)
+ {
+ collisionEvents.Clear ();
+ }
+}
+
+bool ParticleSystemParticles::GetUsesCollisionEvents () const
+{
+ return usesCollisionEvents;
+}
+
+void ParticleSystemParticles::SetUsesEmitAccumulator(int numAccumulators)
+{
+ Assert(numAccumulators <= kParticleSystemMaxNumEmitAccumulators);
+ const size_t count = position.size();
+ for(int i = numEmitAccumulators; i < numAccumulators; i++)
+ InitializeEmitAccumulator(emitAccumulator[i], count);
+
+ numEmitAccumulators = numAccumulators;
+}
+
+void ParticleSystemParticles::CopyFromArrayAOS(ParticleSystemParticle* particles, int size)
+{
+ Assert(usesAxisOfRotation);
+ Assert(numEmitAccumulators == kParticleSystemMaxNumEmitAccumulators);
+ for(int i = 0; i < size; i++)
+ {
+ (*this).position[i] = particles[i].position;
+ (*this).velocity[i] = particles[i].velocity;
+ (*this).animatedVelocity[i] = particles[i].animatedVelocity;
+ (*this).axisOfRotation[i] = particles[i].axisOfRotation;
+ (*this).rotation[i] = particles[i].rotation;
+ if(usesRotationalSpeed)
+ (*this).rotationalSpeed[i] = particles[i].rotationalSpeed;
+ (*this).size[i] = particles[i].size;
+ (*this).color[i] = particles[i].color;
+ (*this).randomSeed[i] = particles[i].randomSeed;
+ (*this).lifetime[i] = particles[i].lifetime;
+ (*this).startLifetime[i] = particles[i].startLifetime;
+ for(int acc = 0; acc < kParticleSystemMaxNumEmitAccumulators; acc++)
+ (*this).emitAccumulator[acc][i] = particles[i].emitAccumulator[acc];
+ }
+}
+
+void ParticleSystemParticles::CopyToArrayAOS(ParticleSystemParticle* particles, int size)
+{
+ Assert(usesAxisOfRotation);
+ Assert(numEmitAccumulators == kParticleSystemMaxNumEmitAccumulators);
+ for(int i = 0; i < size; i++)
+ {
+ particles[i].position = (*this).position[i];
+ particles[i].velocity = (*this).velocity[i];
+ particles[i].animatedVelocity = (*this).animatedVelocity[i];
+ particles[i].axisOfRotation = (*this).axisOfRotation[i];
+ particles[i].rotation = (*this).rotation[i];
+ if(usesRotationalSpeed)
+ particles[i].rotationalSpeed = (*this).rotationalSpeed[i];
+ particles[i].size = (*this).size[i];
+ particles[i].color = (*this).color[i];
+ particles[i].randomSeed = (*this).randomSeed[i];
+ particles[i].lifetime = (*this).lifetime[i];
+ particles[i].startLifetime = (*this).startLifetime[i];
+ for(int acc = 0; acc < kParticleSystemMaxNumEmitAccumulators; acc++)
+ particles[i].emitAccumulator[acc] = (*this).emitAccumulator[acc][i];
+ }
+}
+
+void ParticleSystemParticles::AddParticle(ParticleSystemParticle* particle)
+{
+ const size_t count = array_size();
+ array_resize(count+1);
+ position[count] = particle->position;
+ velocity[count] = particle->velocity;
+ animatedVelocity[count] = Vector3f::zero;
+ lifetime[count] = particle->lifetime;
+ startLifetime[count] = particle->startLifetime;
+ size[count] = particle->size;
+ rotation[count] = particle->rotation;
+ if(usesRotationalSpeed)
+ rotationalSpeed[count] = particle->rotationalSpeed;
+ color[count] = particle->color;
+ randomSeed[count] = particle->randomSeed;
+ if(usesAxisOfRotation)
+ axisOfRotation[count] = particle->axisOfRotation;
+ for(int acc = 0; acc < numEmitAccumulators; acc++)
+ emitAccumulator[acc][count] = 0.0f;
+}
+
+size_t ParticleSystemParticles::array_size () const
+{
+ return position.size();
+}
+
+void ParticleSystemParticles::array_resize (size_t i)
+{
+ position.resize_uninitialized(i);
+ velocity.resize_uninitialized(i);
+ animatedVelocity.resize_uninitialized(i);
+ rotation.resize_uninitialized(i);
+ if(usesRotationalSpeed)
+ rotationalSpeed.resize_uninitialized(i);
+ size.resize_uninitialized(i);
+ color.resize_uninitialized(i);
+ randomSeed.resize_uninitialized(i);
+ lifetime.resize_uninitialized(i);
+ startLifetime.resize_uninitialized(i);
+ if(usesAxisOfRotation)
+ axisOfRotation.resize_uninitialized(i);
+ for(int acc = 0; acc < numEmitAccumulators; acc++)
+ emitAccumulator[acc].resize_uninitialized(i);
+}
+
+void ParticleSystemParticles::element_swap(size_t i, size_t j)
+{
+ std::swap(position[i], position[j]);
+ std::swap(velocity[i], velocity[j]);
+ std::swap(animatedVelocity[i], animatedVelocity[j]);
+ std::swap(rotation[i], rotation[j]);
+ if(usesRotationalSpeed)
+ std::swap(rotationalSpeed[i], rotationalSpeed[j]);
+ std::swap(size[i], size[j]);
+ std::swap(color[i], color[j]);
+ std::swap(randomSeed[i], randomSeed[j]);
+ std::swap(lifetime[i], lifetime[j]);
+ std::swap(startLifetime[i], startLifetime[j]);
+ if(usesAxisOfRotation)
+ std::swap(axisOfRotation[i], axisOfRotation[j]);
+ for(int acc = 0; acc < numEmitAccumulators; acc++)
+ std::swap(emitAccumulator[acc][i], emitAccumulator[acc][j]);
+}
+
+void ParticleSystemParticles::element_assign(size_t i, size_t j)
+{
+ position[i] = position[j];
+ velocity[i] = velocity[j];
+ animatedVelocity[i] = animatedVelocity[j];
+ rotation[i] = rotation[j];
+ if(usesRotationalSpeed)
+ rotationalSpeed[i] = rotationalSpeed[j];
+ size[i] = size[j];
+ color[i] = color[j];
+ randomSeed[i] = randomSeed[j];
+ lifetime[i] = lifetime[j];
+ startLifetime[i] = startLifetime[j];
+ if(usesAxisOfRotation)
+ axisOfRotation[i] = axisOfRotation[j];
+ for(int acc = 0; acc < numEmitAccumulators; acc++)
+ emitAccumulator[acc][i] = emitAccumulator[acc][j];
+}
+
+void ParticleSystemParticles::array_assign_external(void* data, const int numParticles)
+{
+#define SHURIKEN_INCREMENT_ASSIGN_PTRS(element, type) { beginPtr = endPtr; endPtr += numParticles * sizeof(type); (element).assign_external((type*)beginPtr, (type*)endPtr); }
+
+ UInt8* beginPtr = 0;
+ UInt8* endPtr = (UInt8*)data;
+
+ SHURIKEN_INCREMENT_ASSIGN_PTRS(position, Vector3f);
+ SHURIKEN_INCREMENT_ASSIGN_PTRS(velocity, Vector3f);
+ SHURIKEN_INCREMENT_ASSIGN_PTRS(animatedVelocity, Vector3f);
+ SHURIKEN_INCREMENT_ASSIGN_PTRS(rotation, float);
+ if(usesRotationalSpeed)
+ SHURIKEN_INCREMENT_ASSIGN_PTRS(rotationalSpeed, float);
+ SHURIKEN_INCREMENT_ASSIGN_PTRS(size, float);
+ SHURIKEN_INCREMENT_ASSIGN_PTRS(color, ColorRGBA32);
+ SHURIKEN_INCREMENT_ASSIGN_PTRS(randomSeed, UInt32);
+ SHURIKEN_INCREMENT_ASSIGN_PTRS(lifetime, float);
+ SHURIKEN_INCREMENT_ASSIGN_PTRS(startLifetime, float);
+ if(usesAxisOfRotation)
+ SHURIKEN_INCREMENT_ASSIGN_PTRS(axisOfRotation, Vector3f);
+ for(int acc = 0; acc < numEmitAccumulators; acc++)
+ SHURIKEN_INCREMENT_ASSIGN_PTRS(emitAccumulator[acc], float);
+#undef SHURIKEN_INCREMENT_ASSIGN_PTRS
+}
+
+void ParticleSystemParticles::array_merge_preallocated(const ParticleSystemParticles& rhs, const int offset, const bool needAxisOfRotation, const bool needEmitAccumulator)
+{
+#define SHURIKEN_COPY_DATA(element, type) memcpy(&element[offset], &rhs.element[0], count * sizeof(type))
+
+ const size_t count = rhs.array_size();
+ if(0 == count)
+ return;
+
+ Assert((rhs.array_size() + offset) <= array_size());
+ SHURIKEN_COPY_DATA(position, Vector3f);
+ SHURIKEN_COPY_DATA(velocity, Vector3f);
+ SHURIKEN_COPY_DATA(animatedVelocity, Vector3f);
+ SHURIKEN_COPY_DATA(rotation, float);
+ if(usesRotationalSpeed)
+ SHURIKEN_COPY_DATA(rotationalSpeed, float);
+ SHURIKEN_COPY_DATA(size, float);
+ SHURIKEN_COPY_DATA(color, ColorRGBA32);
+ SHURIKEN_COPY_DATA(randomSeed, UInt32);
+ SHURIKEN_COPY_DATA(lifetime, float);
+ SHURIKEN_COPY_DATA(startLifetime, float);
+
+ if(needAxisOfRotation)
+ {
+ Assert(usesAxisOfRotation && rhs.usesAxisOfRotation);
+ SHURIKEN_COPY_DATA(axisOfRotation, Vector3f);
+ }
+ if(needEmitAccumulator)
+ {
+ Assert(numEmitAccumulators && rhs.numEmitAccumulators);
+ Assert(numEmitAccumulators == rhs.numEmitAccumulators);
+ for(int acc = 0; acc < numEmitAccumulators; acc++)
+ SHURIKEN_COPY_DATA(emitAccumulator[acc], float);
+ }
+
+#undef SHURIKEN_COPY_DATA
+}
+
+
+void ParticleSystemParticles::array_assign(const ParticleSystemParticles& rhs)
+{
+ position.assign(rhs.position.begin(), rhs.position.end());
+ velocity.assign(rhs.velocity.begin(), rhs.velocity.end());
+ animatedVelocity.assign(rhs.animatedVelocity.begin(), rhs.animatedVelocity.end());
+ rotation.assign(rhs.rotation.begin(), rhs.rotation.end());
+ if(usesRotationalSpeed)
+ rotationalSpeed.assign(rhs.rotationalSpeed.begin(), rhs.rotationalSpeed.end());
+ size.assign(rhs.size.begin(), rhs.size.end());
+ color.assign(rhs.color.begin(), rhs.color.end());
+ randomSeed.assign(rhs.randomSeed.begin(), rhs.randomSeed.end());
+ lifetime.assign(rhs.lifetime.begin(), rhs.lifetime.end());
+ startLifetime.assign(rhs.startLifetime.begin(), rhs.startLifetime.end());
+ if(usesAxisOfRotation)
+ axisOfRotation.assign(rhs.axisOfRotation.begin(), rhs.axisOfRotation.end());
+ for(int acc = 0; acc < numEmitAccumulators; acc++)
+ emitAccumulator[acc].assign(rhs.emitAccumulator[acc].begin(), rhs.emitAccumulator[acc].end());
+}
+
+void ParticleSystemParticles::array_lerp(ParticleSystemParticles& output, const ParticleSystemParticles& a, const ParticleSystemParticles& b, float factor)
+{
+ DebugAssert(a.array_size() == b.array_size()); // else it doesn't really make sense
+ DebugAssert(a.usesRotationalSpeed == b.usesRotationalSpeed);
+
+ const int count = a.array_size();
+ output.array_resize(count);
+
+ // Note: Not all data is interpolated here intentionally, because it doesn't change anything or because it's incorrect
+
+ #define SHURIKEN_LERP_DATA(element, type) for(int i = 0; i < count; i++) output.element[i] = Lerp(a.element[i], b.element[i], factor)
+ SHURIKEN_LERP_DATA(position, Vector3f);
+ SHURIKEN_LERP_DATA(velocity, Vector3f);
+ SHURIKEN_LERP_DATA(animatedVelocity, Vector3f);
+
+ SHURIKEN_LERP_DATA(rotation, float);
+ if(a.usesRotationalSpeed)
+ SHURIKEN_LERP_DATA(rotationalSpeed, float);
+ SHURIKEN_LERP_DATA(lifetime, float);
+
+ #undef SHURIKEN_LERP_DATA
+}
+
+ParticleSystemParticlesTempData::ParticleSystemParticlesTempData()
+:color(0)
+,size(0)
+,sheetIndex(0)
+,particleCount(0)
+{}
+
+void ParticleSystemParticlesTempData::element_swap(size_t i, size_t j)
+{
+ DebugAssert(i <= particleCount);
+ DebugAssert(j <= particleCount);
+
+ std::swap(color[i], color[j]);
+ std::swap(size[i], size[j]);
+ if(sheetIndex)
+ std::swap(sheetIndex[i], sheetIndex[j]);
+}
+