Пример #1
0
        /// <summary>
        /// apply physical explosion to fragment piece (2D case)
        /// </summary>
        void ApplyExplosion2D(ExploderTransform meshTransform, Vector3 centroid, float force, GameObject original)
        {
            var rigid = rigid2D;

            // apply fragment mass and velocity properties
            var parentVelocity        = Vector2.zero;
            var parentAngularVelocity = 0.0f;
            var mass = settings.FragmentOptions.Mass;

            // inherit velocity and mass from original object
            if (settings.FragmentOptions.InheritParentPhysicsProperty)
            {
                if (original && original.GetComponent <Rigidbody2D>())
                {
                    var parentRigid = original.GetComponent <Rigidbody2D>();

                    parentVelocity        = parentRigid.velocity;
                    parentAngularVelocity = parentRigid.angularVelocity;
                    mass = parentRigid.mass / settings.TargetFragments;
                }
            }

            Vector2 forceVector     = (meshTransform.TransformPoint(centroid) - settings.Position).normalized;
            float   angularVelocity = settings.FragmentOptions.AngularVelocity * (settings.FragmentOptions.RandomAngularVelocityVector ? Random.insideUnitCircle.x : settings.FragmentOptions.AngularVelocityVector.y);

            if (settings.UseForceVector)
            {
                forceVector = settings.ForceVector;
            }

            rigid.velocity        = forceVector * force + parentVelocity;
            rigid.angularVelocity = angularVelocity + parentAngularVelocity;
            rigid.mass            = mass;
        }
Пример #2
0
 /// <summary>
 /// cut mesh by plane
 /// </summary>
 /// <param name="mesh">mesh to cut</param>
 /// <param name="meshTransform">transformation of the mesh</param>
 /// <param name="plane">cutting plane</param>
 /// <param name="triangulateHoles">flag for triangulation of holes</param>
 /// <param name="crossSectionVertexColor">this color will be assigned to cross section, valid only for vertex color shaders</param>
 /// <param name="crossUV">uv mapping area for cross section</param>
 /// <param name="allowOpenMesh">allow cutting of open mesh</param>
 /// <returns>processing time</returns>
 public float Cut(ExploderMesh mesh, ExploderTransform meshTransform, Plane plane, bool triangulateHoles, bool allowOpenMesh, ref List <ExploderMesh> meshes,
                  Color crossSectionVertexColor, Vector4 crossUV)
 {
     this.crossSectionVertexColour = crossSectionVertexColor;
     this.crossSectionUV           = crossUV;
     return(Cut(mesh, meshTransform, plane, triangulateHoles, allowOpenMesh, ref meshes));
 }
Пример #3
0
        private void ApplyExplosion2D(
            ExploderTransform meshTransform,
            Vector3 centroid,
            float force,
            GameObject original)
        {
            Rigidbody2D rigid2D   = this.rigid2D;
            Vector2     vector2_1 = Vector2.get_zero();
            float       num1      = 0.0f;
            float       num2      = this.settings.FragmentOptions.Mass;

            if (this.settings.FragmentOptions.InheritParentPhysicsProperty && Object.op_Implicit((Object)original) && Object.op_Implicit((Object)original.GetComponent <Rigidbody2D>()))
            {
                Rigidbody2D component = (Rigidbody2D)original.GetComponent <Rigidbody2D>();
                vector2_1 = component.get_velocity();
                num1      = component.get_angularVelocity();
                num2      = component.get_mass() / (float)this.settings.TargetFragments;
            }
            Vector3 vector3   = Vector3.op_Subtraction(meshTransform.TransformPoint(centroid), this.settings.Position);
            Vector2 vector2_2 = Vector2.op_Implicit(((Vector3) ref vector3).get_normalized());
            float   num3      = this.settings.FragmentOptions.AngularVelocity * (!this.settings.FragmentOptions.RandomAngularVelocityVector ? (float)this.settings.FragmentOptions.AngularVelocityVector.y : (float)Random.get_insideUnitCircle().x);

            if (this.settings.UseForceVector)
            {
                vector2_2 = Vector2.op_Implicit(this.settings.ForceVector);
            }
            rigid2D.set_velocity(Vector2.op_Addition(Vector2.op_Multiply(vector2_2, force), vector2_1));
            rigid2D.set_angularVelocity(num3 + num1);
            rigid2D.set_mass(num2);
        }
Пример #4
0
        /// <summary>
        /// make inverse transformation of this plane to target space
        /// </summary>
        /// <param name="transform">target transformation space</param>
        public void InverseTransform(ExploderTransform transform)
        {
            // inverse transform normal
            var inverseNormal = transform.InverseTransformDirection(Normal);

            // inverse transform point
            var inversePoint = transform.InverseTransformPoint(Pnt);

            // update plane
            Normal   = inverseNormal;
            Distance = Vector3.Dot(inverseNormal, inversePoint);
        }
