Пример #1
0
        private void UpdateNodeMesh(TreeNode node, List <TreeMaterial> materials, List <TreeVertex> verts, List <TreeTriangle> tris, List <TreeAOSphere> aoSpheres, int buildFlags, float adaptiveQuality, float aoDensity)
        {
            node.triStart  = tris.Count;
            node.triEnd    = tris.Count;
            node.vertStart = verts.Count;
            node.vertEnd   = verts.Count;
            if (node.visible && base.visible)
            {
                Vector2 vector = base.ComputeWindFactor(node, node.offset);
                if (this.geometryMode == 4)
                {
                    if ((((cloneMesh == null) || (cloneVerts == null)) || ((cloneNormals == null) || (cloneTangents == null))) || (cloneUVs == null))
                    {
                        return;
                    }
                    Matrix4x4 localToWorldMatrix = this.instanceMesh.transform.localToWorldMatrix;
                    Matrix4x4 matrixx2           = node.matrix * localToWorldMatrix;
                    int       count = verts.Count;
                    float     num2  = 5f;
                    for (int i = 0; i < cloneVerts.Length; i++)
                    {
                        TreeVertex item = new TreeVertex {
                            pos = matrixx2.MultiplyPoint(cloneVerts[i]),
                            nor = matrixx2.MultiplyVector(cloneNormals[i]).normalized,
                            uv0 = new Vector2(cloneUVs[i].x, cloneUVs[i].y)
                        };
                        Vector3 normalized = matrixx2.MultiplyVector(new Vector3(cloneTangents[i].x, cloneTangents[i].y, cloneTangents[i].z)).normalized;
                        item.tangent = new Vector4(normalized.x, normalized.y, normalized.z, cloneTangents[i].w);
                        float edgeFactor = (cloneVerts[i].magnitude / num2) * base.animationEdge;
                        item.SetAnimationProperties(vector.x, vector.y, edgeFactor, node.animSeed);
                        if ((buildFlags & 1) != 0)
                        {
                            item.SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(item.pos, item.nor, aoSpheres, aoDensity));
                        }
                        verts.Add(item);
                    }
                    for (int j = 0; j < cloneMesh.subMeshCount; j++)
                    {
                        int   num6;
                        int[] triangles = cloneMesh.GetTriangles(j);
                        if ((this.instanceMesh.GetComponent <Renderer>() != null) && (j < this.instanceMesh.GetComponent <Renderer>().sharedMaterials.Length))
                        {
                            num6 = TreeGroup.GetMaterialIndex(this.instanceMesh.GetComponent <Renderer>().sharedMaterials[j], materials, false);
                        }
                        else
                        {
                            num6 = TreeGroup.GetMaterialIndex(null, materials, false);
                        }
                        for (int k = 0; k < triangles.Length; k += 3)
                        {
                            TreeTriangle triangle = new TreeTriangle(num6, triangles[k] + count, triangles[k + 1] + count, triangles[k + 2] + count);
                            tris.Add(triangle);
                        }
                    }
                }
                else if (this.geometryMode == 3)
                {
                    Vector3 eulerAngles = node.rotation.eulerAngles;
                    eulerAngles.z = eulerAngles.x * 2f;
                    eulerAngles.x = 0f;
                    eulerAngles.y = 0f;
                    Quaternion billboardRotation = Quaternion.Euler(eulerAngles);
                    Vector3    normalBase        = new Vector3(TreeGroup.GenerateBendBillboardNormalFactor, TreeGroup.GenerateBendBillboardNormalFactor, 1f);
                    Vector3    tangentBase       = (Vector3)(billboardRotation * new Vector3(1f, 0f, 0f));
                    float      normalFix         = node.scale / (TreeGroup.GenerateBendBillboardNormalFactor * TreeGroup.GenerateBendBillboardNormalFactor);
                    TreeVertex vertex2           = CreateBillboardVertex(node, billboardRotation, normalBase, normalFix, tangentBase, new Vector2(0f, 1f));
                    TreeVertex vertex3           = CreateBillboardVertex(node, billboardRotation, normalBase, normalFix, tangentBase, new Vector2(0f, 0f));
                    TreeVertex vertex4           = CreateBillboardVertex(node, billboardRotation, normalBase, normalFix, tangentBase, new Vector2(1f, 0f));
                    TreeVertex vertex5           = CreateBillboardVertex(node, billboardRotation, normalBase, normalFix, tangentBase, new Vector2(1f, 1f));
                    vertex2.SetAnimationProperties(vector.x, vector.y, base.animationEdge, node.animSeed);
                    vertex3.SetAnimationProperties(vector.x, vector.y, base.animationEdge, node.animSeed);
                    vertex4.SetAnimationProperties(vector.x, vector.y, base.animationEdge, node.animSeed);
                    vertex5.SetAnimationProperties(vector.x, vector.y, base.animationEdge, node.animSeed);
                    if ((buildFlags & 1) != 0)
                    {
                        Vector3 vector8 = (Vector3)(Vector3.right * node.scale);
                        Vector3 vector9 = (Vector3)(Vector3.forward * node.scale);
                        float   ao      = 0f;
                        ao  = TreeGroup.ComputeAmbientOcclusion(vertex2.pos + vector8, Vector3.right, aoSpheres, aoDensity) + TreeGroup.ComputeAmbientOcclusion(vertex2.pos - vector8, -Vector3.right, aoSpheres, aoDensity);
                        ao += TreeGroup.ComputeAmbientOcclusion(vertex2.pos + vector9, Vector3.forward, aoSpheres, aoDensity);
                        ao += TreeGroup.ComputeAmbientOcclusion(vertex2.pos - vector9, -Vector3.forward, aoSpheres, aoDensity);
                        ao /= 4f;
                        vertex2.SetAmbientOcclusion(ao);
                        vertex3.SetAmbientOcclusion(ao);
                        vertex4.SetAmbientOcclusion(ao);
                        vertex5.SetAmbientOcclusion(ao);
                    }
                    int num10 = verts.Count;
                    verts.Add(vertex2);
                    verts.Add(vertex3);
                    verts.Add(vertex4);
                    verts.Add(vertex5);
                    int material = TreeGroup.GetMaterialIndex(this.materialLeaf, materials, false);
                    tris.Add(new TreeTriangle(material, num10, num10 + 2, num10 + 1, true));
                    tris.Add(new TreeTriangle(material, num10, num10 + 3, num10 + 2, true));
                }
                else
                {
                    int num12 = 0;
                    switch (((GeometryMode)this.geometryMode))
                    {
                    case GeometryMode.PLANE:
                        num12 = 1;
                        break;

                    case GeometryMode.CROSS:
                        num12 = 2;
                        break;

                    case GeometryMode.TRI_CROSS:
                        num12 = 3;
                        break;
                    }
                    int       num13             = TreeGroup.GetMaterialIndex(this.materialLeaf, materials, false);
                    Vector2[] vectorArray       = new Vector2[] { new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(1f, 1f) };
                    Vector2[] planeHullVertices = this.GetPlaneHullVertices(this.materialLeaf);
                    if (planeHullVertices == null)
                    {
                        planeHullVertices = vectorArray;
                    }
                    float     scale        = node.scale;
                    Vector3[] vectorArray3 = new Vector3[] { new Vector3(-scale, 0f, -scale), new Vector3(-scale, 0f, scale), new Vector3(scale, 0f, scale), new Vector3(scale, 0f, -scale) };
                    Vector3   vector10     = new Vector3(TreeGroup.GenerateBendNormalFactor, 1f - TreeGroup.GenerateBendNormalFactor, TreeGroup.GenerateBendNormalFactor);
                    Vector3[] vectorArray6 = new Vector3[4];
                    Vector3   vector11     = new Vector3(-vector10.x, vector10.y, -vector10.z);
                    vectorArray6[0] = vector11.normalized;
                    Vector3 vector12 = new Vector3(-vector10.x, vector10.y, 0f);
                    vectorArray6[1] = vector12.normalized;
                    Vector3 vector13 = new Vector3(vector10.x, vector10.y, 0f);
                    vectorArray6[2] = vector13.normalized;
                    Vector3 vector14 = new Vector3(vector10.x, vector10.y, -vector10.z);
                    vectorArray6[3] = vector14.normalized;
                    Vector3[] vectorArray4 = vectorArray6;
                    for (int m = 0; m < num12; m++)
                    {
                        Quaternion rot = Quaternion.Euler(new Vector3(90f, 0f, 0f));
                        switch (m)
                        {
                        case 1:
                            rot = Quaternion.Euler(new Vector3(90f, 90f, 0f));
                            break;

                        case 2:
                            rot = Quaternion.Euler(new Vector3(0f, 90f, 0f));
                            break;
                        }
                        TreeVertex[] tv = new TreeVertex[] { new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex() };
                        for (int n = 0; n < 4; n++)
                        {
                            tv[n].pos     = node.matrix.MultiplyPoint((Vector3)(rot * vectorArray3[n]));
                            tv[n].nor     = node.matrix.MultiplyVector((Vector3)(rot * vectorArray4[n]));
                            tv[n].tangent = TreeGroup.CreateTangent(node, rot, tv[n].nor);
                            tv[n].uv0     = planeHullVertices[n];
                            tv[n].SetAnimationProperties(vector.x, vector.y, base.animationEdge, node.animSeed);
                            if ((buildFlags & 1) != 0)
                            {
                                tv[n].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(tv[n].pos, tv[n].nor, aoSpheres, aoDensity));
                            }
                        }
                        for (int num17 = 0; num17 < 4; num17++)
                        {
                            tv[num17 + 4].Lerp4(tv, planeHullVertices[num17]);
                            tv[num17 + 4].uv0  = tv[num17].uv0;
                            tv[num17 + 4].uv1  = tv[num17].uv1;
                            tv[num17 + 4].flag = tv[num17].flag;
                        }
                        int num18 = verts.Count;
                        for (int num19 = 0; num19 < 4; num19++)
                        {
                            verts.Add(tv[num19 + 4]);
                        }
                        tris.Add(new TreeTriangle(num13, num18, num18 + 1, num18 + 2));
                        tris.Add(new TreeTriangle(num13, num18, num18 + 2, num18 + 3));
                        Vector3 inNormal = node.matrix.MultiplyVector((Vector3)(rot * new Vector3(0f, 1f, 0f)));
                        if (TreeGroup.GenerateDoubleSidedGeometry)
                        {
                            TreeVertex[] vertexArray2 = new TreeVertex[] { new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex() };
                            for (int num20 = 0; num20 < 4; num20++)
                            {
                                vertexArray2[num20].pos       = tv[num20].pos;
                                vertexArray2[num20].nor       = Vector3.Reflect(tv[num20].nor, inNormal);
                                vertexArray2[num20].tangent   = Vector3.Reflect((Vector3)tv[num20].tangent, inNormal);
                                vertexArray2[num20].tangent.w = -1f;
                                vertexArray2[num20].uv0       = tv[num20].uv0;
                                vertexArray2[num20].SetAnimationProperties(vector.x, vector.y, base.animationEdge, node.animSeed);
                                if ((buildFlags & 1) != 0)
                                {
                                    vertexArray2[num20].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(vertexArray2[num20].pos, vertexArray2[num20].nor, aoSpheres, aoDensity));
                                }
                            }
                            for (int num21 = 0; num21 < 4; num21++)
                            {
                                vertexArray2[num21 + 4].Lerp4(vertexArray2, planeHullVertices[num21]);
                                vertexArray2[num21 + 4].uv0  = vertexArray2[num21].uv0;
                                vertexArray2[num21 + 4].uv1  = vertexArray2[num21].uv1;
                                vertexArray2[num21 + 4].flag = vertexArray2[num21].flag;
                            }
                            int num22 = verts.Count;
                            for (int num23 = 0; num23 < 4; num23++)
                            {
                                verts.Add(vertexArray2[num23 + 4]);
                            }
                            tris.Add(new TreeTriangle(num13, num22, num22 + 2, num22 + 1));
                            tris.Add(new TreeTriangle(num13, num22, num22 + 3, num22 + 2));
                        }
                    }
                }
                node.triEnd  = tris.Count;
                node.vertEnd = verts.Count;
            }
        }
