void DrawParticles(ObiActor actor)
        {
            using (m_DrawParticlesPerfMarker.Auto())
            {

                if (mesh == null || material == null || !render || !isActiveAndEnabled || !actor.isActiveAndEnabled || actor.solver == null)
                {
                    return;
                }

                ObiSolver solver = actor.solver;

                // figure out the size of our instance batches:
                meshesPerBatch = Constants.maxInstancesPerBatch;
                batchCount = actor.particleCount / meshesPerBatch + 1;
                meshesPerBatch = Mathf.Min(meshesPerBatch, actor.particleCount);

                Vector4 basis1 = new Vector4(1, 0, 0, 0);
                Vector4 basis2 = new Vector4(0, 1, 0, 0);
                Vector4 basis3 = new Vector4(0, 0, 1, 0);

                //Convert particle data to mesh instances:
                for (int i = 0; i < batchCount; i++)
                {

                    matrices.Clear();
                    colors.Clear();
                    mpb = new MaterialPropertyBlock();
                    int limit = Mathf.Min((i + 1) * meshesPerBatch, actor.activeParticleCount);

                    for (int j = i * meshesPerBatch; j < limit; ++j)
                    {
                        int solverIndex = actor.solverIndices[j];
                        actor.GetParticleAnisotropy(solverIndex, ref basis1, ref basis2, ref basis3);
                        matrices.Add(Matrix4x4.TRS(actor.GetParticlePosition(solverIndex),
                                                   actor.GetParticleOrientation(solverIndex),
                                                   Vector3.Scale(new Vector3(basis1[3], basis2[3], basis3[3]), instanceScale)));
                        colors.Add(actor.GetParticleColor(solverIndex));
                    }

                    if (colors.Count > 0)
                        mpb.SetVectorArray("_Color", colors);

                    // Send the meshes to be drawn:
                    Graphics.DrawMeshInstanced(mesh, 0, material, matrices, mpb);
                }
            }

        }
Пример #2
0
        void ScenePreCull(Camera cam)
        {
            if (mesh == null || material == null || !render || !isActiveAndEnabled || !actor.isActiveAndEnabled || !actor.Initialized)
            {
                return;
            }

            ObiSolver solver = actor.Solver;

            // figure out the size of our instance batches:
            meshesPerBatch = Constants.maxInstancesPerBatch;
            batchCount     = actor.positions.Length / meshesPerBatch + 1;
            meshesPerBatch = Mathf.Min(meshesPerBatch, actor.positions.Length);

            Vector4 basis1;
            Vector4 basis2;
            Vector4 basis3;

            //Convert particle data to mesh instances:
            for (int i = 0; i < batchCount; i++)
            {
                matrices.Clear();
                colors.Clear();
                mpb = new MaterialPropertyBlock();
                int limit = Mathf.Min((i + 1) * meshesPerBatch, actor.active.Length);

                for (int j = i * meshesPerBatch; j < limit; ++j)
                {
                    if (actor.active[j])
                    {
                        actor.GetParticleAnisotropy(j, out basis1, out basis2, out basis3);
                        matrices.Add(Matrix4x4.TRS(actor.GetParticlePosition(j),
                                                   actor.GetParticleOrientation(j),
                                                   Vector3.Scale(new Vector3(basis1[3], basis2[3], basis3[3]), instanceScale)));
                        colors.Add((actor.colors != null && j < actor.colors.Length) ? actor.colors[j] : Color.white);
                    }
                }

                if (colors.Count > 0)
                {
                    mpb.SetVectorArray("_Color", colors);
                }

                // Send the meshes to be drawn:
                Graphics.DrawMeshInstanced(mesh, 0, material, matrices, mpb);
            }
        }
Пример #3
0
        void ScenePreCull(Camera cam)
        {
            if (!isActiveAndEnabled || !actor.isActiveAndEnabled || !actor.Initialized)
            {
                ClearMeshes();
                return;
            }

            CreateMaterialIfNeeded();

            ObiSolver solver = actor.Solver;

            // figure out the size of our drawcall arrays:
            particlesPerDrawcall = Constants.maxVertsPerMesh / 4;
            drawcallCount        = actor.positions.Length / particlesPerDrawcall + 1;
            particlesPerDrawcall = Mathf.Min(particlesPerDrawcall, actor.positions.Length);

            // If the amount of meshes we need to draw the particles has changed:
            if (drawcallCount != meshes.Count)
            {
                // Re-generate meshes:
                ClearMeshes();
                for (int i = 0; i < drawcallCount; i++)
                {
                    Mesh mesh = new Mesh();
                    mesh.name      = "Particle imposters";
                    mesh.hideFlags = HideFlags.HideAndDontSave;
                    mesh.MarkDynamic();
                    meshes.Add(mesh);
                }
            }

            Vector3 position;
            Vector4 basis1;
            Vector4 basis2;
            Vector4 basis3;
            Color   color;

            //Convert particle data to mesh geometry:
            for (int i = 0; i < drawcallCount; i++)
            {
                // Clear all arrays
                vertices.Clear();
                normals.Clear();
                colors.Clear();
                triangles.Clear();
                anisotropy1.Clear();
                anisotropy2.Clear();
                anisotropy3.Clear();

                int index = 0;
                int limit = Mathf.Min((i + 1) * particlesPerDrawcall, actor.active.Length);

                for (int j = i * particlesPerDrawcall; j < limit; ++j)
                {
                    if (actor.active[j])
                    {
                        position = actor.GetParticlePosition(j);
                        actor.GetParticleAnisotropy(j, out basis1, out basis2, out basis3);
                        color = (actor.colors != null && j < actor.colors.Length) ? actor.colors[j] : Color.white;

                        vertices.Add(position);
                        vertices.Add(position);
                        vertices.Add(position);
                        vertices.Add(position);

                        normals.Add(particleOffset0);
                        normals.Add(particleOffset1);
                        normals.Add(particleOffset2);
                        normals.Add(particleOffset3);

                        colors.Add(color);
                        colors.Add(color);
                        colors.Add(color);
                        colors.Add(color);

                        anisotropy1.Add(basis1);
                        anisotropy1.Add(basis1);
                        anisotropy1.Add(basis1);
                        anisotropy1.Add(basis1);

                        anisotropy2.Add(basis2);
                        anisotropy2.Add(basis2);
                        anisotropy2.Add(basis2);
                        anisotropy2.Add(basis2);

                        anisotropy3.Add(basis3);
                        anisotropy3.Add(basis3);
                        anisotropy3.Add(basis3);
                        anisotropy3.Add(basis3);

                        triangles.Add(index + 2);
                        triangles.Add(index + 1);
                        triangles.Add(index);
                        triangles.Add(index + 3);
                        triangles.Add(index + 2);
                        triangles.Add(index);

                        index += 4;
                    }
                }

                Apply(meshes[i]);
            }

            DrawParticles();
        }