Exemple #1
0
 private void Prepare(Mesh oldMesh, bool cachePreparation = true)
 {
     if (!oldMesh.isReadable)
     {
         Debug.LogError((object)"The mesh is not readable. Switch on the \"Read/Write Enabled\" option on the mesh's import settings.");
     }
     else
     {
         bool flag1 = this.type == MeshExploder.ExplosionType.Physics;
         MeshExploder.MeshExplosionPreparation explosionPreparation;
         if (MeshExploder.cache.TryGetValue(oldMesh, out explosionPreparation) && (flag1 && explosionPreparation.physicsMeshes != null || !flag1 && (Object)explosionPreparation.startMesh != (Object)null))
         {
             this.preparation = explosionPreparation;
         }
         else
         {
             Vector3[] vertices1    = oldMesh.vertices;
             Vector3[] normals1     = oldMesh.normals;
             Vector4[] tangents1    = oldMesh.tangents;
             Vector2[] uv           = oldMesh.uv;
             Vector2[] uv2          = oldMesh.uv2;
             Color[]   colors       = oldMesh.colors;
             int       subMeshCount = oldMesh.subMeshCount;
             int[][]   numArray1    = new int[subMeshCount][];
             int[]     numArray2    = !flag1 ? (int[])null : (explosionPreparation.frontMeshTrianglesPerSubMesh = new int[subMeshCount]);
             int       length1      = 0;
             for (int submesh = 0; submesh < subMeshCount; ++submesh)
             {
                 int num = (numArray1[submesh] = oldMesh.GetTriangles(submesh)).Length / 3;
                 if (flag1)
                 {
                     numArray2[submesh] = num;
                 }
                 length1 += num;
             }
             explosionPreparation.totalFrontTriangles = length1;
             int num1    = length1 * 2;
             int length2 = !flag1 ? num1 * 3 : 6;
             if (length2 > 65534)
             {
                 Debug.LogError((object)("The mesh has too many triangles to explode. It must have " + (object)10922 + " or fewer triangles."));
             }
             else
             {
                 Vector3[]    vertices2       = new Vector3[length2];
                 Vector3[]    normals2        = normals1 == null || normals1.Length == 0 ? (Vector3[])null : new Vector3[length2];
                 Vector4[]    tangents2       = tangents1 == null || tangents1.Length == 0 ? (Vector4[])null : new Vector4[length2];
                 Vector2[]    vector2Array1   = uv == null || uv.Length == 0 ? (Vector2[])null : new Vector2[length2];
                 Vector2[]    vector2Array2   = uv2 == null || uv2.Length == 0 ? (Vector2[])null : new Vector2[length2];
                 Color[]      colorArray      = colors == null || colors.Length == 0 ? (Color[])null : new Color[length2];
                 Vector3[]    vector3Array1   = explosionPreparation.triangleCentroids = new Vector3[length1];
                 Mesh[]       meshArray       = explosionPreparation.physicsMeshes = !flag1 ? (Mesh[])null : new Mesh[length1];
                 Quaternion[] quaternionArray = explosionPreparation.rotations = !flag1 ? (Quaternion[])null : new Quaternion[length1];
                 int[]        numArray3;
                 if (flag1)
                 {
                     numArray3 = new int[6] {
                         0, 1, 2, 3, 4, 5
                     }
                 }
                 ;
                 else
                 {
                     numArray3 = (int[])null;
                 }
                 int[]      numArray4  = numArray3;
                 int        index1     = 0;
                 int        index2     = 0;
                 Quaternion quaternion = Quaternion.identity;
                 for (int index3 = 0; index3 < subMeshCount; ++index3)
                 {
                     int[] numArray5 = numArray1[index3];
                     int   length3   = numArray5.Length;
                     int   num2      = 0;
                     while (num2 < length3)
                     {
                         int     num3      = num2;
                         Vector3 vector3_1 = Vector3.zero;
                         for (int index4 = 0; index4 < 2; ++index4)
                         {
                             num2 = num3;
                             bool flag2 = index4 == 1;
                             while (num2 < length3)
                             {
                                 int index5 = numArray5[!flag2 ? num2 : num3 + (2 - (num2 - num3))];
                                 if (flag1 && index1 % 6 == 0)
                                 {
                                     Vector3 vector3_2 = vertices1[index5];
                                     Vector3 vector3_3 = vertices1[numArray5[num2 + 1]];
                                     Vector3 vector3_4 = vertices1[numArray5[num2 + 2]];
                                     Vector3 vector3_5 = Vector3.Cross(vector3_3 - vector3_2, vector3_4 - vector3_2);
                                     quaternionArray[index2] = Quaternion.FromToRotation(Vector3.up, vector3_5);
                                     quaternion            = Quaternion.FromToRotation(vector3_5, Vector3.up);
                                     vector3Array1[index2] = vector3_1 = (vector3_2 + vector3_3 + vector3_4) / 3f;
                                 }
                                 if (!flag2)
                                 {
                                     vertices2[index1] = quaternion * (vertices1[index5] - vector3_1);
                                     if (normals2 != null)
                                     {
                                         normals2[index1] = quaternion * normals1[index5];
                                     }
                                     if (tangents2 != null)
                                     {
                                         tangents2[index1] = (Vector4)(quaternion * (Vector3)tangents1[index5]);
                                     }
                                 }
                                 if (vector2Array1 != null)
                                 {
                                     vector2Array1[index1] = uv[index5];
                                 }
                                 if (vector2Array2 != null)
                                 {
                                     vector2Array2[index1] = uv2[index5];
                                 }
                                 if (colorArray != null)
                                 {
                                     colorArray[index1] = colors[index5];
                                 }
                                 ++num2;
                                 ++index1;
                                 if (index1 % 6 == 0)
                                 {
                                     if (flag1)
                                     {
                                         MeshExplosion.SetBackTriangleVertices(vertices2, normals2, tangents2, 1);
                                         Mesh mesh = new Mesh();
                                         mesh.vertices = vertices2;
                                         if (normals2 != null)
                                         {
                                             mesh.normals = normals2;
                                         }
                                         if (tangents2 != null)
                                         {
                                             mesh.tangents = tangents2;
                                         }
                                         if (vector2Array1 != null)
                                         {
                                             mesh.uv = vector2Array1;
                                         }
                                         if (vector2Array2 != null)
                                         {
                                             mesh.uv2 = vector2Array2;
                                         }
                                         if (colorArray != null)
                                         {
                                             mesh.colors = colorArray;
                                         }
                                         mesh.triangles    = numArray4;
                                         meshArray[index2] = mesh;
                                         index1            = 0;
                                         break;
                                     }
                                     break;
                                 }
                                 if (index1 % 3 == 0 && !flag2)
                                 {
                                     break;
                                 }
                             }
                         }
                         ++index2;
                     }
                 }
                 Vector3 vector3_6 = Vector3.zero;
                 if (!flag1)
                 {
                     Mesh mesh = explosionPreparation.startMesh = new Mesh();
                     mesh.MarkDynamic();
                     mesh.vertices = vertices2;
                     if (normals2 != null)
                     {
                         mesh.normals = normals2;
                     }
                     if (tangents2 != null)
                     {
                         mesh.tangents = tangents2;
                     }
                     if (vector2Array1 != null)
                     {
                         mesh.uv = vector2Array1;
                     }
                     if (vector2Array2 != null)
                     {
                         mesh.uv2 = vector2Array2;
                     }
                     if (colorArray != null)
                     {
                         mesh.colors = colorArray;
                     }
                     mesh.subMeshCount = subMeshCount;
                     int num2 = 0;
                     for (int submesh = 0; submesh < subMeshCount; ++submesh)
                     {
                         int   length3   = numArray1[submesh].Length * 2;
                         int[] triangles = new int[length3];
                         int   index3    = 0;
                         while (index3 < length3)
                         {
                             triangles[index3] = num2;
                             ++index3;
                             ++num2;
                         }
                         mesh.SetTriangles(triangles, submesh);
                     }
                     if (this.useMeshBoundsCenter)
                     {
                         vector3_6 = mesh.bounds.center;
                     }
                 }
                 Vector3[] vector3Array2 = explosionPreparation.triangleNormals = new Vector3[length1];
                 int       index6        = 0;
                 int       index7        = 0;
                 while (index7 < length1)
                 {
                     Vector3 vector3_1;
                     if (flag1)
                     {
                         vector3_1 = vector3Array1[index7];
                     }
                     else
                     {
                         vector3_1             = (vertices2[index6] + vertices2[index6 + 1] + vertices2[index6 + 2]) / 3f;
                         vector3Array1[index7] = vector3_1;
                     }
                     Vector3 vector3_2;
                     if (this.useNormals && normals2 != null)
                     {
                         if (flag1)
                         {
                             normals2 = meshArray[index7].normals;
                             index6   = 0;
                         }
                         vector3_2 = ((normals2[index6] + normals2[index6 + 1] + normals2[index6 + 2]) / 3f).normalized;
                     }
                     else
                     {
                         vector3_2 = vector3_1;
                         if (this.useMeshBoundsCenter)
                         {
                             vector3_2 -= vector3_6;
                         }
                         vector3_2.Normalize();
                     }
                     vector3Array2[index7] = vector3_2;
                     ++index7;
                     index6 += 6;
                 }
                 this.preparation = explosionPreparation;
                 if (cachePreparation)
                 {
                     MeshExploder.cache[oldMesh] = explosionPreparation;
                 }
                 if ((double)this.fadeTime == 0.0 || this.shadersAlreadyHandleTransparency)
                 {
                     return;
                 }
                 foreach (Material sharedMaterial in this.GetComponent <Renderer>().sharedMaterials)
                 {
                     Shader shader         = sharedMaterial.shader;
                     Shader replacementFor = Fade.GetReplacementFor(shader);
                     if ((Object)replacementFor == (Object)null || !replacementFor.name.StartsWith("Transparent/"))
                     {
                         Debug.LogWarning((object)("Couldn't find an explicitly transparent version of shader '" + shader.name + "' so fading may not work. If the shader does support transparency then this warning can be avoided by enabling the 'Shaders Already Handle Transparency' option."));
                     }
                 }
             }
         }
     }
 }
