void UpdateMatrix(ParticleEmitterShape emitShape, Transform trans) { var localScale = trans.localScale; Profiler.BeginSample("Set matrices"); Matrix4x4 id = Matrix4x4.identity; switch (Manager.SimulationSpace) { case Space.World: var rot = trans.rotation; if (m_lastRot != rot || m_lastScale != localScale) { m_emitMatrix = Matrix4x4.TRS(Vector3.zero, rot, localScale); m_emitRotationMatrix = Matrix4x4.TRS(Vector3.zero, rot, Vector3.one); m_lastRot = rot; m_lastScale = localScale; } TCHelper.SetMatrix4(ComputeShader, "emitterMatrix", m_emitMatrix); TCHelper.SetMatrix3(ComputeShader, "emitterRotationMatrix", m_emitRotationMatrix); break; case Space.Local: TCHelper.SetMatrix4(ComputeShader, "emitterMatrix", Matrix4x4.TRS(Vector3.zero, Quaternion.identity, localScale)); TCHelper.SetMatrix3(ComputeShader, "emitterRotationMatrix", id); break; case Space.LocalWithScale: TCHelper.SetMatrix4(ComputeShader, "emitterMatrix", id); TCHelper.SetMatrix3(ComputeShader, "emitterRotationMatrix", id); break; case Space.Parent: if (trans.parent != null) { var rot2 = trans.localRotation; TCHelper.SetMatrix4(ComputeShader, "emitterMatrix", Matrix4x4.TRS(Vector3.zero, rot2, localScale)); TCHelper.SetMatrix3(ComputeShader, "emitterRotationMatrix", Matrix4x4.TRS(Vector3.zero, rot2, Vector3.one)); } break; } if (emitShape.startDirectionType == StartDirectionType.Vector) { TCHelper.SetMatrix3(ComputeShader, "emitterStartRotationMatrix", Matrix4x4.TRS(Vector3.zero, Quaternion.FromToRotation(Vector3.forward, emitShape.startDirectionVector), Vector3.one)); } Profiler.EndSample(); }
void SetShapeData(ParticleEmitterShape emitShape, Transform trans, ref Vector3 prevPos, ref Vector3 prevSpeed) { var emitter = m_emitSet[0]; emitter.EmitOffset = (uint)((Manager.Offset + Manager.NumParticles) % Manager.MaxParticles); if (m_toEmitList == null) { emitter.Shape = (uint)emitShape.shape; switch (emitShape.shape) { case EmitShapes.Box: emitter.CubeSize = emitShape.cubeSize * 0.5f; break; case EmitShapes.Cone: emitter.RadiusMin = emitShape.coneRadius; float tan = Mathf.Tan(emitShape.coneAngle * Mathf.Deg2Rad); emitter.RadiusMax = emitShape.coneRadius + tan * emitShape.coneHeight; emitter.ConePointUnder = new Vector3(0.0f, 0.0f, -Mathf.Tan((90.0f - emitShape.coneAngle) * Mathf.Deg2Rad) * emitShape.coneRadius); emitter.ConeHeight = emitShape.coneHeight; break; case EmitShapes.HemiSphere: emitter.RadiusMin = emitShape.radius.IsConstant ? 0.0f : Mathf.Max(Mathf.Min(emitShape.radius.Min, emitShape.radius.Max), 0); emitter.RadiusMax = emitShape.radius.Max; break; case EmitShapes.Line: emitter.LineLength = emitShape.lineLength; emitter.RadiusMin = 0.0f; emitter.RadiusMax = emitShape.lineRadius; break; case EmitShapes.Mesh: pes.SetMeshData(ComputeShader, EmitKernel, ref emitter); break; case EmitShapes.Ring: emitter.RadiusMin = emitShape.ringRadius; emitter.RadiusMax = emitShape.ringOuterRadius; break; case EmitShapes.Sphere: emitter.RadiusMin = emitShape.radius.IsConstant ? 0.0f : Mathf.Max(Mathf.Min(emitShape.radius.Min, emitShape.radius.Max), 0.0f); emitter.RadiusMax = emitShape.radius.Max; break; } } else { emitter.Shape = (uint)EmitShapes.Mesh + 1; pes.SetListData(ComputeShader, EmitKernel, m_toEmitList); ComputeShader.SetVector("_UseVelSizeColor", m_emitUseVelSizeColor); m_toEmitList = null; } emitter.VelType = (uint)emitShape.startDirectionType; emitter.RandomAngle = Mathf.Cos(emitShape.startDirectionRandomAngle * Mathf.Deg2Rad); var localScale = trans.localScale; emitter.Scale = localScale; UpdateMatrix(emitShape, trans); emitter.Pos = prevPos; var pos = GetEmitPos(trans); Vector3 speed = pos - prevPos; emitter.Vel = speed; prevPos = pos; emitter.Accel = (speed - prevSpeed); prevSpeed = speed; m_emitSet[0] = emitter; m_emitBuffer.SetData(m_emitSet); }