Пример #2
0
        public bool OptimizeMaterial(List <TreeMaterial> materials, List <TreeVertex> vertices, List <TreeTriangle> triangles)
        {
            if (!this.optimizedSolidMaterial || !this.optimizedCutoutMaterial)
            {
                Debug.LogError("Optimized materials haven't been assigned");
                return(false);
            }
            Shader shader;
            Shader shader2;

            TreeData.ExtractOptimizedShaders(materials, out shader, out shader2);
            this.optimizedSolidMaterial.shader  = shader;
            this.optimizedCutoutMaterial.shader = shader2;
            int num     = 1024;
            int num2    = 1024;
            int padding = 32;

            Profiler.BeginSample("OptimizeMaterial");
            float[] array = new float[materials.Count];
            float   num3  = 0f;
            float   num4  = 0f;

            for (int i = 0; i < materials.Count; i++)
            {
                if (!materials[i].tileV)
                {
                    num4 += 1f;
                }
                else
                {
                    num3 += 1f;
                }
            }
            for (int j = 0; j < materials.Count; j++)
            {
                if (materials[j].tileV)
                {
                    array[j] = 1f;
                }
                else
                {
                    array[j] = 1f / num4;
                }
            }
            TextureAtlas textureAtlas = new TextureAtlas();

            for (int k = 0; k < materials.Count; k++)
            {
                Texture2D texture2D       = null;
                Texture2D normal          = null;
                Texture2D gloss           = null;
                Texture2D transtex        = null;
                Texture2D shadowOffsetTex = null;
                Color     color           = new Color(1f, 1f, 1f, 1f);
                float     num5            = 0.03f;
                Vector2   textureScale    = new Vector2(1f, 1f);
                Material  material        = materials[k].material;
                if (material)
                {
                    if (material.HasProperty("_Color"))
                    {
                        color = material.GetColor("_Color");
                    }
                    if (material.HasProperty("_MainTex"))
                    {
                        texture2D    = (material.mainTexture as Texture2D);
                        textureScale = material.GetTextureScale("_MainTex");
                    }
                    if (material.HasProperty("_BumpMap"))
                    {
                        normal = (material.GetTexture("_BumpMap") as Texture2D);
                    }
                    if (material.HasProperty("_GlossMap"))
                    {
                        gloss = (material.GetTexture("_GlossMap") as Texture2D);
                    }
                    if (material.HasProperty("_TranslucencyMap"))
                    {
                        transtex = (material.GetTexture("_TranslucencyMap") as Texture2D);
                    }
                    if (material.HasProperty("_Shininess"))
                    {
                        num5 = material.GetFloat("_Shininess");
                    }
                    if (material.HasProperty("_ShadowOffset"))
                    {
                        shadowOffsetTex = (material.GetTexture("_ShadowOffset") as Texture2D);
                    }
                }
                num5 = Mathf.Clamp(num5, 0.03f, 1f);
                Vector2 scale = new Vector2(array[k], array[k]);
                if (texture2D)
                {
                    scale.x *= (float)num / (float)texture2D.width;
                    scale.y *= (float)num2 / (float)texture2D.height;
                }
                bool tileV = materials[k].tileV;
                if (!tileV)
                {
                    textureScale = new Vector2(1f, 1f);
                }
                textureAtlas.AddTexture("tex" + k, texture2D, color, normal, gloss, transtex, shadowOffsetTex, num5, scale, tileV, textureScale);
            }
            textureAtlas.Pack(ref num, num2, padding, true);
            this.UpdateTextures(textureAtlas, materials);
            Rect    rect      = default(Rect);
            Vector2 texTiling = new Vector2(1f, 1f);
            int     num6      = -1;

            for (int l = 0; l < triangles.Count; l++)
            {
                TreeTriangle treeTriangle = triangles[l];
                if (treeTriangle.materialIndex != num6)
                {
                    num6      = treeTriangle.materialIndex;
                    rect      = textureAtlas.GetUVRect("tex" + treeTriangle.materialIndex);
                    texTiling = textureAtlas.GetTexTiling("tex" + treeTriangle.materialIndex);
                }
                for (int m = 0; m < 3; m++)
                {
                    TreeVertex treeVertex = vertices[treeTriangle.v[m]];
                    if (!treeVertex.flag)
                    {
                        treeVertex.uv0.x = rect.x + treeVertex.uv0.x * rect.width;
                        treeVertex.uv0.y = (rect.y + treeVertex.uv0.y * rect.height) * texTiling.y;
                        treeVertex.flag  = true;
                    }
                }
                if (treeTriangle.isCutout)
                {
                    treeTriangle.materialIndex = 1;
                }
                else
                {
                    treeTriangle.materialIndex = 0;
                }
            }
            Profiler.EndSample();
            return(true);
        }
        private void UpdateNodeMesh(TreeNode node, List <TreeMaterial> materials, List <TreeVertex> verts, List <TreeTriangle> tris, List <TreeAOSphere> aoSpheres, int buildFlags, float adaptiveQuality, float aoDensity)
        {
            node.triStart  = tris.Count;
            node.triEnd    = tris.Count;
            node.vertStart = verts.Count;
            node.vertEnd   = verts.Count;

            // Check for visibility..
            if (!node.visible || !visible)
            {
                return;
            }

            Profiler.BeginSample("TreeGroupLeaf.UpdateNodeMesh");

            Vector2 windFactors = ComputeWindFactor(node, node.offset);

            if (geometryMode == (int)GeometryMode.MESH)
            {
                // Exit if no instance mesh is selected
                if (cloneMesh == null)
                {
                    //    Debug.LogError("No cloneMesh");
                    return;
                }
                if (cloneVerts == null)
                {
                    //     Debug.LogError("No cloneVerts");
                    return;
                }
                if (cloneNormals == null)
                {
                    //    Debug.LogError("No cloneNormals");
                    return;
                }
                if (cloneTangents == null)
                {
                    //   Debug.LogError("No cloneTangents");
                    return;
                }
                if (cloneUVs == null)
                {
                    //   Debug.LogError("No cloneUVs");
                    return;
                }

                Matrix4x4 cloneMatrix = instanceMesh.transform.localToWorldMatrix;
                Matrix4x4 tformMatrix = node.matrix * cloneMatrix;

                int vertOffset = verts.Count;

                float dist = 5.0f;

                // copy verts
                for (int i = 0; i < cloneVerts.Length; i++)
                {
                    TreeVertex v0 = new TreeVertex();
                    v0.pos = tformMatrix.MultiplyPoint(cloneVerts[i]);
                    v0.nor = tformMatrix.MultiplyVector(cloneNormals[i]).normalized;
                    v0.uv0 = new Vector2(cloneUVs[i].x, cloneUVs[i].y);
                    Vector3 tangent = tformMatrix.MultiplyVector(new Vector3(cloneTangents[i].x, cloneTangents[i].y, cloneTangents[i].z)).normalized;
                    v0.tangent = new Vector4(tangent.x, tangent.y, tangent.z, cloneTangents[i].w);

                    // wind
                    float windEdge = (cloneVerts[i].magnitude / dist) * animationEdge;
                    v0.SetAnimationProperties(windFactors.x, windFactors.y, windEdge, node.animSeed);

                    // AO
                    if ((buildFlags & (int)BuildFlag.BuildAmbientOcclusion) != 0)
                    {
                        v0.SetAmbientOcclusion(ComputeAmbientOcclusion(v0.pos, v0.nor, aoSpheres, aoDensity));
                    }

                    verts.Add(v0);
                }

                // copy tris
                for (int s = 0; s < cloneMesh.subMeshCount; s++)
                {
                    int[] instanceTris = cloneMesh.GetTriangles(s);

                    int materialIndex;
                    if (instanceMesh.GetComponent <Renderer>() != null && s < instanceMesh.GetComponent <Renderer>().sharedMaterials.Length)
                    {
                        materialIndex = GetMaterialIndex(instanceMesh.GetComponent <Renderer>().sharedMaterials[s], materials, false);
                    }
                    else
                    {
                        materialIndex = GetMaterialIndex(null, materials, false);
                    }

                    for (int i = 0; i < instanceTris.Length; i += 3)
                    {
                        TreeTriangle t0 = new TreeTriangle(materialIndex, instanceTris[i] + vertOffset, instanceTris[i + 1] + vertOffset, instanceTris[i + 2] + vertOffset);
                        tris.Add(t0);
                    }
                }
            }
            else if (geometryMode == (int)GeometryMode.BILLBOARD)
            {
                // rotation
                Vector3 eulerRot = node.rotation.eulerAngles;
                eulerRot.z = eulerRot.x * 2.0f;
                eulerRot.x = 0.0f;
                eulerRot.y = 0.0f;
                Quaternion billboardRotation = Quaternion.Euler(eulerRot);

                // normal
                Vector3 normalBase = new Vector3(GenerateBendBillboardNormalFactor, GenerateBendBillboardNormalFactor, 1.0f);

                Vector3 tangentBase = billboardRotation * new Vector3(1, 0, 0);
                float   normalFix   = node.scale / (GenerateBendBillboardNormalFactor * GenerateBendBillboardNormalFactor);

                TreeVertex v0 = CreateBillboardVertex(node, billboardRotation, normalBase, normalFix, tangentBase, new Vector2(0, 1));
                TreeVertex v1 = CreateBillboardVertex(node, billboardRotation, normalBase, normalFix, tangentBase, new Vector2(0, 0));
                TreeVertex v2 = CreateBillboardVertex(node, billboardRotation, normalBase, normalFix, tangentBase, new Vector2(1, 0));
                TreeVertex v3 = CreateBillboardVertex(node, billboardRotation, normalBase, normalFix, tangentBase, new Vector2(1, 1));

                // wind
                v0.SetAnimationProperties(windFactors.x, windFactors.y, animationEdge, node.animSeed);
                v1.SetAnimationProperties(windFactors.x, windFactors.y, animationEdge, node.animSeed);
                v2.SetAnimationProperties(windFactors.x, windFactors.y, animationEdge, node.animSeed);
                v3.SetAnimationProperties(windFactors.x, windFactors.y, animationEdge, node.animSeed);

                if ((buildFlags & (int)BuildFlag.BuildAmbientOcclusion) != 0)
                {
                    //  Vector3 pushU = Vector3.up * internalSize;
                    Vector3 pushR = Vector3.right * node.scale;
                    Vector3 pushF = Vector3.forward * node.scale;

                    float a = 0.0f; // ComputeAmbientOcclusion(partID, v0.pos + pushU, Vector3.up, aoSpheres);
                    //a += ComputeAmbientOcclusion(partID, v0.pos - pushU, -Vector3.up, aoSpheres);
                    a  = ComputeAmbientOcclusion(v0.pos + pushR, Vector3.right, aoSpheres, aoDensity);
                    a += ComputeAmbientOcclusion(v0.pos - pushR, -Vector3.right, aoSpheres, aoDensity);
                    a += ComputeAmbientOcclusion(v0.pos + pushF, Vector3.forward, aoSpheres, aoDensity);
                    a += ComputeAmbientOcclusion(v0.pos - pushF, -Vector3.forward, aoSpheres, aoDensity);
                    a /= 4.0f;

                    v0.SetAmbientOcclusion(a);
                    v1.SetAmbientOcclusion(a);
                    v2.SetAmbientOcclusion(a);
                    v3.SetAmbientOcclusion(a);
                }

                int index0 = verts.Count;
                verts.Add(v0);
                verts.Add(v1);
                verts.Add(v2);
                verts.Add(v3);

                int materialIndex = GetMaterialIndex(materialLeaf, materials, false);

                tris.Add(new TreeTriangle(materialIndex, index0, index0 + 2, index0 + 1, true));
                tris.Add(new TreeTriangle(materialIndex, index0, index0 + 3, index0 + 2, true));
            }
            else
            {
                // plane, cross, tri-cross

                int planes = 0;
                switch ((GeometryMode)geometryMode)
                {
                case GeometryMode.PLANE:
                    planes = 1;
                    break;

                case GeometryMode.CROSS:
                    planes = 2;
                    break;

                case GeometryMode.TRI_CROSS:
                    planes = 3;
                    break;
                }

                int materialIndex = GetMaterialIndex(materialLeaf, materials, false);

                Vector2[] rawHull = new Vector2[]
                {
                    new Vector2(0, 1),
                    new Vector2(0, 0),
                    new Vector2(1, 0),
                    new Vector2(1, 1)
                };
                Vector2[] textureHull = GetPlaneHullVertices(materialLeaf);
                if (textureHull == null)
                {
                    textureHull = rawHull;
                }
                float     ns           = node.scale;
                Vector3[] positionsRaw = new Vector3[]
                {
                    new Vector3(-ns, 0f, -ns),
                    new Vector3(-ns, 0f, ns),
                    new Vector3(ns, 0f, ns),
                    new Vector3(ns, 0f, -ns)
                };

                Vector3 normal = new Vector3(GenerateBendNormalFactor, 1.0f - GenerateBendNormalFactor, GenerateBendNormalFactor);

                Vector3[] normalsRaw = new Vector3[]
                {
                    new Vector3(-normal.x, normal.y, -normal.z).normalized,
                    new Vector3(-normal.x, normal.y, 0).normalized, // note z always 0
                    new Vector3(normal.x, normal.y, 0).normalized,  // note z always 0
                    new Vector3(normal.x, normal.y, -normal.z).normalized
                };


                for (int ipl = 0; ipl < planes; ipl++)
                {
                    Quaternion rot = Quaternion.Euler(new Vector3(90, 0, 0));
                    switch (ipl)
                    {
                    case 1:
                        rot = Quaternion.Euler(new Vector3(90, 90, 0));
                        break;

                    case 2:
                        rot = Quaternion.Euler(new Vector3(0, 90, 0));
                        break;
                    }

                    TreeVertex[] tv = new TreeVertex[8]
                    {
                        new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), // initial quad
                        new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex()  // from bounding hull
                    };

                    for (int i = 0; i < 4; ++i)
                    {
                        tv[i].pos     = node.matrix.MultiplyPoint(rot * positionsRaw[i]);
                        tv[i].nor     = node.matrix.MultiplyVector(rot * normalsRaw[i]);
                        tv[i].tangent = CreateTangent(node, rot, tv[i].nor);
                        tv[i].uv0     = textureHull[i];
                        tv[i].SetAnimationProperties(windFactors.x, windFactors.y, animationEdge, node.animSeed);
                        if ((buildFlags & (int)BuildFlag.BuildAmbientOcclusion) != 0)
                        {
                            tv[i].SetAmbientOcclusion(ComputeAmbientOcclusion(tv[i].pos, tv[i].nor, aoSpheres, aoDensity));
                        }
                    }

                    // now lerp positions into correct placed based on the bounding hull
                    for (int i = 0; i < 4; ++i)
                    {
                        tv[i + 4].Lerp4(tv, textureHull[i]);
                        tv[i + 4].uv0  = tv[i].uv0;
                        tv[i + 4].uv1  = tv[i].uv1;
                        tv[i + 4].flag = tv[i].flag;
                    }

                    int index0 = verts.Count;
                    for (int i = 0; i < 4; ++i)
                    {
                        verts.Add(tv[i + 4]);
                    }

                    tris.Add(new TreeTriangle(materialIndex, index0, index0 + 1, index0 + 2));
                    tris.Add(new TreeTriangle(materialIndex, index0, index0 + 2, index0 + 3));

                    Vector3 faceNormal = node.matrix.MultiplyVector(rot * new Vector3(0, 1, 0));

                    if (GenerateDoubleSidedGeometry)
                    {
                        // Duplicate vertices with mirrored normal and tangent
                        TreeVertex[] tv2 = new TreeVertex[8]
                        {
                            new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), // initial quad
                            new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex()  // from bounding hull
                        };
                        for (int i = 0; i < 4; ++i)
                        {
                            tv2[i].pos       = tv[i].pos;
                            tv2[i].nor       = Vector3.Reflect(tv[i].nor, faceNormal);
                            tv2[i].tangent   = Vector3.Reflect(tv[i].tangent, faceNormal);
                            tv2[i].tangent.w = -1;
                            tv2[i].uv0       = tv[i].uv0;
                            tv2[i].SetAnimationProperties(windFactors.x, windFactors.y, animationEdge, node.animSeed);
                            if ((buildFlags & (int)BuildFlag.BuildAmbientOcclusion) != 0)
                            {
                                tv2[i].SetAmbientOcclusion(ComputeAmbientOcclusion(tv2[i].pos, tv2[i].nor, aoSpheres, aoDensity));
                            }
                        }
                        // now lerp positions into correct placed based on the bounding hull
                        for (int i = 0; i < 4; ++i)
                        {
                            tv2[i + 4].Lerp4(tv2, textureHull[i]);
                            tv2[i + 4].uv0  = tv2[i].uv0;
                            tv2[i + 4].uv1  = tv2[i].uv1;
                            tv2[i + 4].flag = tv2[i].flag;
                        }

                        int index4 = verts.Count;
                        for (int i = 0; i < 4; ++i)
                        {
                            verts.Add(tv2[i + 4]);
                        }
                        tris.Add(new TreeTriangle(materialIndex, index4, index4 + 2, index4 + 1));
                        tris.Add(new TreeTriangle(materialIndex, index4, index4 + 3, index4 + 2));
                    }
                }
            }

            node.triEnd  = tris.Count;
            node.vertEnd = verts.Count;

            Profiler.EndSample(); // TreeGroupLeaf.UpdateNodeMesh
        }
Пример #4
0
		private void UpdateNodeMesh(TreeNode node, List<TreeMaterial> materials, List<TreeVertex> verts, List<TreeTriangle> tris, List<TreeAOSphere> aoSpheres, int buildFlags, float adaptiveQuality, float aoDensity)
		{
			node.triStart = tris.Count;
			node.triEnd = tris.Count;
			node.vertStart = verts.Count;
			node.vertEnd = verts.Count;
			if (!node.visible || !this.visible)
			{
				return;
			}
			Profiler.BeginSample("TreeGroupBranch.UpdateNodeMesh");
			int count = verts.Count;
			float approximateLength = node.spline.GetApproximateLength();
			List<RingLoop> list = new List<RingLoop>();
			float adaptiveQuality2 = Mathf.Clamp01(adaptiveQuality * this.lodQualityMultiplier);
			List<float> adaptiveSamples = TreeData.GetAdaptiveSamples(this, node, adaptiveQuality2);
			int adaptiveRadialSegments = TreeData.GetAdaptiveRadialSegments(this.radius, adaptiveQuality2);
			TreeGroupBranch treeGroupBranch = null;
			if (this.parentGroup != null && this.parentGroup.GetType() == typeof(TreeGroupBranch))
			{
				treeGroupBranch = (TreeGroupBranch)this.parentGroup;
			}
			if (this.geometryMode == TreeGroupBranch.GeometryMode.BranchFrond || this.geometryMode == TreeGroupBranch.GeometryMode.Branch)
			{
				int materialIndex = TreeGroup.GetMaterialIndex(this.materialBranch, materials, true);
				float num = 0f;
				float num2 = 0f;
				float num3 = approximateLength / (this.GetRadiusAtTime(node, 0f, false) * 3.14159274f * 2f);
				bool flag = true;
				if (node.parent != null && treeGroupBranch != null)
				{
					num2 = node.offset * node.parent.spline.GetApproximateLength();
				}
				float num4 = 1f - node.capRange;
				for (int i = 0; i < adaptiveSamples.Count; i++)
				{
					float num5 = adaptiveSamples[i];
					Vector3 positionAtTime = node.spline.GetPositionAtTime(num5);
					Quaternion rotationAtTime = node.spline.GetRotationAtTime(num5);
					float radiusAtTime = this.GetRadiusAtTime(node, num5, false);
					Matrix4x4 m = node.matrix * Matrix4x4.TRS(positionAtTime, rotationAtTime, new Vector3(1f, 1f, 1f));
					Vector3 flareWeldAtTime = this.GetFlareWeldAtTime(node, num5);
					float num6 = Mathf.Max(flareWeldAtTime.x, Mathf.Max(flareWeldAtTime.y, flareWeldAtTime.z) * 0.25f);
					if (num5 <= num4)
					{
						adaptiveRadialSegments = TreeData.GetAdaptiveRadialSegments(radiusAtTime + num6, adaptiveQuality2);
					}
					if (flag)
					{
						if (i > 0)
						{
							float num7 = adaptiveSamples[i - 1];
							float num8 = num5 - num7;
							float num9 = (radiusAtTime + this.GetRadiusAtTime(node, num7, false)) * 0.5f;
							num += num8 * approximateLength / (num9 * 3.14159274f * 2f);
						}
					}
					else
					{
						num = num2 + num5 * num3;
					}
					Vector2 vector = base.ComputeWindFactor(node, num5);
					RingLoop ringLoop = new RingLoop();
					ringLoop.Reset(radiusAtTime, m, num, adaptiveRadialSegments);
					ringLoop.SetSurfaceAngle(node.GetSurfaceAngleAtTime(num5));
					ringLoop.SetAnimationProperties(vector.x, vector.y, 0f, node.animSeed);
					ringLoop.SetSpread(flareWeldAtTime.y, flareWeldAtTime.z);
					ringLoop.SetNoise(this.noise * Mathf.Clamp01(this.noiseCurve.Evaluate(num5)), this.noiseScaleU * 10f, this.noiseScaleV * 10f);
					ringLoop.SetFlares(flareWeldAtTime.x, this.flareNoise * 10f);
					int count2 = verts.Count;
					ringLoop.BuildVertices(verts);
					int count3 = verts.Count;
					if ((buildFlags & 2) != 0)
					{
						float num10 = this.weldHeight;
						float num11 = Mathf.Pow(Mathf.Clamp01((1f - num5 - (1f - this.weldHeight)) / this.weldHeight), 1.5f);
						float d = 1f - num11;
						if (num5 < num10 && node.parent != null && node.parent.spline != null)
						{
							Ray ray = default(Ray);
							for (int j = count2; j < count3; j++)
							{
								ray.origin = verts[j].pos;
								ray.direction = m.MultiplyVector(-Vector3.up);
								Vector3 pos = verts[j].pos;
								Vector3 nor = verts[j].nor;
								float num12 = -10000f;
								float num13 = 100000f;
								for (int k = node.parent.triStart; k < node.parent.triEnd; k++)
								{
									object obj = MathUtils.IntersectRayTriangle(ray, verts[tris[k].v[0]].pos, verts[tris[k].v[1]].pos, verts[tris[k].v[2]].pos, true);
									if (obj != null)
									{
										RaycastHit raycastHit = (RaycastHit)obj;
										if (Mathf.Abs(raycastHit.distance) < num13 && raycastHit.distance > num12)
										{
											num13 = Mathf.Abs(raycastHit.distance);
											verts[j].nor = verts[tris[k].v[0]].nor * raycastHit.barycentricCoordinate.x + verts[tris[k].v[1]].nor * raycastHit.barycentricCoordinate.y + verts[tris[k].v[2]].nor * raycastHit.barycentricCoordinate.z;
											verts[j].nor = verts[j].nor * num11 + nor * d;
											verts[j].pos = raycastHit.point * num11 + pos * d;
										}
									}
								}
							}
						}
					}
					list.Add(ringLoop);
					if (num5 == 1f && ringLoop.radius > 0.005f)
					{
						RingLoop ringLoop2 = ringLoop.Clone();
						ringLoop2.radius = 0f;
						ringLoop2.baseOffset += radiusAtTime / 6.28318548f;
						ringLoop2.BuildVertices(verts);
						list.Add(ringLoop2);
					}
				}
				if (list.Count > 0 && list[list.Count - 1].radius > 0.025f && node.breakOffset < 1f)
				{
					float mappingScale = 1f / (this.radius * 3.14159274f * 2f);
					float sphereFactor = 0f;
					float num14 = 1f;
					int mappingMode = 0;
					Material m2 = this.materialBranch;
					if (this.materialBreak != null)
					{
						m2 = this.materialBreak;
					}
					int materialIndex2 = TreeGroup.GetMaterialIndex(m2, materials, false);
					list[list.Count - 1].Cap(sphereFactor, num14, mappingMode, mappingScale, verts, tris, materialIndex2);
				}
				node.triStart = tris.Count;
				for (int l = 0; l < list.Count - 1; l++)
				{
					list[l].Connect(list[l + 1], tris, materialIndex, false, false);
				}
				node.triEnd = tris.Count;
				list.Clear();
			}
			float num15 = Mathf.Min(this.frondRange.x, this.frondRange.y);
			float num16 = Mathf.Max(this.frondRange.x, this.frondRange.y);
			float num17 = num15;
			float num18 = num16;
			num15 = Mathf.Clamp(num15, 0f, node.breakOffset);
			num16 = Mathf.Clamp(num16, 0f, node.breakOffset);
			if ((this.geometryMode == TreeGroupBranch.GeometryMode.BranchFrond || this.geometryMode == TreeGroupBranch.GeometryMode.Frond) && this.frondCount > 0 && num15 != num16)
			{
				bool flag2 = true;
				bool flag3 = true;
				for (int n = 0; n < adaptiveSamples.Count; n++)
				{
					float num19 = adaptiveSamples[n];
					if (num19 < num15)
					{
						adaptiveSamples.RemoveAt(n);
						n--;
					}
					else
					{
						if (num19 == num15)
						{
							flag2 = false;
						}
						else
						{
							if (num19 == num16)
							{
								flag3 = false;
							}
							else
							{
								if (num19 > num16)
								{
									adaptiveSamples.RemoveAt(n);
									n--;
								}
							}
						}
					}
				}
				if (flag2)
				{
					adaptiveSamples.Insert(0, num15);
				}
				if (flag3)
				{
					adaptiveSamples.Add(num16);
				}
				int materialIndex3 = TreeGroup.GetMaterialIndex(this.materialFrond, materials, false);
				float num20 = 1f - node.capRange;
				for (int num21 = 0; num21 < this.frondCount; num21++)
				{
					float num22 = this.frondCrease * 90f * 0.0174532924f;
					float num23 = (this.frondRotation * 360f + (float)num21 * 180f / (float)this.frondCount - 90f) * 0.0174532924f;
					float f = -num23 - num22;
					float f2 = num23 - num22;
					Vector3 a = new Vector3(Mathf.Sin(f), 0f, Mathf.Cos(f));
					Vector3 vector2 = new Vector3(a.z, 0f, -a.x);
					Vector3 a2 = new Vector3(Mathf.Sin(f2), 0f, -Mathf.Cos(f2));
					Vector3 vector3 = new Vector3(-a2.z, 0f, a2.x);
					for (int num24 = 0; num24 < adaptiveSamples.Count; num24++)
					{
						float num25 = adaptiveSamples[num24];
						float y = (num25 - num17) / (num18 - num17);
						float timeParam = num25;
						if (num25 > num20)
						{
							timeParam = num20;
							float f3 = Mathf.Acos(Mathf.Clamp01((num25 - num20) / node.capRange));
							float num26 = Mathf.Sin(f3);
							float y2 = Mathf.Cos(f3) * this.capSmoothing;
							a = new Vector3(Mathf.Sin(f) * num26, y2, Mathf.Cos(f) * num26);
							vector2 = new Vector3(a.z, a.y, -a.x);
							a2 = new Vector3(Mathf.Sin(f2) * num26, y2, -Mathf.Cos(f2) * num26);
							vector3 = new Vector3(-a2.z, a2.y, a2.x);
						}
						Vector3 a3 = new Vector3(0f, 0f, -1f);
						Vector3 positionAtTime2 = node.spline.GetPositionAtTime(timeParam);
						Quaternion rotationAtTime2 = node.spline.GetRotationAtTime(num25);
						float d2 = Mathf.Clamp01(this.frondCurve.Evaluate(num25)) * this.frondWidth * node.GetScale();
						Matrix4x4 matrix4x = node.matrix * Matrix4x4.TRS(positionAtTime2, rotationAtTime2, new Vector3(1f, 1f, 1f));
						if (TreeGroup.GenerateDoubleSidedGeometry)
						{
							for (float num27 = -1f; num27 < 2f; num27 += 2f)
							{
								TreeVertex treeVertex = new TreeVertex();
								treeVertex.pos = matrix4x.MultiplyPoint(a * d2);
								treeVertex.nor = matrix4x.MultiplyVector(vector2 * num27).normalized;
								treeVertex.tangent = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex.nor);
								treeVertex.tangent.w = -num27;
								treeVertex.uv0 = new Vector2(1f, y);
								TreeVertex treeVertex2 = new TreeVertex();
								treeVertex2.pos = matrix4x.MultiplyPoint(Vector3.zero);
								treeVertex2.nor = matrix4x.MultiplyVector(a3 * num27).normalized;
								treeVertex2.tangent = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex2.nor);
								treeVertex2.tangent.w = -num27;
								treeVertex2.uv0 = new Vector2(0.5f, y);
								TreeVertex treeVertex3 = new TreeVertex();
								treeVertex3.pos = matrix4x.MultiplyPoint(Vector3.zero);
								treeVertex3.nor = matrix4x.MultiplyVector(a3 * num27).normalized;
								treeVertex3.tangent = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex3.nor);
								treeVertex3.tangent.w = -num27;
								treeVertex3.uv0 = new Vector2(0.5f, y);
								TreeVertex treeVertex4 = new TreeVertex();
								treeVertex4.pos = matrix4x.MultiplyPoint(a2 * d2);
								treeVertex4.nor = matrix4x.MultiplyVector(vector3 * num27).normalized;
								treeVertex4.tangent = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex4.nor);
								treeVertex4.tangent.w = -num27;
								treeVertex4.uv0 = new Vector2(0f, y);
								Vector2 vector4 = base.ComputeWindFactor(node, num25);
								treeVertex.SetAnimationProperties(vector4.x, vector4.y, this.animationEdge, node.animSeed);
								treeVertex2.SetAnimationProperties(vector4.x, vector4.y, 0f, node.animSeed);
								treeVertex3.SetAnimationProperties(vector4.x, vector4.y, 0f, node.animSeed);
								treeVertex4.SetAnimationProperties(vector4.x, vector4.y, this.animationEdge, node.animSeed);
								verts.Add(treeVertex);
								verts.Add(treeVertex2);
								verts.Add(treeVertex3);
								verts.Add(treeVertex4);
							}
							if (num24 > 0)
							{
								int count4 = verts.Count;
								TreeTriangle treeTriangle = new TreeTriangle(materialIndex3, count4 - 4, count4 - 3, count4 - 11);
								TreeTriangle treeTriangle2 = new TreeTriangle(materialIndex3, count4 - 4, count4 - 11, count4 - 12);
								treeTriangle.flip();
								treeTriangle2.flip();
								TreeTriangle item = new TreeTriangle(materialIndex3, count4 - 8, count4 - 7, count4 - 15);
								TreeTriangle item2 = new TreeTriangle(materialIndex3, count4 - 8, count4 - 15, count4 - 16);
								tris.Add(treeTriangle);
								tris.Add(treeTriangle2);
								tris.Add(item);
								tris.Add(item2);
								TreeTriangle item3 = new TreeTriangle(materialIndex3, count4 - 2, count4 - 9, count4 - 1);
								TreeTriangle item4 = new TreeTriangle(materialIndex3, count4 - 2, count4 - 10, count4 - 9);
								TreeTriangle treeTriangle3 = new TreeTriangle(materialIndex3, count4 - 6, count4 - 13, count4 - 5);
								TreeTriangle treeTriangle4 = new TreeTriangle(materialIndex3, count4 - 6, count4 - 14, count4 - 13);
								treeTriangle3.flip();
								treeTriangle4.flip();
								tris.Add(item3);
								tris.Add(item4);
								tris.Add(treeTriangle3);
								tris.Add(treeTriangle4);
							}
						}
						else
						{
							TreeVertex treeVertex5 = new TreeVertex();
							treeVertex5.pos = matrix4x.MultiplyPoint(a * d2);
							treeVertex5.nor = matrix4x.MultiplyVector(vector2).normalized;
							treeVertex5.uv0 = new Vector2(0f, y);
							TreeVertex treeVertex6 = new TreeVertex();
							treeVertex6.pos = matrix4x.MultiplyPoint(Vector3.zero);
							treeVertex6.nor = matrix4x.MultiplyVector(Vector3.back).normalized;
							treeVertex6.uv0 = new Vector2(0.5f, y);
							TreeVertex treeVertex7 = new TreeVertex();
							treeVertex7.pos = matrix4x.MultiplyPoint(a2 * d2);
							treeVertex7.nor = matrix4x.MultiplyVector(vector3).normalized;
							treeVertex7.uv0 = new Vector2(1f, y);
							Vector2 vector5 = base.ComputeWindFactor(node, num25);
							treeVertex5.SetAnimationProperties(vector5.x, vector5.y, this.animationEdge, node.animSeed);
							treeVertex6.SetAnimationProperties(vector5.x, vector5.y, 0f, node.animSeed);
							treeVertex7.SetAnimationProperties(vector5.x, vector5.y, this.animationEdge, node.animSeed);
							verts.Add(treeVertex5);
							verts.Add(treeVertex6);
							verts.Add(treeVertex7);
							if (num24 > 0)
							{
								int count5 = verts.Count;
								TreeTriangle item5 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 3, count5 - 6);
								TreeTriangle item6 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 6, count5 - 5);
								tris.Add(item5);
								tris.Add(item6);
								TreeTriangle item7 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 4, count5 - 1);
								TreeTriangle item8 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 5, count5 - 4);
								tris.Add(item7);
								tris.Add(item8);
							}
						}
					}
				}
			}
			if ((buildFlags & 1) != 0)
			{
				for (int num28 = count; num28 < verts.Count; num28++)
				{
					verts[num28].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(verts[num28].pos, verts[num28].nor, aoSpheres, aoDensity));
				}
			}
			node.vertEnd = verts.Count;
			Profiler.EndSample();
		}