Exemple #2
0
    void Prepare(Mesh oldMesh, bool cachePreparation = true)
    {
#if UNITY_4_OR_ABOVE
        if (!oldMesh.isReadable)
        {
            Debug.LogError("The mesh is not readable. Switch on the \"Read/Write Enabled\"" +
                           " option on the mesh's import settings.");
            return;
        }
#endif

        var usePhysics = type == ExplosionType.Physics;

        MeshExplosionPreparation prep;

        if (cache.TryGetValue(oldMesh, out prep))
        {
            // The caching is different for physics explosions and non-physics explosions, so make
            // sure that we have the correct stuff:
            if ((usePhysics && prep.physicsMeshes != null) ||
                (!usePhysics && prep.startMesh != null))
            {
                preparation = prep;
                return;
            }
        }

        // Make a copy of the mesh but with every triangle made discrete so that it doesn't share
        // any vertices with any other triangle.

        var oldVertices = oldMesh.vertices;
        var oldNormals  = oldMesh.normals;
        var oldTangents = oldMesh.tangents;
        var oldUV       = oldMesh.uv;
        var oldUV2      = oldMesh.uv2;
        var oldColors   = oldMesh.colors;

        var subMeshCount                 = oldMesh.subMeshCount;
        var oldMeshTriangles             = new int[subMeshCount][];
        var frontMeshTrianglesPerSubMesh = usePhysics ?
                                           prep.frontMeshTrianglesPerSubMesh = new int[subMeshCount] : null;
        int frontTriangles = 0;

        for (var subMesh = 0; subMesh < subMeshCount; ++subMesh)
        {
            int[] triangles;
            oldMeshTriangles[subMesh] = triangles = oldMesh.GetTriangles(subMesh);
            var frontMeshTrianglesInThisSubMesh = triangles.Length / 3;
            if (usePhysics)
            {
                frontMeshTrianglesPerSubMesh[subMesh] = frontMeshTrianglesInThisSubMesh;
            }
            frontTriangles += frontMeshTrianglesInThisSubMesh;
        }

        prep.totalFrontTriangles = frontTriangles;
        var totalTriangles   = frontTriangles * 2; // back faces
        var newTotalVertices = usePhysics ?
                               3 * 2 :             // one triangle, both sides
                               totalTriangles * 3;

        const int vertexLimit = 65534;
        if (newTotalVertices > vertexLimit)
        {
            Debug.LogError("The mesh has too many triangles to explode. It must have" +
                           " " + ((vertexLimit / 3) / 2) + " or fewer triangles.");
            return;
        }

        var newVertices = new Vector3[newTotalVertices];
        var newNormals  = oldNormals == null || oldNormals.Length == 0 ?
                          null : new Vector3[newTotalVertices];
        var newTangents = oldTangents == null || oldTangents.Length == 0 ?
                          null : new Vector4[newTotalVertices];
        var newUV = oldUV == null || oldUV.Length == 0 ?
                    null : new Vector2[newTotalVertices];
        var newUV2 = oldUV2 == null || oldUV2.Length == 0 ?
                     null : new Vector2[newTotalVertices];
        var newColors = oldColors == null || oldColors.Length == 0 ?
                        null : new Color[newTotalVertices];

        var triangleCentroids = prep.triangleCentroids = new Vector3[frontTriangles];

        var physicsMeshes = prep.physicsMeshes = usePhysics ? new Mesh[frontTriangles] : null;
        var rotations     = prep.rotations = usePhysics ? new Quaternion[frontTriangles] : null;

        var physicsMeshTriangles = usePhysics ? new int[] { 0, 1, 2, 3, 4, 5 } : null;

        var newVertexNumber        = 0;
        var wholeMeshTriangleIndex = 0;

        var invRotation = Quaternion.identity;

        for (var subMesh = 0; subMesh < subMeshCount; ++subMesh)
        {
            var triangles = oldMeshTriangles[subMesh];
            var n         = triangles.Length;

            int i = 0;

            while (i < n)
            {
                var triangleStartI = i;
                var centroid       = Vector3.zero;

                for (int repeat = 0; repeat < 2; ++repeat)
                {
                    i = triangleStartI;
                    var back = repeat == 1;

                    while (i < n)
                    {
                        var oldVertexNumber = triangles[back ?
                                                        (triangleStartI + (3 - 1 - (i - triangleStartI))) : i];

                        if (usePhysics && (newVertexNumber % 6) == 0)                           // Start of a triangle
                        {
                            var a = oldVertices[oldVertexNumber];
                            var b = oldVertices[triangles[i + 1]];
                            var c = oldVertices[triangles[i + 2]];

                            var triangleRealNormal = Vector3.Cross(b - a, c - a);
                            // We want to rotate the triangle so that it is flat on the x-z plane.
                            // The reason for that is so that we can use an axis-aligned box
                            // collider to be its physics proxy.
                            rotations[wholeMeshTriangleIndex] =
                                Quaternion.FromToRotation(Vector3.up, triangleRealNormal);
                            invRotation =
                                Quaternion.FromToRotation(triangleRealNormal, Vector3.up);
                            triangleCentroids[wholeMeshTriangleIndex] = centroid =
                                (a + b + c) / 3;
                        }

                        if (!back)
                        {
                            newVertices[newVertexNumber] = invRotation *
                                                           (oldVertices[oldVertexNumber] - centroid);

                            if (newNormals != null)
                            {
                                newNormals[newVertexNumber] = invRotation *
                                                              oldNormals[oldVertexNumber];
                            }
                            if (newTangents != null)
                            {
                                newTangents[newVertexNumber] = invRotation *
                                                               oldTangents[oldVertexNumber];
                            }
                        }
                        else
                        {
                            // This stuff is handled by MeshExplosion.SetBackTriangleVertices().
                        }

                        if (newUV != null)
                        {
                            newUV[newVertexNumber] = oldUV[oldVertexNumber];
                        }
                        if (newUV2 != null)
                        {
                            newUV2[newVertexNumber] = oldUV2[oldVertexNumber];
                        }
                        if (newColors != null)
                        {
                            newColors[newVertexNumber] = oldColors[oldVertexNumber];
                        }

                        // It's important that these are here rather than in a for statement so
                        // that they get executed even if we break.
                        ++i;
                        ++newVertexNumber;

                        if ((newVertexNumber % 6) == 0)                           // End of a triangle
                        {
                            if (usePhysics)
                            {
                                MeshExplosion.SetBackTriangleVertices(
                                    newVertices, newNormals, newTangents, 1);

                                var mesh = new Mesh();

                                mesh.vertices = newVertices;
                                if (newNormals != null)
                                {
                                    mesh.normals = newNormals;
                                }
                                if (newTangents != null)
                                {
                                    mesh.tangents = newTangents;
                                }
                                if (newUV != null)
                                {
                                    mesh.uv = newUV;
                                }
                                if (newUV2 != null)
                                {
                                    mesh.uv2 = newUV2;
                                }
                                if (newColors != null)
                                {
                                    mesh.colors = newColors;
                                }
                                mesh.triangles = physicsMeshTriangles;

                                physicsMeshes[wholeMeshTriangleIndex] = mesh;

                                newVertexNumber = 0;
                            }
                            break;
                        }
                        else if ((newVertexNumber % 3) == 0 && !back)
                        {
                            break;
                        }
                    }
                }

                ++wholeMeshTriangleIndex;
            }
        }

        var newMeshCenter = Vector3.zero;
        if (!usePhysics)
        {
            var newMesh = prep.startMesh = new Mesh();
#if UNITY_4_OR_ABOVE
            newMesh.MarkDynamic();
#endif
            newMesh.vertices = newVertices;
            if (newNormals != null)
            {
                newMesh.normals = newNormals;
            }
            if (newTangents != null)
            {
                newMesh.tangents = newTangents;
            }
            if (newUV != null)
            {
                newMesh.uv = newUV;
            }
            if (newUV2 != null)
            {
                newMesh.uv2 = newUV2;
            }
            if (newColors != null)
            {
                newMesh.colors = newColors;
            }

            newMesh.subMeshCount = subMeshCount;
            newVertexNumber      = 0;
            for (var subMesh = 0; subMesh < subMeshCount; ++subMesh)
            {
                var n            = oldMeshTriangles[subMesh].Length * 2;
                var newTriangles = new int[n];
                for (var i = 0; i < n; ++i, ++newVertexNumber)
                {
                    newTriangles[i] = newVertexNumber;
                }
                newMesh.SetTriangles(newTriangles, subMesh);
            }

            if (useMeshBoundsCenter)
            {
                newMeshCenter = newMesh.bounds.center;
            }
        }

        var triangleNormals = prep.triangleNormals = new Vector3[frontTriangles];

        var firstVertexIndex = 0;
        for (var triangleNumber = 0; triangleNumber < frontTriangles;
             ++triangleNumber, firstVertexIndex += 6)
        {
            Vector3 centroid;
            if (usePhysics)
            {
                centroid = triangleCentroids[triangleNumber];
            }
            else
            {
                centroid =
                    (newVertices[firstVertexIndex] +
                     newVertices[firstVertexIndex + 1] +
                     newVertices[firstVertexIndex + 2]) / 3;
                triangleCentroids[triangleNumber] = centroid;
            }

            Vector3 normal;
            if (useNormals && newNormals != null)
            {
                if (usePhysics)
                {
                    newNormals       = physicsMeshes[triangleNumber].normals;
                    firstVertexIndex = 0;
                }

                normal =
                    ((newNormals[firstVertexIndex] +
                      newNormals[firstVertexIndex + 1] +
                      newNormals[firstVertexIndex + 2]) / 3).normalized;
            }
            else
            {
                normal = centroid;
                if (useMeshBoundsCenter)
                {
                    normal -= newMeshCenter;
                }
                normal.Normalize();
            }

            triangleNormals[triangleNumber] = normal;
        }

        preparation = prep;
        if (cachePreparation)
        {
            cache[oldMesh] = prep;
        }

        if (fadeTime != 0 && !shadersAlreadyHandleTransparency)
        {
            // Preload any replacement shaders that will be needed:
            foreach (var i in GetComponent <Renderer>().sharedMaterials)
            {
                var shader      = i.shader;
                var replacement = Fade.GetReplacementFor(shader);
                if (replacement == null)
                {
                    Debug.LogWarning("Couldn't find an explicitly transparent version of shader" +
                                     " '" + shader.name + "' so fading may not work. If the shader does" +
                                     " support transparency then this warning can be avoided by enabling" +
                                     " the 'Shaders Already Handle Transparency' option.");
                }
            }
        }
    }
