public SetAnimationProperties ( float primaryFactor, float secondaryFactor, float edgeFactor, float phase ) : void | ||
primaryFactor | float | |
secondaryFactor | float | |
edgeFactor | float | |
phase | float | |
Результат | void |
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 }
public void Cap(float sphereFactor, float noise, int mappingMode, float mappingScale, List <TreeVertex> verts, List <TreeTriangle> tris, int materialIndex) { // half number of segments for the cap, fade with spherefactor.. int loops = Mathf.Max(1, (int)((segments / 2) * Mathf.Clamp01(sphereFactor))); int segs = segments; int vloops = loops; if (mappingMode == 1) { // follow mapping requires one extra segment and one extra loop segs += 1; vloops += 1; mappingScale /= Mathf.Max(1.0f, sphereFactor); } int centerV = verts.Count; Vector3 upVector = Vector3.Normalize(matrix.MultiplyVector(Vector3.up)); Vector3 centerPos = matrix.MultiplyPoint(Vector3.zero); // add central vertex TreeVertex v = new TreeVertex(); v.nor = upVector; v.pos = centerPos + (v.nor * sphereFactor * radius); Vector3 tmpTangent = Vector3.Normalize(matrix.MultiplyVector(Vector3.right)); v.tangent = new Vector4(tmpTangent.x, tmpTangent.y, tmpTangent.z, -1.0f); v.SetAnimationProperties(animParams.x, animParams.y, animParams.z, animParams.w); // planar mapping if (mappingMode == 0) { v.uv0 = new Vector2(0.5f, 0.5f); } else { v.uv0 = new Vector2(0.5f, baseOffset + sphereFactor * mappingScale); } verts.Add(v); int voffset = verts.Count; Matrix4x4 invMatrix = matrix.inverse; // add edge vertices for (int l = 0; l < vloops; l++) { float stepAngle = (1.0f - ((float)l / loops)) * Mathf.PI * 0.5f; // when doing top projection use this as the scale of the uvs float uvScale = Mathf.Sin(stepAngle); // position blending float posBlend = uvScale; // normal blending // blend normals depending on sphere factor float normalBlend = (uvScale * Mathf.Clamp01(sphereFactor)) + (uvScale * 0.5f * Mathf.Clamp01(1.0f - sphereFactor)); float cosine = Mathf.Cos(stepAngle); for (int i = 0; i < segs; i++) { TreeVertex copyV = verts[vertOffset + i]; Vector3 uv = invMatrix.MultiplyPoint(copyV.pos).normalized * 0.5f * uvScale; TreeVertex newV = new TreeVertex(); newV.pos = (copyV.pos * posBlend) + (centerPos * (1.0f - posBlend)) + (upVector * cosine * sphereFactor * radius); newV.nor = ((copyV.nor * normalBlend) + (upVector * (1.0f - normalBlend))).normalized; // mix center and original vertex normal.. newV.SetAnimationProperties(animParams.x, animParams.y, animParams.z, animParams.w); if (mappingMode == 0) { // planar mapping newV.tangent = v.tangent; // same tangent as center vertex.. newV.uv0 = new Vector2(0.5f + uv.x, 0.5f + uv.z); } else { // follow mapping newV.tangent = copyV.tangent; // same tangent as copy vertex.. newV.uv0 = new Vector2((float)(i) / segments, baseOffset + sphereFactor * cosine * mappingScale); } verts.Add(newV); } } float capNoiseScale = 3.0f; for (int i = vertOffset; i < verts.Count; i++) { // Noise from position.. float perlinX = verts[i].pos.x * capNoiseScale; float perlinY = verts[i].pos.z * capNoiseScale; float push = (radius * (perlin.Noise(perlinX, perlinY) * noise)); // push along center vertex normal.. ie. local up vector verts[i].pos += v.nor * push; } // add triangles /* * int materialIndex = 3; * if (mappingMode == 1) * { * materialIndex = 0; * } */ for (int l = 0; l < loops; l++) { for (int i = 0; i < segs; i++) { if (l == (vloops - 1)) { // inner loop connects to center vertex.. // this only happens with planar mapping.. int v1 = i + voffset + (segs * l); int v2 = v1 + 1; if (i == (segs - 1)) { v2 = voffset + (segs * l); } tris.Add(new TreeTriangle(materialIndex, centerV, v1, v2, false, false, false)); } else { // connect to next segment int v0 = i + voffset + (segs * l); int v1 = v0 + 1; int v2 = i + voffset + (segs * (l + 1)); int v3 = v2 + 1; if (i == (segs - 1)) { v1 = voffset + (segs * l); v3 = voffset + (segs * (l + 1)); } tris.Add(new TreeTriangle(materialIndex, v0, v1, v3, false, false, false)); tris.Add(new TreeTriangle(materialIndex, v0, v3, v2, false, false, false)); } } } }
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; } }
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(); }
public void BuildVertices(List <TreeVertex> verts) { this.vertOffset = verts.Count; for (int i = 0; i <= segments; i++) { float a = (i * Mathf.PI * 2.0f) / segments; TreeVertex v = new TreeVertex(); float rad = radius; float uvx = 1.0f - ((float)(i) / segments); float uvy = baseOffset; float noiseX = uvx; float noiseY = uvy; if (i == segments) { noiseX = 1.0f; // Loop around } // Weld spreading float spreadFactor = Mathf.Cos(a); float spreadRad = 0.0f; if (spreadFactor > 0.0f) { spreadRad = Mathf.Pow(spreadFactor, 3.0f) * radius * spreadBot; } else { spreadRad = Mathf.Pow(Mathf.Abs(spreadFactor), 3.0f) * radius * spreadTop; } // Noise.. float perlinX = noiseX * noiseScaleU; float perlinY = noiseY * noiseScaleV; rad += (radius * (perlin.Noise(perlinX, perlinY) * noiseScale)); // Flare.. perlinX = noiseX * flareNoise; rad += flareRadius * Mathf.Abs(perlin.Noise(perlinX, 0.12932f)); v.pos = matrix.MultiplyPoint(new Vector3(Mathf.Sin(a) * (rad + (spreadRad * 0.25f)), 0.0f, Mathf.Cos(a) * (rad + spreadRad))); v.uv0 = new Vector2(uvx, uvy); v.SetAnimationProperties(animParams.x, animParams.y, animParams.z, animParams.w); verts.Add(v); } if (radius == 0.0f) { for (int i = 0; i <= segments; i++) { TreeVertex v = verts[i + vertOffset]; float a = (i * Mathf.PI * 2.0f) / segments; float b = a - Mathf.PI * 0.5f; Vector3 normal = Vector3.zero; normal.x = Mathf.Sin(a) * surfAngleCos; normal.y = surfAngleSin; normal.z = Mathf.Cos(a) * surfAngleCos; v.nor = Vector3.Normalize(matrix.MultiplyVector(normal)); Vector3 tangent = Vector3.zero; tangent.x = Mathf.Sin(b); tangent.y = 0.0f; tangent.z = Mathf.Cos(b); tangent = Vector3.Normalize(matrix.MultiplyVector(tangent)); v.tangent = new Vector4(tangent.x, tangent.y, tangent.z, -1.0f); } return; } // Rethink normals.. to take noise into account.. Matrix4x4 matrixInv = matrix.inverse; for (int i = 0; i <= segments; i++) { int a = i - 1; if (a < 0) { a = segments - 1; } int b = i + 1; if (b > segments) { b = 1; } TreeVertex va = verts[a + vertOffset]; TreeVertex vb = verts[b + vertOffset]; TreeVertex vi = verts[i + vertOffset]; // Use the previous and the next vertices in the loop to create the tangent. // It will be tangent to the perfect ring loop in case of no noise. Vector3 tangent = Vector3.Normalize(va.pos - vb.pos); Vector3 normal = matrixInv.MultiplyVector(va.pos - vb.pos); // rotate 90 degrees and normalize normal.y = normal.x; normal.x = normal.z; normal.z = -normal.y; normal.y = 0.0f; normal.Normalize(); // tilt accoring to surface angle normal.x = surfAngleCos * normal.x; normal.y = surfAngleSin; normal.z = surfAngleCos * normal.z; // set normal vi.nor = Vector3.Normalize(matrix.MultiplyVector(normal)); // set tangent vi.tangent.x = tangent.x; vi.tangent.y = tangent.y; vi.tangent.z = tangent.z; vi.tangent.w = -1.0f; } }
public void Cap(float sphereFactor, float noise, int mappingMode, float mappingScale, List<TreeVertex> verts, List<TreeTriangle> tris, int materialIndex) { int num = Mathf.Max(1, (int) ((this.segments / 2) * Mathf.Clamp01(sphereFactor))); int segments = this.segments; int num3 = num; if (mappingMode == 1) { segments++; num3++; mappingScale /= Mathf.Max(1f, sphereFactor); } int count = verts.Count; Vector3 vector = Vector3.Normalize(this.matrix.MultiplyVector(Vector3.up)); Vector3 vector2 = this.matrix.MultiplyPoint(Vector3.zero); TreeVertex item = new TreeVertex { nor = vector }; item.pos = vector2 + ((Vector3) ((item.nor * sphereFactor) * this.radius)); Vector3 vector3 = Vector3.Normalize(this.matrix.MultiplyVector(Vector3.right)); item.tangent = new Vector4(vector3.x, vector3.y, vector3.z, -1f); item.SetAnimationProperties(this.animParams.x, this.animParams.y, this.animParams.z, this.animParams.w); if (mappingMode == 0) { item.uv0 = new Vector2(0.5f, 0.5f); } else { item.uv0 = new Vector2(0.5f, this.baseOffset + (sphereFactor * mappingScale)); } verts.Add(item); int num5 = verts.Count; Matrix4x4 inverse = this.matrix.inverse; for (int i = 0; i < num3; i++) { float f = ((1f - (((float) i) / ((float) num))) * 3.141593f) * 0.5f; float num8 = Mathf.Sin(f); float num9 = num8; float num10 = (num8 * Mathf.Clamp01(sphereFactor)) + ((num8 * 0.5f) * Mathf.Clamp01(1f - sphereFactor)); float num11 = Mathf.Cos(f); for (int m = 0; m < segments; m++) { TreeVertex vertex2 = verts[this.vertOffset + m]; Vector3 vector4 = (Vector3) ((inverse.MultiplyPoint(vertex2.pos).normalized * 0.5f) * num8); TreeVertex vertex3 = new TreeVertex { pos = (Vector3) (((vertex2.pos * num9) + (vector2 * (1f - num9))) + (((vector * num11) * sphereFactor) * this.radius)) }; Vector3 vector6 = (Vector3) ((vertex2.nor * num10) + (vector * (1f - num10))); vertex3.nor = vector6.normalized; vertex3.SetAnimationProperties(this.animParams.x, this.animParams.y, this.animParams.z, this.animParams.w); if (mappingMode == 0) { vertex3.tangent = item.tangent; vertex3.uv0 = new Vector2(0.5f + vector4.x, 0.5f + vector4.z); } else { vertex3.tangent = vertex2.tangent; vertex3.uv0 = new Vector2(((float) m) / ((float) this.segments), this.baseOffset + ((sphereFactor * num11) * mappingScale)); } verts.Add(vertex3); } } float num13 = 3f; for (int j = this.vertOffset; j < verts.Count; j++) { float x = verts[j].pos.x * num13; float y = verts[j].pos.z * num13; float num17 = this.radius * (perlin.Noise(x, y) * noise); TreeVertex local1 = verts[j]; local1.pos += (Vector3) (item.nor * num17); } for (int k = 0; k < num; k++) { for (int n = 0; n < segments; n++) { if (k == (num3 - 1)) { int num20 = (n + num5) + (segments * k); int num21 = num20 + 1; if (n == (segments - 1)) { num21 = num5 + (segments * k); } tris.Add(new TreeTriangle(materialIndex, count, num20, num21, false, false, false)); } else { int num22 = (n + num5) + (segments * k); int num23 = num22 + 1; int num24 = (n + num5) + (segments * (k + 1)); int num25 = num24 + 1; if (n == (segments - 1)) { num23 = num5 + (segments * k); num25 = num5 + (segments * (k + 1)); } tris.Add(new TreeTriangle(materialIndex, num22, num23, num25, false, false, false)); tris.Add(new TreeTriangle(materialIndex, num22, num25, num24, false, false, false)); } } } }
public void BuildVertices(List <TreeVertex> verts) { this.vertOffset = verts.Count; for (int i = 0; i <= this.segments; i++) { float f = ((i * 3.141593f) * 2f) / ((float)this.segments); TreeVertex item = new TreeVertex(); float radius = this.radius; float x = 1f - (((float)i) / ((float)this.segments)); float baseOffset = this.baseOffset; float num6 = x; float num7 = baseOffset; if (i == this.segments) { num6 = 1f; } float num8 = Mathf.Cos(f); float num9 = 0f; if (num8 > 0f) { num9 = (Mathf.Pow(num8, 3f) * this.radius) * this.spreadBot; } else { num9 = (Mathf.Pow(Mathf.Abs(num8), 3f) * this.radius) * this.spreadTop; } float num10 = num6 * this.noiseScaleU; float y = num7 * this.noiseScaleV; radius += this.radius * (perlin.Noise(num10, y) * this.noiseScale); num10 = num6 * this.flareNoise; radius += this.flareRadius * Mathf.Abs(perlin.Noise(num10, 0.12932f)); item.pos = this.matrix.MultiplyPoint(new Vector3(Mathf.Sin(f) * (radius + (num9 * 0.25f)), 0f, Mathf.Cos(f) * (radius + num9))); item.uv0 = new Vector2(x, baseOffset); item.SetAnimationProperties(this.animParams.x, this.animParams.y, this.animParams.z, this.animParams.w); verts.Add(item); } if (this.radius == 0f) { for (int j = 0; j <= this.segments; j++) { TreeVertex vertex2 = verts[j + this.vertOffset]; float num13 = ((j * 3.141593f) * 2f) / ((float)this.segments); float num14 = num13 - 1.570796f; Vector3 zero = Vector3.zero; zero.x = Mathf.Sin(num13) * this.surfAngleCos; zero.y = this.surfAngleSin; zero.z = Mathf.Cos(num13) * this.surfAngleCos; vertex2.nor = Vector3.Normalize(this.matrix.MultiplyVector(zero)); Vector3 v = Vector3.zero; v.x = Mathf.Sin(num14); v.y = 0f; v.z = Mathf.Cos(num14); v = Vector3.Normalize(this.matrix.MultiplyVector(v)); vertex2.tangent = new Vector4(v.x, v.y, v.z, -1f); } } else { Matrix4x4 inverse = this.matrix.inverse; for (int k = 0; k <= this.segments; k++) { int num16 = k - 1; if (num16 < 0) { num16 = this.segments - 1; } int num17 = k + 1; if (num17 > this.segments) { num17 = 1; } TreeVertex vertex3 = verts[num16 + this.vertOffset]; TreeVertex vertex4 = verts[num17 + this.vertOffset]; TreeVertex vertex5 = verts[k + this.vertOffset]; Vector3 vector3 = Vector3.Normalize(vertex3.pos - vertex4.pos); Vector3 vector4 = inverse.MultiplyVector(vertex3.pos - vertex4.pos); vector4.y = vector4.x; vector4.x = vector4.z; vector4.z = -vector4.y; vector4.y = 0f; vector4.Normalize(); vector4.x = this.surfAngleCos * vector4.x; vector4.y = this.surfAngleSin; vector4.z = this.surfAngleCos * vector4.z; vertex5.nor = Vector3.Normalize(this.matrix.MultiplyVector(vector4)); vertex5.tangent.x = vector3.x; vertex5.tangent.y = vector3.y; vertex5.tangent.z = vector3.z; vertex5.tangent.w = -1f; } } }
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; } }
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(); }
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 }
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(); }
public void BuildVertices(List<TreeVertex> verts) { this.vertOffset = verts.Count; for (int i = 0; i <= this.segments; i++) { float f = (float)i * 3.14159274f * 2f / (float)this.segments; TreeVertex treeVertex = new TreeVertex(); float num = this.radius; float num2 = 1f - (float)i / (float)this.segments; float num3 = this.baseOffset; float num4 = num2; float num5 = num3; if (i == this.segments) { num4 = 1f; } float num6 = Mathf.Cos(f); float num7; if (num6 > 0f) { num7 = Mathf.Pow(num6, 3f) * this.radius * this.spreadBot; } else { num7 = Mathf.Pow(Mathf.Abs(num6), 3f) * this.radius * this.spreadTop; } float x = num4 * this.noiseScaleU; float y = num5 * this.noiseScaleV; num += this.radius * (RingLoop.perlin.Noise(x, y) * this.noiseScale); x = num4 * this.flareNoise; num += this.flareRadius * Mathf.Abs(RingLoop.perlin.Noise(x, 0.12932f)); treeVertex.pos = this.matrix.MultiplyPoint(new Vector3(Mathf.Sin(f) * (num + num7 * 0.25f), 0f, Mathf.Cos(f) * (num + num7))); treeVertex.uv0 = new Vector2(num2, num3); treeVertex.SetAnimationProperties(this.animParams.x, this.animParams.y, this.animParams.z, this.animParams.w); verts.Add(treeVertex); } if (this.radius == 0f) { for (int j = 0; j <= this.segments; j++) { TreeVertex treeVertex2 = verts[j + this.vertOffset]; float num8 = (float)j * 3.14159274f * 2f / (float)this.segments; float f2 = num8 - 1.57079637f; Vector3 zero = Vector3.zero; zero.x = Mathf.Sin(num8) * this.surfAngleCos; zero.y = this.surfAngleSin; zero.z = Mathf.Cos(num8) * this.surfAngleCos; treeVertex2.nor = Vector3.Normalize(this.matrix.MultiplyVector(zero)); Vector3 v = Vector3.zero; v.x = Mathf.Sin(f2); v.y = 0f; v.z = Mathf.Cos(f2); v = Vector3.Normalize(this.matrix.MultiplyVector(v)); treeVertex2.tangent = new Vector4(v.x, v.y, v.z, -1f); } return; } Matrix4x4 inverse = this.matrix.inverse; for (int k = 0; k <= this.segments; k++) { int num9 = k - 1; if (num9 < 0) { num9 = this.segments - 1; } int num10 = k + 1; if (num10 > this.segments) { num10 = 1; } TreeVertex treeVertex3 = verts[num9 + this.vertOffset]; TreeVertex treeVertex4 = verts[num10 + this.vertOffset]; TreeVertex treeVertex5 = verts[k + this.vertOffset]; Vector3 vector = Vector3.Normalize(treeVertex3.pos - treeVertex4.pos); Vector3 v2 = inverse.MultiplyVector(treeVertex3.pos - treeVertex4.pos); v2.y = v2.x; v2.x = v2.z; v2.z = -v2.y; v2.y = 0f; v2.Normalize(); v2.x = this.surfAngleCos * v2.x; v2.y = this.surfAngleSin; v2.z = this.surfAngleCos * v2.z; treeVertex5.nor = Vector3.Normalize(this.matrix.MultiplyVector(v2)); treeVertex5.tangent.x = vector.x; treeVertex5.tangent.y = vector.y; treeVertex5.tangent.z = vector.z; treeVertex5.tangent.w = -1f; } }
public void Cap(float sphereFactor, float noise, int mappingMode, float mappingScale, List<TreeVertex> verts, List<TreeTriangle> tris, int materialIndex) { int num = Mathf.Max(1, (int)((float)(this.segments / 2) * Mathf.Clamp01(sphereFactor))); int num2 = this.segments; int num3 = num; if (mappingMode == 1) { num2++; num3++; mappingScale /= Mathf.Max(1f, sphereFactor); } int count = verts.Count; Vector3 vector = Vector3.Normalize(this.matrix.MultiplyVector(Vector3.up)); Vector3 a = this.matrix.MultiplyPoint(Vector3.zero); TreeVertex treeVertex = new TreeVertex(); treeVertex.nor = vector; treeVertex.pos = a + treeVertex.nor * sphereFactor * this.radius; Vector3 vector2 = Vector3.Normalize(this.matrix.MultiplyVector(Vector3.right)); treeVertex.tangent = new Vector4(vector2.x, vector2.y, vector2.z, -1f); treeVertex.SetAnimationProperties(this.animParams.x, this.animParams.y, this.animParams.z, this.animParams.w); if (mappingMode == 0) { treeVertex.uv0 = new Vector2(0.5f, 0.5f); } else { treeVertex.uv0 = new Vector2(0.5f, this.baseOffset + sphereFactor * mappingScale); } verts.Add(treeVertex); int count2 = verts.Count; Matrix4x4 inverse = this.matrix.inverse; for (int i = 0; i < num3; i++) { float f = (1f - (float)i / (float)num) * 3.14159274f * 0.5f; float num4 = Mathf.Sin(f); float num5 = num4; float num6 = num4 * Mathf.Clamp01(sphereFactor) + num4 * 0.5f * Mathf.Clamp01(1f - sphereFactor); float num7 = Mathf.Cos(f); for (int j = 0; j < num2; j++) { TreeVertex treeVertex2 = verts[this.vertOffset + j]; Vector3 vector3 = inverse.MultiplyPoint(treeVertex2.pos).normalized * 0.5f * num4; TreeVertex treeVertex3 = new TreeVertex(); treeVertex3.pos = treeVertex2.pos * num5 + a * (1f - num5) + vector * num7 * sphereFactor * this.radius; treeVertex3.nor = (treeVertex2.nor * num6 + vector * (1f - num6)).normalized; treeVertex3.SetAnimationProperties(this.animParams.x, this.animParams.y, this.animParams.z, this.animParams.w); if (mappingMode == 0) { treeVertex3.tangent = treeVertex.tangent; treeVertex3.uv0 = new Vector2(0.5f + vector3.x, 0.5f + vector3.z); } else { treeVertex3.tangent = treeVertex2.tangent; treeVertex3.uv0 = new Vector2((float)j / (float)this.segments, this.baseOffset + sphereFactor * num7 * mappingScale); } verts.Add(treeVertex3); } } float num8 = 3f; for (int k = this.vertOffset; k < verts.Count; k++) { float x = verts[k].pos.x * num8; float y = verts[k].pos.z * num8; float d = this.radius * (RingLoop.perlin.Noise(x, y) * noise); verts[k].pos += treeVertex.nor * d; } for (int l = 0; l < num; l++) { for (int m = 0; m < num2; m++) { if (l == num3 - 1) { int num9 = m + count2 + num2 * l; int v = num9 + 1; if (m == num2 - 1) { v = count2 + num2 * l; } tris.Add(new TreeTriangle(materialIndex, count, num9, v, false, false, false)); } else { int num10 = m + count2 + num2 * l; int v2 = num10 + 1; int num11 = m + count2 + num2 * (l + 1); int num12 = num11 + 1; if (m == num2 - 1) { v2 = count2 + num2 * l; num12 = count2 + num2 * (l + 1); } tris.Add(new TreeTriangle(materialIndex, num10, v2, num12, false, false, false)); tris.Add(new TreeTriangle(materialIndex, num10, num12, num11, false, false, false)); } } } }
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; } }
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(); }
public void Cap(float sphereFactor, float noise, int mappingMode, float mappingScale, List <TreeVertex> verts, List <TreeTriangle> tris, int materialIndex) { int num = Mathf.Max(1, (int)((float)(this.segments / 2) * Mathf.Clamp01(sphereFactor))); int num2 = this.segments; int num3 = num; if (mappingMode == 1) { num2++; num3++; mappingScale /= Mathf.Max(1f, sphereFactor); } int count = verts.Count; Vector3 vector = Vector3.Normalize(this.matrix.MultiplyVector(Vector3.up)); Vector3 a = this.matrix.MultiplyPoint(Vector3.zero); TreeVertex treeVertex = new TreeVertex(); treeVertex.nor = vector; treeVertex.pos = a + treeVertex.nor * sphereFactor * this.radius; Vector3 vector2 = Vector3.Normalize(this.matrix.MultiplyVector(Vector3.right)); treeVertex.tangent = new Vector4(vector2.x, vector2.y, vector2.z, -1f); treeVertex.SetAnimationProperties(this.animParams.x, this.animParams.y, this.animParams.z, this.animParams.w); if (mappingMode == 0) { treeVertex.uv0 = new Vector2(0.5f, 0.5f); } else { treeVertex.uv0 = new Vector2(0.5f, this.baseOffset + sphereFactor * mappingScale); } verts.Add(treeVertex); int count2 = verts.Count; Matrix4x4 inverse = this.matrix.inverse; for (int i = 0; i < num3; i++) { float f = (1f - (float)i / (float)num) * 3.14159274f * 0.5f; float num4 = Mathf.Sin(f); float num5 = num4; float num6 = num4 * Mathf.Clamp01(sphereFactor) + num4 * 0.5f * Mathf.Clamp01(1f - sphereFactor); float num7 = Mathf.Cos(f); for (int j = 0; j < num2; j++) { TreeVertex treeVertex2 = verts[this.vertOffset + j]; Vector3 vector3 = inverse.MultiplyPoint(treeVertex2.pos).normalized * 0.5f * num4; TreeVertex treeVertex3 = new TreeVertex(); treeVertex3.pos = treeVertex2.pos * num5 + a * (1f - num5) + vector * num7 * sphereFactor * this.radius; treeVertex3.nor = (treeVertex2.nor * num6 + vector * (1f - num6)).normalized; treeVertex3.SetAnimationProperties(this.animParams.x, this.animParams.y, this.animParams.z, this.animParams.w); if (mappingMode == 0) { treeVertex3.tangent = treeVertex.tangent; treeVertex3.uv0 = new Vector2(0.5f + vector3.x, 0.5f + vector3.z); } else { treeVertex3.tangent = treeVertex2.tangent; treeVertex3.uv0 = new Vector2((float)j / (float)this.segments, this.baseOffset + sphereFactor * num7 * mappingScale); } verts.Add(treeVertex3); } } float num8 = 3f; for (int k = this.vertOffset; k < verts.Count; k++) { float x = verts[k].pos.x * num8; float y = verts[k].pos.z * num8; float d = this.radius * (RingLoop.perlin.Noise(x, y) * noise); verts[k].pos += treeVertex.nor * d; } for (int l = 0; l < num; l++) { for (int m = 0; m < num2; m++) { if (l == num3 - 1) { int num9 = m + count2 + num2 * l; int v = num9 + 1; if (m == num2 - 1) { v = count2 + num2 * l; } tris.Add(new TreeTriangle(materialIndex, count, num9, v, false, false, false)); } else { int num10 = m + count2 + num2 * l; int v2 = num10 + 1; int num11 = m + count2 + num2 * (l + 1); int num12 = num11 + 1; if (m == num2 - 1) { v2 = count2 + num2 * l; num12 = count2 + num2 * (l + 1); } tris.Add(new TreeTriangle(materialIndex, num10, v2, num12, false, false, false)); tris.Add(new TreeTriangle(materialIndex, num10, num12, num11, false, false, false)); } } } }
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; } }
public void BuildVertices(List <TreeVertex> verts) { this.vertOffset = verts.Count; for (int i = 0; i <= this.segments; i++) { float f = (float)i * 3.14159274f * 2f / (float)this.segments; TreeVertex treeVertex = new TreeVertex(); float num = this.radius; float num2 = 1f - (float)i / (float)this.segments; float num3 = this.baseOffset; float num4 = num2; float num5 = num3; if (i == this.segments) { num4 = 1f; } float num6 = Mathf.Cos(f); float num7; if (num6 > 0f) { num7 = Mathf.Pow(num6, 3f) * this.radius * this.spreadBot; } else { num7 = Mathf.Pow(Mathf.Abs(num6), 3f) * this.radius * this.spreadTop; } float x = num4 * this.noiseScaleU; float y = num5 * this.noiseScaleV; num += this.radius * (RingLoop.perlin.Noise(x, y) * this.noiseScale); x = num4 * this.flareNoise; num += this.flareRadius * Mathf.Abs(RingLoop.perlin.Noise(x, 0.12932f)); treeVertex.pos = this.matrix.MultiplyPoint(new Vector3(Mathf.Sin(f) * (num + num7 * 0.25f), 0f, Mathf.Cos(f) * (num + num7))); treeVertex.uv0 = new Vector2(num2, num3); treeVertex.SetAnimationProperties(this.animParams.x, this.animParams.y, this.animParams.z, this.animParams.w); verts.Add(treeVertex); } if (this.radius == 0f) { for (int j = 0; j <= this.segments; j++) { TreeVertex treeVertex2 = verts[j + this.vertOffset]; float num8 = (float)j * 3.14159274f * 2f / (float)this.segments; float f2 = num8 - 1.57079637f; Vector3 zero = Vector3.zero; zero.x = Mathf.Sin(num8) * this.surfAngleCos; zero.y = this.surfAngleSin; zero.z = Mathf.Cos(num8) * this.surfAngleCos; treeVertex2.nor = Vector3.Normalize(this.matrix.MultiplyVector(zero)); Vector3 v = Vector3.zero; v.x = Mathf.Sin(f2); v.y = 0f; v.z = Mathf.Cos(f2); v = Vector3.Normalize(this.matrix.MultiplyVector(v)); treeVertex2.tangent = new Vector4(v.x, v.y, v.z, -1f); } return; } Matrix4x4 inverse = this.matrix.inverse; for (int k = 0; k <= this.segments; k++) { int num9 = k - 1; if (num9 < 0) { num9 = this.segments - 1; } int num10 = k + 1; if (num10 > this.segments) { num10 = 1; } TreeVertex treeVertex3 = verts[num9 + this.vertOffset]; TreeVertex treeVertex4 = verts[num10 + this.vertOffset]; TreeVertex treeVertex5 = verts[k + this.vertOffset]; Vector3 vector = Vector3.Normalize(treeVertex3.pos - treeVertex4.pos); Vector3 v2 = inverse.MultiplyVector(treeVertex3.pos - treeVertex4.pos); v2.y = v2.x; v2.x = v2.z; v2.z = -v2.y; v2.y = 0f; v2.Normalize(); v2.x = this.surfAngleCos * v2.x; v2.y = this.surfAngleSin; v2.z = this.surfAngleCos * v2.z; treeVertex5.nor = Vector3.Normalize(this.matrix.MultiplyVector(v2)); treeVertex5.tangent.x = vector.x; treeVertex5.tangent.y = vector.y; treeVertex5.tangent.z = vector.z; treeVertex5.tangent.w = -1f; } }
public void BuildVertices(List<TreeVertex> verts) { this.vertOffset = verts.Count; for (int i = 0; i <= this.segments; i++) { float f = ((i * 3.141593f) * 2f) / ((float) this.segments); TreeVertex item = new TreeVertex(); float radius = this.radius; float x = 1f - (((float) i) / ((float) this.segments)); float baseOffset = this.baseOffset; float num6 = x; float num7 = baseOffset; if (i == this.segments) { num6 = 1f; } float num8 = Mathf.Cos(f); float num9 = 0f; if (num8 > 0f) { num9 = (Mathf.Pow(num8, 3f) * this.radius) * this.spreadBot; } else { num9 = (Mathf.Pow(Mathf.Abs(num8), 3f) * this.radius) * this.spreadTop; } float num10 = num6 * this.noiseScaleU; float y = num7 * this.noiseScaleV; radius += this.radius * (perlin.Noise(num10, y) * this.noiseScale); num10 = num6 * this.flareNoise; radius += this.flareRadius * Mathf.Abs(perlin.Noise(num10, 0.12932f)); item.pos = this.matrix.MultiplyPoint(new Vector3(Mathf.Sin(f) * (radius + (num9 * 0.25f)), 0f, Mathf.Cos(f) * (radius + num9))); item.uv0 = new Vector2(x, baseOffset); item.SetAnimationProperties(this.animParams.x, this.animParams.y, this.animParams.z, this.animParams.w); verts.Add(item); } if (this.radius == 0f) { for (int j = 0; j <= this.segments; j++) { TreeVertex vertex2 = verts[j + this.vertOffset]; float num13 = ((j * 3.141593f) * 2f) / ((float) this.segments); float num14 = num13 - 1.570796f; Vector3 zero = Vector3.zero; zero.x = Mathf.Sin(num13) * this.surfAngleCos; zero.y = this.surfAngleSin; zero.z = Mathf.Cos(num13) * this.surfAngleCos; vertex2.nor = Vector3.Normalize(this.matrix.MultiplyVector(zero)); Vector3 v = Vector3.zero; v.x = Mathf.Sin(num14); v.y = 0f; v.z = Mathf.Cos(num14); v = Vector3.Normalize(this.matrix.MultiplyVector(v)); vertex2.tangent = new Vector4(v.x, v.y, v.z, -1f); } } else { Matrix4x4 inverse = this.matrix.inverse; for (int k = 0; k <= this.segments; k++) { int num16 = k - 1; if (num16 < 0) { num16 = this.segments - 1; } int num17 = k + 1; if (num17 > this.segments) { num17 = 1; } TreeVertex vertex3 = verts[num16 + this.vertOffset]; TreeVertex vertex4 = verts[num17 + this.vertOffset]; TreeVertex vertex5 = verts[k + this.vertOffset]; Vector3 vector3 = Vector3.Normalize(vertex3.pos - vertex4.pos); Vector3 vector4 = inverse.MultiplyVector(vertex3.pos - vertex4.pos); vector4.y = vector4.x; vector4.x = vector4.z; vector4.z = -vector4.y; vector4.y = 0f; vector4.Normalize(); vector4.x = this.surfAngleCos * vector4.x; vector4.y = this.surfAngleSin; vector4.z = this.surfAngleCos * vector4.z; vertex5.nor = Vector3.Normalize(this.matrix.MultiplyVector(vector4)); vertex5.tangent.x = vector3.x; vertex5.tangent.y = vector3.y; vertex5.tangent.z = vector3.z; vertex5.tangent.w = -1f; } } }
public void Cap(float sphereFactor, float noise, int mappingMode, float mappingScale, List <TreeVertex> verts, List <TreeTriangle> tris, int materialIndex) { int num = Mathf.Max(1, (int)((this.segments / 2) * Mathf.Clamp01(sphereFactor))); int segments = this.segments; int num3 = num; if (mappingMode == 1) { segments++; num3++; mappingScale /= Mathf.Max(1f, sphereFactor); } int count = verts.Count; Vector3 vector = Vector3.Normalize(this.matrix.MultiplyVector(Vector3.up)); Vector3 vector2 = this.matrix.MultiplyPoint(Vector3.zero); TreeVertex item = new TreeVertex { nor = vector }; item.pos = vector2 + ((Vector3)((item.nor * sphereFactor) * this.radius)); Vector3 vector3 = Vector3.Normalize(this.matrix.MultiplyVector(Vector3.right)); item.tangent = new Vector4(vector3.x, vector3.y, vector3.z, -1f); item.SetAnimationProperties(this.animParams.x, this.animParams.y, this.animParams.z, this.animParams.w); if (mappingMode == 0) { item.uv0 = new Vector2(0.5f, 0.5f); } else { item.uv0 = new Vector2(0.5f, this.baseOffset + (sphereFactor * mappingScale)); } verts.Add(item); int num5 = verts.Count; Matrix4x4 inverse = this.matrix.inverse; for (int i = 0; i < num3; i++) { float f = ((1f - (((float)i) / ((float)num))) * 3.141593f) * 0.5f; float num8 = Mathf.Sin(f); float num9 = num8; float num10 = (num8 * Mathf.Clamp01(sphereFactor)) + ((num8 * 0.5f) * Mathf.Clamp01(1f - sphereFactor)); float num11 = Mathf.Cos(f); for (int m = 0; m < segments; m++) { TreeVertex vertex2 = verts[this.vertOffset + m]; Vector3 vector4 = (Vector3)((inverse.MultiplyPoint(vertex2.pos).normalized * 0.5f) * num8); TreeVertex vertex3 = new TreeVertex { pos = (Vector3)(((vertex2.pos * num9) + (vector2 * (1f - num9))) + (((vector * num11) * sphereFactor) * this.radius)) }; Vector3 vector6 = (Vector3)((vertex2.nor * num10) + (vector * (1f - num10))); vertex3.nor = vector6.normalized; vertex3.SetAnimationProperties(this.animParams.x, this.animParams.y, this.animParams.z, this.animParams.w); if (mappingMode == 0) { vertex3.tangent = item.tangent; vertex3.uv0 = new Vector2(0.5f + vector4.x, 0.5f + vector4.z); } else { vertex3.tangent = vertex2.tangent; vertex3.uv0 = new Vector2(((float)m) / ((float)this.segments), this.baseOffset + ((sphereFactor * num11) * mappingScale)); } verts.Add(vertex3); } } float num13 = 3f; for (int j = this.vertOffset; j < verts.Count; j++) { float x = verts[j].pos.x * num13; float y = verts[j].pos.z * num13; float num17 = this.radius * (perlin.Noise(x, y) * noise); TreeVertex local1 = verts[j]; local1.pos += (Vector3)(item.nor * num17); } for (int k = 0; k < num; k++) { for (int n = 0; n < segments; n++) { if (k == (num3 - 1)) { int num20 = (n + num5) + (segments * k); int num21 = num20 + 1; if (n == (segments - 1)) { num21 = num5 + (segments * k); } tris.Add(new TreeTriangle(materialIndex, count, num20, num21, false, false, false)); } else { int num22 = (n + num5) + (segments * k); int num23 = num22 + 1; int num24 = (n + num5) + (segments * (k + 1)); int num25 = num24 + 1; if (n == (segments - 1)) { num23 = num5 + (segments * k); num25 = num5 + (segments * (k + 1)); } tris.Add(new TreeTriangle(materialIndex, num22, num23, num25, false, false, false)); tris.Add(new TreeTriangle(materialIndex, num22, num25, num24, false, false, false)); } } } }