Пример #5
0
        /// <summary>
        /// apply physical explosion to fragment piece
        /// </summary>
        public void ApplyExplosion(ExploderTransform meshTransform, Vector3 centroid, Vector3 mainCentroid, ExploderObject.FragmentOption fragmentOption,
                                   bool useForceVector, Vector3 ForceVector, float force, GameObject original, int targetFragments)
        {
            if (rigid2D)
            {
                ApplyExplosion2D(meshTransform, centroid, mainCentroid, fragmentOption, useForceVector, ForceVector, force, original, targetFragments);
                return;
            }

            var rigid = rigidBody;

            // apply fragment mass and velocity properties
            var parentVelocity        = Vector3.zero;
            var parentAngularVelocity = Vector3.zero;
            var mass       = fragmentOption.Mass;
            var useGravity = fragmentOption.UseGravity;

            rigid.maxAngularVelocity = fragmentOption.MaxAngularVelocity;

            // inherit velocity and mass from original object
            if (fragmentOption.InheritParentPhysicsProperty)
            {
                if (original && original.GetComponent <Rigidbody>())
                {
                    var parentRigid = original.GetComponent <Rigidbody>();

                    parentVelocity        = parentRigid.velocity;
                    parentAngularVelocity = parentRigid.angularVelocity;
                    mass       = parentRigid.mass / targetFragments;
                    useGravity = parentRigid.useGravity;
                }
            }

            var forceVector     = (meshTransform.TransformPoint(centroid) - mainCentroid).normalized;
            var angularVelocity = fragmentOption.AngularVelocity * (fragmentOption.RandomAngularVelocityVector ? Random.onUnitSphere : fragmentOption.AngularVelocityVector);

            if (useForceVector)
            {
                forceVector = ForceVector;
            }

            rigid.velocity        = forceVector * force + parentVelocity;
            rigid.angularVelocity = angularVelocity + parentAngularVelocity;
            rigid.mass            = mass;
            maxVelocity           = fragmentOption.MaxVelocity;
            rigid.useGravity      = useGravity;
        }
Пример #6
0
        /// <summary>
        /// apply physical explosion to fragment piece
        /// </summary>
        public void ApplyExplosion(ExploderTransform meshTransform, Vector3 centroid, float force, GameObject original, ExploderParams set)
        {
            this.settings = set;

            if (rigid2D)
            {
                ApplyExplosion2D(meshTransform, centroid, force, original);
                return;
            }

            var rigid = rigidBody;

            // apply fragment mass and velocity properties
            var parentVelocity        = Vector3.zero;
            var parentAngularVelocity = Vector3.zero;
            var mass       = settings.FragmentOptions.Mass;
            var useGravity = settings.FragmentOptions.UseGravity;

            rigid.maxAngularVelocity = settings.FragmentOptions.MaxAngularVelocity;

            // inherit velocity and mass from original object
            if (settings.FragmentOptions.InheritParentPhysicsProperty)
            {
                if (original && original.GetComponent <Rigidbody>())
                {
                    var parentRigid = original.GetComponent <Rigidbody>();

                    parentVelocity        = parentRigid.velocity;
                    parentAngularVelocity = parentRigid.angularVelocity;
                    mass       = parentRigid.mass / settings.TargetFragments;
                    useGravity = parentRigid.useGravity;
                }
            }

            var forceVector     = (meshTransform.TransformPoint(centroid) - settings.Position).normalized;
            var angularVelocity = settings.FragmentOptions.AngularVelocity * (settings.FragmentOptions.RandomAngularVelocityVector ? Random.onUnitSphere : settings.FragmentOptions.AngularVelocityVector);

            if (settings.UseForceVector)
            {
                forceVector = settings.ForceVector;
            }

            rigid.velocity        = forceVector * force + parentVelocity;
            rigid.angularVelocity = angularVelocity + parentAngularVelocity;
            rigid.mass            = mass;
            rigid.useGravity      = useGravity;
        }
