private static void ChangeShaderOnMaterials(TreeData treeData, Shader shader, TreeGroup group, TreeEditorHelper.NodeType nodeType) { if (group is TreeGroupBranch && nodeType == TreeEditorHelper.NodeType.BarkNode) { TreeGroupBranch treeGroupBranch = group as TreeGroupBranch; TreeEditorHelper.ChangeShaderOnMaterial(treeGroupBranch.materialBranch, shader); TreeEditorHelper.ChangeShaderOnMaterial(treeGroupBranch.materialBreak, shader); TreeEditorHelper.ChangeShaderOnMaterial(treeGroupBranch.materialFrond, shader); } else { if (group is TreeGroupLeaf && nodeType == TreeEditorHelper.NodeType.LeafNode) { TreeGroupLeaf treeGroupLeaf = group as TreeGroupLeaf; TreeEditorHelper.ChangeShaderOnMaterial(treeGroupLeaf.materialLeaf, shader); } } int[] childGroupIDs = group.childGroupIDs; for (int i = 0; i < childGroupIDs.Length; i++) { int id = childGroupIDs[i]; TreeGroup group2 = treeData.GetGroup(id); TreeEditorHelper.ChangeShaderOnMaterials(treeData, shader, group2, nodeType); } }
private TreeGroupBranch[] ArrayAdd(TreeGroupBranch[] array, TreeGroupBranch value) { return(new List <TreeGroupBranch>(array) { value }.ToArray()); }
private TreeGroupBranch[] ArrayRemove(TreeGroupBranch[] array, TreeGroupBranch value) { List <TreeGroupBranch> list = new List <TreeGroupBranch>(array); list.Remove(value); return(list.ToArray()); }
private static void GetAllTreeShaders(TreeData treeData, List <string> barkShaders, List <string> leafShaders, TreeGroup group) { if (group is TreeGroupBranch) { TreeGroupBranch treeGroupBranch = group as TreeGroupBranch; TreeEditorHelper.AddShaderFromMaterial(treeGroupBranch.materialBranch, barkShaders, leafShaders); TreeEditorHelper.AddShaderFromMaterial(treeGroupBranch.materialBreak, barkShaders, leafShaders); TreeEditorHelper.AddShaderFromMaterial(treeGroupBranch.materialFrond, barkShaders, leafShaders); } else { if (group is TreeGroupLeaf) { TreeGroupLeaf treeGroupLeaf = group as TreeGroupLeaf; TreeEditorHelper.AddShaderFromMaterial(treeGroupLeaf.materialLeaf, barkShaders, leafShaders); } } int[] childGroupIDs = group.childGroupIDs; for (int i = 0; i < childGroupIDs.Length; i++) { int id = childGroupIDs[i]; TreeGroup group2 = treeData.GetGroup(id); TreeEditorHelper.GetAllTreeShaders(treeData, barkShaders, leafShaders, group2); } }
public TreeGroup AddGroup(TreeGroup parent, Type type) { TreeGroup treeGroup; if (type == typeof(TreeGroupBranch)) { treeGroup = new TreeGroupBranch(); this.branchGroups = this.ArrayAdd(this.branchGroups, treeGroup as TreeGroupBranch); } else { if (type != typeof(TreeGroupLeaf)) { return(null); } treeGroup = new TreeGroupLeaf(); this.leafGroups = this.ArrayAdd(this.leafGroups, treeGroup as TreeGroupLeaf); } treeGroup.uniqueID = this._uniqueID; this._uniqueID++; treeGroup.parentGroupID = 0; treeGroup.distributionFrequency = 1; this.SetGroupParent(treeGroup, parent); return(treeGroup); }
public bool NodeHasWrongMaterial(TreeGroup group) { bool flag = false; if (group is TreeGroupBranch) { TreeGroupBranch branch = group as TreeGroupBranch; flag |= !IsMaterialCorrect(branch.materialBranch); flag |= !IsMaterialCorrect(branch.materialBreak); return(flag | !IsMaterialCorrect(branch.materialFrond)); } if (group is TreeGroupLeaf) { TreeGroupLeaf leaf = group as TreeGroupLeaf; flag |= !IsMaterialCorrect(leaf.materialLeaf); } return(flag); }
public bool NodeHasWrongMaterial(TreeGroup group) { bool result = false; if (group is TreeGroupBranch) { TreeGroupBranch tgb = group as TreeGroupBranch; result |= !IsMaterialCorrect(tgb.materialBranch); result |= !IsMaterialCorrect(tgb.materialBreak); result |= !IsMaterialCorrect(tgb.materialFrond); } else if (group is TreeGroupLeaf) { TreeGroupLeaf tgl = group as TreeGroupLeaf; result |= !IsMaterialCorrect(tgl.materialLeaf); } return(result); }
private static void ChangeShaderOnMaterials(TreeData treeData, Shader shader, TreeGroup group, NodeType nodeType) { if ((group is TreeGroupBranch) && (nodeType == NodeType.BarkNode)) { TreeGroupBranch branch = group as TreeGroupBranch; ChangeShaderOnMaterial(branch.materialBranch, shader); ChangeShaderOnMaterial(branch.materialBreak, shader); ChangeShaderOnMaterial(branch.materialFrond, shader); } else if ((group is TreeGroupLeaf) && (nodeType == NodeType.LeafNode)) { TreeGroupLeaf leaf = group as TreeGroupLeaf; ChangeShaderOnMaterial(leaf.materialLeaf, shader); } foreach (int num in group.childGroupIDs) { TreeGroup group2 = treeData.GetGroup(num); ChangeShaderOnMaterials(treeData, shader, group2, nodeType); } }
private static void GetAllTreeShaders(TreeData treeData, List <string> barkShaders, List <string> leafShaders, TreeGroup group) { if (group is TreeGroupBranch) { TreeGroupBranch branch = group as TreeGroupBranch; AddShaderFromMaterial(branch.materialBranch, barkShaders, leafShaders); AddShaderFromMaterial(branch.materialBreak, barkShaders, leafShaders); AddShaderFromMaterial(branch.materialFrond, barkShaders, leafShaders); } else if (group is TreeGroupLeaf) { TreeGroupLeaf leaf = group as TreeGroupLeaf; AddShaderFromMaterial(leaf.materialLeaf, barkShaders, leafShaders); } foreach (int num in group.childGroupIDs) { TreeGroup group2 = treeData.GetGroup(num); GetAllTreeShaders(treeData, barkShaders, leafShaders, group2); } }
private static void ChangeShaderOnMaterials(TreeData treeData, Shader shader, TreeGroup group, NodeType nodeType) { if (group is TreeGroupBranch && nodeType == NodeType.BarkNode) { TreeGroupBranch tgb = group as TreeGroupBranch; ChangeShaderOnMaterial(tgb.materialBranch, shader); ChangeShaderOnMaterial(tgb.materialBreak, shader); ChangeShaderOnMaterial(tgb.materialFrond, shader); } else if (group is TreeGroupLeaf && nodeType == NodeType.LeafNode) { TreeGroupLeaf tgl = group as TreeGroupLeaf; ChangeShaderOnMaterial(tgl.materialLeaf, shader); } foreach (int id in group.childGroupIDs) { TreeGroup childGroup = treeData.GetGroup(id); ChangeShaderOnMaterials(treeData, shader, childGroup, nodeType); } }
public bool NodeHasWrongMaterial(TreeGroup group) { bool flag = false; if (group is TreeGroupBranch) { TreeGroupBranch treeGroupBranch = group as TreeGroupBranch; flag |= !TreeEditorHelper.IsMaterialCorrect(treeGroupBranch.materialBranch); flag |= !TreeEditorHelper.IsMaterialCorrect(treeGroupBranch.materialBreak); flag |= !TreeEditorHelper.IsMaterialCorrect(treeGroupBranch.materialFrond); } else { if (group is TreeGroupLeaf) { TreeGroupLeaf treeGroupLeaf = group as TreeGroupLeaf; flag |= !TreeEditorHelper.IsMaterialCorrect(treeGroupLeaf.materialLeaf); } } return(flag); }
private static void GetAllTreeShaders(TreeData treeData, List <string> barkShaders, List <string> leafShaders, TreeGroup group) { if (group is TreeGroupBranch) { TreeGroupBranch tgb = group as TreeGroupBranch; AddShaderFromMaterial(tgb.materialBranch, barkShaders, leafShaders); AddShaderFromMaterial(tgb.materialBreak, barkShaders, leafShaders); AddShaderFromMaterial(tgb.materialFrond, barkShaders, leafShaders); } else if (group is TreeGroupLeaf) { TreeGroupLeaf tgl = group as TreeGroupLeaf; AddShaderFromMaterial(tgl.materialLeaf, barkShaders, leafShaders); } foreach (int id in group.childGroupIDs) { TreeGroup childGroup = treeData.GetGroup(id); GetAllTreeShaders(treeData, barkShaders, leafShaders, childGroup); } }
public TreeGroup AddGroup(TreeGroup parent, System.Type type) { TreeGroup g = null; if (type == typeof(TreeGroupBranch)) { g = new TreeGroupBranch(); this.branchGroups = this.ArrayAdd(this.branchGroups, g as TreeGroupBranch); } else if (type == typeof(TreeGroupLeaf)) { g = new TreeGroupLeaf(); this.leafGroups = this.ArrayAdd(this.leafGroups, g as TreeGroupLeaf); } else { return null; } g.uniqueID = this._uniqueID; this._uniqueID++; g.parentGroupID = 0; g.distributionFrequency = 1; this.SetGroupParent(g, parent); return g; }
private TreeGroupBranch[] ArrayAdd(TreeGroupBranch[] array, TreeGroupBranch value) { return new List<TreeGroupBranch>(array) { value }.ToArray(); }
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(); }
private TreeGroupBranch[] ArrayAdd(TreeGroupBranch[] array, TreeGroupBranch value) { List<TreeGroupBranch> list = new List<TreeGroupBranch>(array) { value }; return list.ToArray(); }
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 TreeGroupBranch[] ArrayRemove(TreeGroupBranch[] array, TreeGroupBranch value) { List<TreeGroupBranch> list = new List<TreeGroupBranch>(array); list.Remove(value); return list.ToArray(); }
public TreeGroup AddGroup(TreeGroup parent, Type type) { TreeGroup treeGroup; if (type == typeof(TreeGroupBranch)) { treeGroup = new TreeGroupBranch(); this.branchGroups = this.ArrayAdd(this.branchGroups, treeGroup as TreeGroupBranch); } else { if (type != typeof(TreeGroupLeaf)) { return null; } treeGroup = new TreeGroupLeaf(); this.leafGroups = this.ArrayAdd(this.leafGroups, treeGroup as TreeGroupLeaf); } treeGroup.uniqueID = this._uniqueID; this._uniqueID++; treeGroup.parentGroupID = 0; treeGroup.distributionFrequency = 1; this.SetGroupParent(treeGroup, parent); return treeGroup; }
public void InspectorBranch(TreeData treeData, TreeGroupBranch group) { this.InspectorEditTools(base.target as Tree); GUIContent[] names = new GUIContent[] { TreeEditorHelper.GetGUIContent("Distribution|Adjusts the count and placement of branches in the group. Use the curves to fine tune position, rotation and scale. The curves are relative to the parent branch or to the area spread in case of a trunk."), TreeEditorHelper.GetGUIContent("Geometry|Select what type of geometry is generated for this branch group and which materials are applied. LOD Multiplier allows you to adjust the quality of this group relative to tree's LOD Quality."), TreeEditorHelper.GetGUIContent("Shape|Adjusts the shape and growth of the branches. Use the curves to fine tune the shape, all curves are relative to the branch itself."), TreeEditorHelper.GetGUIContent("Fronds|"), TreeEditorHelper.GetGUIContent("Wind|Adjusts the parameters used for animating this group of branches. The wind zones are only active in Play Mode.") }; bool enabled = GUI.enabled; if (s_SelectedGroup.lockFlags != 0) { this.GUIunlockbox(treeData); } BeginSettingsSection(0, names); this.InspectorDistribution(treeData, group); EndSettingsSection(); BeginSettingsSection(1, names); this.PrepareSpacing(false); group.lodQualityMultiplier = this.GUISlider(PropertyType.Normal, lodMultiplierString, group.lodQualityMultiplier, 0f, 2f, false); group.geometryMode = (TreeGroupBranch.GeometryMode) this.GUIPopup(PropertyType.FullUpdate, geometryModeString, categoryNamesOptions, (int) group.geometryMode, false); if (group.geometryMode != TreeGroupBranch.GeometryMode.Frond) { group.materialBranch = this.GUIMaterialField(PropertyType.FullUpdate, group.uniqueID, branchMaterialString, group.materialBranch, TreeEditorHelper.NodeType.BarkNode); } group.materialBreak = this.GUIMaterialField(PropertyType.FullUpdate, group.uniqueID, breakMaterialString, group.materialBreak, TreeEditorHelper.NodeType.BarkNode); if (group.geometryMode != TreeGroupBranch.GeometryMode.Branch) { group.materialFrond = this.GUIMaterialField(PropertyType.FullUpdate, group.uniqueID, frondMaterialString, group.materialFrond, TreeEditorHelper.NodeType.BarkNode); } EndSettingsSection(); BeginSettingsSection(2, names); this.PrepareSpacing(true); GUI.enabled = group.lockFlags == 0; group.height = this.GUIMinMaxSlider(PropertyType.Normal, lengthString, group.height, 0.1f, 50f, false); GUI.enabled = group.geometryMode != TreeGroupBranch.GeometryMode.Frond; group.radiusMode = this.GUIToggle(PropertyType.Normal, relativeLengthString, group.radiusMode, false); GUI.enabled = group.geometryMode != TreeGroupBranch.GeometryMode.Frond; group.radius = this.GUISlider(PropertyType.Normal, radiusString, group.radius, 0.1f, 5f, true); AnimationCurve radiusCurve = group.radiusCurve; if (this.GUICurve(PropertyType.Normal, radiusCurve, this.m_CurveRangesA)) { group.radiusCurve = radiusCurve; } GUI.enabled = group.geometryMode != TreeGroupBranch.GeometryMode.Frond; group.capSmoothing = this.GUISlider(PropertyType.Normal, capSmoothingString, group.capSmoothing, 0f, 1f, false); GUI.enabled = true; EditorGUILayout.Space(); GUI.enabled = group.lockFlags == 0; group.crinklyness = this.GUISlider(PropertyType.Normal, crinklynessString, group.crinklyness, 0f, 1f, true); radiusCurve = group.crinkCurve; if (this.GUICurve(PropertyType.Normal, radiusCurve, this.m_CurveRangesA)) { group.crinkCurve = radiusCurve; } GUI.enabled = group.lockFlags == 0; group.seekBlend = this.GUISlider(PropertyType.Normal, seekSunString, group.seekBlend, 0f, 1f, true); radiusCurve = group.seekCurve; if (this.GUICurve(PropertyType.Normal, radiusCurve, this.m_CurveRangesB)) { group.seekCurve = radiusCurve; } GUI.enabled = true; EditorGUILayout.Space(); GUI.enabled = group.geometryMode != TreeGroupBranch.GeometryMode.Frond; group.noise = this.GUISlider(PropertyType.Normal, noiseString, group.noise, 0f, 1f, true); radiusCurve = group.noiseCurve; if (this.GUICurve(PropertyType.Normal, radiusCurve, this.m_CurveRangesA)) { group.noiseCurve = radiusCurve; } group.noiseScaleU = this.GUISlider(PropertyType.Normal, noiseScaleUString, group.noiseScaleU, 0f, 1f, false); group.noiseScaleV = this.GUISlider(PropertyType.Normal, noiseScaleVString, group.noiseScaleV, 0f, 1f, false); EditorGUILayout.Space(); GUI.enabled = group.geometryMode != TreeGroupBranch.GeometryMode.Frond; if (treeData.GetGroup(group.parentGroupID) == treeData.root) { group.flareSize = this.GUISlider(PropertyType.Normal, flareRadiusString, group.flareSize, 0f, 5f, false); group.flareHeight = this.GUISlider(PropertyType.Normal, flareHeightString, group.flareHeight, 0f, 1f, false); group.flareNoise = this.GUISlider(PropertyType.Normal, flareNoiseString, group.flareNoise, 0f, 1f, false); } else { group.weldHeight = this.GUISlider(PropertyType.Normal, weldLengthString, group.weldHeight, 0.01f, 1f, false); group.weldSpreadTop = this.GUISlider(PropertyType.Normal, spreadTopString, group.weldSpreadTop, 0f, 1f, false); group.weldSpreadBottom = this.GUISlider(PropertyType.Normal, spreadBottomString, group.weldSpreadBottom, 0f, 1f, false); } EditorGUILayout.Space(); group.breakingChance = this.GUISlider(PropertyType.Normal, breakChanceString, group.breakingChance, 0f, 1f, false); group.breakingSpot = this.GUIMinMaxSlider(PropertyType.Normal, breakLocationString, group.breakingSpot, 0f, 1f, false); EndSettingsSection(); if (group.geometryMode != TreeGroupBranch.GeometryMode.Branch) { BeginSettingsSection(3, names); this.PrepareSpacing(true); group.frondCount = this.GUIIntSlider(PropertyType.Normal, frondCountString, group.frondCount, 1, 0x10, false); group.frondWidth = this.GUISlider(PropertyType.Normal, frondWidthString, group.frondWidth, 0.1f, 10f, true); radiusCurve = group.frondCurve; if (this.GUICurve(PropertyType.Normal, radiusCurve, this.m_CurveRangesA)) { group.frondCurve = radiusCurve; } group.frondRange = this.GUIMinMaxSlider(PropertyType.Normal, frondRangeString, group.frondRange, 0f, 1f, false); group.frondRotation = this.GUISlider(PropertyType.Normal, frondRotationString, group.frondRotation, 0f, 1f, false); group.frondCrease = this.GUISlider(PropertyType.Normal, frondCreaseString, group.frondCrease, -1f, 1f, false); GUI.enabled = true; EndSettingsSection(); } BeginSettingsSection(4, names); this.InspectorAnimation(treeData, group); EndSettingsSection(); GUI.enabled = enabled; EditorGUILayout.Space(); }
public void InspectorBranch(TreeData treeData, TreeGroupBranch group) { this.InspectorEditTools(this.target as Tree); GUIContent[] names = new GUIContent[] { TreeEditorHelper.GetGUIContent("TreeEditor.TreeGroupBranch.Distribution"), TreeEditorHelper.GetGUIContent("TreeEditor.TreeGroupBranch.Geometry"), TreeEditorHelper.GetGUIContent("TreeEditor.TreeGroupBranch.Shape"), TreeEditorHelper.GetGUIContent("TreeEditor.TreeGroupBranch.Fronds"), TreeEditorHelper.GetGUIContent("TreeEditor.TreeGroupBranch.Animation") }; string str = "TreeEditor.TreeGroupBranch."; bool enabled = GUI.enabled; if (TreeEditor.s_SelectedGroup.lockFlags != 0) { this.GUIunlockbox(treeData); } TreeEditor.BeginSettingsSection(0, names); this.InspectorDistribution(treeData, group); TreeEditor.EndSettingsSection(); TreeEditor.BeginSettingsSection(1, names); this.PrepareSpacing(false); group.lodQualityMultiplier = this.GUISlider(TreeEditor.PropertyType.Normal, str + "LODQuality", group.lodQualityMultiplier, 0f, 2f, false); string[] optionIDs = new string[] { "BranchOnly", "BranchAndFronds", "FrondsOnly" }; group.geometryMode = (TreeGroupBranch.GeometryMode)this.GUIPopup(TreeEditor.PropertyType.FullUpdate, str + "GeometryMode", str + "GeometryModeOption", optionIDs, (int)group.geometryMode, false); if (group.geometryMode != TreeGroupBranch.GeometryMode.Frond) { group.materialBranch = this.GUIMaterialField(TreeEditor.PropertyType.FullUpdate, group.uniqueID, str + "BranchMaterial", group.materialBranch, TreeEditorHelper.NodeType.BarkNode); } group.materialBreak = this.GUIMaterialField(TreeEditor.PropertyType.FullUpdate, group.uniqueID, str + "BreakMaterial", group.materialBreak, TreeEditorHelper.NodeType.BarkNode); if (group.geometryMode != TreeGroupBranch.GeometryMode.Branch) { group.materialFrond = this.GUIMaterialField(TreeEditor.PropertyType.FullUpdate, group.uniqueID, str + "FrondMaterial", group.materialFrond, TreeEditorHelper.NodeType.BarkNode); } TreeEditor.EndSettingsSection(); TreeEditor.BeginSettingsSection(2, names); this.PrepareSpacing(true); GUI.enabled = (group.lockFlags == 0); group.height = this.GUIMinMaxSlider(TreeEditor.PropertyType.Normal, str + "Length", group.height, 0.1f, 50f, false); GUI.enabled = (group.geometryMode != TreeGroupBranch.GeometryMode.Frond); group.radiusMode = this.GUIToggle(TreeEditor.PropertyType.Normal, str + "IsLengthRelative", group.radiusMode, false); GUI.enabled = (group.geometryMode != TreeGroupBranch.GeometryMode.Frond); group.radius = this.GUISlider(TreeEditor.PropertyType.Normal, str + "Radius", group.radius, 0.1f, 5f, true); AnimationCurve animationCurve = group.radiusCurve; if (this.GUICurve(TreeEditor.PropertyType.Normal, animationCurve, this.m_CurveRangesA)) { group.radiusCurve = animationCurve; } GUI.enabled = (group.geometryMode != TreeGroupBranch.GeometryMode.Frond); group.capSmoothing = this.GUISlider(TreeEditor.PropertyType.Normal, str + "CapSmoothing", group.capSmoothing, 0f, 1f, false); GUI.enabled = true; EditorGUILayout.Space(); GUI.enabled = (group.lockFlags == 0); group.crinklyness = this.GUISlider(TreeEditor.PropertyType.Normal, str + "Crinklyness", group.crinklyness, 0f, 1f, true); animationCurve = group.crinkCurve; if (this.GUICurve(TreeEditor.PropertyType.Normal, animationCurve, this.m_CurveRangesA)) { group.crinkCurve = animationCurve; } GUI.enabled = (group.lockFlags == 0); group.seekBlend = this.GUISlider(TreeEditor.PropertyType.Normal, str + "SeekSunGround", group.seekBlend, 0f, 1f, true); animationCurve = group.seekCurve; if (this.GUICurve(TreeEditor.PropertyType.Normal, animationCurve, this.m_CurveRangesB)) { group.seekCurve = animationCurve; } GUI.enabled = true; EditorGUILayout.Space(); GUI.enabled = (group.geometryMode != TreeGroupBranch.GeometryMode.Frond); group.noise = this.GUISlider(TreeEditor.PropertyType.Normal, str + "Noise", group.noise, 0f, 1f, true); animationCurve = group.noiseCurve; if (this.GUICurve(TreeEditor.PropertyType.Normal, animationCurve, this.m_CurveRangesA)) { group.noiseCurve = animationCurve; } group.noiseScaleU = this.GUISlider(TreeEditor.PropertyType.Normal, str + "NoiseScaleU", group.noiseScaleU, 0f, 1f, false); group.noiseScaleV = this.GUISlider(TreeEditor.PropertyType.Normal, str + "NoiseScaleV", group.noiseScaleV, 0f, 1f, false); EditorGUILayout.Space(); GUI.enabled = (group.geometryMode != TreeGroupBranch.GeometryMode.Frond); if (treeData.GetGroup(group.parentGroupID) == treeData.root) { group.flareSize = this.GUISlider(TreeEditor.PropertyType.Normal, str + "FlareRadius", group.flareSize, 0f, 5f, false); group.flareHeight = this.GUISlider(TreeEditor.PropertyType.Normal, str + "FlareHeight", group.flareHeight, 0f, 1f, false); group.flareNoise = this.GUISlider(TreeEditor.PropertyType.Normal, str + "FlareNoise", group.flareNoise, 0f, 1f, false); } else { group.weldHeight = this.GUISlider(TreeEditor.PropertyType.Normal, str + "WeldHeight", group.weldHeight, 0.01f, 1f, false); group.weldSpreadTop = this.GUISlider(TreeEditor.PropertyType.Normal, str + "WeldSpreadTop", group.weldSpreadTop, 0f, 1f, false); group.weldSpreadBottom = this.GUISlider(TreeEditor.PropertyType.Normal, str + "WeldSpreadBottom", group.weldSpreadBottom, 0f, 1f, false); } EditorGUILayout.Space(); group.breakingChance = this.GUISlider(TreeEditor.PropertyType.Normal, str + "BreakChance", group.breakingChance, 0f, 1f, false); group.breakingSpot = this.GUIMinMaxSlider(TreeEditor.PropertyType.Normal, str + "BreakLocation", group.breakingSpot, 0f, 1f, false); TreeEditor.EndSettingsSection(); if (group.geometryMode != TreeGroupBranch.GeometryMode.Branch) { TreeEditor.BeginSettingsSection(3, names); this.PrepareSpacing(true); group.frondCount = this.GUIIntSlider(TreeEditor.PropertyType.Normal, str + "FrondCount", group.frondCount, 1, 16, false); group.frondWidth = this.GUISlider(TreeEditor.PropertyType.Normal, str + "FrondWidth", group.frondWidth, 0.1f, 10f, true); animationCurve = group.frondCurve; if (this.GUICurve(TreeEditor.PropertyType.Normal, animationCurve, this.m_CurveRangesA)) { group.frondCurve = animationCurve; } group.frondRange = this.GUIMinMaxSlider(TreeEditor.PropertyType.Normal, str + "FrondRange", group.frondRange, 0f, 1f, false); group.frondRotation = this.GUISlider(TreeEditor.PropertyType.Normal, str + "FrondRotation", group.frondRotation, 0f, 1f, false); group.frondCrease = this.GUISlider(TreeEditor.PropertyType.Normal, str + "FrondCrease", group.frondCrease, -1f, 1f, false); GUI.enabled = true; TreeEditor.EndSettingsSection(); } TreeEditor.BeginSettingsSection(4, names); this.InspectorAnimation(treeData, group); TreeEditor.EndSettingsSection(); GUI.enabled = enabled; EditorGUILayout.Space(); }