Пример #5
0
		private void UpdateNodeMesh(TreeNode node, List<TreeMaterial> materials, List<TreeVertex> verts, List<TreeTriangle> tris, List<TreeAOSphere> aoSpheres, int buildFlags, float adaptiveQuality, float aoDensity)
		{
			node.triStart = tris.Count;
			node.triEnd = tris.Count;
			node.vertStart = verts.Count;
			node.vertEnd = verts.Count;
			if (!node.visible || !this.visible)
			{
				return;
			}
			Profiler.BeginSample("TreeGroupLeaf.UpdateNodeMesh");
			Vector2 vector = base.ComputeWindFactor(node, node.offset);
			if (this.geometryMode == 4)
			{
				if (TreeGroupLeaf.cloneMesh == null)
				{
					return;
				}
				if (TreeGroupLeaf.cloneVerts == null)
				{
					return;
				}
				if (TreeGroupLeaf.cloneNormals == null)
				{
					return;
				}
				if (TreeGroupLeaf.cloneTangents == null)
				{
					return;
				}
				if (TreeGroupLeaf.cloneUVs == null)
				{
					return;
				}
				Matrix4x4 localToWorldMatrix = this.instanceMesh.transform.localToWorldMatrix;
				Matrix4x4 matrix4x = node.matrix * localToWorldMatrix;
				int count = verts.Count;
				float num = 5f;
				for (int i = 0; i < TreeGroupLeaf.cloneVerts.Length; i++)
				{
					TreeVertex treeVertex = new TreeVertex();
					treeVertex.pos = matrix4x.MultiplyPoint(TreeGroupLeaf.cloneVerts[i]);
					treeVertex.nor = matrix4x.MultiplyVector(TreeGroupLeaf.cloneNormals[i]).normalized;
					treeVertex.uv0 = new Vector2(TreeGroupLeaf.cloneUVs[i].x, TreeGroupLeaf.cloneUVs[i].y);
					Vector3 normalized = matrix4x.MultiplyVector(new Vector3(TreeGroupLeaf.cloneTangents[i].x, TreeGroupLeaf.cloneTangents[i].y, TreeGroupLeaf.cloneTangents[i].z)).normalized;
					treeVertex.tangent = new Vector4(normalized.x, normalized.y, normalized.z, TreeGroupLeaf.cloneTangents[i].w);
					float edgeFactor = TreeGroupLeaf.cloneVerts[i].magnitude / num * this.animationEdge;
					treeVertex.SetAnimationProperties(vector.x, vector.y, edgeFactor, node.animSeed);
					if ((buildFlags & 1) != 0)
					{
						treeVertex.SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(treeVertex.pos, treeVertex.nor, aoSpheres, aoDensity));
					}
					verts.Add(treeVertex);
				}
				for (int j = 0; j < TreeGroupLeaf.cloneMesh.subMeshCount; j++)
				{
					int[] triangles = TreeGroupLeaf.cloneMesh.GetTriangles(j);
					int materialIndex;
					if (this.instanceMesh.GetComponent<Renderer>() != null && j < this.instanceMesh.GetComponent<Renderer>().sharedMaterials.Length)
					{
						materialIndex = TreeGroup.GetMaterialIndex(this.instanceMesh.GetComponent<Renderer>().sharedMaterials[j], materials, false);
					}
					else
					{
						materialIndex = TreeGroup.GetMaterialIndex(null, materials, false);
					}
					for (int k = 0; k < triangles.Length; k += 3)
					{
						TreeTriangle item = new TreeTriangle(materialIndex, triangles[k] + count, triangles[k + 1] + count, triangles[k + 2] + count);
						tris.Add(item);
					}
				}
			}
			else
			{
				if (this.geometryMode == 3)
				{
					Vector3 eulerAngles = node.rotation.eulerAngles;
					eulerAngles.z = eulerAngles.x * 2f;
					eulerAngles.x = 0f;
					eulerAngles.y = 0f;
					Quaternion quaternion = Quaternion.Euler(eulerAngles);
					Vector3 normalBase = new Vector3(TreeGroup.GenerateBendBillboardNormalFactor, TreeGroup.GenerateBendBillboardNormalFactor, 1f);
					Vector3 tangentBase = quaternion * new Vector3(1f, 0f, 0f);
					float normalFix = node.scale / (TreeGroup.GenerateBendBillboardNormalFactor * TreeGroup.GenerateBendBillboardNormalFactor);
					TreeVertex treeVertex2 = TreeGroupLeaf.CreateBillboardVertex(node, quaternion, normalBase, normalFix, tangentBase, new Vector2(0f, 1f));
					TreeVertex treeVertex3 = TreeGroupLeaf.CreateBillboardVertex(node, quaternion, normalBase, normalFix, tangentBase, new Vector2(0f, 0f));
					TreeVertex treeVertex4 = TreeGroupLeaf.CreateBillboardVertex(node, quaternion, normalBase, normalFix, tangentBase, new Vector2(1f, 0f));
					TreeVertex treeVertex5 = TreeGroupLeaf.CreateBillboardVertex(node, quaternion, normalBase, normalFix, tangentBase, new Vector2(1f, 1f));
					treeVertex2.SetAnimationProperties(vector.x, vector.y, this.animationEdge, node.animSeed);
					treeVertex3.SetAnimationProperties(vector.x, vector.y, this.animationEdge, node.animSeed);
					treeVertex4.SetAnimationProperties(vector.x, vector.y, this.animationEdge, node.animSeed);
					treeVertex5.SetAnimationProperties(vector.x, vector.y, this.animationEdge, node.animSeed);
					if ((buildFlags & 1) != 0)
					{
						Vector3 b = Vector3.right * node.scale;
						Vector3 b2 = Vector3.forward * node.scale;
						float num2 = TreeGroup.ComputeAmbientOcclusion(treeVertex2.pos + b, Vector3.right, aoSpheres, aoDensity);
						num2 += TreeGroup.ComputeAmbientOcclusion(treeVertex2.pos - b, -Vector3.right, aoSpheres, aoDensity);
						num2 += TreeGroup.ComputeAmbientOcclusion(treeVertex2.pos + b2, Vector3.forward, aoSpheres, aoDensity);
						num2 += TreeGroup.ComputeAmbientOcclusion(treeVertex2.pos - b2, -Vector3.forward, aoSpheres, aoDensity);
						num2 /= 4f;
						treeVertex2.SetAmbientOcclusion(num2);
						treeVertex3.SetAmbientOcclusion(num2);
						treeVertex4.SetAmbientOcclusion(num2);
						treeVertex5.SetAmbientOcclusion(num2);
					}
					int count2 = verts.Count;
					verts.Add(treeVertex2);
					verts.Add(treeVertex3);
					verts.Add(treeVertex4);
					verts.Add(treeVertex5);
					int materialIndex2 = TreeGroup.GetMaterialIndex(this.materialLeaf, materials, false);
					tris.Add(new TreeTriangle(materialIndex2, count2, count2 + 2, count2 + 1, true));
					tris.Add(new TreeTriangle(materialIndex2, count2, count2 + 3, count2 + 2, true));
				}
				else
				{
					int num3 = 0;
					switch (this.geometryMode)
					{
					case 0:
						num3 = 1;
						break;
					case 1:
						num3 = 2;
						break;
					case 2:
						num3 = 3;
						break;
					}
					int materialIndex3 = TreeGroup.GetMaterialIndex(this.materialLeaf, materials, false);
					Vector2[] array = new Vector2[]
					{
						new Vector2(0f, 1f),
						new Vector2(0f, 0f),
						new Vector2(1f, 0f),
						new Vector2(1f, 1f)
					};
					Vector2[] array2 = this.GetPlaneHullVertices(this.materialLeaf);
					if (array2 == null)
					{
						array2 = array;
					}
					float scale = node.scale;
					Vector3[] array3 = new Vector3[]
					{
						new Vector3(-scale, 0f, -scale),
						new Vector3(-scale, 0f, scale),
						new Vector3(scale, 0f, scale),
						new Vector3(scale, 0f, -scale)
					};
					Vector3 vector2 = new Vector3(TreeGroup.GenerateBendNormalFactor, 1f - TreeGroup.GenerateBendNormalFactor, TreeGroup.GenerateBendNormalFactor);
					Vector3[] expr_788 = new Vector3[4];
					int arg_7B4_0_cp_1 = 0;
					Vector3 vector3 = new Vector3(-vector2.x, vector2.y, -vector2.z);
					expr_788[arg_7B4_0_cp_1] = vector3.normalized;
					int arg_7E2_0_cp_1 = 1;
					Vector3 vector4 = new Vector3(-vector2.x, vector2.y, 0f);
					expr_788[arg_7E2_0_cp_1] = vector4.normalized;
					int arg_80F_0_cp_1 = 2;
					Vector3 vector5 = new Vector3(vector2.x, vector2.y, 0f);
					expr_788[arg_80F_0_cp_1] = vector5.normalized;
					int arg_83F_0_cp_1 = 3;
					Vector3 vector6 = new Vector3(vector2.x, vector2.y, -vector2.z);
					expr_788[arg_83F_0_cp_1] = vector6.normalized;
					Vector3[] array4 = expr_788;
					for (int l = 0; l < num3; l++)
					{
						Quaternion quaternion2 = Quaternion.Euler(new Vector3(90f, 0f, 0f));
						int num4 = l;
						if (num4 != 1)
						{
							if (num4 == 2)
							{
								quaternion2 = Quaternion.Euler(new Vector3(0f, 90f, 0f));
							}
						}
						else
						{
							quaternion2 = Quaternion.Euler(new Vector3(90f, 90f, 0f));
						}
						TreeVertex[] array5 = new TreeVertex[]
						{
							new TreeVertex(),
							new TreeVertex(),
							new TreeVertex(),
							new TreeVertex(),
							new TreeVertex(),
							new TreeVertex(),
							new TreeVertex(),
							new TreeVertex()
						};
						for (int m = 0; m < 4; m++)
						{
							array5[m].pos = node.matrix.MultiplyPoint(quaternion2 * array3[m]);
							array5[m].nor = node.matrix.MultiplyVector(quaternion2 * array4[m]);
							array5[m].tangent = TreeGroup.CreateTangent(node, quaternion2, array5[m].nor);
							array5[m].uv0 = array2[m];
							array5[m].SetAnimationProperties(vector.x, vector.y, this.animationEdge, node.animSeed);
							if ((buildFlags & 1) != 0)
							{
								array5[m].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(array5[m].pos, array5[m].nor, aoSpheres, aoDensity));
							}
						}
						for (int n = 0; n < 4; n++)
						{
							array5[n + 4].Lerp4(array5, array2[n]);
							array5[n + 4].uv0 = array5[n].uv0;
							array5[n + 4].uv1 = array5[n].uv1;
							array5[n + 4].flag = array5[n].flag;
						}
						int count3 = verts.Count;
						for (int num5 = 0; num5 < 4; num5++)
						{
							verts.Add(array5[num5 + 4]);
						}
						tris.Add(new TreeTriangle(materialIndex3, count3, count3 + 1, count3 + 2));
						tris.Add(new TreeTriangle(materialIndex3, count3, count3 + 2, count3 + 3));
						Vector3 inNormal = node.matrix.MultiplyVector(quaternion2 * new Vector3(0f, 1f, 0f));
						if (TreeGroup.GenerateDoubleSidedGeometry)
						{
							TreeVertex[] array6 = new TreeVertex[]
							{
								new TreeVertex(),
								new TreeVertex(),
								new TreeVertex(),
								new TreeVertex(),
								new TreeVertex(),
								new TreeVertex(),
								new TreeVertex(),
								new TreeVertex()
							};
							for (int num6 = 0; num6 < 4; num6++)
							{
								array6[num6].pos = array5[num6].pos;
								array6[num6].nor = Vector3.Reflect(array5[num6].nor, inNormal);
								array6[num6].tangent = Vector3.Reflect(array5[num6].tangent, inNormal);
								array6[num6].tangent.w = -1f;
								array6[num6].uv0 = array5[num6].uv0;
								array6[num6].SetAnimationProperties(vector.x, vector.y, this.animationEdge, node.animSeed);
								if ((buildFlags & 1) != 0)
								{
									array6[num6].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(array6[num6].pos, array6[num6].nor, aoSpheres, aoDensity));
								}
							}
							for (int num7 = 0; num7 < 4; num7++)
							{
								array6[num7 + 4].Lerp4(array6, array2[num7]);
								array6[num7 + 4].uv0 = array6[num7].uv0;
								array6[num7 + 4].uv1 = array6[num7].uv1;
								array6[num7 + 4].flag = array6[num7].flag;
							}
							int count4 = verts.Count;
							for (int num8 = 0; num8 < 4; num8++)
							{
								verts.Add(array6[num8 + 4]);
							}
							tris.Add(new TreeTriangle(materialIndex3, count4, count4 + 2, count4 + 1));
							tris.Add(new TreeTriangle(materialIndex3, count4, count4 + 3, count4 + 2));
						}
					}
				}
			}
			node.triEnd = tris.Count;
			node.vertEnd = verts.Count;
			Profiler.EndSample();
		}