Пример #7
0
 public void ApplyExplosion(
     ExploderTransform meshTransform,
     Vector3 centroid,
     float force,
     GameObject original,
     ExploderParams set)
 {
     this.settings = set;
     if (Object.op_Implicit((Object)this.rigid2D))
     {
         this.ApplyExplosion2D(meshTransform, centroid, force, original);
     }
     else
     {
         Rigidbody rigidBody  = this.rigidBody;
         Vector3   vector3_1  = Vector3.get_zero();
         Vector3   vector3_2  = Vector3.get_zero();
         float     num        = this.settings.FragmentOptions.Mass;
         bool      useGravity = this.settings.FragmentOptions.UseGravity;
         rigidBody.set_maxAngularVelocity(this.settings.FragmentOptions.MaxAngularVelocity);
         if (this.settings.FragmentOptions.InheritParentPhysicsProperty && Object.op_Implicit((Object)original) && Object.op_Implicit((Object)original.GetComponent <Rigidbody>()))
         {
             Rigidbody component = (Rigidbody)original.GetComponent <Rigidbody>();
             vector3_1  = component.get_velocity();
             vector3_2  = component.get_angularVelocity();
             num        = component.get_mass() / (float)this.settings.TargetFragments;
             useGravity = component.get_useGravity();
         }
         Vector3 vector3_3 = Vector3.op_Subtraction(meshTransform.TransformPoint(centroid), this.settings.Position);
         Vector3 vector3_4 = ((Vector3) ref vector3_3).get_normalized();
         Vector3 vector3_5 = Vector3.op_Multiply(this.settings.FragmentOptions.AngularVelocity, !this.settings.FragmentOptions.RandomAngularVelocityVector ? this.settings.FragmentOptions.AngularVelocityVector : Random.get_onUnitSphere());
         if (this.settings.UseForceVector)
         {
             vector3_4 = this.settings.ForceVector;
         }
         rigidBody.set_velocity(Vector3.op_Addition(Vector3.op_Multiply(vector3_4, force), vector3_1));
         rigidBody.set_angularVelocity(Vector3.op_Addition(vector3_5, vector3_2));
         rigidBody.set_mass(num);
         rigidBody.set_useGravity(useGravity);
     }
 }
Пример #8
0
        /// <summary>
        /// apply physical explosion to fragment piece (2D case)
        /// </summary>
        void ApplyExplosion2D(ExploderTransform meshTransform, Vector3 centroid, Vector3 mainCentroid,
                              ExploderObject.FragmentOption fragmentOption,
                              bool useForceVector, Vector2 ForceVector, float force, GameObject original,
                              int targetFragments)
        {
            var rigid = rigid2D;

            // apply fragment mass and velocity properties
            var parentVelocity        = Vector2.zero;
            var parentAngularVelocity = 0.0f;
            var mass = fragmentOption.Mass;

            // inherit velocity and mass from original object
            if (fragmentOption.InheritParentPhysicsProperty)
            {
                if (original && original.GetComponent <Rigidbody2D>())
                {
                    var parentRigid = original.GetComponent <Rigidbody2D>();

                    parentVelocity        = parentRigid.velocity;
                    parentAngularVelocity = parentRigid.angularVelocity;
                    mass = parentRigid.mass / targetFragments;
                }
            }

            Vector2 forceVector     = (meshTransform.TransformPoint(centroid) - mainCentroid).normalized;
            float   angularVelocity = fragmentOption.AngularVelocity * (fragmentOption.RandomAngularVelocityVector ? Random.insideUnitCircle.x : fragmentOption.AngularVelocityVector.y);

            if (useForceVector)
            {
                forceVector = ForceVector;
            }

            rigid.velocity        = forceVector * force + parentVelocity;
            rigid.angularVelocity = angularVelocity + parentAngularVelocity;
            rigid.mass            = mass;
            maxVelocity           = fragmentOption.MaxVelocity;
        }
Пример #9
0
        float Cut(ExploderMesh mesh, ExploderTransform meshTransform, Plane plane, bool triangulateHoles, bool allowOpenMesh, ref List <ExploderMesh> meshes)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();

#if PROFILING
            MeasureIt.Begin("CutAllocations");
#endif

            // cache mesh data
            var trianglesNum    = mesh.triangles.Length;
            var verticesNum     = mesh.vertices.Length;
            var meshTriangles   = mesh.triangles;
            var meshTangents    = mesh.tangents;
            var meshColors      = mesh.colors32;
            var meshVertices    = mesh.vertices;
            var meshNormals     = mesh.normals;
            var meshUV          = mesh.uv;
            var useMeshTangents = meshTangents != null && meshTangents.Length > 0;
            var useVertexColors = meshColors != null && meshColors.Length > 0;
            var useNormals      = meshNormals != null && meshNormals.Length > 0;

            // preallocate buffers
            AllocateBuffers(trianglesNum, verticesNum, useMeshTangents, useVertexColors);

            ExploderMesh mesh0, mesh1;

#if PROFILING
            MeasureIt.End("CutAllocations");
            MeasureIt.Begin("CutCycleFirstPass");
