Esempio n. 1
0
        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.SetMatrix(ComputeShader, SID._EmitterMatrix, m_emitMatrix);
                TCHelper.SetMatrix(ComputeShader, SID._EmitterRotationMatrix, m_emitRotationMatrix);

                break;

            case Space.Local:
                TCHelper.SetMatrix(ComputeShader, SID._EmitterMatrix, Matrix4x4.TRS(Vector3.zero, Quaternion.identity, localScale));
                TCHelper.SetMatrix(ComputeShader, SID._EmitterRotationMatrix, id);
                break;

            case Space.LocalWithScale:
                TCHelper.SetMatrix(ComputeShader, SID._EmitterMatrix, id);
                TCHelper.SetMatrix(ComputeShader, SID._EmitterRotationMatrix, id);
                break;

            case Space.Parent:
                if (trans.parent != null)
                {
                    var rot2 = trans.localRotation;
                    TCHelper.SetMatrix(ComputeShader, SID._EmitterMatrix, Matrix4x4.TRS(Vector3.zero, rot2, localScale));
                    TCHelper.SetMatrix(ComputeShader, SID._EmitterRotationMatrix, Matrix4x4.TRS(Vector3.zero, rot2, Vector3.one));
                }
                break;
            }

            if (emitShape.startDirectionType == StartDirection.Vector)
            {
                TCHelper.SetMatrix(ComputeShader, SID._EmitterStartRotationMatrix,
                                   Matrix4x4.TRS(Vector3.zero, Quaternion.FromToRotation(Vector3.forward, emitShape.startDirectionVector), Vector3.one));
            }

            Profiler.EndSample();
        }