Exemple #3
0
    // Token: 0x06002F6F RID: 12143 RVA: 0x000E6914 File Offset: 0x000E4D14
    private void Update()
    {
        if (this.vertices == null)
        {
            string name = base.GetType().Name;
            Debug.LogError(string.Concat(new string[]
            {
                "The ",
                name,
                " component should not be used directly. Add the ",
                typeof(MeshExploder).Name,
                " component to your object and it will take care of creating the explosion object and adding the ",
                name,
                " component."
            }));
            base.enabled = false;
            return;
        }
        float deltaTime = Time.deltaTime;

        this.explosionTime += deltaTime;
        if (this.tangents != null && this.tangents.Length == 0)
        {
            this.tangents = null;
        }
        Vector3[] triangleNormals = this.preparation.triangleNormals;
        Vector3   a    = (!this.useGravity) ? default(Vector3) : this.thisTransform.InverseTransformDirection(Physics.gravity);
        int       num  = this.vertices.Length / 3 / 2;
        int       num2 = 0;
        int       i    = 0;

        while (i < num)
        {
            float   d      = this.triangleSpeeds[i] * deltaTime;
            float   angle  = this.triangleRotationSpeeds[i] * deltaTime;
            Vector3 a2     = triangleNormals[i];
            Vector3 vector = a2 * d;
            if (this.useGravity)
            {
                vector += this.explosionTime * a * deltaTime;
            }
            Quaternion rotation = Quaternion.AngleAxis(angle, this.triangleRotationAxes[i]);
            Vector3    vector2  = this.triangleCurrentCentroids[i];
            Vector3    vector3  = vector2 + vector;
            for (int j = 0; j < 3; j++)
            {
                int num3 = num2 + j;
                this.vertices[num3] = rotation * (this.vertices[num3] - vector2) + vector3;
                if (this.normals != null)
                {
                    this.normals[num3] = rotation * this.normals[num3];
                }
                if (this.tangents != null)
                {
                    this.tangents[num3] = rotation * this.tangents[num3];
                }
            }
            this.triangleCurrentCentroids[i] = vector3;
            i++;
            num2 += 6;
        }
        MeshExplosion.SetBackTriangleVertices(this.vertices, this.normals, this.tangents, this.preparation.totalFrontTriangles);
        this.mesh.vertices = this.vertices;
        this.mesh.normals  = this.normals;
        this.mesh.tangents = this.tangents;
        this.mesh.RecalculateBounds();
    }