#endif

            // first pass - find complete triangles on both sides of the plane
            for (int i = 0; i < trianglesNum; i += 3)
            {
                // get triangle points
                var v0 = meshVertices[meshTriangles[i]];
                var v1 = meshVertices[meshTriangles[i + 1]];
                var v2 = meshVertices[meshTriangles[i + 2]];

                var side0 = plane.GetSideFix(ref v0);
                var side1 = plane.GetSideFix(ref v1);
                var side2 = plane.GetSideFix(ref v2);

                meshVertices[meshTriangles[i]]     = v0;
                meshVertices[meshTriangles[i + 1]] = v1;
                meshVertices[meshTriangles[i + 2]] = v2;

//                Utils.Log(plane.Pnt + " " + v0 + " " + v1 + " " + " " + v2);

                // all points on one side
                if (side0 == side1 && side1 == side2)
                {
                    var idx = side0 ? 0 : 1;

                    if (meshTriangles[i] >= triCache.Length)
                    {
                        ExploderUtils.Log("TriCacheError " + meshTriangles[i] + " " + triCache.Length + " " + meshVertices.Length);
                    }

                    if (triCache[meshTriangles[i]] == 0)
                    {
                        triangles[idx].Add(triCounter[idx]);
                        vertices[idx].Add(meshVertices[meshTriangles[i]]);
                        uvs[idx].Add(meshUV[meshTriangles[i]]);

                        if (useNormals)
                        {
                            normals[idx].Add(meshNormals[meshTriangles[i]]);
                        }

                        if (useMeshTangents)
                        {
                            tangents[idx].Add(meshTangents[meshTriangles[i]]);
                        }

                        if (useVertexColors)
                        {
                            vertexColors[idx].Add(meshColors[meshTriangles[i]]);
                        }

                        centroid[idx] += meshVertices[meshTriangles[i]];

                        triCache[meshTriangles[i]] = triCounter[idx] + 1;
                        triCounter[idx]++;
                    }
                    else
                    {
                        triangles[idx].Add(triCache[meshTriangles[i]] - 1);
                    }

                    if (triCache[meshTriangles[i + 1]] == 0)
                    {
                        triangles[idx].Add(triCounter[idx]);
                        vertices[idx].Add(meshVertices[meshTriangles[i + 1]]);
                        uvs[idx].Add(meshUV[meshTriangles[i + 1]]);

                        if (useNormals)
                        {
                            normals[idx].Add(meshNormals[meshTriangles[i + 1]]);
                        }

                        if (useMeshTangents)
                        {
                            tangents[idx].Add(meshTangents[meshTriangles[i + 1]]);
                        }

                        if (useVertexColors)
                        {
                            vertexColors[idx].Add(meshColors[meshTriangles[i + 1]]);
                        }

                        centroid[idx] += meshVertices[meshTriangles[i + 1]];

                        triCache[meshTriangles[i + 1]] = triCounter[idx] + 1;
                        triCounter[idx]++;
                    }
                    else
                    {
                        triangles[idx].Add(triCache[meshTriangles[i + 1]] - 1);
                    }

                    if (triCache[meshTriangles[i + 2]] == 0)
                    {
                        triangles[idx].Add(triCounter[idx]);
                        vertices[idx].Add(meshVertices[meshTriangles[i + 2]]);
                        uvs[idx].Add(meshUV[meshTriangles[i + 2]]);

                        if (useNormals)
                        {
                            normals[idx].Add(meshNormals[meshTriangles[i + 2]]);
                        }

                        if (useMeshTangents)
                        {
                            tangents[idx].Add(meshTangents[meshTriangles[i + 2]]);
                        }

                        if (useVertexColors)
                        {
                            vertexColors[idx].Add(meshColors[meshTriangles[i + 2]]);
                        }

                        centroid[idx] += meshVertices[meshTriangles[i + 2]];

                        triCache[meshTriangles[i + 2]] = triCounter[idx] + 1;
                        triCounter[idx]++;
                    }
                    else
                    {
                        triangles[idx].Add(triCache[meshTriangles[i + 2]] - 1);
                    }
                }
                else
                {
                    // intersection triangles add to list and process it in second pass
                    cutTris.Add(i);
                }
            }

            if (vertices[0].Count == 0)
            {
                centroid[0] = meshVertices[0];
            }
            else
            {
                centroid[0] /= vertices[0].Count;
            }

            if (vertices[1].Count == 0)
            {
                centroid[1] = meshVertices[1];
            }
            else
            {
                centroid[1] /= vertices[1].Count;
            }

//            UnityEngine.Debug.LogFormat("cut: {0} -- {1}, normal: {2}, tris: {3}", vertices[0].Count, vertices[1].Count, plane.Normal, cutTris.Count);

#if PROFILING
            MeasureIt.End("CutCycleFirstPass");
            MeasureIt.Begin("CutCycleSecondPass");