Пример #6
0
 private void UpdateNodeMesh(TreeNode node, List<TreeMaterial> materials, List<TreeVertex> verts, List<TreeTriangle> tris, List<TreeAOSphere> aoSpheres, int buildFlags, float adaptiveQuality, float aoDensity)
 {
     node.triStart = tris.Count;
     node.triEnd = tris.Count;
     node.vertStart = verts.Count;
     node.vertEnd = verts.Count;
     if (node.visible && base.visible)
     {
         int count = verts.Count;
         float approximateLength = node.spline.GetApproximateLength();
         List<RingLoop> list = new List<RingLoop>();
         float num3 = Mathf.Clamp01(adaptiveQuality * this.lodQualityMultiplier);
         List<float> list2 = TreeData.GetAdaptiveSamples(this, node, num3);
         int adaptiveRadialSegments = TreeData.GetAdaptiveRadialSegments(this.radius, num3);
         TreeGroupBranch parentGroup = null;
         if ((base.parentGroup != null) && (base.parentGroup.GetType() == typeof(TreeGroupBranch)))
         {
             parentGroup = (TreeGroupBranch) base.parentGroup;
         }
         if ((this.geometryMode == GeometryMode.BranchFrond) || (this.geometryMode == GeometryMode.Branch))
         {
             int materialIndex = TreeGroup.GetMaterialIndex(this.materialBranch, materials, true);
             float bOffset = 0f;
             float num7 = 0f;
             float num8 = approximateLength / ((this.GetRadiusAtTime(node, 0f, false) * 3.141593f) * 2f);
             bool flag = true;
             if ((node.parent != null) && (parentGroup != null))
             {
                 num7 = node.offset * node.parent.spline.GetApproximateLength();
             }
             float num9 = 1f - node.capRange;
             for (int i = 0; i < list2.Count; i++)
             {
                 float timeParam = list2[i];
                 Vector3 positionAtTime = node.spline.GetPositionAtTime(timeParam);
                 Quaternion rotationAtTime = node.spline.GetRotationAtTime(timeParam);
                 float r = this.GetRadiusAtTime(node, timeParam, false);
                 Matrix4x4 m = node.matrix * Matrix4x4.TRS(positionAtTime, rotationAtTime, new Vector3(1f, 1f, 1f));
                 Vector3 flareWeldAtTime = this.GetFlareWeldAtTime(node, timeParam);
                 float num13 = Mathf.Max(flareWeldAtTime.x, Mathf.Max(flareWeldAtTime.y, flareWeldAtTime.z) * 0.25f);
                 if (timeParam <= num9)
                 {
                     adaptiveRadialSegments = TreeData.GetAdaptiveRadialSegments(r + num13, num3);
                 }
                 if (flag)
                 {
                     if (i > 0)
                     {
                         float t = list2[i - 1];
                         float num15 = timeParam - t;
                         float num16 = (r + this.GetRadiusAtTime(node, t, false)) * 0.5f;
                         bOffset += (num15 * approximateLength) / ((num16 * 3.141593f) * 2f);
                     }
                 }
                 else
                 {
                     bOffset = num7 + (timeParam * num8);
                 }
                 Vector2 vector3 = base.ComputeWindFactor(node, timeParam);
                 RingLoop item = new RingLoop();
                 item.Reset(r, m, bOffset, adaptiveRadialSegments);
                 item.SetSurfaceAngle(node.GetSurfaceAngleAtTime(timeParam));
                 item.SetAnimationProperties(vector3.x, vector3.y, 0f, node.animSeed);
                 item.SetSpread(flareWeldAtTime.y, flareWeldAtTime.z);
                 item.SetNoise(this.noise * Mathf.Clamp01(this.noiseCurve.Evaluate(timeParam)), this.noiseScaleU * 10f, this.noiseScaleV * 10f);
                 item.SetFlares(flareWeldAtTime.x, this.flareNoise * 10f);
                 int num17 = verts.Count;
                 item.BuildVertices(verts);
                 int num18 = verts.Count;
                 if ((buildFlags & 2) != 0)
                 {
                     float weldHeight = this.weldHeight;
                     float num20 = Mathf.Pow(Mathf.Clamp01(((1f - timeParam) - (1f - this.weldHeight)) / this.weldHeight), 1.5f);
                     float num21 = 1f - num20;
                     if ((timeParam < weldHeight) && ((node.parent != null) && (node.parent.spline != null)))
                     {
                         Ray ray = new Ray();
                         for (int k = num17; k < num18; k++)
                         {
                             ray.origin = verts[k].pos;
                             ray.direction = m.MultiplyVector(-Vector3.up);
                             Vector3 pos = verts[k].pos;
                             Vector3 nor = verts[k].nor;
                             float num23 = -10000f;
                             float num24 = 100000f;
                             for (int n = node.parent.triStart; n < node.parent.triEnd; n++)
                             {
                                 object obj2 = MathUtils.IntersectRayTriangle(ray, verts[tris[n].v[0]].pos, verts[tris[n].v[1]].pos, verts[tris[n].v[2]].pos, true);
                                 if (obj2 != null)
                                 {
                                     RaycastHit hit = (RaycastHit) obj2;
                                     if ((Mathf.Abs(hit.distance) < num24) && (hit.distance > num23))
                                     {
                                         num24 = Mathf.Abs(hit.distance);
                                         verts[k].nor = (Vector3) (((verts[tris[n].v[0]].nor * hit.barycentricCoordinate.x) + (verts[tris[n].v[1]].nor * hit.barycentricCoordinate.y)) + (verts[tris[n].v[2]].nor * hit.barycentricCoordinate.z));
                                         verts[k].nor = (Vector3) ((verts[k].nor * num20) + (nor * num21));
                                         verts[k].pos = (Vector3) ((hit.point * num20) + (pos * num21));
                                     }
                                 }
                             }
                         }
                     }
                 }
                 list.Add(item);
                 if ((timeParam == 1f) && (item.radius > 0.005f))
                 {
                     RingLoop loop2 = item.Clone();
                     loop2.radius = 0f;
                     loop2.baseOffset += r / 6.283185f;
                     loop2.BuildVertices(verts);
                     list.Add(loop2);
                 }
             }
             if (((list.Count > 0) && (list[list.Count - 1].radius > 0.025f)) && (node.breakOffset < 1f))
             {
                 float mappingScale = 1f / ((this.radius * 3.141593f) * 2f);
                 float sphereFactor = 0f;
                 float noise = 1f;
                 int mappingMode = 0;
                 Material materialBranch = this.materialBranch;
                 if (this.materialBreak != null)
                 {
                     materialBranch = this.materialBreak;
                 }
                 int num30 = TreeGroup.GetMaterialIndex(materialBranch, materials, false);
                 list[list.Count - 1].Cap(sphereFactor, noise, mappingMode, mappingScale, verts, tris, num30);
             }
             node.triStart = tris.Count;
             for (int j = 0; j < (list.Count - 1); j++)
             {
                 list[j].Connect(list[j + 1], tris, materialIndex, false, false);
             }
             node.triEnd = tris.Count;
             list.Clear();
         }
         float num32 = Mathf.Min(this.frondRange.x, this.frondRange.y);
         float num33 = Mathf.Max(this.frondRange.x, this.frondRange.y);
         float num34 = num32;
         float num35 = num33;
         num32 = Mathf.Clamp(num32, 0f, node.breakOffset);
         num33 = Mathf.Clamp(num33, 0f, node.breakOffset);
         if (((this.geometryMode == GeometryMode.BranchFrond) || (this.geometryMode == GeometryMode.Frond)) && ((this.frondCount > 0) && (num32 != num33)))
         {
             bool flag2 = true;
             bool flag3 = true;
             for (int num36 = 0; num36 < list2.Count; num36++)
             {
                 float num37 = list2[num36];
                 if (num37 < num32)
                 {
                     list2.RemoveAt(num36);
                     num36--;
                 }
                 else if (num37 == num32)
                 {
                     flag2 = false;
                 }
                 else if (num37 == num33)
                 {
                     flag3 = false;
                 }
                 else if (num37 > num33)
                 {
                     list2.RemoveAt(num36);
                     num36--;
                 }
             }
             if (flag2)
             {
                 list2.Insert(0, num32);
             }
             if (flag3)
             {
                 list2.Add(num33);
             }
             int material = TreeGroup.GetMaterialIndex(this.materialFrond, materials, false);
             float num39 = 1f - node.capRange;
             for (int num40 = 0; num40 < this.frondCount; num40++)
             {
                 float num41 = (this.frondCrease * 90f) * 0.01745329f;
                 float num42 = (((this.frondRotation * 360f) + ((num40 * 180f) / ((float) this.frondCount))) - 90f) * 0.01745329f;
                 float f = -num42 - num41;
                 float num44 = num42 - num41;
                 Vector3 vector9 = new Vector3(Mathf.Sin(f), 0f, Mathf.Cos(f));
                 Vector3 v = new Vector3(vector9.z, 0f, -vector9.x);
                 Vector3 vector11 = new Vector3(Mathf.Sin(num44), 0f, -Mathf.Cos(num44));
                 Vector3 vector12 = new Vector3(-vector11.z, 0f, vector11.x);
                 for (int num45 = 0; num45 < list2.Count; num45++)
                 {
                     float num46 = list2[num45];
                     float y = (num46 - num34) / (num35 - num34);
                     float num48 = num46;
                     if (num46 > num39)
                     {
                         num48 = num39;
                         float num49 = Mathf.Acos(Mathf.Clamp01((num46 - num39) / node.capRange));
                         float num50 = Mathf.Sin(num49);
                         float num51 = Mathf.Cos(num49) * this.capSmoothing;
                         vector9 = new Vector3(Mathf.Sin(f) * num50, num51, Mathf.Cos(f) * num50);
                         v = new Vector3(vector9.z, vector9.y, -vector9.x);
                         vector11 = new Vector3(Mathf.Sin(num44) * num50, num51, -Mathf.Cos(num44) * num50);
                         vector12 = new Vector3(-vector11.z, vector11.y, vector11.x);
                     }
                     Vector3 vector13 = new Vector3(0f, 0f, -1f);
                     Vector3 vector14 = node.spline.GetPositionAtTime(num48);
                     Quaternion q = node.spline.GetRotationAtTime(num46);
                     float num52 = (Mathf.Clamp01(this.frondCurve.Evaluate(num46)) * this.frondWidth) * node.GetScale();
                     Matrix4x4 matrixx2 = node.matrix * Matrix4x4.TRS(vector14, q, new Vector3(1f, 1f, 1f));
                     if (TreeGroup.GenerateDoubleSidedGeometry)
                     {
                         for (float num53 = -1f; num53 < 2f; num53 += 2f)
                         {
                             TreeVertex vertex = new TreeVertex {
                                 pos = matrixx2.MultiplyPoint((Vector3) (vector9 * num52)),
                                 nor = matrixx2.MultiplyVector((Vector3) (v * num53)).normalized
                             };
                             vertex.tangent = TreeGroup.CreateTangent(node, q, vertex.nor);
                             vertex.tangent.w = -num53;
                             vertex.uv0 = new Vector2(1f, y);
                             TreeVertex vertex2 = new TreeVertex {
                                 pos = matrixx2.MultiplyPoint(Vector3.zero),
                                 nor = matrixx2.MultiplyVector((Vector3) (vector13 * num53)).normalized
                             };
                             vertex2.tangent = TreeGroup.CreateTangent(node, q, vertex2.nor);
                             vertex2.tangent.w = -num53;
                             vertex2.uv0 = new Vector2(0.5f, y);
                             TreeVertex vertex3 = new TreeVertex {
                                 pos = matrixx2.MultiplyPoint(Vector3.zero),
                                 nor = matrixx2.MultiplyVector((Vector3) (vector13 * num53)).normalized
                             };
                             vertex3.tangent = TreeGroup.CreateTangent(node, q, vertex3.nor);
                             vertex3.tangent.w = -num53;
                             vertex3.uv0 = new Vector2(0.5f, y);
                             TreeVertex vertex4 = new TreeVertex {
                                 pos = matrixx2.MultiplyPoint((Vector3) (vector11 * num52)),
                                 nor = matrixx2.MultiplyVector((Vector3) (vector12 * num53)).normalized
                             };
                             vertex4.tangent = TreeGroup.CreateTangent(node, q, vertex4.nor);
                             vertex4.tangent.w = -num53;
                             vertex4.uv0 = new Vector2(0f, y);
                             Vector2 vector19 = base.ComputeWindFactor(node, num46);
                             vertex.SetAnimationProperties(vector19.x, vector19.y, base.animationEdge, node.animSeed);
                             vertex2.SetAnimationProperties(vector19.x, vector19.y, 0f, node.animSeed);
                             vertex3.SetAnimationProperties(vector19.x, vector19.y, 0f, node.animSeed);
                             vertex4.SetAnimationProperties(vector19.x, vector19.y, base.animationEdge, node.animSeed);
                             verts.Add(vertex);
                             verts.Add(vertex2);
                             verts.Add(vertex3);
                             verts.Add(vertex4);
                         }
                         if (num45 > 0)
                         {
                             int num54 = verts.Count;
                             TreeTriangle triangle = new TreeTriangle(material, num54 - 4, num54 - 3, num54 - 11);
                             TreeTriangle triangle2 = new TreeTriangle(material, num54 - 4, num54 - 11, num54 - 12);
                             triangle.flip();
                             triangle2.flip();
                             TreeTriangle triangle3 = new TreeTriangle(material, num54 - 8, num54 - 7, num54 - 15);
                             TreeTriangle triangle4 = new TreeTriangle(material, num54 - 8, num54 - 15, num54 - 0x10);
                             tris.Add(triangle);
                             tris.Add(triangle2);
                             tris.Add(triangle3);
                             tris.Add(triangle4);
                             TreeTriangle triangle5 = new TreeTriangle(material, num54 - 2, num54 - 9, num54 - 1);
                             TreeTriangle triangle6 = new TreeTriangle(material, num54 - 2, num54 - 10, num54 - 9);
                             TreeTriangle triangle7 = new TreeTriangle(material, num54 - 6, num54 - 13, num54 - 5);
                             TreeTriangle triangle8 = new TreeTriangle(material, num54 - 6, num54 - 14, num54 - 13);
                             triangle7.flip();
                             triangle8.flip();
                             tris.Add(triangle5);
                             tris.Add(triangle6);
                             tris.Add(triangle7);
                             tris.Add(triangle8);
                         }
                     }
                     else
                     {
                         TreeVertex vertex5 = new TreeVertex {
                             pos = matrixx2.MultiplyPoint((Vector3) (vector9 * num52)),
                             nor = matrixx2.MultiplyVector(v).normalized,
                             uv0 = new Vector2(0f, y)
                         };
                         TreeVertex vertex6 = new TreeVertex {
                             pos = matrixx2.MultiplyPoint(Vector3.zero),
                             nor = matrixx2.MultiplyVector(Vector3.back).normalized,
                             uv0 = new Vector2(0.5f, y)
                         };
                         TreeVertex vertex7 = new TreeVertex {
                             pos = matrixx2.MultiplyPoint((Vector3) (vector11 * num52)),
                             nor = matrixx2.MultiplyVector(vector12).normalized,
                             uv0 = new Vector2(1f, y)
                         };
                         Vector2 vector23 = base.ComputeWindFactor(node, num46);
                         vertex5.SetAnimationProperties(vector23.x, vector23.y, base.animationEdge, node.animSeed);
                         vertex6.SetAnimationProperties(vector23.x, vector23.y, 0f, node.animSeed);
                         vertex7.SetAnimationProperties(vector23.x, vector23.y, base.animationEdge, node.animSeed);
                         verts.Add(vertex5);
                         verts.Add(vertex6);
                         verts.Add(vertex7);
                         if (num45 > 0)
                         {
                             int num55 = verts.Count;
                             TreeTriangle triangle9 = new TreeTriangle(material, num55 - 2, num55 - 3, num55 - 6);
                             TreeTriangle triangle10 = new TreeTriangle(material, num55 - 2, num55 - 6, num55 - 5);
                             tris.Add(triangle9);
                             tris.Add(triangle10);
                             TreeTriangle triangle11 = new TreeTriangle(material, num55 - 2, num55 - 4, num55 - 1);
                             TreeTriangle triangle12 = new TreeTriangle(material, num55 - 2, num55 - 5, num55 - 4);
                             tris.Add(triangle11);
                             tris.Add(triangle12);
                         }
                     }
                 }
             }
         }
         if ((buildFlags & 1) != 0)
         {
             for (int num56 = count; num56 < verts.Count; num56++)
             {
                 verts[num56].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(verts[num56].pos, verts[num56].nor, aoSpheres, aoDensity));
             }
         }
         node.vertEnd = verts.Count;
     }
 }