Esempio n. 2
0
 private static extern void Internal_setShape(IntPtr thisPtr, ParticleEmitterShape shape);
        public static void DrawEmitterShape(ParticleEmitterShape pes, Transform transform, TCWireframeDrawer drawer)
        {
            var col = new Color(0.6f, 0.9f, 1.0f);

            Handles.color = col;

            switch (pes.shape)
            {
            case EmitShapes.Sphere:
                pes.radius.Max = RadiusHandle(transform, pes.radius.Max, true);

                if (!pes.radius.IsConstant)
                {
                    Handles.color = new Color(0.6f, 0.9f, 1.0f, 0.4f);

                    if (pes.radius.Min > 0.0f)
                    {
                        pes.radius.Min = RadiusHandle(transform, pes.radius.Min, true);
                    }
                    Handles.color = col;
                }
                break;


            case EmitShapes.Box:
                pes.cubeSize = CubeHandle(transform, pes.cubeSize);
                break;

            case EmitShapes.HemiSphere:
                pes.radius.Value = HemisphereHandle(transform, pes.radius.Max, true);

                if (!pes.radius.IsConstant)
                {
                    if (pes.radius.Min > 0.0f)
                    {
                        pes.radius.Min = HemisphereHandle(transform, pes.radius.Min, true);
                    }
                }

                break;

            case EmitShapes.Cone:

                float coneAngle  = pes.coneAngle;
                float coneHeight = pes.coneHeight;
                float coneRadius = pes.coneRadius;


                ConeHandle(ref coneAngle, ref coneHeight, ref coneRadius, transform);

                pes.coneAngle  = coneAngle;
                pes.coneHeight = coneHeight;
                pes.coneRadius = coneRadius;

                break;

            case EmitShapes.Ring:

                float ringRadius = pes.ringRadius;
                float ringOuter  = pes.ringOuterRadius;

                TorusHandle(ref ringRadius, ref ringOuter, transform);

                pes.ringRadius      = ringRadius;
                pes.ringOuterRadius = ringOuter;
                break;

            case EmitShapes.Line:
                pes.lineLength = LineHandle(pes.lineLength, transform);
                break;

            case EmitShapes.Mesh:
                if (pes.emitMesh == null)
                {
                    break;
                }

                drawer.DrawWireMesh(transform);
                break;
            }
        }
        private static void Draw(ParticleSystem component)
        {
            SceneObject so = component.SceneObject;

            // Draw collision planes, if enabled
            Gizmos.Color = Color.Yellow;
            ParticleEvolver[] evolvers = component.Evolvers;
            foreach (var entry in evolvers)
            {
                if (entry is ParticleCollisions collisions)
                {
                    if (collisions.Options.mode == ParticleCollisionMode.Plane)
                    {
                        void DrawPlane(Vector3 position, Vector3 right, Vector3 up, Vector3 forward)
                        {
                            Vector3 topLeft  = position - right + up;
                            Vector3 topRight = position + right + up;
                            Vector3 botLeft  = position - right - up;
                            Vector3 botRight = position + right - up;

                            Gizmos.DrawLine(topLeft, topRight);
                            Gizmos.DrawLine(topRight, botRight);
                            Gizmos.DrawLine(botRight, botLeft);
                            Gizmos.DrawLine(botLeft, topLeft);

                            Gizmos.DrawLine(position, position + forward * 0.4f);
                        }

                        SceneObject[] planeObjects = collisions.PlaneObjects;
                        foreach (var planeSO in planeObjects)
                        {
                            Vector3 position = planeSO.Position;
                            Vector3 right    = planeSO.Rotation.Rotate(Vector3.XAxis);
                            Vector3 up       = planeSO.Rotation.Rotate(Vector3.YAxis);
                            Vector3 forward  = planeSO.Forward;

                            DrawPlane(position, right, up, forward);
                        }

                        Plane[] planes = collisions.Planes;
                        foreach (var plane in planes)
                        {
                            Vector3 right, up;
                            Vector3.OrthogonalComplement(plane.normal, out right, out up);

                            DrawPlane(plane.normal * plane.d, right, up, plane.normal);
                        }
                    }
                }
            }

            // Draw emitter shapes
            Gizmos.Transform = Matrix4.TRS(so.Position, Quaternion.LookRotation(so.Rotation.Forward, so.Rotation.Up), Vector3.One);
            Gizmos.Color     = Color.Green;

            ParticleEmitter[] emitters = component.Emitters;
            foreach (var entry in emitters)
            {
                ParticleEmitterShape shape = entry?.Shape;
                if (shape == null)
                {
                    continue;
                }

                if (shape is ParticleEmitterBoxShape boxShape)
                {
                    Gizmos.DrawWireCube(Vector3.Zero, boxShape.Options.extents);
                }
                else if (shape is ParticleEmitterSphereShape sphereShape)
                {
                    ParticleSphereShapeOptions options = sphereShape.Options;
                    Gizmos.DrawWireSphere(Vector3.Zero, options.radius);

                    if (options.thickness > 0.0f)
                    {
                        float innerRadius = options.radius * (1.0f - MathEx.Clamp01(options.thickness));
                        if (options.thickness < 1.0f)
                        {
                            Gizmos.Color = Color.Green * new Color(0.5f, 0.5f, 0.5f);
                            Gizmos.DrawWireSphere(Vector3.Zero, innerRadius);
                        }

                        Gizmos.Color = Color.Green * new Color(0.25f, 0.25f, 0.25f);
                        Gizmos.DrawLine(Vector3.XAxis * innerRadius, Vector3.XAxis * options.radius);
                        Gizmos.DrawLine(-Vector3.XAxis * innerRadius, -Vector3.XAxis * options.radius);
                        Gizmos.DrawLine(Vector3.YAxis * innerRadius, Vector3.YAxis * options.radius);
                        Gizmos.DrawLine(-Vector3.YAxis * innerRadius, -Vector3.YAxis * options.radius);
                        Gizmos.DrawLine(Vector3.ZAxis * innerRadius, Vector3.ZAxis * options.radius);
                        Gizmos.DrawLine(-Vector3.ZAxis * innerRadius, -Vector3.ZAxis * options.radius);
                    }
                }
                else if (shape is ParticleEmitterHemisphereShape hemisphereShape)
                {
                    ParticleHemisphereShapeOptions options = hemisphereShape.Options;
                    Gizmos.DrawWireHemisphere(Vector3.Zero, options.radius);
                    DrawArcWithThickness(Vector3.Zero, options.radius, new Degree(360.0f), options.thickness, Color.Green);

                    if (options.thickness > 0.0f)
                    {
                        float innerRadius = options.radius * (1.0f - MathEx.Clamp01(options.thickness));
                        if (options.thickness < 1.0f)
                        {
                            Gizmos.Color = Color.Green * new Color(0.5f, 0.5f, 0.5f);
                            Gizmos.DrawWireHemisphere(Vector3.Zero, innerRadius);
                        }

                        Gizmos.Color = Color.Green * new Color(0.25f, 0.25f, 0.25f);
                        Gizmos.DrawLine(Vector3.XAxis * innerRadius, Vector3.XAxis * options.radius);
                        Gizmos.DrawLine(-Vector3.XAxis * innerRadius, -Vector3.XAxis * options.radius);
                        Gizmos.DrawLine(Vector3.YAxis * innerRadius, Vector3.YAxis * options.radius);
                        Gizmos.DrawLine(-Vector3.YAxis * innerRadius, -Vector3.YAxis * options.radius);
                        Gizmos.DrawLine(Vector3.ZAxis * innerRadius, Vector3.ZAxis * options.radius);
                    }
                }
                else if (shape is ParticleEmitterCircleShape circleShape)
                {
                    ParticleCircleShapeOptions options = circleShape.Options;
                    DrawArcWithThickness(Vector3.Zero, options.radius, options.arc, options.thickness, Color.Green);
                }
                else if (shape is ParticleEmitterLineShape lineShape)
                {
                    float halfLength = lineShape.Options.length * 0.5f;
                    Gizmos.DrawLine(new Vector3(-halfLength, 0.0f, 0.0f), new Vector3(halfLength, 0.0f, 0.0f));
                }
                else if (shape is ParticleEmitterRectShape rectShape)
                {
                    Vector2 extents = rectShape.Options.extents;
                    Vector3 right   = new Vector3(extents.x, 0.0f, 0.0f);
                    Vector3 up      = new Vector3(0.0f, extents.y, 0.0f);

                    Vector3 topLeft  = -right + up;
                    Vector3 topRight = right + up;
                    Vector3 botLeft  = -right - up;
                    Vector3 botRight = right - up;

                    Gizmos.DrawLine(topLeft, topRight);
                    Gizmos.DrawLine(topRight, botRight);
                    Gizmos.DrawLine(botRight, botLeft);
                    Gizmos.DrawLine(botLeft, topLeft);
                }
                else if (shape is ParticleEmitterConeShape coneShape)
                {
                    ParticleConeShapeOptions options = coneShape.Options;

                    float  topRadius  = options.radius;
                    float  baseRadius = options.length * MathEx.Tan(options.angle);
                    Radian arc        = options.arc;

                    if (topRadius > 0.0f)
                    {
                        DrawArcWithThickness(Vector3.Zero, topRadius, arc, options.thickness, Color.Green);
                    }

                    DrawArcWithThickness(new Vector3(0.0f, 0.0f, -options.length), baseRadius, arc, options.thickness,
                                         Color.Green);

                    Gizmos.Color = Color.Green;
                    DrawConeBorder(topRadius, baseRadius, arc, options.length);

                    if (options.thickness > 0.0f && options.thickness < 1.0f)
                    {
                        Gizmos.Color = Color.Green * new Color(0.5f, 0.5f, 0.5f);
                        DrawConeBorder(
                            topRadius * (1.0f - MathEx.Clamp01(options.thickness)),
                            baseRadius * (1.0f - MathEx.Clamp01(options.thickness)), arc, options.length);
                    }
                }
                else if (shape is ParticleEmitterStaticMeshShape staticMeshShape)
                {
                    RRef <Mesh> mesh = staticMeshShape.Options.mesh;
                    if (mesh.IsLoaded)
                    {
                        Gizmos.DrawWireMesh(mesh.Value.MeshData);
                    }
                }
                else if (shape is ParticleEmitterSkinnedMeshShape skinnedMeshShape)
                {
                    Renderable renderable = skinnedMeshShape.Options.renderable;
                    if (renderable != null)
                    {
                        RRef <Mesh> mesh = renderable.Mesh;
                        if (mesh.IsLoaded)
                        {
                            Gizmos.DrawWireMesh(mesh.Value.MeshData);
                        }
                    }
                }
            }

            // Draw manual bounds
            if (!component.Settings.UseAutomaticBounds)
            {
                Gizmos.Color = Color.LightGray;

                AABox bounds = component.Settings.CustomBounds;
                Gizmos.DrawWireCube(bounds.Center, bounds.Size * 0.5f);
            }
        }