#endif

            if (cutTris.Count < 1)
            {
                stopWatch.Stop();
                return(stopWatch.ElapsedMilliseconds);
            }

            AllocateContours(cutTris.Count);

            // second pass - cut intersecting triangles in half
            foreach (var cutTri in cutTris)
            {
                var triangle = new Triangle
                {
                    ids      = new[] { meshTriangles[cutTri + 0], meshTriangles[cutTri + 1], meshTriangles[cutTri + 2] },
                    pos      = new[] { meshVertices[meshTriangles[cutTri + 0]], meshVertices[meshTriangles[cutTri + 1]], meshVertices[meshTriangles[cutTri + 2]] },
                    normal   = useNormals ? new[] { meshNormals[meshTriangles[cutTri + 0]], meshNormals[meshTriangles[cutTri + 1]], meshNormals[meshTriangles[cutTri + 2]] } : new[] { Vector3.zero, Vector3.zero, Vector3.zero },
                    uvs      = new[] { meshUV[meshTriangles[cutTri + 0]], meshUV[meshTriangles[cutTri + 1]], meshUV[meshTriangles[cutTri + 2]] },
                    tangents = useMeshTangents ? new[] { meshTangents[meshTriangles[cutTri + 0]], meshTangents[meshTriangles[cutTri + 1]], meshTangents[meshTriangles[cutTri + 2]] } : new [] { Vector4.zero, Vector4.zero, Vector4.zero },
                    colors   = useVertexColors ? new[] { meshColors[meshTriangles[cutTri + 0]], meshColors[meshTriangles[cutTri + 1]], meshColors[meshTriangles[cutTri + 2]] } : new Color32[] { Color.white, Color.white, Color.white },
                };

                // check points with a plane
                var side0 = plane.GetSide(triangle.pos[0]);
                var side1 = plane.GetSide(triangle.pos[1]);
                var side2 = plane.GetSide(triangle.pos[2]);

                float   t0, t1;
                Vector3 s0 = Vector3.zero, s1 = Vector3.zero;

                var idxLeft  = side0 ? 0 : 1;
                var idxRight = 1 - idxLeft;

                if (side0 == side1)
                {
                    var a = plane.IntersectSegment(triangle.pos[2], triangle.pos[0], out t0, ref s0);
                    var b = plane.IntersectSegment(triangle.pos[2], triangle.pos[1], out t1, ref s1);

                    ExploderUtils.Assert(a && b, "!!!!!!!!!!!!!!!");

                    // left side ... 2 triangles
                    var s0Left = AddIntersectionPoint(s0, triangle, triangle.ids[2], triangle.ids[0], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft], tangents[idxLeft], vertexColors[idxLeft], useMeshTangents, useVertexColors, useNormals);
                    var s1Left = AddIntersectionPoint(s1, triangle, triangle.ids[2], triangle.ids[1], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft], tangents[idxLeft], vertexColors[idxLeft], useMeshTangents, useVertexColors, useNormals);
                    var v0Left = AddTrianglePoint(triangle.pos[0], triangle.normal[0], triangle.uvs[0], triangle.tangents[0], triangle.colors[0], triangle.ids[0], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft], tangents[idxLeft], vertexColors[idxLeft], useMeshTangents, useVertexColors, useNormals);
                    var v1Left = AddTrianglePoint(triangle.pos[1], triangle.normal[1], triangle.uvs[1], triangle.tangents[1], triangle.colors[1], triangle.ids[1], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft], tangents[idxLeft], vertexColors[idxLeft], useMeshTangents, useVertexColors, useNormals);

                    // Triangle (s0, v0, s1)
                    triangles[idxLeft].Add(s0Left);
                    triangles[idxLeft].Add(v0Left);
                    triangles[idxLeft].Add(s1Left);

                    // Triangle (s1, v0, v1)
                    triangles[idxLeft].Add(s1Left);
                    triangles[idxLeft].Add(v0Left);
                    triangles[idxLeft].Add(v1Left);

                    // right side ... 1 triangle
                    var s0Right = AddIntersectionPoint(s0, triangle, triangle.ids[2], triangle.ids[0], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight], tangents[idxRight], vertexColors[idxRight], useMeshTangents, useVertexColors, useNormals);
                    var s1Right = AddIntersectionPoint(s1, triangle, triangle.ids[2], triangle.ids[1], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight], tangents[idxRight], vertexColors[idxRight], useMeshTangents, useVertexColors, useNormals);
                    var v2Right = AddTrianglePoint(triangle.pos[2], triangle.normal[2], triangle.uvs[2], triangle.tangents[2], triangle.colors[2], triangle.ids[2], triCache, cornerVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight], tangents[idxRight], vertexColors[idxRight], useMeshTangents, useVertexColors, useNormals);

                    // Triangle (v2, s0, s1)
                    triangles[idxRight].Add(v2Right);
                    triangles[idxRight].Add(s0Right);
                    triangles[idxRight].Add(s1Right);

                    // buffer intersection vertices for triangulation
                    if (triangulateHoles)
                    {
                        if (idxLeft == 0)
                        {
                            contour.AddTriangle(cutTri, s0Left, s1Left, s0, s1);
                        }
                        else
                        {
                            contour.AddTriangle(cutTri, s0Right, s1Right, s0, s1);
                        }
                    }
                }
                else if (side0 == side2)
                {
                    var a = plane.IntersectSegment(triangle.pos[1], triangle.pos[0], out t0, ref s1);
                    var b = plane.IntersectSegment(triangle.pos[1], triangle.pos[2], out t1, ref s0);

                    ExploderUtils.Assert(a && b, "!!!!!!!!!!!!!");

                    // left side ... 2 triangles
                    var s0Left = AddIntersectionPoint(s0, triangle, triangle.ids[1], triangle.ids[2], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft], tangents[idxLeft], vertexColors[idxLeft], useMeshTangents, useVertexColors, useNormals);
                    var s1Left = AddIntersectionPoint(s1, triangle, triangle.ids[1], triangle.ids[0], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft], tangents[idxLeft], vertexColors[idxLeft], useMeshTangents, useVertexColors, useNormals);
                    var v0Left = AddTrianglePoint(triangle.pos[0], triangle.normal[0], triangle.uvs[0], triangle.tangents[0], triangle.colors[0], triangle.ids[0], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft], tangents[idxLeft], vertexColors[idxLeft], useMeshTangents, useVertexColors, useNormals);
                    var v2Left = AddTrianglePoint(triangle.pos[2], triangle.normal[2], triangle.uvs[2], triangle.tangents[2], triangle.colors[2], triangle.ids[2], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft], tangents[idxLeft], vertexColors[idxLeft], useMeshTangents, useVertexColors, useNormals);

                    // Triangle (v2, s1, s0)
                    triangles[idxLeft].Add(v2Left);
                    triangles[idxLeft].Add(s1Left);
                    triangles[idxLeft].Add(s0Left);

                    // Triangle (v2, v0, s1)
                    triangles[idxLeft].Add(v2Left);
                    triangles[idxLeft].Add(v0Left);
                    triangles[idxLeft].Add(s1Left);

                    // right side ... 1 triangle
                    var s0Right = AddIntersectionPoint(s0, triangle, triangle.ids[1], triangle.ids[2], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight], tangents[idxRight], vertexColors[idxRight], useMeshTangents, useVertexColors, useNormals);
                    var s1Right = AddIntersectionPoint(s1, triangle, triangle.ids[1], triangle.ids[0], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight], tangents[idxRight], vertexColors[idxRight], useMeshTangents, useVertexColors, useNormals);
                    var v1Right = AddTrianglePoint(triangle.pos[1], triangle.normal[1], triangle.uvs[1], triangle.tangents[1], triangle.colors[1], triangle.ids[1], triCache, cornerVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight], tangents[idxRight], vertexColors[idxRight], useMeshTangents, useVertexColors, useNormals);

                    // Triangle (s0, s1, v1)
                    triangles[idxRight].Add(s0Right);
                    triangles[idxRight].Add(s1Right);
                    triangles[idxRight].Add(v1Right);

                    // buffer intersection vertices for triangulation
                    if (triangulateHoles)
                    {
                        if (idxLeft == 0)
                        {
                            contour.AddTriangle(cutTri, s0Left, s1Left, s0, s1);
                        }
                        else
                        {
                            contour.AddTriangle(cutTri, s0Right, s1Right, s0, s1);
                        }
                    }
                }
                else
                {
                    var a = plane.IntersectSegment(triangle.pos[0], triangle.pos[1], out t0, ref s0);
                    var b = plane.IntersectSegment(triangle.pos[0], triangle.pos[2], out t1, ref s1);

                    ExploderUtils.Assert(a && b, "!!!!!!!!!!!!!");

                    // right side ... 2 triangles
                    var s0Right = AddIntersectionPoint(s0, triangle, triangle.ids[0], triangle.ids[1], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight], tangents[idxRight], vertexColors[idxRight], useMeshTangents, useVertexColors, useNormals);
                    var s1Right = AddIntersectionPoint(s1, triangle, triangle.ids[0], triangle.ids[2], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight], tangents[idxRight], vertexColors[idxRight], useMeshTangents, useVertexColors, useNormals);
                    var v1Right = AddTrianglePoint(triangle.pos[1], triangle.normal[1], triangle.uvs[1], triangle.tangents[1], triangle.colors[1], triangle.ids[1], triCache, cornerVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight], tangents[idxRight], vertexColors[idxRight], useMeshTangents, useVertexColors, useNormals);
                    var v2Right = AddTrianglePoint(triangle.pos[2], triangle.normal[2], triangle.uvs[2], triangle.tangents[2], triangle.colors[2], triangle.ids[2], triCache, cornerVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight], tangents[idxRight], vertexColors[idxRight], useMeshTangents, useVertexColors, useNormals);

                    // Triangle (v2, s1, v1)
                    triangles[idxRight].Add(v2Right);
                    triangles[idxRight].Add(s1Right);
                    triangles[idxRight].Add(v1Right);

                    // Triangle (s1, s0, v1)
                    triangles[idxRight].Add(s1Right);
                    triangles[idxRight].Add(s0Right);
                    triangles[idxRight].Add(v1Right);

                    // left side ... 1 triangle
                    var s0Left = AddIntersectionPoint(s0, triangle, triangle.ids[0], triangle.ids[1], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft], tangents[idxLeft], vertexColors[idxLeft], useMeshTangents, useVertexColors, useNormals);
                    var s1Left = AddIntersectionPoint(s1, triangle, triangle.ids[0], triangle.ids[2], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft], tangents[idxLeft], vertexColors[idxLeft], useMeshTangents, useVertexColors, useNormals);
                    var v0Left = AddTrianglePoint(triangle.pos[0], triangle.normal[0], triangle.uvs[0], triangle.tangents[0], triangle.colors[0], triangle.ids[0], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft], tangents[idxLeft], vertexColors[idxLeft], useMeshTangents, useVertexColors, useNormals);

                    // Triangle (s1, v0, s0)
                    triangles[idxLeft].Add(s1Left);
                    triangles[idxLeft].Add(v0Left);
                    triangles[idxLeft].Add(s0Left);

                    // buffer intersection vertices for triangulation
                    if (triangulateHoles)
                    {
                        if (idxLeft == 0)
                        {
                            contour.AddTriangle(cutTri, s0Left, s1Left, s0, s1);
                        }
                        else
                        {
                            contour.AddTriangle(cutTri, s0Right, s1Right, s0, s1);
                        }
                    }
                }
            }