Пример #7
0
        private void UpdateNodeMesh(TreeNode node, List <TreeMaterial> materials, List <TreeVertex> verts, List <TreeTriangle> tris, List <TreeAOSphere> aoSpheres, int buildFlags, float adaptiveQuality, float aoDensity)
        {
            node.triStart  = tris.Count;
            node.triEnd    = tris.Count;
            node.vertStart = verts.Count;
            node.vertEnd   = verts.Count;
            if (!node.visible || !this.visible)
            {
                return;
            }
            Profiler.BeginSample("TreeGroupLeaf.UpdateNodeMesh");
            Vector2 vector = base.ComputeWindFactor(node, node.offset);

            if (this.geometryMode == 4)
            {
                if (TreeGroupLeaf.cloneMesh == null)
                {
                    return;
                }
                if (TreeGroupLeaf.cloneVerts == null)
                {
                    return;
                }
                if (TreeGroupLeaf.cloneNormals == null)
                {
                    return;
                }
                if (TreeGroupLeaf.cloneTangents == null)
                {
                    return;
                }
                if (TreeGroupLeaf.cloneUVs == null)
                {
                    return;
                }
                Matrix4x4 localToWorldMatrix = this.instanceMesh.transform.localToWorldMatrix;
                Matrix4x4 matrix4x           = node.matrix * localToWorldMatrix;
                int       count = verts.Count;
                float     num   = 5f;
                for (int i = 0; i < TreeGroupLeaf.cloneVerts.Length; i++)
                {
                    TreeVertex treeVertex = new TreeVertex();
                    treeVertex.pos = matrix4x.MultiplyPoint(TreeGroupLeaf.cloneVerts[i]);
                    treeVertex.nor = matrix4x.MultiplyVector(TreeGroupLeaf.cloneNormals[i]).normalized;
                    treeVertex.uv0 = new Vector2(TreeGroupLeaf.cloneUVs[i].x, TreeGroupLeaf.cloneUVs[i].y);
                    Vector3 normalized = matrix4x.MultiplyVector(new Vector3(TreeGroupLeaf.cloneTangents[i].x, TreeGroupLeaf.cloneTangents[i].y, TreeGroupLeaf.cloneTangents[i].z)).normalized;
                    treeVertex.tangent = new Vector4(normalized.x, normalized.y, normalized.z, TreeGroupLeaf.cloneTangents[i].w);
                    float edgeFactor = TreeGroupLeaf.cloneVerts[i].magnitude / num * this.animationEdge;
                    treeVertex.SetAnimationProperties(vector.x, vector.y, edgeFactor, node.animSeed);
                    if ((buildFlags & 1) != 0)
                    {
                        treeVertex.SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(treeVertex.pos, treeVertex.nor, aoSpheres, aoDensity));
                    }
                    verts.Add(treeVertex);
                }
                for (int j = 0; j < TreeGroupLeaf.cloneMesh.subMeshCount; j++)
                {
                    int[] triangles = TreeGroupLeaf.cloneMesh.GetTriangles(j);
                    int   materialIndex;
                    if (this.instanceMesh.GetComponent <Renderer>() != null && j < this.instanceMesh.GetComponent <Renderer>().sharedMaterials.Length)
                    {
                        materialIndex = TreeGroup.GetMaterialIndex(this.instanceMesh.GetComponent <Renderer>().sharedMaterials[j], materials, false);
                    }
                    else
                    {
                        materialIndex = TreeGroup.GetMaterialIndex(null, materials, false);
                    }
                    for (int k = 0; k < triangles.Length; k += 3)
                    {
                        TreeTriangle item = new TreeTriangle(materialIndex, triangles[k] + count, triangles[k + 1] + count, triangles[k + 2] + count);
                        tris.Add(item);
                    }
                }
            }
            else
            {
                if (this.geometryMode == 3)
                {
                    Vector3 eulerAngles = node.rotation.eulerAngles;
                    eulerAngles.z = eulerAngles.x * 2f;
                    eulerAngles.x = 0f;
                    eulerAngles.y = 0f;
                    Quaternion quaternion  = Quaternion.Euler(eulerAngles);
                    Vector3    normalBase  = new Vector3(TreeGroup.GenerateBendBillboardNormalFactor, TreeGroup.GenerateBendBillboardNormalFactor, 1f);
                    Vector3    tangentBase = quaternion * new Vector3(1f, 0f, 0f);
                    float      normalFix   = node.scale / (TreeGroup.GenerateBendBillboardNormalFactor * TreeGroup.GenerateBendBillboardNormalFactor);
                    TreeVertex treeVertex2 = TreeGroupLeaf.CreateBillboardVertex(node, quaternion, normalBase, normalFix, tangentBase, new Vector2(0f, 1f));
                    TreeVertex treeVertex3 = TreeGroupLeaf.CreateBillboardVertex(node, quaternion, normalBase, normalFix, tangentBase, new Vector2(0f, 0f));
                    TreeVertex treeVertex4 = TreeGroupLeaf.CreateBillboardVertex(node, quaternion, normalBase, normalFix, tangentBase, new Vector2(1f, 0f));
                    TreeVertex treeVertex5 = TreeGroupLeaf.CreateBillboardVertex(node, quaternion, normalBase, normalFix, tangentBase, new Vector2(1f, 1f));
                    treeVertex2.SetAnimationProperties(vector.x, vector.y, this.animationEdge, node.animSeed);
                    treeVertex3.SetAnimationProperties(vector.x, vector.y, this.animationEdge, node.animSeed);
                    treeVertex4.SetAnimationProperties(vector.x, vector.y, this.animationEdge, node.animSeed);
                    treeVertex5.SetAnimationProperties(vector.x, vector.y, this.animationEdge, node.animSeed);
                    if ((buildFlags & 1) != 0)
                    {
                        Vector3 b    = Vector3.right * node.scale;
                        Vector3 b2   = Vector3.forward * node.scale;
                        float   num2 = TreeGroup.ComputeAmbientOcclusion(treeVertex2.pos + b, Vector3.right, aoSpheres, aoDensity);
                        num2 += TreeGroup.ComputeAmbientOcclusion(treeVertex2.pos - b, -Vector3.right, aoSpheres, aoDensity);
                        num2 += TreeGroup.ComputeAmbientOcclusion(treeVertex2.pos + b2, Vector3.forward, aoSpheres, aoDensity);
                        num2 += TreeGroup.ComputeAmbientOcclusion(treeVertex2.pos - b2, -Vector3.forward, aoSpheres, aoDensity);
                        num2 /= 4f;
                        treeVertex2.SetAmbientOcclusion(num2);
                        treeVertex3.SetAmbientOcclusion(num2);
                        treeVertex4.SetAmbientOcclusion(num2);
                        treeVertex5.SetAmbientOcclusion(num2);
                    }
                    int count2 = verts.Count;
                    verts.Add(treeVertex2);
                    verts.Add(treeVertex3);
                    verts.Add(treeVertex4);
                    verts.Add(treeVertex5);
                    int materialIndex2 = TreeGroup.GetMaterialIndex(this.materialLeaf, materials, false);
                    tris.Add(new TreeTriangle(materialIndex2, count2, count2 + 2, count2 + 1, true));
                    tris.Add(new TreeTriangle(materialIndex2, count2, count2 + 3, count2 + 2, true));
                }
                else
                {
                    int num3 = 0;
                    switch (this.geometryMode)
                    {
                    case 0:
                        num3 = 1;
                        break;

                    case 1:
                        num3 = 2;
                        break;

                    case 2:
                        num3 = 3;
                        break;
                    }
                    int       materialIndex3 = TreeGroup.GetMaterialIndex(this.materialLeaf, materials, false);
                    Vector2[] array          = new Vector2[]
                    {
                        new Vector2(0f, 1f),
                        new Vector2(0f, 0f),
                        new Vector2(1f, 0f),
                        new Vector2(1f, 1f)
                    };
                    Vector2[] array2 = this.GetPlaneHullVertices(this.materialLeaf);
                    if (array2 == null)
                    {
                        array2 = array;
                    }
                    float     scale  = node.scale;
                    Vector3[] array3 = new Vector3[]
                    {
                        new Vector3(-scale, 0f, -scale),
                        new Vector3(-scale, 0f, scale),
                        new Vector3(scale, 0f, scale),
                        new Vector3(scale, 0f, -scale)
                    };
                    Vector3   vector2        = new Vector3(TreeGroup.GenerateBendNormalFactor, 1f - TreeGroup.GenerateBendNormalFactor, TreeGroup.GenerateBendNormalFactor);
                    Vector3[] expr_788       = new Vector3[4];
                    int       arg_7B4_0_cp_1 = 0;
                    Vector3   vector3        = new Vector3(-vector2.x, vector2.y, -vector2.z);
                    expr_788[arg_7B4_0_cp_1] = vector3.normalized;
                    int     arg_7E2_0_cp_1 = 1;
                    Vector3 vector4        = new Vector3(-vector2.x, vector2.y, 0f);
                    expr_788[arg_7E2_0_cp_1] = vector4.normalized;
                    int     arg_80F_0_cp_1 = 2;
                    Vector3 vector5        = new Vector3(vector2.x, vector2.y, 0f);
                    expr_788[arg_80F_0_cp_1] = vector5.normalized;
                    int     arg_83F_0_cp_1 = 3;
                    Vector3 vector6        = new Vector3(vector2.x, vector2.y, -vector2.z);
                    expr_788[arg_83F_0_cp_1] = vector6.normalized;
                    Vector3[] array4 = expr_788;
                    for (int l = 0; l < num3; l++)
                    {
                        Quaternion quaternion2 = Quaternion.Euler(new Vector3(90f, 0f, 0f));
                        int        num4        = l;
                        if (num4 != 1)
                        {
                            if (num4 == 2)
                            {
                                quaternion2 = Quaternion.Euler(new Vector3(0f, 90f, 0f));
                            }
                        }
                        else
                        {
                            quaternion2 = Quaternion.Euler(new Vector3(90f, 90f, 0f));
                        }
                        TreeVertex[] array5 = new TreeVertex[]
                        {
                            new TreeVertex(),
                            new TreeVertex(),
                            new TreeVertex(),
                            new TreeVertex(),
                            new TreeVertex(),
                            new TreeVertex(),
                            new TreeVertex(),
                            new TreeVertex()
                        };
                        for (int m = 0; m < 4; m++)
                        {
                            array5[m].pos     = node.matrix.MultiplyPoint(quaternion2 * array3[m]);
                            array5[m].nor     = node.matrix.MultiplyVector(quaternion2 * array4[m]);
                            array5[m].tangent = TreeGroup.CreateTangent(node, quaternion2, array5[m].nor);
                            array5[m].uv0     = array2[m];
                            array5[m].SetAnimationProperties(vector.x, vector.y, this.animationEdge, node.animSeed);
                            if ((buildFlags & 1) != 0)
                            {
                                array5[m].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(array5[m].pos, array5[m].nor, aoSpheres, aoDensity));
                            }
                        }
                        for (int n = 0; n < 4; n++)
                        {
                            array5[n + 4].Lerp4(array5, array2[n]);
                            array5[n + 4].uv0  = array5[n].uv0;
                            array5[n + 4].uv1  = array5[n].uv1;
                            array5[n + 4].flag = array5[n].flag;
                        }
                        int count3 = verts.Count;
                        for (int num5 = 0; num5 < 4; num5++)
                        {
                            verts.Add(array5[num5 + 4]);
                        }
                        tris.Add(new TreeTriangle(materialIndex3, count3, count3 + 1, count3 + 2));
                        tris.Add(new TreeTriangle(materialIndex3, count3, count3 + 2, count3 + 3));
                        Vector3 inNormal = node.matrix.MultiplyVector(quaternion2 * new Vector3(0f, 1f, 0f));
                        if (TreeGroup.GenerateDoubleSidedGeometry)
                        {
                            TreeVertex[] array6 = new TreeVertex[]
                            {
                                new TreeVertex(),
                                new TreeVertex(),
                                new TreeVertex(),
                                new TreeVertex(),
                                new TreeVertex(),
                                new TreeVertex(),
                                new TreeVertex(),
                                new TreeVertex()
                            };
                            for (int num6 = 0; num6 < 4; num6++)
                            {
                                array6[num6].pos       = array5[num6].pos;
                                array6[num6].nor       = Vector3.Reflect(array5[num6].nor, inNormal);
                                array6[num6].tangent   = Vector3.Reflect(array5[num6].tangent, inNormal);
                                array6[num6].tangent.w = -1f;
                                array6[num6].uv0       = array5[num6].uv0;
                                array6[num6].SetAnimationProperties(vector.x, vector.y, this.animationEdge, node.animSeed);
                                if ((buildFlags & 1) != 0)
                                {
                                    array6[num6].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(array6[num6].pos, array6[num6].nor, aoSpheres, aoDensity));
                                }
                            }
                            for (int num7 = 0; num7 < 4; num7++)
                            {
                                array6[num7 + 4].Lerp4(array6, array2[num7]);
                                array6[num7 + 4].uv0  = array6[num7].uv0;
                                array6[num7 + 4].uv1  = array6[num7].uv1;
                                array6[num7 + 4].flag = array6[num7].flag;
                            }
                            int count4 = verts.Count;
                            for (int num8 = 0; num8 < 4; num8++)
                            {
                                verts.Add(array6[num8 + 4]);
                            }
                            tris.Add(new TreeTriangle(materialIndex3, count4, count4 + 2, count4 + 1));
                            tris.Add(new TreeTriangle(materialIndex3, count4, count4 + 3, count4 + 2));
                        }
                    }
                }
            }
            node.triEnd  = tris.Count;
            node.vertEnd = verts.Count;
            Profiler.EndSample();
        }
