public TreeNode() { this.spline = null; this.parentID = 0; this.groupID = 0; this.parent = null; this.group = null; this.seed = 1234; this.breakOffset = 1f; this.visible = true; this.animSeed = 0f; this.scale = 1f; this.rotation = Quaternion.identity; this.matrix = Matrix4x4.identity; }
private static TreeVertex CreateBillboardVertex(TreeNode node, Quaternion billboardRotation, Vector3 normalBase, float normalFix, Vector3 tangentBase, Vector2 uv) { TreeVertex vertex = new TreeVertex { pos = node.matrix.MultiplyPoint(Vector3.zero), uv0 = uv }; uv = ((Vector2) (2f * uv)) - Vector2.one; vertex.nor = (Vector3) (billboardRotation * new Vector3(uv.x * node.scale, uv.y * node.scale, 0f)); vertex.nor.z = normalFix; Vector3 vector2 = (Vector3) (billboardRotation * new Vector3(uv.x * normalBase.x, uv.y * normalBase.y, normalBase.z)); Vector3 normalized = vector2.normalized; Vector3 vector3 = tangentBase - ((Vector3) (normalized * Vector3.Dot(tangentBase, normalized))); vertex.tangent = vector3.normalized; vertex.tangent.w = 0f; return vertex; }
public TreeNode AddNode(TreeGroup g, TreeNode parent, bool validate) { if (g == null) { return null; } TreeNode n = new TreeNode { uniqueID = this._uniqueID }; this._uniqueID++; this.SetNodeParent(n, parent); n.groupID = g.uniqueID; n.group = g; g.nodeIDs = this.ArrayAdd(g.nodeIDs, n.uniqueID); g.nodes.Add(n); this.nodes = this.ArrayAdd(this.nodes, n); if (validate) { this.ValidateReferences(); } return n; }
private void DuplicateSelected(TreeData treeData) { this.UndoStoreSelected(EditMode.Duplicate); if (s_SelectedNode != null) { s_SelectedNode = treeData.DuplicateNode(s_SelectedNode); s_SelectedGroup.Lock(); } else { this.SelectGroup(treeData.DuplicateGroup(s_SelectedGroup)); } this.m_WantCompleteUpdate = true; UpdateMesh(base.target as Tree); this.m_WantCompleteUpdate = false; }
private Bounds CalcBounds(TreeData treeData, Matrix4x4 objMatrix, TreeNode node) { Matrix4x4 matrixx = objMatrix * node.matrix; if (((treeData.GetGroup(node.groupID).GetType() == typeof(TreeGroupBranch)) && (node.spline != null)) && (node.spline.nodes.Length > 0)) { Bounds bounds = new Bounds(matrixx.MultiplyPoint(node.spline.nodes[0].point), Vector3.zero); for (int i = 1; i < node.spline.nodes.Length; i++) { bounds.Encapsulate(matrixx.MultiplyPoint(node.spline.nodes[i].point)); } return bounds; } return new Bounds(matrixx.MultiplyPoint(Vector3.zero), Vector3.zero); }
private void UpdateNodeMesh(TreeNode node, List<TreeMaterial> materials, List<TreeVertex> verts, List<TreeTriangle> tris, List<TreeAOSphere> aoSpheres, int buildFlags, float adaptiveQuality, float aoDensity) { node.triStart = tris.Count; node.triEnd = tris.Count; node.vertStart = verts.Count; node.vertEnd = verts.Count; if (!node.visible || !this.visible) { return; } Profiler.BeginSample("TreeGroupBranch.UpdateNodeMesh"); int count = verts.Count; float approximateLength = node.spline.GetApproximateLength(); List<RingLoop> list = new List<RingLoop>(); float adaptiveQuality2 = Mathf.Clamp01(adaptiveQuality * this.lodQualityMultiplier); List<float> adaptiveSamples = TreeData.GetAdaptiveSamples(this, node, adaptiveQuality2); int adaptiveRadialSegments = TreeData.GetAdaptiveRadialSegments(this.radius, adaptiveQuality2); TreeGroupBranch treeGroupBranch = null; if (this.parentGroup != null && this.parentGroup.GetType() == typeof(TreeGroupBranch)) { treeGroupBranch = (TreeGroupBranch)this.parentGroup; } if (this.geometryMode == TreeGroupBranch.GeometryMode.BranchFrond || this.geometryMode == TreeGroupBranch.GeometryMode.Branch) { int materialIndex = TreeGroup.GetMaterialIndex(this.materialBranch, materials, true); float num = 0f; float num2 = 0f; float num3 = approximateLength / (this.GetRadiusAtTime(node, 0f, false) * 3.14159274f * 2f); bool flag = true; if (node.parent != null && treeGroupBranch != null) { num2 = node.offset * node.parent.spline.GetApproximateLength(); } float num4 = 1f - node.capRange; for (int i = 0; i < adaptiveSamples.Count; i++) { float num5 = adaptiveSamples[i]; Vector3 positionAtTime = node.spline.GetPositionAtTime(num5); Quaternion rotationAtTime = node.spline.GetRotationAtTime(num5); float radiusAtTime = this.GetRadiusAtTime(node, num5, false); Matrix4x4 m = node.matrix * Matrix4x4.TRS(positionAtTime, rotationAtTime, new Vector3(1f, 1f, 1f)); Vector3 flareWeldAtTime = this.GetFlareWeldAtTime(node, num5); float num6 = Mathf.Max(flareWeldAtTime.x, Mathf.Max(flareWeldAtTime.y, flareWeldAtTime.z) * 0.25f); if (num5 <= num4) { adaptiveRadialSegments = TreeData.GetAdaptiveRadialSegments(radiusAtTime + num6, adaptiveQuality2); } if (flag) { if (i > 0) { float num7 = adaptiveSamples[i - 1]; float num8 = num5 - num7; float num9 = (radiusAtTime + this.GetRadiusAtTime(node, num7, false)) * 0.5f; num += num8 * approximateLength / (num9 * 3.14159274f * 2f); } } else { num = num2 + num5 * num3; } Vector2 vector = base.ComputeWindFactor(node, num5); RingLoop ringLoop = new RingLoop(); ringLoop.Reset(radiusAtTime, m, num, adaptiveRadialSegments); ringLoop.SetSurfaceAngle(node.GetSurfaceAngleAtTime(num5)); ringLoop.SetAnimationProperties(vector.x, vector.y, 0f, node.animSeed); ringLoop.SetSpread(flareWeldAtTime.y, flareWeldAtTime.z); ringLoop.SetNoise(this.noise * Mathf.Clamp01(this.noiseCurve.Evaluate(num5)), this.noiseScaleU * 10f, this.noiseScaleV * 10f); ringLoop.SetFlares(flareWeldAtTime.x, this.flareNoise * 10f); int count2 = verts.Count; ringLoop.BuildVertices(verts); int count3 = verts.Count; if ((buildFlags & 2) != 0) { float num10 = this.weldHeight; float num11 = Mathf.Pow(Mathf.Clamp01((1f - num5 - (1f - this.weldHeight)) / this.weldHeight), 1.5f); float d = 1f - num11; if (num5 < num10 && node.parent != null && node.parent.spline != null) { Ray ray = default(Ray); for (int j = count2; j < count3; j++) { ray.origin = verts[j].pos; ray.direction = m.MultiplyVector(-Vector3.up); Vector3 pos = verts[j].pos; Vector3 nor = verts[j].nor; float num12 = -10000f; float num13 = 100000f; for (int k = node.parent.triStart; k < node.parent.triEnd; k++) { object obj = MathUtils.IntersectRayTriangle(ray, verts[tris[k].v[0]].pos, verts[tris[k].v[1]].pos, verts[tris[k].v[2]].pos, true); if (obj != null) { RaycastHit raycastHit = (RaycastHit)obj; if (Mathf.Abs(raycastHit.distance) < num13 && raycastHit.distance > num12) { num13 = Mathf.Abs(raycastHit.distance); verts[j].nor = verts[tris[k].v[0]].nor * raycastHit.barycentricCoordinate.x + verts[tris[k].v[1]].nor * raycastHit.barycentricCoordinate.y + verts[tris[k].v[2]].nor * raycastHit.barycentricCoordinate.z; verts[j].nor = verts[j].nor * num11 + nor * d; verts[j].pos = raycastHit.point * num11 + pos * d; } } } } } } list.Add(ringLoop); if (num5 == 1f && ringLoop.radius > 0.005f) { RingLoop ringLoop2 = ringLoop.Clone(); ringLoop2.radius = 0f; ringLoop2.baseOffset += radiusAtTime / 6.28318548f; ringLoop2.BuildVertices(verts); list.Add(ringLoop2); } } if (list.Count > 0 && list[list.Count - 1].radius > 0.025f && node.breakOffset < 1f) { float mappingScale = 1f / (this.radius * 3.14159274f * 2f); float sphereFactor = 0f; float num14 = 1f; int mappingMode = 0; Material m2 = this.materialBranch; if (this.materialBreak != null) { m2 = this.materialBreak; } int materialIndex2 = TreeGroup.GetMaterialIndex(m2, materials, false); list[list.Count - 1].Cap(sphereFactor, num14, mappingMode, mappingScale, verts, tris, materialIndex2); } node.triStart = tris.Count; for (int l = 0; l < list.Count - 1; l++) { list[l].Connect(list[l + 1], tris, materialIndex, false, false); } node.triEnd = tris.Count; list.Clear(); } float num15 = Mathf.Min(this.frondRange.x, this.frondRange.y); float num16 = Mathf.Max(this.frondRange.x, this.frondRange.y); float num17 = num15; float num18 = num16; num15 = Mathf.Clamp(num15, 0f, node.breakOffset); num16 = Mathf.Clamp(num16, 0f, node.breakOffset); if ((this.geometryMode == TreeGroupBranch.GeometryMode.BranchFrond || this.geometryMode == TreeGroupBranch.GeometryMode.Frond) && this.frondCount > 0 && num15 != num16) { bool flag2 = true; bool flag3 = true; for (int n = 0; n < adaptiveSamples.Count; n++) { float num19 = adaptiveSamples[n]; if (num19 < num15) { adaptiveSamples.RemoveAt(n); n--; } else { if (num19 == num15) { flag2 = false; } else { if (num19 == num16) { flag3 = false; } else { if (num19 > num16) { adaptiveSamples.RemoveAt(n); n--; } } } } } if (flag2) { adaptiveSamples.Insert(0, num15); } if (flag3) { adaptiveSamples.Add(num16); } int materialIndex3 = TreeGroup.GetMaterialIndex(this.materialFrond, materials, false); float num20 = 1f - node.capRange; for (int num21 = 0; num21 < this.frondCount; num21++) { float num22 = this.frondCrease * 90f * 0.0174532924f; float num23 = (this.frondRotation * 360f + (float)num21 * 180f / (float)this.frondCount - 90f) * 0.0174532924f; float f = -num23 - num22; float f2 = num23 - num22; Vector3 a = new Vector3(Mathf.Sin(f), 0f, Mathf.Cos(f)); Vector3 vector2 = new Vector3(a.z, 0f, -a.x); Vector3 a2 = new Vector3(Mathf.Sin(f2), 0f, -Mathf.Cos(f2)); Vector3 vector3 = new Vector3(-a2.z, 0f, a2.x); for (int num24 = 0; num24 < adaptiveSamples.Count; num24++) { float num25 = adaptiveSamples[num24]; float y = (num25 - num17) / (num18 - num17); float timeParam = num25; if (num25 > num20) { timeParam = num20; float f3 = Mathf.Acos(Mathf.Clamp01((num25 - num20) / node.capRange)); float num26 = Mathf.Sin(f3); float y2 = Mathf.Cos(f3) * this.capSmoothing; a = new Vector3(Mathf.Sin(f) * num26, y2, Mathf.Cos(f) * num26); vector2 = new Vector3(a.z, a.y, -a.x); a2 = new Vector3(Mathf.Sin(f2) * num26, y2, -Mathf.Cos(f2) * num26); vector3 = new Vector3(-a2.z, a2.y, a2.x); } Vector3 a3 = new Vector3(0f, 0f, -1f); Vector3 positionAtTime2 = node.spline.GetPositionAtTime(timeParam); Quaternion rotationAtTime2 = node.spline.GetRotationAtTime(num25); float d2 = Mathf.Clamp01(this.frondCurve.Evaluate(num25)) * this.frondWidth * node.GetScale(); Matrix4x4 matrix4x = node.matrix * Matrix4x4.TRS(positionAtTime2, rotationAtTime2, new Vector3(1f, 1f, 1f)); if (TreeGroup.GenerateDoubleSidedGeometry) { for (float num27 = -1f; num27 < 2f; num27 += 2f) { TreeVertex treeVertex = new TreeVertex(); treeVertex.pos = matrix4x.MultiplyPoint(a * d2); treeVertex.nor = matrix4x.MultiplyVector(vector2 * num27).normalized; treeVertex.tangent = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex.nor); treeVertex.tangent.w = -num27; treeVertex.uv0 = new Vector2(1f, y); TreeVertex treeVertex2 = new TreeVertex(); treeVertex2.pos = matrix4x.MultiplyPoint(Vector3.zero); treeVertex2.nor = matrix4x.MultiplyVector(a3 * num27).normalized; treeVertex2.tangent = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex2.nor); treeVertex2.tangent.w = -num27; treeVertex2.uv0 = new Vector2(0.5f, y); TreeVertex treeVertex3 = new TreeVertex(); treeVertex3.pos = matrix4x.MultiplyPoint(Vector3.zero); treeVertex3.nor = matrix4x.MultiplyVector(a3 * num27).normalized; treeVertex3.tangent = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex3.nor); treeVertex3.tangent.w = -num27; treeVertex3.uv0 = new Vector2(0.5f, y); TreeVertex treeVertex4 = new TreeVertex(); treeVertex4.pos = matrix4x.MultiplyPoint(a2 * d2); treeVertex4.nor = matrix4x.MultiplyVector(vector3 * num27).normalized; treeVertex4.tangent = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex4.nor); treeVertex4.tangent.w = -num27; treeVertex4.uv0 = new Vector2(0f, y); Vector2 vector4 = base.ComputeWindFactor(node, num25); treeVertex.SetAnimationProperties(vector4.x, vector4.y, this.animationEdge, node.animSeed); treeVertex2.SetAnimationProperties(vector4.x, vector4.y, 0f, node.animSeed); treeVertex3.SetAnimationProperties(vector4.x, vector4.y, 0f, node.animSeed); treeVertex4.SetAnimationProperties(vector4.x, vector4.y, this.animationEdge, node.animSeed); verts.Add(treeVertex); verts.Add(treeVertex2); verts.Add(treeVertex3); verts.Add(treeVertex4); } if (num24 > 0) { int count4 = verts.Count; TreeTriangle treeTriangle = new TreeTriangle(materialIndex3, count4 - 4, count4 - 3, count4 - 11); TreeTriangle treeTriangle2 = new TreeTriangle(materialIndex3, count4 - 4, count4 - 11, count4 - 12); treeTriangle.flip(); treeTriangle2.flip(); TreeTriangle item = new TreeTriangle(materialIndex3, count4 - 8, count4 - 7, count4 - 15); TreeTriangle item2 = new TreeTriangle(materialIndex3, count4 - 8, count4 - 15, count4 - 16); tris.Add(treeTriangle); tris.Add(treeTriangle2); tris.Add(item); tris.Add(item2); TreeTriangle item3 = new TreeTriangle(materialIndex3, count4 - 2, count4 - 9, count4 - 1); TreeTriangle item4 = new TreeTriangle(materialIndex3, count4 - 2, count4 - 10, count4 - 9); TreeTriangle treeTriangle3 = new TreeTriangle(materialIndex3, count4 - 6, count4 - 13, count4 - 5); TreeTriangle treeTriangle4 = new TreeTriangle(materialIndex3, count4 - 6, count4 - 14, count4 - 13); treeTriangle3.flip(); treeTriangle4.flip(); tris.Add(item3); tris.Add(item4); tris.Add(treeTriangle3); tris.Add(treeTriangle4); } } else { TreeVertex treeVertex5 = new TreeVertex(); treeVertex5.pos = matrix4x.MultiplyPoint(a * d2); treeVertex5.nor = matrix4x.MultiplyVector(vector2).normalized; treeVertex5.uv0 = new Vector2(0f, y); TreeVertex treeVertex6 = new TreeVertex(); treeVertex6.pos = matrix4x.MultiplyPoint(Vector3.zero); treeVertex6.nor = matrix4x.MultiplyVector(Vector3.back).normalized; treeVertex6.uv0 = new Vector2(0.5f, y); TreeVertex treeVertex7 = new TreeVertex(); treeVertex7.pos = matrix4x.MultiplyPoint(a2 * d2); treeVertex7.nor = matrix4x.MultiplyVector(vector3).normalized; treeVertex7.uv0 = new Vector2(1f, y); Vector2 vector5 = base.ComputeWindFactor(node, num25); treeVertex5.SetAnimationProperties(vector5.x, vector5.y, this.animationEdge, node.animSeed); treeVertex6.SetAnimationProperties(vector5.x, vector5.y, 0f, node.animSeed); treeVertex7.SetAnimationProperties(vector5.x, vector5.y, this.animationEdge, node.animSeed); verts.Add(treeVertex5); verts.Add(treeVertex6); verts.Add(treeVertex7); if (num24 > 0) { int count5 = verts.Count; TreeTriangle item5 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 3, count5 - 6); TreeTriangle item6 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 6, count5 - 5); tris.Add(item5); tris.Add(item6); TreeTriangle item7 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 4, count5 - 1); TreeTriangle item8 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 5, count5 - 4); tris.Add(item7); tris.Add(item8); } } } } } if ((buildFlags & 1) != 0) { for (int num28 = count; num28 < verts.Count; num28++) { verts[num28].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(verts[num28].pos, verts[num28].nor, aoSpheres, aoDensity)); } } node.vertEnd = verts.Count; Profiler.EndSample(); }
private Vector3 GetFlareWeldAtTime(TreeNode node, float time) { float scale = node.GetScale(); float num = 0f; float num2 = 0f; if (this.flareHeight > 0.001f) { float value = (1f - time - (1f - this.flareHeight)) / this.flareHeight; num = Mathf.Pow(Mathf.Clamp01(value), 1.5f) * scale; } if (this.weldHeight > 0.001f) { float value2 = (1f - time - (1f - this.weldHeight)) / this.weldHeight; num2 = Mathf.Pow(Mathf.Clamp01(value2), 1.5f) * scale; } return new Vector3(num * this.flareSize, num2 * this.weldSpreadTop * TreeGroupBranch.spreadMul, num2 * this.weldSpreadBottom * TreeGroupBranch.spreadMul); }
private void SelectGroup(TreeGroup group) { if (group == null) { Debug.Log("GROUP SELECTION IS NULL!"); } if (this.m_TreeEditorHelper.NodeHasWrongMaterial(group)) { s_ShowCategory = 1; } s_SelectedGroup = group; s_SelectedNode = null; s_SelectedPoint = -1; EditorUtility.SetDirty(this.target); Tree target = this.target as Tree; if (target != null) { EditorUtility.SetSelectedWireframeHidden(target.GetComponent<Renderer>(), !(s_SelectedGroup is TreeGroupRoot)); } }
public TreeNode DuplicateNode(TreeNode n) { TreeGroup group = this.GetGroup(n.groupID); if (group == null) { return null; } TreeNode treeNode = this.AddNode(group, this.GetNode(n.parentID)); this.CopyFields(n, treeNode); return treeNode; }
private Vector3 GetFlareWeldAtTime(TreeNode node, float time) { float scale = node.GetScale(); float num2 = 0f; float num3 = 0f; if (this.flareHeight > 0.001f) { float num4 = ((1f - time) - (1f - this.flareHeight)) / this.flareHeight; num2 = Mathf.Pow(Mathf.Clamp01(num4), 1.5f) * scale; } if (this.weldHeight > 0.001f) { float num5 = ((1f - time) - (1f - this.weldHeight)) / this.weldHeight; num3 = Mathf.Pow(Mathf.Clamp01(num5), 1.5f) * scale; } return new Vector3(num2 * this.flareSize, (num3 * this.weldSpreadTop) * spreadMul, (num3 * this.weldSpreadBottom) * spreadMul); }
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 static TreeVertex CreateBillboardVertex(TreeNode node, Quaternion billboardRotation, Vector3 normalBase, float normalFix, Vector3 tangentBase, Vector2 uv) { TreeVertex treeVertex = new TreeVertex(); treeVertex.pos = node.matrix.MultiplyPoint(Vector3.zero); treeVertex.uv0 = uv; uv = 2f * uv - Vector2.one; treeVertex.nor = billboardRotation * new Vector3(uv.x * node.scale, uv.y * node.scale, 0f); treeVertex.nor.z = normalFix; Vector3 normalized = (billboardRotation * new Vector3(uv.x * normalBase.x, uv.y * normalBase.y, normalBase.z)).normalized; treeVertex.tangent = (tangentBase - normalized * Vector3.Dot(tangentBase, normalized)).normalized; treeVertex.tangent.w = 0f; return treeVertex; }
public virtual float GetRadiusAtTime(TreeNode node, float t, bool includeModifications) { return 0f; }
protected static Vector4 CreateTangent(TreeNode node, Quaternion rot, Vector3 normal) { Vector3 lhs = node.matrix.MultiplyVector((Vector3) (rot * new Vector3(1f, 0f, 0f))); lhs -= (Vector3) (normal * Vector3.Dot(lhs, normal)); lhs.Normalize(); return new Vector4(lhs.x, lhs.y, lhs.z, 1f); }
public Vector2 ComputeWindFactor(TreeNode node, float offset) { Vector2 vector; if (node.group.parentGroup.GetType() == typeof(TreeGroupRoot)) { vector = new Vector2(0f, 0f); } else { vector = node.parent.group.ComputeWindFactor(node.parent, node.offset); } float scale = node.GetScale(); vector.x += (((offset * offset) * offset) * scale) * this.animationPrimary; vector.y += ((offset * offset) * scale) * this.animationSecondary; return vector; }
public void DeleteNode(TreeNode n) { this.DeleteNode(n, true); }
public void DeleteNode(TreeNode n, bool validate) { TreeGroup group = this.GetGroup(n.groupID); if (group != null) { group.nodeIDs = this.ArrayRemove(group.nodeIDs, n.uniqueID); group.nodes.Remove(n); for (int i = 0; i < group.childGroups.Count; i++) { TreeGroup treeGroup = group.childGroups[i]; for (int j = treeGroup.nodes.Count - 1; j >= 0; j--) { if (treeGroup.nodes[j] != null && treeGroup.nodes[j].parentID == n.uniqueID) { this.DeleteNode(treeGroup.nodes[j], false); } } } } n.group = null; n.groupID = 0; n.parent = null; n.parentID = 0; this.nodes = this.ArrayRemove(this.nodes, n); if (validate) { this.ValidateReferences(); } }
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; } }
public static List<float> GetAdaptiveSamples(TreeGroup group, TreeNode node, float adaptiveQuality) { List<float> list = new List<float>(); if (node.spline == null) { return list; } float num = 1f - node.capRange; SplineNode[] array = node.spline.GetNodes(); for (int i = 0; i < array.Length; i++) { if (array[i].time >= node.breakOffset) { list.Add(node.breakOffset); break; } if (array[i].time > num) { list.Add(num); break; } list.Add(array[i].time); } list.Sort(); if (list.Count < 2) { return list; } float num2 = 1f; if (group.GetType() == typeof(TreeGroupBranch)) { num2 = ((TreeGroupBranch)group).radius; } float num3 = Mathf.Lerp(0.999f, 0.99999f, adaptiveQuality); float num4 = Mathf.Lerp(0.5f, 0.985f, adaptiveQuality); float num5 = Mathf.Lerp(0.3f * num2, 0.1f * num2, adaptiveQuality); int num6 = 200; int j = 0; while (j < list.Count - 1) { for (int k = j; k < list.Count - 1; k++) { Quaternion rotationAtTime = node.spline.GetRotationAtTime(list[k]); Quaternion rotationAtTime2 = node.spline.GetRotationAtTime(list[k + 1]); Vector3 lhs = rotationAtTime * Vector3.up; Vector3 rhs = rotationAtTime2 * Vector3.up; Vector3 lhs2 = rotationAtTime * Vector3.right; Vector3 rhs2 = rotationAtTime2 * Vector3.right; Vector3 lhs3 = rotationAtTime * Vector3.forward; Vector3 rhs3 = rotationAtTime2 * Vector3.forward; float radiusAtTime = group.GetRadiusAtTime(node, list[k], true); float radiusAtTime2 = group.GetRadiusAtTime(node, list[k + 1], true); bool flag = false; if (Vector3.Dot(lhs, rhs) < num4) { flag = true; } if (Vector3.Dot(lhs2, rhs2) < num4) { flag = true; } if (Vector3.Dot(lhs3, rhs3) < num4) { flag = true; } if (Mathf.Abs(radiusAtTime - radiusAtTime2) > num5) { flag = true; } if (flag) { num6--; if (num6 > 0) { float item = (list[k] + list[k + 1]) * 0.5f; list.Insert(k + 1, item); break; } } j = k + 1; } } for (int l = 0; l < list.Count - 2; l++) { Vector3 positionAtTime = node.spline.GetPositionAtTime(list[l]); Vector3 positionAtTime2 = node.spline.GetPositionAtTime(list[l + 1]); Vector3 positionAtTime3 = node.spline.GetPositionAtTime(list[l + 2]); float radiusAtTime3 = group.GetRadiusAtTime(node, list[l], true); float radiusAtTime4 = group.GetRadiusAtTime(node, list[l + 1], true); float radiusAtTime5 = group.GetRadiusAtTime(node, list[l + 2], true); Vector3 normalized = (positionAtTime2 - positionAtTime).normalized; Vector3 normalized2 = (positionAtTime3 - positionAtTime).normalized; bool flag2 = false; if (Vector3.Dot(normalized, normalized2) >= num3) { flag2 = true; } if (Mathf.Abs(radiusAtTime3 - radiusAtTime4) > num5) { flag2 = false; } if (Mathf.Abs(radiusAtTime4 - radiusAtTime5) > num5) { flag2 = false; } if (flag2) { list.RemoveAt(l + 1); l--; } } if (node.capRange > 0f) { int num7 = 1 + Mathf.CeilToInt(node.capRange * 16f * adaptiveQuality); for (int m = 0; m < num7; m++) { float f = (float)(m + 1) / (float)num7 * 3.14159274f * 0.5f; float num8 = Mathf.Sin(f); float num9 = num + node.capRange * num8; if (num9 < node.breakOffset) { list.Add(num9); } } list.Sort(); } if (1f <= node.breakOffset) { if (list[list.Count - 1] < 1f) { list.Add(1f); } else { list[list.Count - 1] = 1f; } } return list; }
public void UpdateSpline(TreeNode node) { if (base.lockFlags == 0) { UnityEngine.Random.InitState(node.seed); if (node.spline == null) { TreeSpline spline = new TreeSpline(); node.spline = spline; } float num = this.height.y * node.GetScale(); float num2 = 1f; int num3 = (int) Mathf.Round(num / num2); float num4 = 0f; Quaternion identity = Quaternion.identity; Vector3 pos = new Vector3(0f, 0f, 0f); Matrix4x4 matrixx2 = node.matrix * base.GetRootMatrix(); Matrix4x4 inverse = matrixx2.inverse; Quaternion b = MathUtils.QuaternionFromMatrix(inverse) * Quaternion.Euler(0f, node.angle, 0f); Quaternion quaternion3 = MathUtils.QuaternionFromMatrix(inverse) * Quaternion.Euler(-180f, node.angle, 0f); node.spline.Reset(); node.spline.AddPoint(pos, 0f); for (int i = 0; i < num3; i++) { float y = num2; if (i == (num3 - 1)) { y = num - num4; } num4 += y; float time = num4 / num; float num8 = Mathf.Clamp(this.seekCurve.Evaluate(time), -1f, 1f); float t = Mathf.Clamp01(num8) * this.seekBlend; float num10 = Mathf.Clamp01(-num8) * this.seekBlend; identity = Quaternion.Slerp(Quaternion.Slerp(identity, b, t), quaternion3, num10); float num11 = this.crinklyness * Mathf.Clamp01(this.crinkCurve.Evaluate(time)); Quaternion quaternion4 = Quaternion.Euler(new Vector3(180f * (UnityEngine.Random.value - 0.5f), node.angle, 180f * (UnityEngine.Random.value - 0.5f))); identity = Quaternion.Slerp(identity, quaternion4, num11); pos += identity * new Vector3(0f, y, 0f); node.spline.AddPoint(pos, time); } node.spline.UpdateTime(); node.spline.UpdateRotations(); } }
private void SelectNode(TreeNode node, TreeData treeData) { this.SelectGroup((node != null) ? treeData.GetGroup(node.groupID) : treeData.root); s_SelectedNode = node; s_SelectedPoint = -1; }
private TreeNode[] ArrayAdd(TreeNode[] array, TreeNode value) { return new List<TreeNode>(array) { value }.ToArray(); }
public override float GetRadiusAtTime(TreeNode node, float time, bool includeModifications) { if (this.geometryMode == TreeGroupBranch.GeometryMode.Frond) { return 0f; } float num = Mathf.Clamp01(this.radiusCurve.Evaluate(time)) * node.size; float num2 = 1f - node.capRange; if (time > num2) { float f = Mathf.Acos(Mathf.Clamp01((time - num2) / node.capRange)); float num3 = Mathf.Sin(f); num *= num3; } if (includeModifications) { Vector3 flareWeldAtTime = this.GetFlareWeldAtTime(node, time); num += Mathf.Max(flareWeldAtTime.x, Mathf.Max(flareWeldAtTime.y, flareWeldAtTime.z) * 0.25f) * 0.1f; } return num; }
private TreeNode[] ArrayRemove(TreeNode[] array, TreeNode value) { List<TreeNode> list = new List<TreeNode>(array); list.Remove(value); return list.ToArray(); }
public void UpdateSpline(TreeNode node) { if (this.lockFlags != 0) { return; } UnityEngine.Random.seed = node.seed; if (node.spline == null) { TreeSpline spline = new TreeSpline(); node.spline = spline; } float num = this.height.y * node.GetScale(); float num2 = 1f; int num3 = (int)Mathf.Round(num / num2); float num4 = 0f; Quaternion quaternion = Quaternion.identity; Vector3 vector = new Vector3(0f, 0f, 0f); Matrix4x4 inverse = (node.matrix * base.GetRootMatrix()).inverse; Quaternion to = MathUtils.QuaternionFromMatrix(inverse) * Quaternion.Euler(0f, node.angle, 0f); Quaternion to2 = MathUtils.QuaternionFromMatrix(inverse) * Quaternion.Euler(-180f, node.angle, 0f); node.spline.Reset(); node.spline.AddPoint(vector, 0f); for (int i = 0; i < num3; i++) { float num5 = num2; if (i == num3 - 1) { num5 = num - num4; } num4 += num5; float num6 = num4 / num; float num7 = Mathf.Clamp(this.seekCurve.Evaluate(num6), -1f, 1f); float t = Mathf.Clamp01(num7) * this.seekBlend; float t2 = Mathf.Clamp01(-num7) * this.seekBlend; quaternion = Quaternion.Slerp(quaternion, to, t); quaternion = Quaternion.Slerp(quaternion, to2, t2); float t3 = this.crinklyness * Mathf.Clamp01(this.crinkCurve.Evaluate(num6)); Quaternion to3 = Quaternion.Euler(new Vector3(180f * (UnityEngine.Random.value - 0.5f), node.angle, 180f * (UnityEngine.Random.value - 0.5f))); quaternion = Quaternion.Slerp(quaternion, to3, t3); vector += quaternion * new Vector3(0f, num5, 0f); node.spline.AddPoint(vector, num6); } node.spline.UpdateTime(); node.spline.UpdateRotations(); }
public TreeNode AddNode(TreeGroup g, TreeNode parent) { return this.AddNode(g, parent, true); }
private void DeleteSelected(TreeData treeData) { this.UndoStoreSelected(EditMode.Delete); if (s_SelectedNode != null) { if (s_SelectedPoint >= 1) { if (s_SelectedNode.spline.nodes.Length > 2) { if (s_SelectedGroup.lockFlags == 0) { s_SelectedGroup.Lock(); } s_SelectedNode.spline.RemoveNode(s_SelectedPoint); s_SelectedPoint = Mathf.Max(s_SelectedPoint - 1, 0); } } else { if ((s_SelectedGroup != null) && (s_SelectedGroup.nodeIDs.Length == 1)) { s_SelectedNode = null; this.DeleteSelected(treeData); return; } treeData.DeleteNode(s_SelectedNode); s_SelectedGroup.Lock(); this.SelectGroup(s_SelectedGroup); } } else if (s_SelectedGroup != null) { TreeGroup group = treeData.GetGroup(s_SelectedGroup.parentGroupID); if (group == null) { return; } treeData.DeleteGroup(s_SelectedGroup); this.SelectGroup(group); } this.m_WantCompleteUpdate = true; UpdateMesh(base.target as Tree); this.m_WantCompleteUpdate = false; }
public TreeNode AddNode(TreeGroup g, TreeNode parent, bool validate) { if (g == null) { return null; } TreeNode treeNode = new TreeNode(); treeNode.uniqueID = this._uniqueID; this._uniqueID++; this.SetNodeParent(treeNode, parent); treeNode.groupID = g.uniqueID; treeNode.group = g; g.nodeIDs = this.ArrayAdd(g.nodeIDs, treeNode.uniqueID); g.nodes.Add(treeNode); this.nodes = this.ArrayAdd(this.nodes, treeNode); if (validate) { this.ValidateReferences(); } return treeNode; }
private float FindClosestOffset(TreeData data, Matrix4x4 objMatrix, TreeNode node, Ray mouseRay, ref float rotation) { TreeGroup group = data.GetGroup(node.groupID); if (group == null) { return 0f; } if (group.GetType() != typeof(TreeGroupBranch)) { return 0f; } data.ValidateReferences(); Matrix4x4 matrixx = objMatrix * node.matrix; float num2 = 1f / (node.spline.GetNodeCount() * 10f); float time = 0f; float num4 = 1E+07f; Vector3 zero = Vector3.zero; Vector3 closestRay = Vector3.zero; Vector3 vector3 = matrixx.MultiplyPoint(node.spline.GetPositionAtTime(0f)); for (float i = num2; i <= 1f; i += num2) { Vector3 vector4 = matrixx.MultiplyPoint(node.spline.GetPositionAtTime(i)); float squaredDist = 0f; float s = 0f; zero = MathUtils.ClosestPtSegmentRay(vector3, vector4, mouseRay, out squaredDist, out s, out closestRay); if (squaredDist < num4) { time = (i - num2) + (num2 * s); num4 = squaredDist; float radiusAtTime = node.GetRadiusAtTime(time); float t = 0f; if (MathUtils.ClosestPtRaySphere(mouseRay, zero, radiusAtTime, ref t, ref closestRay)) { Matrix4x4 matrixx3 = matrixx * node.GetLocalMatrixAtTime(time); Matrix4x4 inverse = matrixx3.inverse; Vector3 v = closestRay - zero; v = inverse.MultiplyVector(v); rotation = Mathf.Atan2(v.x, v.z) * 57.29578f; } } vector3 = vector4; } data.ClearReferences(); return time; }
public void SetNodeParent(TreeNode n, TreeNode parent) { if (parent != null) { n.parentID = parent.uniqueID; n.parent = parent; } else { n.parentID = 0; n.parent = null; } }