#if PROFILING
            MeasureIt.End("CutCycleSecondPass");
#endif

            if (triangulateHoles)
            {
#if PROFILING
                MeasureIt.Begin("FindContours");
#endif

                contour.FindContours();

                if (contour.contour.Count == 0 || contour.contour[0].Count < 3)
                {
//                    triangulateHoles = false;

                    if (allowOpenMesh)
                    {
                        triangulateHoles = false;
                    }
                    else
                    {
                        stopWatch.Stop();
                        return(stopWatch.ElapsedMilliseconds);
                    }
                }

#if PROFILING
                MeasureIt.End("FindContours");
#endif
            }

            List <int>[] trianglesCut = null;
            var          centroid0    = Vector3.zero;
            var          centroid1    = Vector3.zero;
            var          min0         = Vector3.zero;
            var          max0         = Vector3.zero;
            var          min1         = Vector3.zero;
            var          max1         = Vector3.zero;

            ExploderMesh.CalculateCentroid(vertices[0], ref centroid0, ref min0, ref max0);
            ExploderMesh.CalculateCentroid(vertices[1], ref centroid1, ref min1, ref max1);

            if (triangulateHoles)
            {
#if PROFILING
                MeasureIt.Begin("Triangulate");
#endif

                trianglesCut = new List <int>[2]
                {
                    new List <int>(contour.MidPointsCount),
                    new List <int>(contour.MidPointsCount)
                };

                Triangulate(contour.contour, plane, vertices, normals, uvs, tangents, vertexColors, trianglesCut, true, useMeshTangents, useVertexColors, useNormals);

#if PROFILING
                MeasureIt.End("Triangulate");
#endif
            }

            if (vertices[0].Count > 3 && vertices[1].Count > 3)
            {
#if PROFILING
                MeasureIt.Begin("CutEndCopyBack");
#endif

                mesh0 = new ExploderMesh();
                mesh1 = new ExploderMesh();

                var verticesArray0 = vertices[0].ToArray();
                var verticesArray1 = vertices[1].ToArray();

                mesh0.vertices = verticesArray0;
                mesh0.uv       = uvs[0].ToArray();

                mesh1.vertices = verticesArray1;
                mesh1.uv       = uvs[1].ToArray();

                if (useNormals)
                {
                    mesh0.normals = normals[0].ToArray();
                    mesh1.normals = normals[1].ToArray();
                }

                if (useMeshTangents)
                {
                    mesh0.tangents = tangents[0].ToArray();
                    mesh1.tangents = tangents[1].ToArray();
                }

                if (useVertexColors)
                {
                    mesh0.colors32 = vertexColors[0].ToArray();
                    mesh1.colors32 = vertexColors[1].ToArray();
                }

                if (trianglesCut != null && trianglesCut[0].Count > 3)
                {
                    triangles[0].AddRange(trianglesCut[0]);
                    triangles[1].AddRange(trianglesCut[1]);
                }

                mesh0.triangles = triangles[0].ToArray();
                mesh1.triangles = triangles[1].ToArray();

                mesh0.centroid = centroid0;
                mesh0.min      = min0;
                mesh0.max      = max0;

                mesh1.centroid = centroid1;
                mesh1.min      = min1;
                mesh1.max      = max1;

#if PROFILING
                MeasureIt.End("CutEndCopyBack");
#endif

                meshes = new List <ExploderMesh> {
                    mesh0, mesh1
                };

                stopWatch.Stop();
                return(stopWatch.ElapsedMilliseconds);
            }

            stopWatch.Stop();