Пример #8
0
 private void UpdateNodeMesh(TreeNode node, List <TreeMaterial> materials, List <TreeVertex> verts, List <TreeTriangle> tris, List <TreeAOSphere> aoSpheres, int buildFlags, float adaptiveQuality, float aoDensity)
 {
     node.triStart  = tris.Count;
     node.triEnd    = tris.Count;
     node.vertStart = verts.Count;
     node.vertEnd   = verts.Count;
     if (node.visible && base.visible)
     {
         int             count             = verts.Count;
         float           approximateLength = node.spline.GetApproximateLength();
         List <RingLoop> list  = new List <RingLoop>();
         float           num3  = Mathf.Clamp01(adaptiveQuality * this.lodQualityMultiplier);
         List <float>    list2 = TreeData.GetAdaptiveSamples(this, node, num3);
         int             adaptiveRadialSegments = TreeData.GetAdaptiveRadialSegments(this.radius, num3);
         TreeGroupBranch parentGroup            = null;
         if ((base.parentGroup != null) && (base.parentGroup.GetType() == typeof(TreeGroupBranch)))
         {
             parentGroup = (TreeGroupBranch)base.parentGroup;
         }
         if ((this.geometryMode == GeometryMode.BranchFrond) || (this.geometryMode == GeometryMode.Branch))
         {
             int   materialIndex = TreeGroup.GetMaterialIndex(this.materialBranch, materials, true);
             float bOffset       = 0f;
             float num7          = 0f;
             float num8          = approximateLength / ((this.GetRadiusAtTime(node, 0f, false) * 3.141593f) * 2f);
             bool  flag          = true;
             if ((node.parent != null) && (parentGroup != null))
             {
                 num7 = node.offset * node.parent.spline.GetApproximateLength();
             }
             float num9 = 1f - node.capRange;
             for (int i = 0; i < list2.Count; i++)
             {
                 float      timeParam      = list2[i];
                 Vector3    positionAtTime = node.spline.GetPositionAtTime(timeParam);
                 Quaternion rotationAtTime = node.spline.GetRotationAtTime(timeParam);
                 float      r = this.GetRadiusAtTime(node, timeParam, false);
                 Matrix4x4  m = node.matrix * Matrix4x4.TRS(positionAtTime, rotationAtTime, new Vector3(1f, 1f, 1f));
                 Vector3    flareWeldAtTime = this.GetFlareWeldAtTime(node, timeParam);
                 float      num13           = Mathf.Max(flareWeldAtTime.x, Mathf.Max(flareWeldAtTime.y, flareWeldAtTime.z) * 0.25f);
                 if (timeParam <= num9)
                 {
                     adaptiveRadialSegments = TreeData.GetAdaptiveRadialSegments(r + num13, num3);
                 }
                 if (flag)
                 {
                     if (i > 0)
                     {
                         float t     = list2[i - 1];
                         float num15 = timeParam - t;
                         float num16 = (r + this.GetRadiusAtTime(node, t, false)) * 0.5f;
                         bOffset += (num15 * approximateLength) / ((num16 * 3.141593f) * 2f);
                     }
                 }
                 else
                 {
                     bOffset = num7 + (timeParam * num8);
                 }
                 Vector2  vector3 = base.ComputeWindFactor(node, timeParam);
                 RingLoop item    = new RingLoop();
                 item.Reset(r, m, bOffset, adaptiveRadialSegments);
                 item.SetSurfaceAngle(node.GetSurfaceAngleAtTime(timeParam));
                 item.SetAnimationProperties(vector3.x, vector3.y, 0f, node.animSeed);
                 item.SetSpread(flareWeldAtTime.y, flareWeldAtTime.z);
                 item.SetNoise(this.noise * Mathf.Clamp01(this.noiseCurve.Evaluate(timeParam)), this.noiseScaleU * 10f, this.noiseScaleV * 10f);
                 item.SetFlares(flareWeldAtTime.x, this.flareNoise * 10f);
                 int num17 = verts.Count;
                 item.BuildVertices(verts);
                 int num18 = verts.Count;
                 if ((buildFlags & 2) != 0)
                 {
                     float weldHeight = this.weldHeight;
                     float num20      = Mathf.Pow(Mathf.Clamp01(((1f - timeParam) - (1f - this.weldHeight)) / this.weldHeight), 1.5f);
                     float num21      = 1f - num20;
                     if ((timeParam < weldHeight) && ((node.parent != null) && (node.parent.spline != null)))
                     {
                         Ray ray = new Ray();
                         for (int k = num17; k < num18; k++)
                         {
                             ray.origin    = verts[k].pos;
                             ray.direction = m.MultiplyVector(-Vector3.up);
                             Vector3 pos   = verts[k].pos;
                             Vector3 nor   = verts[k].nor;
                             float   num23 = -10000f;
                             float   num24 = 100000f;
                             for (int n = node.parent.triStart; n < node.parent.triEnd; n++)
                             {
                                 object obj2 = MathUtils.IntersectRayTriangle(ray, verts[tris[n].v[0]].pos, verts[tris[n].v[1]].pos, verts[tris[n].v[2]].pos, true);
                                 if (obj2 != null)
                                 {
                                     RaycastHit hit = (RaycastHit)obj2;
                                     if ((Mathf.Abs(hit.distance) < num24) && (hit.distance > num23))
                                     {
                                         num24        = Mathf.Abs(hit.distance);
                                         verts[k].nor = (Vector3)(((verts[tris[n].v[0]].nor * hit.barycentricCoordinate.x) + (verts[tris[n].v[1]].nor * hit.barycentricCoordinate.y)) + (verts[tris[n].v[2]].nor * hit.barycentricCoordinate.z));
                                         verts[k].nor = (Vector3)((verts[k].nor * num20) + (nor * num21));
                                         verts[k].pos = (Vector3)((hit.point * num20) + (pos * num21));
                                     }
                                 }
                             }
                         }
                     }
                 }
                 list.Add(item);
                 if ((timeParam == 1f) && (item.radius > 0.005f))
                 {
                     RingLoop loop2 = item.Clone();
                     loop2.radius      = 0f;
                     loop2.baseOffset += r / 6.283185f;
                     loop2.BuildVertices(verts);
                     list.Add(loop2);
                 }
             }
             if (((list.Count > 0) && (list[list.Count - 1].radius > 0.025f)) && (node.breakOffset < 1f))
             {
                 float    mappingScale   = 1f / ((this.radius * 3.141593f) * 2f);
                 float    sphereFactor   = 0f;
                 float    noise          = 1f;
                 int      mappingMode    = 0;
                 Material materialBranch = this.materialBranch;
                 if (this.materialBreak != null)
                 {
                     materialBranch = this.materialBreak;
                 }
                 int num30 = TreeGroup.GetMaterialIndex(materialBranch, materials, false);
                 list[list.Count - 1].Cap(sphereFactor, noise, mappingMode, mappingScale, verts, tris, num30);
             }
             node.triStart = tris.Count;
             for (int j = 0; j < (list.Count - 1); j++)
             {
                 list[j].Connect(list[j + 1], tris, materialIndex, false, false);
             }
             node.triEnd = tris.Count;
             list.Clear();
         }
         float num32 = Mathf.Min(this.frondRange.x, this.frondRange.y);
         float num33 = Mathf.Max(this.frondRange.x, this.frondRange.y);
         float num34 = num32;
         float num35 = num33;
         num32 = Mathf.Clamp(num32, 0f, node.breakOffset);
         num33 = Mathf.Clamp(num33, 0f, node.breakOffset);
         if (((this.geometryMode == GeometryMode.BranchFrond) || (this.geometryMode == GeometryMode.Frond)) && ((this.frondCount > 0) && (num32 != num33)))
         {
             bool flag2 = true;
             bool flag3 = true;
             for (int num36 = 0; num36 < list2.Count; num36++)
             {
                 float num37 = list2[num36];
                 if (num37 < num32)
                 {
                     list2.RemoveAt(num36);
                     num36--;
                 }
                 else if (num37 == num32)
                 {
                     flag2 = false;
                 }
                 else if (num37 == num33)
                 {
                     flag3 = false;
                 }
                 else if (num37 > num33)
                 {
                     list2.RemoveAt(num36);
                     num36--;
                 }
             }
             if (flag2)
             {
                 list2.Insert(0, num32);
             }
             if (flag3)
             {
                 list2.Add(num33);
             }
             int   material = TreeGroup.GetMaterialIndex(this.materialFrond, materials, false);
             float num39    = 1f - node.capRange;
             for (int num40 = 0; num40 < this.frondCount; num40++)
             {
                 float   num41    = (this.frondCrease * 90f) * 0.01745329f;
                 float   num42    = (((this.frondRotation * 360f) + ((num40 * 180f) / ((float)this.frondCount))) - 90f) * 0.01745329f;
                 float   f        = -num42 - num41;
                 float   num44    = num42 - num41;
                 Vector3 vector9  = new Vector3(Mathf.Sin(f), 0f, Mathf.Cos(f));
                 Vector3 v        = new Vector3(vector9.z, 0f, -vector9.x);
                 Vector3 vector11 = new Vector3(Mathf.Sin(num44), 0f, -Mathf.Cos(num44));
                 Vector3 vector12 = new Vector3(-vector11.z, 0f, vector11.x);
                 for (int num45 = 0; num45 < list2.Count; num45++)
                 {
                     float num46 = list2[num45];
                     float y     = (num46 - num34) / (num35 - num34);
                     float num48 = num46;
                     if (num46 > num39)
                     {
                         num48 = num39;
                         float num49 = Mathf.Acos(Mathf.Clamp01((num46 - num39) / node.capRange));
                         float num50 = Mathf.Sin(num49);
                         float num51 = Mathf.Cos(num49) * this.capSmoothing;
                         vector9  = new Vector3(Mathf.Sin(f) * num50, num51, Mathf.Cos(f) * num50);
                         v        = new Vector3(vector9.z, vector9.y, -vector9.x);
                         vector11 = new Vector3(Mathf.Sin(num44) * num50, num51, -Mathf.Cos(num44) * num50);
                         vector12 = new Vector3(-vector11.z, vector11.y, vector11.x);
                     }
                     Vector3    vector13 = new Vector3(0f, 0f, -1f);
                     Vector3    vector14 = node.spline.GetPositionAtTime(num48);
                     Quaternion q        = node.spline.GetRotationAtTime(num46);
                     float      num52    = (Mathf.Clamp01(this.frondCurve.Evaluate(num46)) * this.frondWidth) * node.GetScale();
                     Matrix4x4  matrixx2 = node.matrix * Matrix4x4.TRS(vector14, q, new Vector3(1f, 1f, 1f));
                     if (TreeGroup.GenerateDoubleSidedGeometry)
                     {
                         for (float num53 = -1f; num53 < 2f; num53 += 2f)
                         {
                             TreeVertex vertex = new TreeVertex {
                                 pos = matrixx2.MultiplyPoint((Vector3)(vector9 * num52)),
                                 nor = matrixx2.MultiplyVector((Vector3)(v * num53)).normalized
                             };
                             vertex.tangent   = TreeGroup.CreateTangent(node, q, vertex.nor);
                             vertex.tangent.w = -num53;
                             vertex.uv0       = new Vector2(1f, y);
                             TreeVertex vertex2 = new TreeVertex {
                                 pos = matrixx2.MultiplyPoint(Vector3.zero),
                                 nor = matrixx2.MultiplyVector((Vector3)(vector13 * num53)).normalized
                             };
                             vertex2.tangent   = TreeGroup.CreateTangent(node, q, vertex2.nor);
                             vertex2.tangent.w = -num53;
                             vertex2.uv0       = new Vector2(0.5f, y);
                             TreeVertex vertex3 = new TreeVertex {
                                 pos = matrixx2.MultiplyPoint(Vector3.zero),
                                 nor = matrixx2.MultiplyVector((Vector3)(vector13 * num53)).normalized
                             };
                             vertex3.tangent   = TreeGroup.CreateTangent(node, q, vertex3.nor);
                             vertex3.tangent.w = -num53;
                             vertex3.uv0       = new Vector2(0.5f, y);
                             TreeVertex vertex4 = new TreeVertex {
                                 pos = matrixx2.MultiplyPoint((Vector3)(vector11 * num52)),
                                 nor = matrixx2.MultiplyVector((Vector3)(vector12 * num53)).normalized
                             };
                             vertex4.tangent   = TreeGroup.CreateTangent(node, q, vertex4.nor);
                             vertex4.tangent.w = -num53;
                             vertex4.uv0       = new Vector2(0f, y);
                             Vector2 vector19 = base.ComputeWindFactor(node, num46);
                             vertex.SetAnimationProperties(vector19.x, vector19.y, base.animationEdge, node.animSeed);
                             vertex2.SetAnimationProperties(vector19.x, vector19.y, 0f, node.animSeed);
                             vertex3.SetAnimationProperties(vector19.x, vector19.y, 0f, node.animSeed);
                             vertex4.SetAnimationProperties(vector19.x, vector19.y, base.animationEdge, node.animSeed);
                             verts.Add(vertex);
                             verts.Add(vertex2);
                             verts.Add(vertex3);
                             verts.Add(vertex4);
                         }
                         if (num45 > 0)
                         {
                             int          num54     = verts.Count;
                             TreeTriangle triangle  = new TreeTriangle(material, num54 - 4, num54 - 3, num54 - 11);
                             TreeTriangle triangle2 = new TreeTriangle(material, num54 - 4, num54 - 11, num54 - 12);
                             triangle.flip();
                             triangle2.flip();
                             TreeTriangle triangle3 = new TreeTriangle(material, num54 - 8, num54 - 7, num54 - 15);
                             TreeTriangle triangle4 = new TreeTriangle(material, num54 - 8, num54 - 15, num54 - 0x10);
                             tris.Add(triangle);
                             tris.Add(triangle2);
                             tris.Add(triangle3);
                             tris.Add(triangle4);
                             TreeTriangle triangle5 = new TreeTriangle(material, num54 - 2, num54 - 9, num54 - 1);
                             TreeTriangle triangle6 = new TreeTriangle(material, num54 - 2, num54 - 10, num54 - 9);
                             TreeTriangle triangle7 = new TreeTriangle(material, num54 - 6, num54 - 13, num54 - 5);
                             TreeTriangle triangle8 = new TreeTriangle(material, num54 - 6, num54 - 14, num54 - 13);
                             triangle7.flip();
                             triangle8.flip();
                             tris.Add(triangle5);
                             tris.Add(triangle6);
                             tris.Add(triangle7);
                             tris.Add(triangle8);
                         }
                     }
                     else
                     {
                         TreeVertex vertex5 = new TreeVertex {
                             pos = matrixx2.MultiplyPoint((Vector3)(vector9 * num52)),
                             nor = matrixx2.MultiplyVector(v).normalized,
                             uv0 = new Vector2(0f, y)
                         };
                         TreeVertex vertex6 = new TreeVertex {
                             pos = matrixx2.MultiplyPoint(Vector3.zero),
                             nor = matrixx2.MultiplyVector(Vector3.back).normalized,
                             uv0 = new Vector2(0.5f, y)
                         };
                         TreeVertex vertex7 = new TreeVertex {
                             pos = matrixx2.MultiplyPoint((Vector3)(vector11 * num52)),
                             nor = matrixx2.MultiplyVector(vector12).normalized,
                             uv0 = new Vector2(1f, y)
                         };
                         Vector2 vector23 = base.ComputeWindFactor(node, num46);
                         vertex5.SetAnimationProperties(vector23.x, vector23.y, base.animationEdge, node.animSeed);
                         vertex6.SetAnimationProperties(vector23.x, vector23.y, 0f, node.animSeed);
                         vertex7.SetAnimationProperties(vector23.x, vector23.y, base.animationEdge, node.animSeed);
                         verts.Add(vertex5);
                         verts.Add(vertex6);
                         verts.Add(vertex7);
                         if (num45 > 0)
                         {
                             int          num55      = verts.Count;
                             TreeTriangle triangle9  = new TreeTriangle(material, num55 - 2, num55 - 3, num55 - 6);
                             TreeTriangle triangle10 = new TreeTriangle(material, num55 - 2, num55 - 6, num55 - 5);
                             tris.Add(triangle9);
                             tris.Add(triangle10);
                             TreeTriangle triangle11 = new TreeTriangle(material, num55 - 2, num55 - 4, num55 - 1);
                             TreeTriangle triangle12 = new TreeTriangle(material, num55 - 2, num55 - 5, num55 - 4);
                             tris.Add(triangle11);
                             tris.Add(triangle12);
                         }
                     }
                 }
             }
         }
         if ((buildFlags & 1) != 0)
         {
             for (int num56 = count; num56 < verts.Count; num56++)
             {
                 verts[num56].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(verts[num56].pos, verts[num56].nor, aoSpheres, aoDensity));
             }
         }
         node.vertEnd = verts.Count;
     }
 }