Esempio n. 5
0
        public static void DrawEmitterShape(ParticleEmitterShape pes, Transform transform)
        {
            var col = new Color(0.6f, 0.9f, 1.0f);

            Handles.color = col;

            switch (pes.shape)
            {
            case EmitShapes.Sphere:
                pes.radius.Max = RadiusHandle(transform, pes.radius.Max, true);

                if (!pes.radius.IsConstant)
                {
                    Handles.color = new Color(0.6f, 0.9f, 1.0f, 0.4f);

                    if (pes.radius.Min > 0.0f)
                    {
                        pes.radius.Min = RadiusHandle(transform, pes.radius.Min, true);
                    }

                    Handles.color = col;
                }

                break;

            case EmitShapes.Box:
                pes.cubeSize = CubeHandle(transform, pes.cubeSize);
                break;

            case EmitShapes.HemiSphere:
                pes.radius.Value = HemisphereHandle(transform, pes.radius.Max, true);

                if (!pes.radius.IsConstant)
                {
                    if (pes.radius.Min > 0.0f)
                    {
                        pes.radius.Min = HemisphereHandle(transform, pes.radius.Min, true);
                    }
                }

                break;

            case EmitShapes.Cone:
                float coneAngle  = pes.coneAngle;
                float coneHeight = pes.coneHeight;
                float coneRadius = pes.coneRadius;

                ConeHandle(ref coneAngle, ref coneHeight, ref coneRadius, transform);

                pes.coneAngle  = coneAngle;
                pes.coneHeight = coneHeight;
                pes.coneRadius = coneRadius;
                break;

            case EmitShapes.Ring:
                float ringRadius = pes.ringRadius;
                float ringOuter  = pes.ringOuterRadius;

                TorusHandle(ref ringRadius, ref ringOuter, transform);

                pes.ringRadius      = ringRadius;
                pes.ringOuterRadius = ringOuter;
                break;

            case EmitShapes.Line:
                pes.lineLength = LineHandle(pes.lineLength, transform);
                break;

            case EmitShapes.Mesh:
                if (pes.emitMesh == null)
                {
                    break;
                }

                if (s_lineMat == null)
                {
                    s_lineMat           = new Material(Shader.Find("Hidden/TCWireframeShader"));
                    s_lineMat.hideFlags = HideFlags.HideAndDontSave;
                }

                GL.wireframe = true;
                for (int i = 0; i < s_lineMat.passCount; ++i)
                {
                    s_lineMat.SetPass(i);
                    Graphics.DrawMeshNow(pes.emitMesh, Matrix4x4.TRS(transform.position, transform.rotation, transform.localScale));
                }

                GL.wireframe = false;

                break;
            }
        }
Esempio n. 6
0
        void SetShapeData(ParticleEmitterShape emitShape, Transform trans, ref Vector3 prevPos, ref Vector3 prevSpeed)
        {
            var emitter = m_emitSet[0];


            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:
                emitShape.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;
            }

            if (m_toEmitList != null)
            {
                ComputeShader.SetFloat(SID._UseEmitList, 1.0f);
                pes.SetListData(ComputeShader, EmitKernel, m_toEmitList);
                ComputeShader.SetVector(SID._UseVelSizeColorPos, m_emitUseVelSizeColorPos);
                m_toEmitList = null;
            }
            else
            {
                ComputeShader.SetFloat(SID._UseEmitList, 0.0f);
            }

            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(SystemComp, 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);
        }