//            UnityEngine.Debug.Log("Empty cut! " + vertices[0].Count + " " + vertices[1].Count);

            return(stopWatch.ElapsedMilliseconds);
        }
Пример #10
0
        private float Cut(
            ExploderMesh mesh,
            ExploderTransform meshTransform,
            Plane plane,
            bool triangulateHoles,
            bool allowOpenMesh,
            ref List <ExploderMesh> meshes)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            int length1 = mesh.triangles.Length;
            int length2 = mesh.vertices.Length;

            int[]     triangles1 = mesh.triangles;
            Vector4[] tangents   = mesh.tangents;
            Color32[] colors32   = mesh.colors32;
            Vector3[] vertices   = mesh.vertices;
            Vector3[] normals    = mesh.normals;
            Vector2[] uv         = mesh.uv;
            bool      flag1      = tangents != null && tangents.Length > 0;
            bool      flag2      = colors32 != null && colors32.Length > 0;
            bool      useNormals = normals != null && normals.Length > 0;

            this.AllocateBuffers(length1, length2, flag1, flag2);
            for (int index1 = 0; index1 < length1; index1 += 3)
            {
                Vector3 n1       = vertices[triangles1[index1]];
                Vector3 n2       = vertices[triangles1[index1 + 1]];
                Vector3 n3       = vertices[triangles1[index1 + 2]];
                bool    sideFix1 = plane.GetSideFix(ref n1);
                bool    sideFix2 = plane.GetSideFix(ref n2);
                bool    sideFix3 = plane.GetSideFix(ref n3);
                vertices[triangles1[index1]]     = n1;
                vertices[triangles1[index1 + 1]] = n2;
                vertices[triangles1[index1 + 2]] = n3;
                if (sideFix1 == sideFix2 && sideFix2 == sideFix3)
                {
                    int index2 = !sideFix1 ? 1 : 0;
                    if (triangles1[index1] < this.triCache.Length)
                    {
                        ;
                    }
                    if (this.triCache[triangles1[index1]] == 0)
                    {
                        this.triangles[index2].Add(this.triCounter[index2]);
                        this.vertices[index2].Add(vertices[triangles1[index1]]);
                        this.uvs[index2].Add(uv[triangles1[index1]]);
                        if (useNormals)
                        {
                            this.normals[index2].Add(normals[triangles1[index1]]);
                        }
                        if (flag1)
                        {
                            this.tangents[index2].Add(tangents[triangles1[index1]]);
                        }
                        if (flag2)
                        {
                            this.vertexColors[index2].Add(colors32[triangles1[index1]]);
                        }
                        ref Vector3 local = ref this.centroid[index2];
                        local = Vector3.op_Addition(local, vertices[triangles1[index1]]);
                        this.triCache[triangles1[index1]] = this.triCounter[index2] + 1;
                        ++this.triCounter[index2];
                    }
                    else
                    {
                        this.triangles[index2].Add(this.triCache[triangles1[index1]] - 1);
                    }
                    if (this.triCache[triangles1[index1 + 1]] == 0)
                    {
                        this.triangles[index2].Add(this.triCounter[index2]);
                        this.vertices[index2].Add(vertices[triangles1[index1 + 1]]);
                        this.uvs[index2].Add(uv[triangles1[index1 + 1]]);
                        if (useNormals)
                        {
                            this.normals[index2].Add(normals[triangles1[index1 + 1]]);
                        }
                        if (flag1)
                        {
                            this.tangents[index2].Add(tangents[triangles1[index1 + 1]]);
                        }
                        if (flag2)
                        {
                            this.vertexColors[index2].Add(colors32[triangles1[index1 + 1]]);
                        }
                        ref Vector3 local = ref this.centroid[index2];
                        local = Vector3.op_Addition(local, vertices[triangles1[index1 + 1]]);
                        this.triCache[triangles1[index1 + 1]] = this.triCounter[index2] + 1;
                        ++this.triCounter[index2];
                    }