Пример #9
0
        private void UpdateNodeMesh(TreeNode node, List <TreeMaterial> materials, List <TreeVertex> verts, List <TreeTriangle> tris, List <TreeAOSphere> aoSpheres, int buildFlags, float adaptiveQuality, float aoDensity)
        {
            node.triStart  = tris.Count;
            node.triEnd    = tris.Count;
            node.vertStart = verts.Count;
            node.vertEnd   = verts.Count;
            if (!node.visible || !this.visible)
            {
                return;
            }
            Profiler.BeginSample("TreeGroupBranch.UpdateNodeMesh");
            int             count             = verts.Count;
            float           approximateLength = node.spline.GetApproximateLength();
            List <RingLoop> list                   = new List <RingLoop>();
            float           adaptiveQuality2       = Mathf.Clamp01(adaptiveQuality * this.lodQualityMultiplier);
            List <float>    adaptiveSamples        = TreeData.GetAdaptiveSamples(this, node, adaptiveQuality2);
            int             adaptiveRadialSegments = TreeData.GetAdaptiveRadialSegments(this.radius, adaptiveQuality2);
            TreeGroupBranch treeGroupBranch        = null;

            if (this.parentGroup != null && this.parentGroup.GetType() == typeof(TreeGroupBranch))
            {
                treeGroupBranch = (TreeGroupBranch)this.parentGroup;
            }
            if (this.geometryMode == TreeGroupBranch.GeometryMode.BranchFrond || this.geometryMode == TreeGroupBranch.GeometryMode.Branch)
            {
                int   materialIndex = TreeGroup.GetMaterialIndex(this.materialBranch, materials, true);
                float num           = 0f;
                float num2          = 0f;
                float num3          = approximateLength / (this.GetRadiusAtTime(node, 0f, false) * 3.14159274f * 2f);
                bool  flag          = true;
                if (node.parent != null && treeGroupBranch != null)
                {
                    num2 = node.offset * node.parent.spline.GetApproximateLength();
                }
                float num4 = 1f - node.capRange;
                for (int i = 0; i < adaptiveSamples.Count; i++)
                {
                    float      num5           = adaptiveSamples[i];
                    Vector3    positionAtTime = node.spline.GetPositionAtTime(num5);
                    Quaternion rotationAtTime = node.spline.GetRotationAtTime(num5);
                    float      radiusAtTime   = this.GetRadiusAtTime(node, num5, false);
                    Matrix4x4  m = node.matrix * Matrix4x4.TRS(positionAtTime, rotationAtTime, new Vector3(1f, 1f, 1f));
                    Vector3    flareWeldAtTime = this.GetFlareWeldAtTime(node, num5);
                    float      num6            = Mathf.Max(flareWeldAtTime.x, Mathf.Max(flareWeldAtTime.y, flareWeldAtTime.z) * 0.25f);
                    if (num5 <= num4)
                    {
                        adaptiveRadialSegments = TreeData.GetAdaptiveRadialSegments(radiusAtTime + num6, adaptiveQuality2);
                    }
                    if (flag)
                    {
                        if (i > 0)
                        {
                            float num7 = adaptiveSamples[i - 1];
                            float num8 = num5 - num7;
                            float num9 = (radiusAtTime + this.GetRadiusAtTime(node, num7, false)) * 0.5f;
                            num += num8 * approximateLength / (num9 * 3.14159274f * 2f);
                        }
                    }
                    else
                    {
                        num = num2 + num5 * num3;
                    }
                    Vector2  vector   = base.ComputeWindFactor(node, num5);
                    RingLoop ringLoop = new RingLoop();
                    ringLoop.Reset(radiusAtTime, m, num, adaptiveRadialSegments);
                    ringLoop.SetSurfaceAngle(node.GetSurfaceAngleAtTime(num5));
                    ringLoop.SetAnimationProperties(vector.x, vector.y, 0f, node.animSeed);
                    ringLoop.SetSpread(flareWeldAtTime.y, flareWeldAtTime.z);
                    ringLoop.SetNoise(this.noise * Mathf.Clamp01(this.noiseCurve.Evaluate(num5)), this.noiseScaleU * 10f, this.noiseScaleV * 10f);
                    ringLoop.SetFlares(flareWeldAtTime.x, this.flareNoise * 10f);
                    int count2 = verts.Count;
                    ringLoop.BuildVertices(verts);
                    int count3 = verts.Count;
                    if ((buildFlags & 2) != 0)
                    {
                        float num10 = this.weldHeight;
                        float num11 = Mathf.Pow(Mathf.Clamp01((1f - num5 - (1f - this.weldHeight)) / this.weldHeight), 1.5f);
                        float d     = 1f - num11;
                        if (num5 < num10 && node.parent != null && node.parent.spline != null)
                        {
                            Ray ray = default(Ray);
                            for (int j = count2; j < count3; j++)
                            {
                                ray.origin    = verts[j].pos;
                                ray.direction = m.MultiplyVector(-Vector3.up);
                                Vector3 pos   = verts[j].pos;
                                Vector3 nor   = verts[j].nor;
                                float   num12 = -10000f;
                                float   num13 = 100000f;
                                for (int k = node.parent.triStart; k < node.parent.triEnd; k++)
                                {
                                    object obj = MathUtils.IntersectRayTriangle(ray, verts[tris[k].v[0]].pos, verts[tris[k].v[1]].pos, verts[tris[k].v[2]].pos, true);
                                    if (obj != null)
                                    {
                                        RaycastHit raycastHit = (RaycastHit)obj;
                                        if (Mathf.Abs(raycastHit.distance) < num13 && raycastHit.distance > num12)
                                        {
                                            num13        = Mathf.Abs(raycastHit.distance);
                                            verts[j].nor = verts[tris[k].v[0]].nor * raycastHit.barycentricCoordinate.x + verts[tris[k].v[1]].nor * raycastHit.barycentricCoordinate.y + verts[tris[k].v[2]].nor * raycastHit.barycentricCoordinate.z;
                                            verts[j].nor = verts[j].nor * num11 + nor * d;
                                            verts[j].pos = raycastHit.point * num11 + pos * d;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    list.Add(ringLoop);
                    if (num5 == 1f && ringLoop.radius > 0.005f)
                    {
                        RingLoop ringLoop2 = ringLoop.Clone();
                        ringLoop2.radius      = 0f;
                        ringLoop2.baseOffset += radiusAtTime / 6.28318548f;
                        ringLoop2.BuildVertices(verts);
                        list.Add(ringLoop2);
                    }
                }
                if (list.Count > 0 && list[list.Count - 1].radius > 0.025f && node.breakOffset < 1f)
                {
                    float    mappingScale = 1f / (this.radius * 3.14159274f * 2f);
                    float    sphereFactor = 0f;
                    float    num14        = 1f;
                    int      mappingMode  = 0;
                    Material m2           = this.materialBranch;
                    if (this.materialBreak != null)
                    {
                        m2 = this.materialBreak;
                    }
                    int materialIndex2 = TreeGroup.GetMaterialIndex(m2, materials, false);
                    list[list.Count - 1].Cap(sphereFactor, num14, mappingMode, mappingScale, verts, tris, materialIndex2);
                }
                node.triStart = tris.Count;
                for (int l = 0; l < list.Count - 1; l++)
                {
                    list[l].Connect(list[l + 1], tris, materialIndex, false, false);
                }
                node.triEnd = tris.Count;
                list.Clear();
            }
            float num15 = Mathf.Min(this.frondRange.x, this.frondRange.y);
            float num16 = Mathf.Max(this.frondRange.x, this.frondRange.y);
            float num17 = num15;
            float num18 = num16;

            num15 = Mathf.Clamp(num15, 0f, node.breakOffset);
            num16 = Mathf.Clamp(num16, 0f, node.breakOffset);
            if ((this.geometryMode == TreeGroupBranch.GeometryMode.BranchFrond || this.geometryMode == TreeGroupBranch.GeometryMode.Frond) && this.frondCount > 0 && num15 != num16)
            {
                bool flag2 = true;
                bool flag3 = true;
                for (int n = 0; n < adaptiveSamples.Count; n++)
                {
                    float num19 = adaptiveSamples[n];
                    if (num19 < num15)
                    {
                        adaptiveSamples.RemoveAt(n);
                        n--;
                    }
                    else
                    {
                        if (num19 == num15)
                        {
                            flag2 = false;
                        }
                        else
                        {
                            if (num19 == num16)
                            {
                                flag3 = false;
                            }
                            else
                            {
                                if (num19 > num16)
                                {
                                    adaptiveSamples.RemoveAt(n);
                                    n--;
                                }
                            }
                        }
                    }
                }
                if (flag2)
                {
                    adaptiveSamples.Insert(0, num15);
                }
                if (flag3)
                {
                    adaptiveSamples.Add(num16);
                }
                int   materialIndex3 = TreeGroup.GetMaterialIndex(this.materialFrond, materials, false);
                float num20          = 1f - node.capRange;
                for (int num21 = 0; num21 < this.frondCount; num21++)
                {
                    float   num22   = this.frondCrease * 90f * 0.0174532924f;
                    float   num23   = (this.frondRotation * 360f + (float)num21 * 180f / (float)this.frondCount - 90f) * 0.0174532924f;
                    float   f       = -num23 - num22;
                    float   f2      = num23 - num22;
                    Vector3 a       = new Vector3(Mathf.Sin(f), 0f, Mathf.Cos(f));
                    Vector3 vector2 = new Vector3(a.z, 0f, -a.x);
                    Vector3 a2      = new Vector3(Mathf.Sin(f2), 0f, -Mathf.Cos(f2));
                    Vector3 vector3 = new Vector3(-a2.z, 0f, a2.x);
                    for (int num24 = 0; num24 < adaptiveSamples.Count; num24++)
                    {
                        float num25     = adaptiveSamples[num24];
                        float y         = (num25 - num17) / (num18 - num17);
                        float timeParam = num25;
                        if (num25 > num20)
                        {
                            timeParam = num20;
                            float f3    = Mathf.Acos(Mathf.Clamp01((num25 - num20) / node.capRange));
                            float num26 = Mathf.Sin(f3);
                            float y2    = Mathf.Cos(f3) * this.capSmoothing;
                            a       = new Vector3(Mathf.Sin(f) * num26, y2, Mathf.Cos(f) * num26);
                            vector2 = new Vector3(a.z, a.y, -a.x);
                            a2      = new Vector3(Mathf.Sin(f2) * num26, y2, -Mathf.Cos(f2) * num26);
                            vector3 = new Vector3(-a2.z, a2.y, a2.x);
                        }
                        Vector3    a3 = new Vector3(0f, 0f, -1f);
                        Vector3    positionAtTime2 = node.spline.GetPositionAtTime(timeParam);
                        Quaternion rotationAtTime2 = node.spline.GetRotationAtTime(num25);
                        float      d2       = Mathf.Clamp01(this.frondCurve.Evaluate(num25)) * this.frondWidth * node.GetScale();
                        Matrix4x4  matrix4x = node.matrix * Matrix4x4.TRS(positionAtTime2, rotationAtTime2, new Vector3(1f, 1f, 1f));
                        if (TreeGroup.GenerateDoubleSidedGeometry)
                        {
                            for (float num27 = -1f; num27 < 2f; num27 += 2f)
                            {
                                TreeVertex treeVertex = new TreeVertex();
                                treeVertex.pos       = matrix4x.MultiplyPoint(a * d2);
                                treeVertex.nor       = matrix4x.MultiplyVector(vector2 * num27).normalized;
                                treeVertex.tangent   = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex.nor);
                                treeVertex.tangent.w = -num27;
                                treeVertex.uv0       = new Vector2(1f, y);
                                TreeVertex treeVertex2 = new TreeVertex();
                                treeVertex2.pos       = matrix4x.MultiplyPoint(Vector3.zero);
                                treeVertex2.nor       = matrix4x.MultiplyVector(a3 * num27).normalized;
                                treeVertex2.tangent   = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex2.nor);
                                treeVertex2.tangent.w = -num27;
                                treeVertex2.uv0       = new Vector2(0.5f, y);
                                TreeVertex treeVertex3 = new TreeVertex();
                                treeVertex3.pos       = matrix4x.MultiplyPoint(Vector3.zero);
                                treeVertex3.nor       = matrix4x.MultiplyVector(a3 * num27).normalized;
                                treeVertex3.tangent   = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex3.nor);
                                treeVertex3.tangent.w = -num27;
                                treeVertex3.uv0       = new Vector2(0.5f, y);
                                TreeVertex treeVertex4 = new TreeVertex();
                                treeVertex4.pos       = matrix4x.MultiplyPoint(a2 * d2);
                                treeVertex4.nor       = matrix4x.MultiplyVector(vector3 * num27).normalized;
                                treeVertex4.tangent   = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex4.nor);
                                treeVertex4.tangent.w = -num27;
                                treeVertex4.uv0       = new Vector2(0f, y);
                                Vector2 vector4 = base.ComputeWindFactor(node, num25);
                                treeVertex.SetAnimationProperties(vector4.x, vector4.y, this.animationEdge, node.animSeed);
                                treeVertex2.SetAnimationProperties(vector4.x, vector4.y, 0f, node.animSeed);
                                treeVertex3.SetAnimationProperties(vector4.x, vector4.y, 0f, node.animSeed);
                                treeVertex4.SetAnimationProperties(vector4.x, vector4.y, this.animationEdge, node.animSeed);
                                verts.Add(treeVertex);
                                verts.Add(treeVertex2);
                                verts.Add(treeVertex3);
                                verts.Add(treeVertex4);
                            }
                            if (num24 > 0)
                            {
                                int          count4        = verts.Count;
                                TreeTriangle treeTriangle  = new TreeTriangle(materialIndex3, count4 - 4, count4 - 3, count4 - 11);
                                TreeTriangle treeTriangle2 = new TreeTriangle(materialIndex3, count4 - 4, count4 - 11, count4 - 12);
                                treeTriangle.flip();
                                treeTriangle2.flip();
                                TreeTriangle item  = new TreeTriangle(materialIndex3, count4 - 8, count4 - 7, count4 - 15);
                                TreeTriangle item2 = new TreeTriangle(materialIndex3, count4 - 8, count4 - 15, count4 - 16);
                                tris.Add(treeTriangle);
                                tris.Add(treeTriangle2);
                                tris.Add(item);
                                tris.Add(item2);
                                TreeTriangle item3         = new TreeTriangle(materialIndex3, count4 - 2, count4 - 9, count4 - 1);
                                TreeTriangle item4         = new TreeTriangle(materialIndex3, count4 - 2, count4 - 10, count4 - 9);
                                TreeTriangle treeTriangle3 = new TreeTriangle(materialIndex3, count4 - 6, count4 - 13, count4 - 5);
                                TreeTriangle treeTriangle4 = new TreeTriangle(materialIndex3, count4 - 6, count4 - 14, count4 - 13);
                                treeTriangle3.flip();
                                treeTriangle4.flip();
                                tris.Add(item3);
                                tris.Add(item4);
                                tris.Add(treeTriangle3);
                                tris.Add(treeTriangle4);
                            }
                        }
                        else
                        {
                            TreeVertex treeVertex5 = new TreeVertex();
                            treeVertex5.pos = matrix4x.MultiplyPoint(a * d2);
                            treeVertex5.nor = matrix4x.MultiplyVector(vector2).normalized;
                            treeVertex5.uv0 = new Vector2(0f, y);
                            TreeVertex treeVertex6 = new TreeVertex();
                            treeVertex6.pos = matrix4x.MultiplyPoint(Vector3.zero);
                            treeVertex6.nor = matrix4x.MultiplyVector(Vector3.back).normalized;
                            treeVertex6.uv0 = new Vector2(0.5f, y);
                            TreeVertex treeVertex7 = new TreeVertex();
                            treeVertex7.pos = matrix4x.MultiplyPoint(a2 * d2);
                            treeVertex7.nor = matrix4x.MultiplyVector(vector3).normalized;
                            treeVertex7.uv0 = new Vector2(1f, y);
                            Vector2 vector5 = base.ComputeWindFactor(node, num25);
                            treeVertex5.SetAnimationProperties(vector5.x, vector5.y, this.animationEdge, node.animSeed);
                            treeVertex6.SetAnimationProperties(vector5.x, vector5.y, 0f, node.animSeed);
                            treeVertex7.SetAnimationProperties(vector5.x, vector5.y, this.animationEdge, node.animSeed);
                            verts.Add(treeVertex5);
                            verts.Add(treeVertex6);
                            verts.Add(treeVertex7);
                            if (num24 > 0)
                            {
                                int          count5 = verts.Count;
                                TreeTriangle item5  = new TreeTriangle(materialIndex3, count5 - 2, count5 - 3, count5 - 6);
                                TreeTriangle item6  = new TreeTriangle(materialIndex3, count5 - 2, count5 - 6, count5 - 5);
                                tris.Add(item5);
                                tris.Add(item6);
                                TreeTriangle item7 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 4, count5 - 1);
                                TreeTriangle item8 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 5, count5 - 4);
                                tris.Add(item7);
                                tris.Add(item8);
                            }
                        }
                    }
                }
            }
            if ((buildFlags & 1) != 0)
            {
                for (int num28 = count; num28 < verts.Count; num28++)
                {
                    verts[num28].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(verts[num28].pos, verts[num28].nor, aoSpheres, aoDensity));
                }
            }
            node.vertEnd = verts.Count;
            Profiler.EndSample();
        }
        private void UpdateNodeMesh(TreeNode node, List <TreeMaterial> materials, List <TreeVertex> verts, List <TreeTriangle> tris, List <TreeAOSphere> aoSpheres, int buildFlags, float adaptiveQuality, float aoDensity)
        {
            // Clear tri range
            node.triStart  = tris.Count;
            node.triEnd    = tris.Count;
            node.vertStart = verts.Count;
            node.vertEnd   = verts.Count;

            // Check for visibility
            if (!node.visible || !visible)
            {
                return;
            }

            Profiler.BeginSample("TreeGroupBranch.UpdateNodeMesh");

            int vertOffset = verts.Count;

            float totalHeight = node.spline.GetApproximateLength();// *node.GetScale(); //height * node.GetScale();

            // list to hold the ring loops
            List <RingLoop> ringloops = new List <RingLoop>();

            // Modify LOD to fit local settings
            float lodQuality = Mathf.Clamp01(adaptiveQuality * lodQualityMultiplier);

            // LOD settings
            List <float> heightSamples = TreeData.GetAdaptiveSamples(this, node, lodQuality);
            int          radialSamples = TreeData.GetAdaptiveRadialSegments(radius, lodQuality);

            //
            // Parent branch group if any..
            TreeGroupBranch parentBranchGroup = null;

            if ((parentGroup != null) && (parentGroup.GetType() == typeof(TreeGroupBranch)))
            {
                parentBranchGroup = (TreeGroupBranch)parentGroup;
            }

            if ((geometryMode == GeometryMode.BranchFrond) || (geometryMode == GeometryMode.Branch))
            {
                int materialIndex = GetMaterialIndex(materialBranch, materials, true);

                float uvOffset     = 0.0f;
                float uvBaseOffset = 0.0f;
                float uvStep       = totalHeight / (GetRadiusAtTime(node, 0.0f, false) * Mathf.PI * 2.0f);
                bool  uvAdapt      = true;

                if (node.parent != null && parentBranchGroup != null)
                {
                    uvBaseOffset = node.offset * node.parent.spline.GetApproximateLength();
                }

                float capStart = 1.0f - node.capRange;
                for (int i = 0; i < heightSamples.Count; i++)
                {
                    float t = heightSamples[i];

                    Vector3    pos = node.spline.GetPositionAtTime(t);
                    Quaternion rot = node.spline.GetRotationAtTime(t);
                    float      rad = GetRadiusAtTime(node, t, false);

                    Matrix4x4 m = node.matrix * Matrix4x4.TRS(pos, rot, new Vector3(1, 1, 1));

                    // total offset for wind animation
                    //float totalOffset = (totalOffsetBase + t);

                    // flare / weld spreading
                    Vector3 flareWeldSpread = GetFlareWeldAtTime(node, t);

                    // Do adaptive LOD for ringloops
                    float radModify = Mathf.Max(flareWeldSpread.x, Mathf.Max(flareWeldSpread.y, flareWeldSpread.z) * 0.25f);

                    // keep the same number of vertices per ring for the cap.. to give a nicer result
                    if (t <= capStart)
                    {
                        radialSamples = TreeData.GetAdaptiveRadialSegments(rad + radModify, lodQuality);
                    }

                    // uv offset..
                    if (uvAdapt)
                    {
                        if (i > 0)
                        {
                            float preT    = heightSamples[i - 1];
                            float uvDelta = t - preT;
                            float uvRad   = (rad + GetRadiusAtTime(node, preT, false)) * 0.5f;
                            uvOffset += (uvDelta * totalHeight) / (uvRad * Mathf.PI * 2.0f);
                        }
                    }
                    else
                    {
                        uvOffset = uvBaseOffset + (t * uvStep);
                    }

                    // wind
                    Vector2 windFactors = ComputeWindFactor(node, t);

                    RingLoop r = new RingLoop();
                    r.Reset(rad, m, uvOffset, radialSamples);
                    r.SetSurfaceAngle(node.GetSurfaceAngleAtTime(t));
                    r.SetAnimationProperties(windFactors.x, windFactors.y, 0.0f, node.animSeed);
                    r.SetSpread(flareWeldSpread.y, flareWeldSpread.z);
                    r.SetNoise(noise * Mathf.Clamp01(noiseCurve.Evaluate(t)), noiseScaleU * 10.0f, noiseScaleV * 10.0f);
                    r.SetFlares(flareWeldSpread.x, flareNoise * 10.0f);

                    int vertStart = verts.Count;
                    r.BuildVertices(verts);
                    int vertEnd = verts.Count;


                    if ((buildFlags & (int)BuildFlag.BuildWeldParts) != 0)
                    {
                        float projectionRange    = weldHeight;
                        float projectionBlend    = Mathf.Pow(Mathf.Clamp01(((1.0f - t) - (1.0f - weldHeight)) / weldHeight), 1.5f);
                        float invProjectionBlend = 1.0f - projectionBlend;

                        if (t < projectionRange)
                        {
                            if ((node.parent != null) && (node.parent.spline != null))
                            {
                                Ray ray = new Ray();
                                for (int v = vertStart; v < vertEnd; v++)
                                {
                                    ray.origin    = verts[v].pos;
                                    ray.direction = m.MultiplyVector(-Vector3.up);

                                    Vector3 origPos = verts[v].pos;
                                    Vector3 origNor = verts[v].nor;

                                    float minDist = -10000.0f;
                                    float maxDist = 100000.0f;
                                    // project vertices onto parent
                                    for (int tri = node.parent.triStart; tri < node.parent.triEnd; tri++)
                                    {
                                        object hit = MathUtils.IntersectRayTriangle(ray, verts[tris[tri].v[0]].pos,
                                                                                    verts[tris[tri].v[1]].pos,
                                                                                    verts[tris[tri].v[2]].pos, true);
                                        if (hit != null)
                                        {
                                            RaycastHit rayHit = ((RaycastHit)hit);
                                            if ((Mathf.Abs(rayHit.distance) < maxDist) && (rayHit.distance > minDist))
                                            {
                                                maxDist      = Mathf.Abs(rayHit.distance);
                                                verts[v].nor = (verts[tris[tri].v[0]].nor * rayHit.barycentricCoordinate.x) +
                                                               (verts[tris[tri].v[1]].nor * rayHit.barycentricCoordinate.y) +
                                                               (verts[tris[tri].v[2]].nor * rayHit.barycentricCoordinate.z);

                                                verts[v].nor = (verts[v].nor * projectionBlend) + (origNor * invProjectionBlend);

                                                verts[v].pos = (rayHit.point * projectionBlend) + (origPos * invProjectionBlend);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }


                    ringloops.Add(r);

                    // make sure we cap the puppy..
                    if ((t == 1.0f) && (r.radius > 0.005f))
                    {
                        RingLoop r2 = r.Clone();
                        r2.radius      = 0.0f;
                        r2.baseOffset += rad / (Mathf.PI * 2.0f);
                        r2.BuildVertices(verts);
                        ringloops.Add(r2);
                    }
                }

                // Cap
                // if needed..
                if (ringloops.Count > 0)
                {
                    if (ringloops[ringloops.Count - 1].radius > 0.025f)
                    {
                        if (node.breakOffset < 1.0f)
                        {
                            float    mappingScale     = 1.0f / (radius * Mathf.PI * 2.0f);
                            float    tempCapSpherical = 0.0f;
                            float    tempCapNoise     = 1.0f;
                            int      tempCapMapping   = 0;
                            Material tempCapMaterial  = materialBranch;

                            if (materialBreak != null)
                            {
                                tempCapMaterial = materialBreak;
                            }

                            int capMaterialIndex = GetMaterialIndex(tempCapMaterial, materials, false);

                            ringloops[ringloops.Count - 1].Cap(tempCapSpherical, tempCapNoise, tempCapMapping, mappingScale,
                                                               verts,
                                                               tris,
                                                               capMaterialIndex);
                        }
                    }
                }

                // Build triangles
                // Debug.Log("MAT INDEX: "+materialIndex);
                node.triStart = tris.Count;
                for (int i = 0; i < (ringloops.Count - 1); i++)
                {
                    ringloops[i].Connect(ringloops[i + 1], tris, materialIndex, false, false);
                }
                node.triEnd = tris.Count;

                ringloops.Clear();
            }

            // Build fronds
            float frondMin = Mathf.Min(frondRange.x, frondRange.y);
            float frondMax = Mathf.Max(frondRange.x, frondRange.y);

            // Mapping range.. may be different from min/max if broken..
            float frondMappingMin = frondMin;
            float frondMappingMax = frondMax;

            // Include breaking
            frondMin = Mathf.Clamp(frondMin, 0.0f, node.breakOffset);
            frondMax = Mathf.Clamp(frondMax, 0.0f, node.breakOffset);

            if ((geometryMode == GeometryMode.BranchFrond) || (geometryMode == GeometryMode.Frond))
            {
                if ((frondCount > 0) && (frondMin != frondMax))
                {
                    bool needStartPoint = true;
                    bool needEndPoint   = true;

                    for (int i = 0; i < heightSamples.Count; i++)
                    {
                        float t = heightSamples[i];

                        if (t < frondMin)
                        {
                            heightSamples.RemoveAt(i);
                            i--;
                        }
                        else if (t == frondMin)
                        {
                            needStartPoint = false;
                        }
                        else if (t == frondMax)
                        {
                            needEndPoint = false;
                        }
                        else if (t > frondMax)
                        {
                            heightSamples.RemoveAt(i);
                            i--;
                        }
                    }

                    if (needStartPoint)
                    {
                        heightSamples.Insert(0, frondMin);
                    }
                    if (needEndPoint)
                    {
                        heightSamples.Add(frondMax);
                    }

                    int frondMaterialIndex = GetMaterialIndex(materialFrond, materials, false);

                    float capStart = 1.0f - node.capRange;
                    //float capRadius = GetRadiusAtTime(capStart);
                    for (int j = 0; j < frondCount; j++)
                    {
                        float   crease     = (frondCrease * 90.0f) * Mathf.Deg2Rad;
                        float   angle      = ((frondRotation * 360.0f) + (((float)j * 180.0f) / frondCount) - 90.0f) * Mathf.Deg2Rad;
                        float   angleA     = -angle - crease;
                        float   angleB     = angle - crease;
                        Vector3 directionA = new Vector3(Mathf.Sin(angleA), 0.0f, Mathf.Cos(angleA));
                        Vector3 normalA    = new Vector3(directionA.z, 0.0f, -directionA.x);
                        Vector3 directionB = new Vector3(Mathf.Sin(angleB), 0.0f, -Mathf.Cos(angleB));
                        Vector3 normalB    = new Vector3(-directionB.z, 0.0f, directionB.x);

                        //float totalOffsetBase = GetTotalOffset();

                        for (int i = 0; i < heightSamples.Count; i++)
                        {
                            float t = heightSamples[i];
                            float v = (t - frondMappingMin) / (frondMappingMax - frondMappingMin);

                            // handle soft capping..
                            float t2 = t;
                            if (t > capStart)
                            {
                                t2 = capStart;

                                float capAngle    = Mathf.Acos(Mathf.Clamp01((t - capStart) / node.capRange));
                                float sinCapAngle = Mathf.Sin(capAngle);
                                float cosCapAngle = Mathf.Cos(capAngle) * capSmoothing;

                                directionA = new Vector3(Mathf.Sin(angleA) * sinCapAngle, cosCapAngle, Mathf.Cos(angleA) * sinCapAngle);
                                normalA    = new Vector3(directionA.z, directionA.y, -directionA.x);
                                directionB = new Vector3(Mathf.Sin(angleB) * sinCapAngle, cosCapAngle, -Mathf.Cos(angleB) * sinCapAngle);
                                normalB    = new Vector3(-directionB.z, directionB.y, directionB.x);
                            }

                            Vector3 normalMid = new Vector3(0, 0, -1);

                            Vector3    pos = node.spline.GetPositionAtTime(t2);
                            Quaternion rot = node.spline.GetRotationAtTime(t);
                            float      rad = (Mathf.Clamp01(frondCurve.Evaluate(t)) * frondWidth * node.GetScale());

                            Matrix4x4 m = node.matrix * Matrix4x4.TRS(pos, rot, new Vector3(1, 1, 1));

                            if (GenerateDoubleSidedGeometry)
                            {
                                // Generate double sided geometry to compensate for lack of VFACE shader semantic
                                // Twice the poly count
                                // Split vertices along back seam, to avoid bent normals.. 8 verts instead of 3

                                for (float side = -1; side < 2; side += 2)
                                {
                                    TreeVertex v0 = new TreeVertex();
                                    v0.pos       = m.MultiplyPoint(directionA * rad);
                                    v0.nor       = m.MultiplyVector(normalA * side).normalized;
                                    v0.tangent   = CreateTangent(node, rot, v0.nor);
                                    v0.tangent.w = -side;
                                    v0.uv0       = new Vector2(1.0f, v);

                                    TreeVertex v1 = new TreeVertex();
                                    v1.pos       = m.MultiplyPoint(Vector3.zero);
                                    v1.nor       = m.MultiplyVector(normalMid * side).normalized;
                                    v1.tangent   = CreateTangent(node, rot, v1.nor);
                                    v1.tangent.w = -side;
                                    v1.uv0       = new Vector2(0.5f, v);

                                    TreeVertex v2 = new TreeVertex();
                                    v2.pos       = m.MultiplyPoint(Vector3.zero);
                                    v2.nor       = m.MultiplyVector(normalMid * side).normalized;
                                    v2.tangent   = CreateTangent(node, rot, v2.nor);
                                    v2.tangent.w = -side;
                                    v2.uv0       = new Vector2(0.5f, v);

                                    TreeVertex v3 = new TreeVertex();
                                    v3.pos       = m.MultiplyPoint(directionB * rad);
                                    v3.nor       = m.MultiplyVector(normalB * side).normalized;
                                    v3.tangent   = CreateTangent(node, rot, v3.nor);
                                    v3.tangent.w = -side;
                                    v3.uv0       = new Vector2(0.0f, v);

                                    // Animation properties..
                                    Vector2 windFactors = ComputeWindFactor(node, t);

                                    v0.SetAnimationProperties(windFactors.x, windFactors.y, animationEdge, node.animSeed);
                                    v1.SetAnimationProperties(windFactors.x, windFactors.y, 0.0f, node.animSeed); // no edge flutter for center vertex
                                    v2.SetAnimationProperties(windFactors.x, windFactors.y, 0.0f, node.animSeed); // no edge flutter for center vertex
                                    v3.SetAnimationProperties(windFactors.x, windFactors.y, animationEdge, node.animSeed);

                                    verts.Add(v0); verts.Add(v1); verts.Add(v2); verts.Add(v3);
                                }

                                if (i > 0)
                                {
                                    int voffset = verts.Count;

                                    //
                                    // theoretical left side :)
                                    //
                                    // back
                                    TreeTriangle tri0 = new TreeTriangle(frondMaterialIndex, voffset - 4, voffset - 3, voffset - 11);
                                    TreeTriangle tri1 = new TreeTriangle(frondMaterialIndex, voffset - 4, voffset - 11, voffset - 12);
                                    tri0.flip(); tri1.flip();

                                    // front
                                    TreeTriangle tri2 = new TreeTriangle(frondMaterialIndex, voffset - 8, voffset - 7, voffset - 15);
                                    TreeTriangle tri3 = new TreeTriangle(frondMaterialIndex, voffset - 8, voffset - 15, voffset - 16);

                                    tris.Add(tri0); tris.Add(tri1);
                                    tris.Add(tri2); tris.Add(tri3);

                                    //
                                    // theoretical right side :)
                                    //
                                    // front
                                    TreeTriangle tri4 = new TreeTriangle(frondMaterialIndex, voffset - 2, voffset - 9, voffset - 1);
                                    TreeTriangle tri5 = new TreeTriangle(frondMaterialIndex, voffset - 2, voffset - 10, voffset - 9);

                                    // back
                                    TreeTriangle tri6 = new TreeTriangle(frondMaterialIndex, voffset - 6, voffset - 13, voffset - 5);
                                    TreeTriangle tri7 = new TreeTriangle(frondMaterialIndex, voffset - 6, voffset - 14, voffset - 13);
                                    tri6.flip(); tri7.flip();

                                    tris.Add(tri4); tris.Add(tri5);
                                    tris.Add(tri6); tris.Add(tri7);
                                }
                            }
                            else
                            {
                                // Single sided geometry .. we'll keep this for later

                                TreeVertex v0 = new TreeVertex();
                                v0.pos = m.MultiplyPoint(directionA * rad);
                                v0.nor = m.MultiplyVector(normalA).normalized;
                                v0.uv0 = new Vector2(0.0f, v);

                                TreeVertex v1 = new TreeVertex();
                                v1.pos = m.MultiplyPoint(Vector3.zero);
                                v1.nor = m.MultiplyVector(Vector3.back).normalized;
                                v1.uv0 = new Vector2(0.5f, v);

                                TreeVertex v2 = new TreeVertex();
                                v2.pos = m.MultiplyPoint(directionB * rad);
                                v2.nor = m.MultiplyVector(normalB).normalized;
                                v2.uv0 = new Vector2(1.0f, v);

                                // Animation properties..
                                Vector2 windFactors = ComputeWindFactor(node, t);

                                v0.SetAnimationProperties(windFactors.x, windFactors.y, animationEdge, node.animSeed);
                                v1.SetAnimationProperties(windFactors.x, windFactors.y, 0.0f, node.animSeed); // no edge flutter for center vertex
                                v2.SetAnimationProperties(windFactors.x, windFactors.y, animationEdge, node.animSeed);

                                verts.Add(v0); verts.Add(v1); verts.Add(v2);

                                if (i > 0)
                                {
                                    int voffset = verts.Count;

                                    TreeTriangle tri0 = new TreeTriangle(frondMaterialIndex, voffset - 2, voffset - 3, voffset - 6);
                                    TreeTriangle tri1 = new TreeTriangle(frondMaterialIndex, voffset - 2, voffset - 6, voffset - 5);
                                    tris.Add(tri0); tris.Add(tri1);

                                    TreeTriangle tri2 = new TreeTriangle(frondMaterialIndex, voffset - 2, voffset - 4, voffset - 1);
                                    TreeTriangle tri3 = new TreeTriangle(frondMaterialIndex, voffset - 2, voffset - 5, voffset - 4);
                                    tris.Add(tri2); tris.Add(tri3);
                                }
                            }
                        }
                    }
                }
            }

            // compute ambient occlusion..
            if ((buildFlags & (int)BuildFlag.BuildAmbientOcclusion) != 0)
            {
                for (int i = vertOffset; i < verts.Count; i++)
                {
                    verts[i].SetAmbientOcclusion(ComputeAmbientOcclusion(verts[i].pos, verts[i].nor, aoSpheres, aoDensity));
                }
            }

            node.vertEnd = verts.Count;

            Profiler.EndSample(); // TreeGroupBranch.UpdateNodeMesh
        }
Пример #11
0
        private void UpdateNodeMesh(TreeNode node, List<TreeMaterial> materials, List<TreeVertex> verts, List<TreeTriangle> tris, List<TreeAOSphere> aoSpheres, int buildFlags, float adaptiveQuality, float aoDensity)
        {
            node.triStart = tris.Count;
            node.triEnd = tris.Count;
            node.vertStart = verts.Count;
            node.vertEnd = verts.Count;
            if (node.visible && base.visible)
            {
                Vector2 vector = base.ComputeWindFactor(node, node.offset);
                if (this.geometryMode == 4)
                {
                    if ((((cloneMesh == null) || (cloneVerts == null)) || ((cloneNormals == null) || (cloneTangents == null))) || (cloneUVs == null))
                    {
                        return;
                    }
                    Matrix4x4 localToWorldMatrix = this.instanceMesh.transform.localToWorldMatrix;
                    Matrix4x4 matrixx2 = node.matrix * localToWorldMatrix;
                    int count = verts.Count;
                    float num2 = 5f;
                    for (int i = 0; i < cloneVerts.Length; i++)
                    {
                        TreeVertex item = new TreeVertex {
                            pos = matrixx2.MultiplyPoint(cloneVerts[i]),
                            nor = matrixx2.MultiplyVector(cloneNormals[i]).normalized,
                            uv0 = new Vector2(cloneUVs[i].x, cloneUVs[i].y)
                        };
                        Vector3 normalized = matrixx2.MultiplyVector(new Vector3(cloneTangents[i].x, cloneTangents[i].y, cloneTangents[i].z)).normalized;
                        item.tangent = new Vector4(normalized.x, normalized.y, normalized.z, cloneTangents[i].w);
                        float edgeFactor = (cloneVerts[i].magnitude / num2) * base.animationEdge;
                        item.SetAnimationProperties(vector.x, vector.y, edgeFactor, node.animSeed);
                        if ((buildFlags & 1) != 0)
                        {
                            item.SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(item.pos, item.nor, aoSpheres, aoDensity));
                        }
                        verts.Add(item);
                    }
                    for (int j = 0; j < cloneMesh.subMeshCount; j++)
                    {
                        int num6;
                        int[] triangles = cloneMesh.GetTriangles(j);
                        if ((this.instanceMesh.GetComponent<Renderer>() != null) && (j < this.instanceMesh.GetComponent<Renderer>().sharedMaterials.Length))
                        {
                            num6 = TreeGroup.GetMaterialIndex(this.instanceMesh.GetComponent<Renderer>().sharedMaterials[j], materials, false);
                        }
                        else
                        {
                            num6 = TreeGroup.GetMaterialIndex(null, materials, false);
                        }
                        for (int k = 0; k < triangles.Length; k += 3)
                        {
                            TreeTriangle triangle = new TreeTriangle(num6, triangles[k] + count, triangles[k + 1] + count, triangles[k + 2] + count);
                            tris.Add(triangle);
                        }
                    }
                }
                else if (this.geometryMode == 3)
                {
                    Vector3 eulerAngles = node.rotation.eulerAngles;
                    eulerAngles.z = eulerAngles.x * 2f;
                    eulerAngles.x = 0f;
                    eulerAngles.y = 0f;
                    Quaternion billboardRotation = Quaternion.Euler(eulerAngles);
                    Vector3 normalBase = new Vector3(TreeGroup.GenerateBendBillboardNormalFactor, TreeGroup.GenerateBendBillboardNormalFactor, 1f);
                    Vector3 tangentBase = (Vector3) (billboardRotation * new Vector3(1f, 0f, 0f));
                    float normalFix = node.scale / (TreeGroup.GenerateBendBillboardNormalFactor * TreeGroup.GenerateBendBillboardNormalFactor);
                    TreeVertex vertex2 = CreateBillboardVertex(node, billboardRotation, normalBase, normalFix, tangentBase, new Vector2(0f, 1f));
                    TreeVertex vertex3 = CreateBillboardVertex(node, billboardRotation, normalBase, normalFix, tangentBase, new Vector2(0f, 0f));
                    TreeVertex vertex4 = CreateBillboardVertex(node, billboardRotation, normalBase, normalFix, tangentBase, new Vector2(1f, 0f));
                    TreeVertex vertex5 = CreateBillboardVertex(node, billboardRotation, normalBase, normalFix, tangentBase, new Vector2(1f, 1f));
                    vertex2.SetAnimationProperties(vector.x, vector.y, base.animationEdge, node.animSeed);
                    vertex3.SetAnimationProperties(vector.x, vector.y, base.animationEdge, node.animSeed);
                    vertex4.SetAnimationProperties(vector.x, vector.y, base.animationEdge, node.animSeed);
                    vertex5.SetAnimationProperties(vector.x, vector.y, base.animationEdge, node.animSeed);
                    if ((buildFlags & 1) != 0)
                    {
                        Vector3 vector8 = (Vector3) (Vector3.right * node.scale);
                        Vector3 vector9 = (Vector3) (Vector3.forward * node.scale);
                        float ao = 0f;
                        ao = TreeGroup.ComputeAmbientOcclusion(vertex2.pos + vector8, Vector3.right, aoSpheres, aoDensity) + TreeGroup.ComputeAmbientOcclusion(vertex2.pos - vector8, -Vector3.right, aoSpheres, aoDensity);
                        ao += TreeGroup.ComputeAmbientOcclusion(vertex2.pos + vector9, Vector3.forward, aoSpheres, aoDensity);
                        ao += TreeGroup.ComputeAmbientOcclusion(vertex2.pos - vector9, -Vector3.forward, aoSpheres, aoDensity);
                        ao /= 4f;
                        vertex2.SetAmbientOcclusion(ao);
                        vertex3.SetAmbientOcclusion(ao);
                        vertex4.SetAmbientOcclusion(ao);
                        vertex5.SetAmbientOcclusion(ao);
                    }
                    int num10 = verts.Count;
                    verts.Add(vertex2);
                    verts.Add(vertex3);
                    verts.Add(vertex4);
                    verts.Add(vertex5);
                    int material = TreeGroup.GetMaterialIndex(this.materialLeaf, materials, false);
                    tris.Add(new TreeTriangle(material, num10, num10 + 2, num10 + 1, true));
                    tris.Add(new TreeTriangle(material, num10, num10 + 3, num10 + 2, true));
                }
                else
                {
                    int num12 = 0;
                    switch (((GeometryMode) this.geometryMode))
                    {
                        case GeometryMode.PLANE:
                            num12 = 1;
                            break;

                        case GeometryMode.CROSS:
                            num12 = 2;
                            break;

                        case GeometryMode.TRI_CROSS:
                            num12 = 3;
                            break;
                    }
                    int num13 = TreeGroup.GetMaterialIndex(this.materialLeaf, materials, false);
                    Vector2[] vectorArray = new Vector2[] { new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(1f, 1f) };
                    Vector2[] planeHullVertices = this.GetPlaneHullVertices(this.materialLeaf);
                    if (planeHullVertices == null)
                    {
                        planeHullVertices = vectorArray;
                    }
                    float scale = node.scale;
                    Vector3[] vectorArray3 = new Vector3[] { new Vector3(-scale, 0f, -scale), new Vector3(-scale, 0f, scale), new Vector3(scale, 0f, scale), new Vector3(scale, 0f, -scale) };
                    Vector3 vector10 = new Vector3(TreeGroup.GenerateBendNormalFactor, 1f - TreeGroup.GenerateBendNormalFactor, TreeGroup.GenerateBendNormalFactor);
                    Vector3[] vectorArray6 = new Vector3[4];
                    Vector3 vector11 = new Vector3(-vector10.x, vector10.y, -vector10.z);
                    vectorArray6[0] = vector11.normalized;
                    Vector3 vector12 = new Vector3(-vector10.x, vector10.y, 0f);
                    vectorArray6[1] = vector12.normalized;
                    Vector3 vector13 = new Vector3(vector10.x, vector10.y, 0f);
                    vectorArray6[2] = vector13.normalized;
                    Vector3 vector14 = new Vector3(vector10.x, vector10.y, -vector10.z);
                    vectorArray6[3] = vector14.normalized;
                    Vector3[] vectorArray4 = vectorArray6;
                    for (int m = 0; m < num12; m++)
                    {
                        Quaternion rot = Quaternion.Euler(new Vector3(90f, 0f, 0f));
                        switch (m)
                        {
                            case 1:
                                rot = Quaternion.Euler(new Vector3(90f, 90f, 0f));
                                break;

                            case 2:
                                rot = Quaternion.Euler(new Vector3(0f, 90f, 0f));
                                break;
                        }
                        TreeVertex[] tv = new TreeVertex[] { new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex() };
                        for (int n = 0; n < 4; n++)
                        {
                            tv[n].pos = node.matrix.MultiplyPoint((Vector3) (rot * vectorArray3[n]));
                            tv[n].nor = node.matrix.MultiplyVector((Vector3) (rot * vectorArray4[n]));
                            tv[n].tangent = TreeGroup.CreateTangent(node, rot, tv[n].nor);
                            tv[n].uv0 = planeHullVertices[n];
                            tv[n].SetAnimationProperties(vector.x, vector.y, base.animationEdge, node.animSeed);
                            if ((buildFlags & 1) != 0)
                            {
                                tv[n].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(tv[n].pos, tv[n].nor, aoSpheres, aoDensity));
                            }
                        }
                        for (int num17 = 0; num17 < 4; num17++)
                        {
                            tv[num17 + 4].Lerp4(tv, planeHullVertices[num17]);
                            tv[num17 + 4].uv0 = tv[num17].uv0;
                            tv[num17 + 4].uv1 = tv[num17].uv1;
                            tv[num17 + 4].flag = tv[num17].flag;
                        }
                        int num18 = verts.Count;
                        for (int num19 = 0; num19 < 4; num19++)
                        {
                            verts.Add(tv[num19 + 4]);
                        }
                        tris.Add(new TreeTriangle(num13, num18, num18 + 1, num18 + 2));
                        tris.Add(new TreeTriangle(num13, num18, num18 + 2, num18 + 3));
                        Vector3 inNormal = node.matrix.MultiplyVector((Vector3) (rot * new Vector3(0f, 1f, 0f)));
                        if (TreeGroup.GenerateDoubleSidedGeometry)
                        {
                            TreeVertex[] vertexArray2 = new TreeVertex[] { new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex(), new TreeVertex() };
                            for (int num20 = 0; num20 < 4; num20++)
                            {
                                vertexArray2[num20].pos = tv[num20].pos;
                                vertexArray2[num20].nor = Vector3.Reflect(tv[num20].nor, inNormal);
                                vertexArray2[num20].tangent = Vector3.Reflect((Vector3) tv[num20].tangent, inNormal);
                                vertexArray2[num20].tangent.w = -1f;
                                vertexArray2[num20].uv0 = tv[num20].uv0;
                                vertexArray2[num20].SetAnimationProperties(vector.x, vector.y, base.animationEdge, node.animSeed);
                                if ((buildFlags & 1) != 0)
                                {
                                    vertexArray2[num20].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(vertexArray2[num20].pos, vertexArray2[num20].nor, aoSpheres, aoDensity));
                                }
                            }
                            for (int num21 = 0; num21 < 4; num21++)
                            {
                                vertexArray2[num21 + 4].Lerp4(vertexArray2, planeHullVertices[num21]);
                                vertexArray2[num21 + 4].uv0 = vertexArray2[num21].uv0;
                                vertexArray2[num21 + 4].uv1 = vertexArray2[num21].uv1;
                                vertexArray2[num21 + 4].flag = vertexArray2[num21].flag;
                            }
                            int num22 = verts.Count;
                            for (int num23 = 0; num23 < 4; num23++)
                            {
                                verts.Add(vertexArray2[num23 + 4]);
                            }
                            tris.Add(new TreeTriangle(num13, num22, num22 + 2, num22 + 1));
                            tris.Add(new TreeTriangle(num13, num22, num22 + 3, num22 + 2));
                        }
                    }
                }
                node.triEnd = tris.Count;
                node.vertEnd = verts.Count;
            }
        }