void Start() { treeData = tree.data as TreeEditor.TreeData; startHeight = new Vector3(transform.position.x, transform.position.y - height + 0.1f, transform.position.z); transform.position = startHeight; randTargetHeight = Random.Range(6, 10); //top follow below player low = more vertical randSpeedMin = Random.Range(0.05f, 0.2f); randSpeedMax = Random.Range(0.5f, 0.8f); //treeData.root.seed = Random.Range(0, 999999); //treeData.UpdateMesh(tree.transform.worldToLocalMatrix, out material); }
void SwitchLeaves() { Tree treeObject = gameObject.GetComponent <Tree> (); TreeEditor.TreeData treeData = treeObject.data as TreeEditor.TreeData; TreeEditor.TreeGroupLeaf[] treeGroupLeaves = treeData.leafGroups; foreach (TreeEditor.TreeGroupLeaf treeGroupLeaf in treeGroupLeaves) { treeGroupLeaf.visible = !treeGroupLeaf.visible; } Material[] materials; treeData.UpdateMesh(treeObject.transform.worldToLocalMatrix, out materials); }
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); } }
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); } }
private Bounds CalcBounds(TreeData treeData, Matrix4x4 objMatrix, TreeNode node) { Matrix4x4 matrix4x = objMatrix * node.matrix; Bounds result; if (treeData.GetGroup(node.groupID).GetType() == typeof(TreeGroupBranch) && node.spline != null && node.spline.nodes.Length > 0) { result = new Bounds(matrix4x.MultiplyPoint(node.spline.nodes[0].point), Vector3.zero); for (int i = 1; i < node.spline.nodes.Length; i++) { result.Encapsulate(matrix4x.MultiplyPoint(node.spline.nodes[i].point)); } } else { result = new Bounds(matrix4x.MultiplyPoint(Vector3.zero), Vector3.zero); } return result; }
public void InspectorDistribution(TreeData treeData, TreeGroup group) { if (group != null) { this.PrepareSpacing(true); bool flag = true; if (group.lockFlags != 0) { flag = false; } GUI.enabled = flag; int seed = group.seed; group.seed = this.GUIIntSlider(PropertyType.Normal, group.GroupSeedString, group.seed, 0, 0xf423f, false); if (group.seed != seed) { treeData.UpdateSeed(group.uniqueID); } seed = group.distributionFrequency; group.distributionFrequency = this.GUIIntSlider(PropertyType.FullUndo, group.FrequencyString, group.distributionFrequency, 1, 100, false); if (group.distributionFrequency != seed) { treeData.UpdateFrequency(group.uniqueID); } seed = (int) group.distributionMode; group.distributionMode = (TreeGroup.DistributionMode) this.GUIPopup(PropertyType.Normal, group.DistributionModeString, inspectorDistributionPopupOptions, (int) group.distributionMode, true); if (group.distributionMode != seed) { treeData.UpdateDistribution(group.uniqueID); } AnimationCurve distributionCurve = group.distributionCurve; if (this.GUICurve(PropertyType.Normal, distributionCurve, this.m_CurveRangesA)) { group.distributionCurve = distributionCurve; treeData.UpdateDistribution(group.uniqueID); } if (group.distributionMode != TreeGroup.DistributionMode.Random) { float distributionTwirl = group.distributionTwirl; group.distributionTwirl = this.GUISlider(PropertyType.Normal, group.TwirlString, group.distributionTwirl, -1f, 1f, false); if (group.distributionTwirl != distributionTwirl) { treeData.UpdateDistribution(group.uniqueID); } } if (group.distributionMode == TreeGroup.DistributionMode.Whorled) { seed = group.distributionNodes; group.distributionNodes = this.GUIIntSlider(PropertyType.Normal, group.WhorledStepString, group.distributionNodes, 1, 0x15, false); if (group.distributionNodes != seed) { treeData.UpdateDistribution(group.uniqueID); } } group.distributionScale = this.GUISlider(PropertyType.Normal, group.GrowthScaleString, group.distributionScale, 0f, 1f, true); distributionCurve = group.distributionScaleCurve; if (this.GUICurve(PropertyType.Normal, distributionCurve, this.m_CurveRangesA)) { group.distributionScaleCurve = distributionCurve; } group.distributionPitch = this.GUISlider(PropertyType.Normal, group.GrowthAngleString, group.distributionPitch, 0f, 1f, true); distributionCurve = group.distributionPitchCurve; if (this.GUICurve(PropertyType.Normal, distributionCurve, this.m_CurveRangesB)) { group.distributionPitchCurve = distributionCurve; } GUI.enabled = true; EditorGUILayout.Space(); } }
public void InspectorAnimation(TreeData treeData, TreeGroup group) { if (group != null) { this.PrepareSpacing(false); group.animationPrimary = this.GUISlider(PropertyType.Normal, group.MainWindString, group.animationPrimary, 0f, 1f, false); if (treeData.GetGroup(group.parentGroupID) != treeData.root) { group.animationSecondary = this.GUISlider(PropertyType.Normal, group.MainTurbulenceString, group.animationSecondary, 0f, 1f, false); } GUI.enabled = true; if (!(group is TreeGroupBranch) || ((group as TreeGroupBranch).geometryMode != TreeGroupBranch.GeometryMode.Branch)) { group.animationEdge = this.GUISlider(PropertyType.Normal, group.EdgeTurbulenceString, group.animationEdge, 0f, 1f, false); } this.GUIPropBegin(); if (GUILayout.Button(TreeEditorHelper.GetGUIContent("Create Wind Zone|Creates a default wind zone, which is required for animating trees while playing the game."), new GUILayoutOption[0])) { CreateDefaultWindZone(); } this.GUIPropEnd(); } }
private bool UpdateTextures(TextureAtlas atlas, List <TreeMaterial> materials) { if (!this.root.enableMaterialOptimize) { return(false); } bool flag = this.optimizedSolidMaterial.GetTexture("_MainTex") != null && this.optimizedSolidMaterial.GetTexture("_BumpSpecMap") != null && this.optimizedSolidMaterial.GetTexture("_TranslucencyMap") != null && this.optimizedCutoutMaterial.GetTexture("_MainTex") != null && this.optimizedCutoutMaterial.GetTexture("_ShadowTex") != null && this.optimizedCutoutMaterial.GetTexture("_BumpSpecMap") != null && this.optimizedCutoutMaterial.GetTexture("_TranslucencyMap"); UnityEngine.Object[] array = new UnityEngine.Object[materials.Count]; for (int i = 0; i < materials.Count; i++) { array[i] = materials[i].material; } string text = InternalEditorUtility.CalculateHashForObjectsAndDependencies(array); text += atlas.GetHashCode(); if (this.materialHash == text && flag) { this.UpdateShadowTexture(this.optimizedCutoutMaterial.GetTexture("_ShadowTex") as Texture2D, atlas.atlasWidth, atlas.atlasHeight); return(false); } this.materialHash = text; int atlasWidth = atlas.atlasWidth; int atlasHeight = atlas.atlasHeight; int atlasPadding = atlas.atlasPadding; Texture2D texture2D = new Texture2D(atlasWidth, atlasHeight, TextureFormat.ARGB32, true); Texture2D texture2D2 = new Texture2D(atlasWidth, atlasHeight, TextureFormat.RGB24, true); Texture2D texture2D3 = new Texture2D(atlasWidth, atlasHeight, TextureFormat.ARGB32, true); Texture2D texture2D4 = new Texture2D(atlasWidth, atlasHeight, TextureFormat.ARGB32, true); texture2D.name = "diffuse"; texture2D2.name = "shadow"; texture2D3.name = "normal_specular"; texture2D4.name = "translucency_gloss"; SavedRenderTargetState savedRenderTargetState = new SavedRenderTargetState(); EditorUtility.SetTemporarilyAllowIndieRenderTexture(true); RenderTexture temporary = RenderTexture.GetTemporary(atlasWidth, atlasHeight, 0, RenderTextureFormat.ARGB32); Color white = Color.white; Color color = new Color(0.03f, 0.5f, 0f, 0.5f); Color color2 = new Color(0f, 0f, 0f, 0f); Texture2D texture2D5 = new Texture2D(1, 1); texture2D5.SetPixel(0, 0, white); texture2D5.Apply(); Texture2D texture2D6 = new Texture2D(1, 1); texture2D6.SetPixel(0, 0, white); texture2D6.Apply(); Texture2D texture2D7 = new Texture2D(1, 1); texture2D7.SetPixel(0, 0, color); texture2D7.Apply(); Texture2D texture2D8 = new Texture2D(1, 1); texture2D8.SetPixel(0, 0, color2); texture2D8.Apply(); Texture2D texture2D9 = texture2D8; Texture2D texture2D10 = new Texture2D(1, 1); texture2D10.SetPixel(0, 0, Color.white); texture2D10.Apply(); Material material = EditorGUIUtility.LoadRequired("Inspectors/TreeCreator/TreeTextureCombinerMaterial.mat") as Material; for (int j = 0; j < 4; j++) { RenderTexture.active = temporary; GL.LoadPixelMatrix(0f, (float)atlasWidth, 0f, (float)atlasHeight); material.SetVector("_TexSize", new Vector4((float)atlasWidth, (float)atlasHeight, 0f, 0f)); switch (j) { case 0: GL.Clear(false, true, color); break; case 1: GL.Clear(false, true, color2); break; case 2: GL.Clear(false, true, color2); break; case 3: GL.Clear(false, true, color2); break; } for (int k = 0; k < atlas.nodes.Count; k++) { TextureAtlas.TextureNode textureNode = atlas.nodes[k]; Rect packedRect = textureNode.packedRect; Texture texture = null; Texture texture2 = null; Color color3 = default(Color); switch (j) { case 0: texture = textureNode.normalTexture; texture2 = textureNode.shadowOffsetTexture; color3 = new Color(textureNode.shininess, 0f, 0f, 0f); if (texture == null) { texture = texture2D7; } if (texture2 == null) { texture2 = texture2D9; } break; case 1: texture = textureNode.diffuseTexture; color3 = textureNode.diffuseColor; if (texture == null) { texture = texture2D5; } break; case 2: texture = textureNode.translucencyTexture; texture2 = textureNode.glossTexture; if (texture == null) { texture = texture2D10; } if (texture2 == null) { texture2 = texture2D8; } break; case 3: texture2 = textureNode.diffuseTexture; if (texture2 == null) { texture2 = texture2D5; } break; } if (textureNode.tileV) { float x = packedRect.x; float num = (float)atlasPadding / 2f; for (float num2 = num; num2 > 0f; num2 -= 1f) { Rect rect = new Rect(packedRect); Rect rect2 = new Rect(packedRect); rect.x = x - num2; rect2.x = x + num2; this.DrawTexture(rect, texture, texture2, material, color3, j); this.DrawTexture(rect2, texture, texture2, material, color3, j); } } this.DrawTexture(packedRect, texture, texture2, material, color3, j); } switch (j) { case 0: texture2D3.ReadPixels(new Rect(0f, 0f, (float)atlasWidth, (float)atlasHeight), 0, 0); texture2D3.Apply(true); break; case 1: texture2D.ReadPixels(new Rect(0f, 0f, (float)atlasWidth, (float)atlasHeight), 0, 0); texture2D.Apply(true); break; case 2: texture2D4.ReadPixels(new Rect(0f, 0f, (float)atlasWidth, (float)atlasHeight), 0, 0); texture2D4.Apply(true); break; case 3: texture2D2.ReadPixels(new Rect(0f, 0f, (float)atlasWidth, (float)atlasHeight), 0, 0); texture2D2.Apply(true); break; } } savedRenderTargetState.Restore(); this.optimizedSolidMaterial.SetPass(0); RenderTexture.ReleaseTemporary(temporary); UnityEngine.Object.DestroyImmediate(texture2D5); UnityEngine.Object.DestroyImmediate(texture2D6); UnityEngine.Object.DestroyImmediate(texture2D10); UnityEngine.Object.DestroyImmediate(texture2D8); UnityEngine.Object.DestroyImmediate(texture2D7); EditorUtility.SetTemporarilyAllowIndieRenderTexture(false); Texture2D[] array2 = new Texture2D[] { texture2D, texture2D3, texture2D4, texture2D2 }; array2 = TreeData.WriteOptimizedTextures(AssetDatabase.GetAssetPath(this), array2); UnityEngine.Object.DestroyImmediate(texture2D); UnityEngine.Object.DestroyImmediate(texture2D3); UnityEngine.Object.DestroyImmediate(texture2D4); UnityEngine.Object.DestroyImmediate(texture2D2); this.optimizedSolidMaterial.SetTexture("_MainTex", array2[0]); this.optimizedSolidMaterial.SetTexture("_BumpSpecMap", array2[1]); this.optimizedSolidMaterial.SetTexture("_TranslucencyMap", array2[2]); this.optimizedCutoutMaterial.SetTexture("_MainTex", array2[0]); this.optimizedCutoutMaterial.SetTexture("_BumpSpecMap", array2[1]); this.optimizedCutoutMaterial.SetTexture("_TranslucencyMap", array2[2]); this.optimizedCutoutMaterial.SetTexture("_ShadowTex", array2[3]); this.UpdateShadowTexture(array2[3], atlas.atlasWidth, atlas.atlasHeight); return(true); }
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 lhs = objMatrix * node.matrix; float num = 1f / ((float)node.spline.GetNodeCount() * 10f); float num2 = 0f; float num3 = 1E+07f; Vector3 vector = Vector3.zero; Vector3 zero = Vector3.zero; Vector3 p = lhs.MultiplyPoint(node.spline.GetPositionAtTime(0f)); for (float num4 = num; num4 <= 1f; num4 += num) { Vector3 vector2 = lhs.MultiplyPoint(node.spline.GetPositionAtTime(num4)); float num5 = 0f; float num6 = 0f; vector = MathUtils.ClosestPtSegmentRay(p, vector2, mouseRay, out num5, out num6, out zero); if (num5 < num3) { num2 = num4 - num + num * num6; num3 = num5; float radiusAtTime = node.GetRadiusAtTime(num2); float num7 = 0f; if (MathUtils.ClosestPtRaySphere(mouseRay, vector, radiusAtTime, ref num7, ref zero)) { Matrix4x4 inverse = (lhs * node.GetLocalMatrixAtTime(num2)).inverse; Vector3 v = zero - vector; v = inverse.MultiplyVector(v); rotation = Mathf.Atan2(v.x, v.z) * 57.29578f; } } p = vector2; } data.ClearReferences(); return num2; }
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 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 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 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 void UpdateFrequency(TreeData owner) { Profiler.BeginSample("UpdateFrequency"); if (this.distributionFrequency < 1) { this.distributionFrequency = 1; } if (this.parentGroup == null) { this.distributionFrequency = 1; if (this.nodes.Count < 1) { owner.AddNode(this, null, false); } } else { if (this.lockFlags == 0 && this.parentGroup != null) { int num = 0; for (int i = 0; i < this.parentGroup.nodes.Count; i++) { int num2 = Mathf.RoundToInt((float)this.distributionFrequency * this.parentGroup.nodes[i].GetScale()); if (num2 < 1) { num2 = 1; } for (int j = 0; j < num2; j++) { if (num < this.nodes.Count) { owner.SetNodeParent(this.nodes[num], this.parentGroup.nodes[i]); } else { owner.AddNode(this, this.parentGroup.nodes[i], false); } num++; } } if (num < this.nodes.Count) { List<TreeNode> list = new List<TreeNode>(); for (int k = num; k < this.nodes.Count; k++) { list.Add(this.nodes[k]); } for (int l = 0; l < list.Count; l++) { owner.DeleteNode(list[l], false); } } this.UpdateSeed(); this.UpdateDistribution(true, false); } } for (int m = 0; m < this.childGroups.Count; m++) { this.childGroups[m].UpdateFrequency(owner); } Profiler.EndSample(); }
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 DrawHierachy(TreeData treeData, Renderer renderer, Rect sizeRect) { if (styles == null) { styles = new Styles(); } this.hierachySpread = this.hierachyNodeSize + this.hierachyNodeSpace; this.hierachyView = sizeRect; Event event2 = new Event(Event.current); List<HierachyNode> nodes = new List<HierachyNode>(); this.BuildHierachyNodes(treeData, nodes, treeData.root, 0); this.LayoutHierachyNodes(nodes, sizeRect); float num = 16f; Vector2 zero = Vector2.zero; if (sizeRect.width < this.hierachyRect.width) { zero.y -= 16f; } bool changed = GUI.changed; this.hierachyDisplayRect = GUILayoutUtility.GetRect(sizeRect.width, this.hierachyRect.height + num); this.hierachyDisplayRect.width = sizeRect.width; GUI.Box(this.hierachyDisplayRect, GUIContent.none, styles.nodeBackground); this.hierachyScroll = GUI.BeginScrollView(this.hierachyDisplayRect, this.hierachyScroll, this.hierachyRect, false, false); GUI.changed = changed; this.HandleDragHierachyNodes(treeData, nodes); this.DrawHierachyNodes(treeData, nodes, treeData.root, (Vector2) (zero / 2f), 1f, 1f); if ((this.dragNode != null) && this.isDragging) { Vector2 vector2 = Event.current.mousePosition - this.dragClickPos; this.DrawHierachyNodes(treeData, nodes, this.dragNode.group, vector2 + ((Vector2) (zero / 2f)), 0.5f, 0.5f); } GUI.EndScrollView(); MeshFilter component = renderer.GetComponent<MeshFilter>(); if (((component != null) && (component.sharedMesh != null)) && (renderer != null)) { int length = component.sharedMesh.vertices.Length; int num3 = component.sharedMesh.triangles.Length / 3; int num4 = renderer.sharedMaterials.Length; Rect position = new Rect((this.hierachyDisplayRect.xMax - 80f) - 4f, ((this.hierachyDisplayRect.yMax + zero.y) - 40f) - 4f, 80f, 40f); string text = TreeEditorHelper.GetGUIContent("Hierachy Stats").text.Replace("[v]", length.ToString()).Replace("[t]", num3.ToString()).Replace("[m]", num4.ToString()).Replace(" / ", "\n"); GUI.Label(position, text, EditorStyles.helpBox); } if ((event2.type == EventType.ScrollWheel) && (Event.current.type == EventType.Used)) { Event.current = event2; } }
private void UpdateNodeMesh(TreeNode node, List <TreeMaterial> materials, List <TreeVertex> verts, List <TreeTriangle> tris, List <TreeAOSphere> aoSpheres, int buildFlags, float adaptiveQuality, float aoDensity) { node.triStart = tris.Count; node.triEnd = tris.Count; node.vertStart = verts.Count; node.vertEnd = verts.Count; if (!node.visible || !this.visible) { return; } Profiler.BeginSample("TreeGroupBranch.UpdateNodeMesh"); int count = verts.Count; float approximateLength = node.spline.GetApproximateLength(); List <RingLoop> list = new List <RingLoop>(); float adaptiveQuality2 = Mathf.Clamp01(adaptiveQuality * this.lodQualityMultiplier); List <float> adaptiveSamples = TreeData.GetAdaptiveSamples(this, node, adaptiveQuality2); int adaptiveRadialSegments = TreeData.GetAdaptiveRadialSegments(this.radius, adaptiveQuality2); TreeGroupBranch treeGroupBranch = null; if (this.parentGroup != null && this.parentGroup.GetType() == typeof(TreeGroupBranch)) { treeGroupBranch = (TreeGroupBranch)this.parentGroup; } if (this.geometryMode == TreeGroupBranch.GeometryMode.BranchFrond || this.geometryMode == TreeGroupBranch.GeometryMode.Branch) { int materialIndex = TreeGroup.GetMaterialIndex(this.materialBranch, materials, true); float num = 0f; float num2 = 0f; float num3 = approximateLength / (this.GetRadiusAtTime(node, 0f, false) * 3.14159274f * 2f); bool flag = true; if (node.parent != null && treeGroupBranch != null) { num2 = node.offset * node.parent.spline.GetApproximateLength(); } float num4 = 1f - node.capRange; for (int i = 0; i < adaptiveSamples.Count; i++) { float num5 = adaptiveSamples[i]; Vector3 positionAtTime = node.spline.GetPositionAtTime(num5); Quaternion rotationAtTime = node.spline.GetRotationAtTime(num5); float radiusAtTime = this.GetRadiusAtTime(node, num5, false); Matrix4x4 m = node.matrix * Matrix4x4.TRS(positionAtTime, rotationAtTime, new Vector3(1f, 1f, 1f)); Vector3 flareWeldAtTime = this.GetFlareWeldAtTime(node, num5); float num6 = Mathf.Max(flareWeldAtTime.x, Mathf.Max(flareWeldAtTime.y, flareWeldAtTime.z) * 0.25f); if (num5 <= num4) { adaptiveRadialSegments = TreeData.GetAdaptiveRadialSegments(radiusAtTime + num6, adaptiveQuality2); } if (flag) { if (i > 0) { float num7 = adaptiveSamples[i - 1]; float num8 = num5 - num7; float num9 = (radiusAtTime + this.GetRadiusAtTime(node, num7, false)) * 0.5f; num += num8 * approximateLength / (num9 * 3.14159274f * 2f); } } else { num = num2 + num5 * num3; } Vector2 vector = base.ComputeWindFactor(node, num5); RingLoop ringLoop = new RingLoop(); ringLoop.Reset(radiusAtTime, m, num, adaptiveRadialSegments); ringLoop.SetSurfaceAngle(node.GetSurfaceAngleAtTime(num5)); ringLoop.SetAnimationProperties(vector.x, vector.y, 0f, node.animSeed); ringLoop.SetSpread(flareWeldAtTime.y, flareWeldAtTime.z); ringLoop.SetNoise(this.noise * Mathf.Clamp01(this.noiseCurve.Evaluate(num5)), this.noiseScaleU * 10f, this.noiseScaleV * 10f); ringLoop.SetFlares(flareWeldAtTime.x, this.flareNoise * 10f); int count2 = verts.Count; ringLoop.BuildVertices(verts); int count3 = verts.Count; if ((buildFlags & 2) != 0) { float num10 = this.weldHeight; float num11 = Mathf.Pow(Mathf.Clamp01((1f - num5 - (1f - this.weldHeight)) / this.weldHeight), 1.5f); float d = 1f - num11; if (num5 < num10 && node.parent != null && node.parent.spline != null) { Ray ray = default(Ray); for (int j = count2; j < count3; j++) { ray.origin = verts[j].pos; ray.direction = m.MultiplyVector(-Vector3.up); Vector3 pos = verts[j].pos; Vector3 nor = verts[j].nor; float num12 = -10000f; float num13 = 100000f; for (int k = node.parent.triStart; k < node.parent.triEnd; k++) { object obj = MathUtils.IntersectRayTriangle(ray, verts[tris[k].v[0]].pos, verts[tris[k].v[1]].pos, verts[tris[k].v[2]].pos, true); if (obj != null) { RaycastHit raycastHit = (RaycastHit)obj; if (Mathf.Abs(raycastHit.distance) < num13 && raycastHit.distance > num12) { num13 = Mathf.Abs(raycastHit.distance); verts[j].nor = verts[tris[k].v[0]].nor * raycastHit.barycentricCoordinate.x + verts[tris[k].v[1]].nor * raycastHit.barycentricCoordinate.y + verts[tris[k].v[2]].nor * raycastHit.barycentricCoordinate.z; verts[j].nor = verts[j].nor * num11 + nor * d; verts[j].pos = raycastHit.point * num11 + pos * d; } } } } } } list.Add(ringLoop); if (num5 == 1f && ringLoop.radius > 0.005f) { RingLoop ringLoop2 = ringLoop.Clone(); ringLoop2.radius = 0f; ringLoop2.baseOffset += radiusAtTime / 6.28318548f; ringLoop2.BuildVertices(verts); list.Add(ringLoop2); } } if (list.Count > 0 && list[list.Count - 1].radius > 0.025f && node.breakOffset < 1f) { float mappingScale = 1f / (this.radius * 3.14159274f * 2f); float sphereFactor = 0f; float num14 = 1f; int mappingMode = 0; Material m2 = this.materialBranch; if (this.materialBreak != null) { m2 = this.materialBreak; } int materialIndex2 = TreeGroup.GetMaterialIndex(m2, materials, false); list[list.Count - 1].Cap(sphereFactor, num14, mappingMode, mappingScale, verts, tris, materialIndex2); } node.triStart = tris.Count; for (int l = 0; l < list.Count - 1; l++) { list[l].Connect(list[l + 1], tris, materialIndex, false, false); } node.triEnd = tris.Count; list.Clear(); } float num15 = Mathf.Min(this.frondRange.x, this.frondRange.y); float num16 = Mathf.Max(this.frondRange.x, this.frondRange.y); float num17 = num15; float num18 = num16; num15 = Mathf.Clamp(num15, 0f, node.breakOffset); num16 = Mathf.Clamp(num16, 0f, node.breakOffset); if ((this.geometryMode == TreeGroupBranch.GeometryMode.BranchFrond || this.geometryMode == TreeGroupBranch.GeometryMode.Frond) && this.frondCount > 0 && num15 != num16) { bool flag2 = true; bool flag3 = true; for (int n = 0; n < adaptiveSamples.Count; n++) { float num19 = adaptiveSamples[n]; if (num19 < num15) { adaptiveSamples.RemoveAt(n); n--; } else { if (num19 == num15) { flag2 = false; } else { if (num19 == num16) { flag3 = false; } else { if (num19 > num16) { adaptiveSamples.RemoveAt(n); n--; } } } } } if (flag2) { adaptiveSamples.Insert(0, num15); } if (flag3) { adaptiveSamples.Add(num16); } int materialIndex3 = TreeGroup.GetMaterialIndex(this.materialFrond, materials, false); float num20 = 1f - node.capRange; for (int num21 = 0; num21 < this.frondCount; num21++) { float num22 = this.frondCrease * 90f * 0.0174532924f; float num23 = (this.frondRotation * 360f + (float)num21 * 180f / (float)this.frondCount - 90f) * 0.0174532924f; float f = -num23 - num22; float f2 = num23 - num22; Vector3 a = new Vector3(Mathf.Sin(f), 0f, Mathf.Cos(f)); Vector3 vector2 = new Vector3(a.z, 0f, -a.x); Vector3 a2 = new Vector3(Mathf.Sin(f2), 0f, -Mathf.Cos(f2)); Vector3 vector3 = new Vector3(-a2.z, 0f, a2.x); for (int num24 = 0; num24 < adaptiveSamples.Count; num24++) { float num25 = adaptiveSamples[num24]; float y = (num25 - num17) / (num18 - num17); float timeParam = num25; if (num25 > num20) { timeParam = num20; float f3 = Mathf.Acos(Mathf.Clamp01((num25 - num20) / node.capRange)); float num26 = Mathf.Sin(f3); float y2 = Mathf.Cos(f3) * this.capSmoothing; a = new Vector3(Mathf.Sin(f) * num26, y2, Mathf.Cos(f) * num26); vector2 = new Vector3(a.z, a.y, -a.x); a2 = new Vector3(Mathf.Sin(f2) * num26, y2, -Mathf.Cos(f2) * num26); vector3 = new Vector3(-a2.z, a2.y, a2.x); } Vector3 a3 = new Vector3(0f, 0f, -1f); Vector3 positionAtTime2 = node.spline.GetPositionAtTime(timeParam); Quaternion rotationAtTime2 = node.spline.GetRotationAtTime(num25); float d2 = Mathf.Clamp01(this.frondCurve.Evaluate(num25)) * this.frondWidth * node.GetScale(); Matrix4x4 matrix4x = node.matrix * Matrix4x4.TRS(positionAtTime2, rotationAtTime2, new Vector3(1f, 1f, 1f)); if (TreeGroup.GenerateDoubleSidedGeometry) { for (float num27 = -1f; num27 < 2f; num27 += 2f) { TreeVertex treeVertex = new TreeVertex(); treeVertex.pos = matrix4x.MultiplyPoint(a * d2); treeVertex.nor = matrix4x.MultiplyVector(vector2 * num27).normalized; treeVertex.tangent = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex.nor); treeVertex.tangent.w = -num27; treeVertex.uv0 = new Vector2(1f, y); TreeVertex treeVertex2 = new TreeVertex(); treeVertex2.pos = matrix4x.MultiplyPoint(Vector3.zero); treeVertex2.nor = matrix4x.MultiplyVector(a3 * num27).normalized; treeVertex2.tangent = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex2.nor); treeVertex2.tangent.w = -num27; treeVertex2.uv0 = new Vector2(0.5f, y); TreeVertex treeVertex3 = new TreeVertex(); treeVertex3.pos = matrix4x.MultiplyPoint(Vector3.zero); treeVertex3.nor = matrix4x.MultiplyVector(a3 * num27).normalized; treeVertex3.tangent = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex3.nor); treeVertex3.tangent.w = -num27; treeVertex3.uv0 = new Vector2(0.5f, y); TreeVertex treeVertex4 = new TreeVertex(); treeVertex4.pos = matrix4x.MultiplyPoint(a2 * d2); treeVertex4.nor = matrix4x.MultiplyVector(vector3 * num27).normalized; treeVertex4.tangent = TreeGroup.CreateTangent(node, rotationAtTime2, treeVertex4.nor); treeVertex4.tangent.w = -num27; treeVertex4.uv0 = new Vector2(0f, y); Vector2 vector4 = base.ComputeWindFactor(node, num25); treeVertex.SetAnimationProperties(vector4.x, vector4.y, this.animationEdge, node.animSeed); treeVertex2.SetAnimationProperties(vector4.x, vector4.y, 0f, node.animSeed); treeVertex3.SetAnimationProperties(vector4.x, vector4.y, 0f, node.animSeed); treeVertex4.SetAnimationProperties(vector4.x, vector4.y, this.animationEdge, node.animSeed); verts.Add(treeVertex); verts.Add(treeVertex2); verts.Add(treeVertex3); verts.Add(treeVertex4); } if (num24 > 0) { int count4 = verts.Count; TreeTriangle treeTriangle = new TreeTriangle(materialIndex3, count4 - 4, count4 - 3, count4 - 11); TreeTriangle treeTriangle2 = new TreeTriangle(materialIndex3, count4 - 4, count4 - 11, count4 - 12); treeTriangle.flip(); treeTriangle2.flip(); TreeTriangle item = new TreeTriangle(materialIndex3, count4 - 8, count4 - 7, count4 - 15); TreeTriangle item2 = new TreeTriangle(materialIndex3, count4 - 8, count4 - 15, count4 - 16); tris.Add(treeTriangle); tris.Add(treeTriangle2); tris.Add(item); tris.Add(item2); TreeTriangle item3 = new TreeTriangle(materialIndex3, count4 - 2, count4 - 9, count4 - 1); TreeTriangle item4 = new TreeTriangle(materialIndex3, count4 - 2, count4 - 10, count4 - 9); TreeTriangle treeTriangle3 = new TreeTriangle(materialIndex3, count4 - 6, count4 - 13, count4 - 5); TreeTriangle treeTriangle4 = new TreeTriangle(materialIndex3, count4 - 6, count4 - 14, count4 - 13); treeTriangle3.flip(); treeTriangle4.flip(); tris.Add(item3); tris.Add(item4); tris.Add(treeTriangle3); tris.Add(treeTriangle4); } } else { TreeVertex treeVertex5 = new TreeVertex(); treeVertex5.pos = matrix4x.MultiplyPoint(a * d2); treeVertex5.nor = matrix4x.MultiplyVector(vector2).normalized; treeVertex5.uv0 = new Vector2(0f, y); TreeVertex treeVertex6 = new TreeVertex(); treeVertex6.pos = matrix4x.MultiplyPoint(Vector3.zero); treeVertex6.nor = matrix4x.MultiplyVector(Vector3.back).normalized; treeVertex6.uv0 = new Vector2(0.5f, y); TreeVertex treeVertex7 = new TreeVertex(); treeVertex7.pos = matrix4x.MultiplyPoint(a2 * d2); treeVertex7.nor = matrix4x.MultiplyVector(vector3).normalized; treeVertex7.uv0 = new Vector2(1f, y); Vector2 vector5 = base.ComputeWindFactor(node, num25); treeVertex5.SetAnimationProperties(vector5.x, vector5.y, this.animationEdge, node.animSeed); treeVertex6.SetAnimationProperties(vector5.x, vector5.y, 0f, node.animSeed); treeVertex7.SetAnimationProperties(vector5.x, vector5.y, this.animationEdge, node.animSeed); verts.Add(treeVertex5); verts.Add(treeVertex6); verts.Add(treeVertex7); if (num24 > 0) { int count5 = verts.Count; TreeTriangle item5 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 3, count5 - 6); TreeTriangle item6 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 6, count5 - 5); tris.Add(item5); tris.Add(item6); TreeTriangle item7 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 4, count5 - 1); TreeTriangle item8 = new TreeTriangle(materialIndex3, count5 - 2, count5 - 5, count5 - 4); tris.Add(item7); tris.Add(item8); } } } } } if ((buildFlags & 1) != 0) { for (int num28 = count; num28 < verts.Count; num28++) { verts[num28].SetAmbientOcclusion(TreeGroup.ComputeAmbientOcclusion(verts[num28].pos, verts[num28].nor, aoSpheres, aoDensity)); } } node.vertEnd = verts.Count; Profiler.EndSample(); }
private void GUIunlockbox(TreeData treeData) { GUILayout.BeginVertical(EditorStyles.helpBox, new GUILayoutOption[0]); GUIContent gUIContent = TreeEditorHelper.GetGUIContent("This group has been edited by hand. Some parameters may not be available.|"); gUIContent.image = styles.warningIcon.image; GUILayout.Label(gUIContent, EditorStyles.wordWrappedMiniLabel, new GUILayoutOption[0]); GUIStyle style = new GUIStyle("minibutton") { wordWrap = true }; if (GUILayout.Button(TreeEditorHelper.GetGUIContent("Convert to procedural group. All hand editing will be lost!|"), style, new GUILayoutOption[0])) { treeData.UnlockGroup(s_SelectedGroup); this.m_WantCompleteUpdate = true; } GUILayout.EndVertical(); }
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 bool OptimizeMaterial(List <TreeMaterial> materials, List <TreeVertex> vertices, List <TreeTriangle> triangles) { if (!this.optimizedSolidMaterial || !this.optimizedCutoutMaterial) { Debug.LogError("Optimized materials haven't been assigned"); return(false); } Shader shader; Shader shader2; TreeData.ExtractOptimizedShaders(materials, out shader, out shader2); this.optimizedSolidMaterial.shader = shader; this.optimizedCutoutMaterial.shader = shader2; int num = 1024; int num2 = 1024; int padding = 32; Profiler.BeginSample("OptimizeMaterial"); float[] array = new float[materials.Count]; float num3 = 0f; float num4 = 0f; for (int i = 0; i < materials.Count; i++) { if (!materials[i].tileV) { num4 += 1f; } else { num3 += 1f; } } for (int j = 0; j < materials.Count; j++) { if (materials[j].tileV) { array[j] = 1f; } else { array[j] = 1f / num4; } } TextureAtlas textureAtlas = new TextureAtlas(); for (int k = 0; k < materials.Count; k++) { Texture2D texture2D = null; Texture2D normal = null; Texture2D gloss = null; Texture2D transtex = null; Texture2D shadowOffsetTex = null; Color color = new Color(1f, 1f, 1f, 1f); float num5 = 0.03f; Vector2 textureScale = new Vector2(1f, 1f); Material material = materials[k].material; if (material) { if (material.HasProperty("_Color")) { color = material.GetColor("_Color"); } if (material.HasProperty("_MainTex")) { texture2D = (material.mainTexture as Texture2D); textureScale = material.GetTextureScale("_MainTex"); } if (material.HasProperty("_BumpMap")) { normal = (material.GetTexture("_BumpMap") as Texture2D); } if (material.HasProperty("_GlossMap")) { gloss = (material.GetTexture("_GlossMap") as Texture2D); } if (material.HasProperty("_TranslucencyMap")) { transtex = (material.GetTexture("_TranslucencyMap") as Texture2D); } if (material.HasProperty("_Shininess")) { num5 = material.GetFloat("_Shininess"); } if (material.HasProperty("_ShadowOffset")) { shadowOffsetTex = (material.GetTexture("_ShadowOffset") as Texture2D); } } num5 = Mathf.Clamp(num5, 0.03f, 1f); Vector2 scale = new Vector2(array[k], array[k]); if (texture2D) { scale.x *= (float)num / (float)texture2D.width; scale.y *= (float)num2 / (float)texture2D.height; } bool tileV = materials[k].tileV; if (!tileV) { textureScale = new Vector2(1f, 1f); } textureAtlas.AddTexture("tex" + k, texture2D, color, normal, gloss, transtex, shadowOffsetTex, num5, scale, tileV, textureScale); } textureAtlas.Pack(ref num, num2, padding, true); this.UpdateTextures(textureAtlas, materials); Rect rect = default(Rect); Vector2 texTiling = new Vector2(1f, 1f); int num6 = -1; for (int l = 0; l < triangles.Count; l++) { TreeTriangle treeTriangle = triangles[l]; if (treeTriangle.materialIndex != num6) { num6 = treeTriangle.materialIndex; rect = textureAtlas.GetUVRect("tex" + treeTriangle.materialIndex); texTiling = textureAtlas.GetTexTiling("tex" + treeTriangle.materialIndex); } for (int m = 0; m < 3; m++) { TreeVertex treeVertex = vertices[treeTriangle.v[m]]; if (!treeVertex.flag) { treeVertex.uv0.x = rect.x + treeVertex.uv0.x * rect.width; treeVertex.uv0.y = (rect.y + treeVertex.uv0.y * rect.height) * texTiling.y; treeVertex.flag = true; } } if (treeTriangle.isCutout) { treeTriangle.materialIndex = 1; } else { treeTriangle.materialIndex = 0; } } Profiler.EndSample(); return(true); }
public void UpdateFrequency(TreeData owner) { Profiler.BeginSample("UpdateFrequency"); if (this.distributionFrequency < 1) { this.distributionFrequency = 1; } if (this.parentGroup == null) { this.distributionFrequency = 1; if (this.nodes.Count < 1) { owner.AddNode(this, null, false); } } else { if (this.lockFlags == 0 && this.parentGroup != null) { int num = 0; for (int i = 0; i < this.parentGroup.nodes.Count; i++) { int num2 = Mathf.RoundToInt((float)this.distributionFrequency * this.parentGroup.nodes[i].GetScale()); if (num2 < 1) { num2 = 1; } for (int j = 0; j < num2; j++) { if (num < this.nodes.Count) { owner.SetNodeParent(this.nodes[num], this.parentGroup.nodes[i]); } else { owner.AddNode(this, this.parentGroup.nodes[i], false); } num++; } } if (num < this.nodes.Count) { List <TreeNode> list = new List <TreeNode>(); for (int k = num; k < this.nodes.Count; k++) { list.Add(this.nodes[k]); } for (int l = 0; l < list.Count; l++) { owner.DeleteNode(list[l], false); } } this.UpdateSeed(); this.UpdateDistribution(true, false); } } for (int m = 0; m < this.childGroups.Count; m++) { this.childGroups[m].UpdateFrequency(owner); } Profiler.EndSample(); }
public void UpdateFrequency(TreeData owner) { if (this.distributionFrequency < 1) { this.distributionFrequency = 1; } if (this.parentGroup == null) { this.distributionFrequency = 1; if (this.nodes.Count < 1) { owner.AddNode(this, null, false); } } else if ((this.lockFlags == 0) && (this.parentGroup != null)) { int num = 0; for (int j = 0; j < this.parentGroup.nodes.Count; j++) { int num3 = Mathf.RoundToInt(this.distributionFrequency * this.parentGroup.nodes[j].GetScale()); if (num3 < 1) { num3 = 1; } for (int k = 0; k < num3; k++) { if (num < this.nodes.Count) { owner.SetNodeParent(this.nodes[num], this.parentGroup.nodes[j]); } else { owner.AddNode(this, this.parentGroup.nodes[j], false); } num++; } } if (num < this.nodes.Count) { List<TreeNode> list = new List<TreeNode>(); for (int m = num; m < this.nodes.Count; m++) { list.Add(this.nodes[m]); } for (int n = 0; n < list.Count; n++) { owner.DeleteNode(list[n], false); } } this.UpdateSeed(); this.UpdateDistribution(true, false); } for (int i = 0; i < this.childGroups.Count; i++) { this.childGroups[i].UpdateFrequency(owner); } }
private void VerifySelection(TreeData treeData) { TreeGroup treeGroup = TreeEditor.s_SelectedGroup; TreeNode treeNode = TreeEditor.s_SelectedNode; if (treeGroup != null) { treeGroup = treeData.GetGroup(treeGroup.uniqueID); } if (treeNode != null) { treeNode = treeData.GetNode(treeNode.uniqueID); } if (treeGroup != treeData.root && treeGroup != null && !treeData.IsAncestor(treeData.root, treeGroup)) { treeGroup = null; treeNode = null; } if (treeNode != null && treeData.GetGroup(treeNode.groupID) != treeGroup) { treeNode = null; } if (treeGroup == null) { treeGroup = treeData.root; } if (TreeEditor.s_SelectedGroup != null && treeGroup == TreeEditor.s_SelectedGroup) { return; } this.SelectGroup(treeGroup); if (treeNode != null) { this.SelectNode(treeNode, treeData); } }
public void OnEnable(TreeData treeData) { m_TreeData = treeData; }
public void InspectorLeaf(TreeData treeData, TreeGroupLeaf group) { this.InspectorEditTools(base.target as Tree); GUIContent[] contentArray1 = new GUIContent[6]; contentArray1[0] = TreeEditorHelper.GetGUIContent("Distribution|Adjusts the count and placement of leaves in the group. Use the curves to fine tune position, rotation and scale. The curves are relative to the parent branch."); contentArray1[1] = TreeEditorHelper.GetGUIContent("Geometry|Select what type of geometry is generated for this leaf group and which materials are applied. If you use a custom mesh, its materials will be used."); contentArray1[2] = TreeEditorHelper.GetGUIContent("Shape|Adjusts the shape and growth of the leaves."); contentArray1[5] = TreeEditorHelper.GetGUIContent("Wind|Adjusts the parameters used for animating this group of leaves. Wind zones are only active in Play Mode. If you select too high values for Main Wind and Main Turbulence the leaves may float away from the branches."); GUIContent[] names = contentArray1; 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.geometryMode = this.GUIPopup(PropertyType.FullUpdate, geometryModeLeafString, geometryModeOptions, group.geometryMode, false); if (group.geometryMode != 4) { group.materialLeaf = this.GUIMaterialField(PropertyType.FullUpdate, group.uniqueID, materialLeafString, group.materialLeaf, TreeEditorHelper.NodeType.LeafNode); } if (group.geometryMode == 4) { group.instanceMesh = this.GUIObjectField(PropertyType.FullUpdate, meshString, group.instanceMesh, typeof(GameObject), false) as GameObject; } EndSettingsSection(); BeginSettingsSection(2, names); this.PrepareSpacing(false); group.size = this.GUIMinMaxSlider(PropertyType.Normal, sizeString, group.size, 0.1f, 2f, false); group.perpendicularAlign = this.GUISlider(PropertyType.Normal, perpendicularAlignString, group.perpendicularAlign, 0f, 1f, false); group.horizontalAlign = this.GUISlider(PropertyType.Normal, horizontalAlignString, group.horizontalAlign, 0f, 1f, false); EndSettingsSection(); BeginSettingsSection(5, names); this.PrepareSpacing(false); this.InspectorAnimation(treeData, group); EndSettingsSection(); GUI.enabled = enabled; EditorGUILayout.Space(); }
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(); }
private bool OnCheckHotkeys(TreeData treeData, bool checkFrameSelected) { switch (Event.current.type) { case EventType.ValidateCommand: if (((Event.current.commandName == "SoftDelete") || (Event.current.commandName == "Delete")) && ((s_SelectedGroup != null) && (s_SelectedGroup != treeData.root))) { Event.current.Use(); } if ((Event.current.commandName == "FrameSelected") && checkFrameSelected) { Event.current.Use(); } if (Event.current.commandName == "UndoRedoPerformed") { Event.current.Use(); } break; case EventType.ExecuteCommand: if (((Event.current.commandName == "SoftDelete") || (Event.current.commandName == "Delete")) && ((s_SelectedGroup != null) && (s_SelectedGroup != treeData.root))) { this.DeleteSelected(treeData); Event.current.Use(); } if ((Event.current.commandName == "FrameSelected") && checkFrameSelected) { this.FrameSelected(base.target as Tree); Event.current.Use(); } if (Event.current.commandName == "UndoRedoPerformed") { float num = GenerateMaterialHash(treeData.optimizedCutoutMaterial); if (s_CutoutMaterialHashBeforeUndo != num) { s_CutoutMaterialHashBeforeUndo = num; } else { treeData.materialHash = s_SavedSourceMaterialsHash; this.m_StartPointRotationDirty = true; UpdateMesh(base.target as Tree); } Event.current.Use(); return true; } if (Event.current.commandName == "CurveChangeCompleted") { UpdateMesh(base.target as Tree); Event.current.Use(); return true; } break; } return false; }
public void InspectorHierachy(TreeData treeData, Renderer renderer) { if (s_SelectedGroup == null) { Debug.Log("NO GROUP SELECTED!"); } else { EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]); GUILayout.BeginVertical(new GUILayoutOption[0]); bool changed = GUI.changed; Rect sizeRect = this.GUIPropBegin(); this.DrawHierachy(treeData, renderer, sizeRect); if (GUI.changed != changed) { this.m_WantCompleteUpdate = true; } this.GUIPropEnd(false); this.GUIPropBegin(); int num = -1; GUILayout.BeginHorizontal(styles.toolbar, new GUILayoutOption[0]); if (GUILayout.Button(styles.iconRefresh, styles.toolbarButton, new GUILayoutOption[0])) { TreeGroupLeaf.s_TextureHullsDirty = true; UpdateMesh(base.target as Tree); } GUILayout.FlexibleSpace(); GUI.enabled = s_SelectedGroup.CanHaveSubGroups(); if (GUILayout.Button(styles.iconAddLeaves, styles.toolbarButton, new GUILayoutOption[0])) { num = 0; } if (GUILayout.Button(styles.iconAddBranches, styles.toolbarButton, new GUILayoutOption[0])) { num = 1; } GUI.enabled = true; if (s_SelectedGroup == treeData.root) { GUI.enabled = false; } if (GUILayout.Button(styles.iconDuplicate, styles.toolbarButton, new GUILayoutOption[0])) { num = 3; } if (GUILayout.Button(styles.iconTrash, styles.toolbarButton, new GUILayoutOption[0])) { num = 2; } GUI.enabled = true; GUILayout.EndHorizontal(); switch (num) { case 0: { this.UndoStoreSelected(EditMode.CreateGroup); TreeGroup group = treeData.AddGroup(s_SelectedGroup, typeof(TreeGroupLeaf)); this.SelectGroup(group); this.m_WantCompleteUpdate = true; Event.current.Use(); break; } case 1: { this.UndoStoreSelected(EditMode.CreateGroup); TreeGroup group2 = treeData.AddGroup(s_SelectedGroup, typeof(TreeGroupBranch)); this.SelectGroup(group2); this.m_WantCompleteUpdate = true; Event.current.Use(); break; } case 2: this.DeleteSelected(treeData); Event.current.Use(); break; case 3: this.DuplicateSelected(treeData); Event.current.Use(); break; } this.GUIPropEnd(false); GUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); } }
private bool OnCheckHotkeys(TreeData treeData, bool checkFrameSelected) { EventType type = Event.current.type; if (type != EventType.ValidateCommand) { if (type == EventType.ExecuteCommand) { if ((Event.current.commandName == "SoftDelete" || Event.current.commandName == "Delete") && TreeEditor.s_SelectedGroup != null && TreeEditor.s_SelectedGroup != treeData.root) { this.DeleteSelected(treeData); Event.current.Use(); } if (Event.current.commandName == "FrameSelected" && checkFrameSelected) { this.FrameSelected(this.target as Tree); Event.current.Use(); } if (Event.current.commandName == "UndoRedoPerformed") { float num = TreeEditor.GenerateMaterialHash(treeData.optimizedCutoutMaterial); if (TreeEditor.s_CutoutMaterialHashBeforeUndo != num) { TreeEditor.s_CutoutMaterialHashBeforeUndo = num; } else { treeData.materialHash = TreeEditor.s_SavedSourceMaterialsHash; this.m_StartPointRotationDirty = true; TreeEditor.UpdateMesh(this.target as Tree); } Event.current.Use(); return true; } if (Event.current.commandName == "CurveChangeCompleted") { TreeEditor.UpdateMesh(this.target as Tree); Event.current.Use(); return true; } } } else { if ((Event.current.commandName == "SoftDelete" || Event.current.commandName == "Delete") && TreeEditor.s_SelectedGroup != null && TreeEditor.s_SelectedGroup != treeData.root) { Event.current.Use(); } if (Event.current.commandName == "FrameSelected" && checkFrameSelected) { Event.current.Use(); } if (Event.current.commandName == "UndoRedoPerformed") { Event.current.Use(); } } return false; }
public void InspectorRoot(TreeData treeData, TreeGroupRoot group) { GUIContent[] contentArray1 = new GUIContent[6]; contentArray1[0] = TreeEditorHelper.GetGUIContent("Distribution|"); contentArray1[1] = TreeEditorHelper.GetGUIContent("Geometry|"); contentArray1[2] = TreeEditorHelper.GetGUIContent("Material|Controls global material properties of the tree."); GUIContent[] names = contentArray1; bool enabled = GUI.enabled; BeginSettingsSection(0, names); this.PrepareSpacing(false); int seed = group.seed; group.seed = this.GUIIntSlider(PropertyType.Normal, treeSeedString, group.seed, 0, 0x98967f, false); if (group.seed != seed) { treeData.UpdateSeed(group.uniqueID); } group.rootSpread = this.GUISlider(PropertyType.Normal, areaSpreadString, group.rootSpread, 0f, 10f, false); group.groundOffset = this.GUISlider(PropertyType.Normal, groundOffsetString, group.groundOffset, 0f, 10f, false); EndSettingsSection(); BeginSettingsSection(1, names); this.PrepareSpacing(false); group.adaptiveLODQuality = this.GUISlider(PropertyType.FullUndo, lodQualityString, group.adaptiveLODQuality, 0f, 1f, false); group.enableAmbientOcclusion = this.GUIToggle(PropertyType.FullUndo, ambientOcclusionString, group.enableAmbientOcclusion, false); GUI.enabled = group.enableAmbientOcclusion; group.aoDensity = this.GUISlider(PropertyType.Normal, aoDensityString, group.aoDensity, 0f, 1f, false); GUI.enabled = true; EndSettingsSection(); Material optimizedCutoutMaterial = treeData.optimizedCutoutMaterial; if (optimizedCutoutMaterial != null) { BeginSettingsSection(2, names); this.PrepareSpacing(false); bool changed = GUI.changed; bool flag3 = this.GUIMaterialColor(optimizedCutoutMaterial, "_TranslucencyColor", translucencyColorString) | this.GUIMaterialSlider(optimizedCutoutMaterial, "_TranslucencyViewDependency", transViewDepString); flag3 |= this.GUIMaterialSlider(optimizedCutoutMaterial, "_Cutoff", alphaCutoffString); flag3 |= this.GUIMaterialSlider(optimizedCutoutMaterial, "_ShadowStrength", shadowStrengthString); if (flag3 | this.GUIMaterialFloatField(optimizedCutoutMaterial, "_ShadowOffsetScale", shadowOffsetString)) { s_CutoutMaterialHashBeforeUndo = GenerateMaterialHash(treeData.optimizedCutoutMaterial); } group.shadowTextureQuality = this.GUIPopup(PropertyType.FullUpdate, shadowCasterResString, leafMaterialOptions, group.shadowTextureQuality, false); GUI.changed = changed; EndSettingsSection(); } GUI.enabled = enabled; EditorGUILayout.Space(); }
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 void BuildHierachyNodes(TreeData treeData, List<HierachyNode> nodes, TreeGroup group, int depth) { HierachyNode item = new HierachyNode { group = group, pos = new Vector3(0f, depth * this.hierachySpread.y, 0f) }; nodes.Add(item); for (int i = 0; i < group.childGroupIDs.Length; i++) { TreeGroup group2 = treeData.GetGroup(group.childGroupIDs[i]); this.BuildHierachyNodes(treeData, nodes, group2, depth - 1); } }
public void OnEnable(TreeData treeData) { this.m_TreeData = treeData; }
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; }
// // Controls generation of nodes based on frequency // public void UpdateFrequency(TreeData owner) { Profiler.BeginSample("UpdateFrequency"); // Must have at least 1 if (distributionFrequency < 1) { distributionFrequency = 1; } if (parentGroup == null) { // Only root can have no parent.. // Must have 1 as distribution frequency distributionFrequency = 1; if (nodes.Count < 1) { owner.AddNode(this, null, false); } } else if ((lockFlags == 0) && (parentGroup != null)) { // Exact count depends on parent int newTotalCount = 0; for (int n = 0; n < parentGroup.nodes.Count; n++) { int tempFrequency = Mathf.RoundToInt(distributionFrequency * parentGroup.nodes[n].GetScale()); // make sure there is at least one node.. if (tempFrequency < 1) { tempFrequency = 1; } for (int i = 0; i < tempFrequency; i++) { if (newTotalCount < nodes.Count) { owner.SetNodeParent(nodes[newTotalCount], parentGroup.nodes[n]); } else { owner.AddNode(this, parentGroup.nodes[n], false); } newTotalCount++; } } // remove excess nodes if (newTotalCount < nodes.Count) { List <TreeNode> killNodes = new List <TreeNode>(); for (int i = newTotalCount; i < nodes.Count; i++) { killNodes.Add(nodes[i]); } for (int i = 0; i < killNodes.Count; i++) { owner.DeleteNode(killNodes[i], false); } //owner.ValidateReferences(); } UpdateSeed(); UpdateDistribution(true, false); } // Update child groups.. for (int i = 0; i < childGroups.Count; i++) { childGroups[i].UpdateFrequency(owner); } Profiler.EndSample(); // UpdateFrequency }
private void DrawHierachyNodes(TreeData treeData, List<HierachyNode> nodes, TreeGroup group, Vector2 offset, float alpha, float fade) { if (((this.dragNode != null) && this.isDragging) && (this.dragNode.group == group)) { alpha = 0.5f; fade = 0.75f; } Vector3 vector = new Vector3(0f, this.hierachyNodeSize.y * 0.5f, 0f); Vector3 vector2 = new Vector3(offset.x, offset.y); Handles.color = new Color(0f, 0f, 0f, 0.5f * alpha); if (EditorGUIUtility.isProSkin) { Handles.color = new Color(0.4f, 0.4f, 0.4f, 0.5f * alpha); } HierachyNode node = null; for (int i = 0; i < nodes.Count; i++) { if (group == nodes[i].group) { node = nodes[i]; break; } } if (node != null) { for (int j = 0; j < group.childGroupIDs.Length; j++) { TreeGroup group2 = treeData.GetGroup(group.childGroupIDs[j]); for (int m = 0; m < nodes.Count; m++) { if (nodes[m].group == group2) { Handles.DrawLine((node.pos + vector2) - vector, (nodes[m].pos + vector2) + vector); } } } Rect position = node.rect; position.x += offset.x; position.y += offset.y; int index = 0; if (node == this.dropNode) { index = 1; } else if (s_SelectedGroup == node.group) { if (s_SelectedNode != null) { index = 1; } else { index = 1; } } GUI.backgroundColor = new Color(1f, 1f, 1f, alpha); GUI.contentColor = new Color(1f, 1f, 1f, alpha); GUI.Label(position, GUIContent.none, styles.nodeBoxes[index]); Rect rect2 = new Rect((position.x + (position.width / 2f)) - 4f, position.y - 2f, 0f, 0f); Rect rect3 = new Rect((position.x + (position.width / 2f)) - 4f, (position.y + position.height) - 2f, 0f, 0f); Rect rect4 = new Rect(position.x + 1f, position.yMax - 36f, 32f, 32f); Rect rect5 = new Rect(position.xMax - 18f, position.yMax - 18f, 16f, 16f); Rect rect6 = new Rect(position.x, position.y, position.width - 2f, 16f); bool flag = true; int num5 = 0; GUIContent gUIContent = new GUIContent(); System.Type type = group.GetType(); if (type != typeof(TreeGroupBranch)) { if (type == typeof(TreeGroupLeaf)) { gUIContent = TreeEditorHelper.GetGUIContent("|Leaf Group"); num5 = 3; } else if (type == typeof(TreeGroupRoot)) { gUIContent = TreeEditorHelper.GetGUIContent("|Tree Root Node"); num5 = 4; flag = false; } } else { gUIContent = TreeEditorHelper.GetGUIContent("|Branch Group"); TreeGroupBranch branch = (TreeGroupBranch) group; switch (branch.geometryMode) { case TreeGroupBranch.GeometryMode.BranchFrond: num5 = 0; break; case TreeGroupBranch.GeometryMode.Branch: num5 = 1; break; case TreeGroupBranch.GeometryMode.Frond: num5 = 2; break; } } if (flag) { Rect hierachyNodeVisRect = this.GetHierachyNodeVisRect(position); GUIContent content = TreeEditorHelper.GetGUIContent("|Show / Hide Group"); content.image = styles.visibilityIcons[!group.visible ? 1 : 0].image; GUI.contentColor = new Color(1f, 1f, 1f, 0.7f); if (GUI.Button(hierachyNodeVisRect, content, GUIStyle.none)) { group.visible = !group.visible; GUI.changed = true; } GUI.contentColor = Color.white; } gUIContent.image = styles.nodeIcons[num5].image; GUI.contentColor = new Color(1f, 1f, 1f, !group.visible ? 0.5f : 1f); if (GUI.Button(rect4, gUIContent, GUIStyle.none) || (this.dragNode == node)) { TreeGroup group3 = s_SelectedGroup; this.SelectGroup(group); if (group3 == s_SelectedGroup) { Tree target = base.target as Tree; this.FrameSelected(target); } } GUI.contentColor = Color.white; if (group.CanHaveSubGroups()) { GUI.Label(rect2, GUIContent.none, styles.pinLabel); } if (flag) { GUIContent content3 = TreeEditorHelper.GetGUIContent("|Node Count"); content3.text = group.nodeIDs.Length.ToString(); GUI.Label(rect6, content3, styles.nodeLabelTop); if (this.m_TreeEditorHelper.NodeHasWrongMaterial(group)) { GUI.DrawTexture(rect5, ConsoleWindow.iconErrorSmall); } else if (group.lockFlags != 0) { GUI.DrawTexture(rect5, styles.warningIcon.image); } GUI.Label(rect3, GUIContent.none, styles.pinLabel); } for (int k = 0; k < group.childGroupIDs.Length; k++) { TreeGroup group4 = treeData.GetGroup(group.childGroupIDs[k]); this.DrawHierachyNodes(treeData, nodes, group4, offset, alpha * fade, fade); } GUI.backgroundColor = Color.white; GUI.contentColor = Color.white; } }
private void SelectNode(TreeNode node, TreeData treeData) { this.SelectGroup((node != null) ? treeData.GetGroup(node.groupID) : treeData.root); s_SelectedNode = node; s_SelectedPoint = -1; }
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; }
private void VerifySelection(TreeData treeData) { TreeGroup g = s_SelectedGroup; TreeNode node = s_SelectedNode; if (g != null) { g = treeData.GetGroup(g.uniqueID); } if (node != null) { node = treeData.GetNode(node.uniqueID); } if (((g != treeData.root) && (g != null)) && !treeData.IsAncestor(treeData.root, g)) { g = null; node = null; } if ((node != null) && (treeData.GetGroup(node.groupID) != g)) { node = null; } if (g == null) { g = treeData.root; } if ((s_SelectedGroup == null) || (g != s_SelectedGroup)) { this.SelectGroup(g); if (node != null) { this.SelectNode(node, treeData); } } }
private void HandleDragHierachyNodes(TreeData treeData, List<HierachyNode> nodes) { if (this.dragNode == null) { this.isDragging = false; this.dropNode = null; } int controlID = GUIUtility.GetControlID(FocusType.Passive); EventType typeForControl = Event.current.GetTypeForControl(controlID); if ((typeForControl == EventType.MouseDown) && (Event.current.button == 0)) { for (int i = 0; i < nodes.Count; i++) { if ((nodes[i].rect.Contains(Event.current.mousePosition) && !this.GetHierachyNodeVisRect(nodes[i].rect).Contains(Event.current.mousePosition)) && !(nodes[i].group is TreeGroupRoot)) { this.dragClickPos = Event.current.mousePosition; this.dragNode = nodes[i]; GUIUtility.hotControl = controlID; Event.current.Use(); break; } } } if (this.dragNode != null) { this.dropNode = null; for (int j = 0; j < nodes.Count; j++) { if (nodes[j].rect.Contains(Event.current.mousePosition)) { TreeGroup ancestor = this.dragNode.group; TreeGroup group = nodes[j].group; if (((group != ancestor) && group.CanHaveSubGroups()) && ((treeData.GetGroup(ancestor.parentGroupID) != group) && !treeData.IsAncestor(ancestor, group))) { this.dropNode = nodes[j]; break; } } } switch (typeForControl) { case EventType.MouseMove: case EventType.MouseDrag: { Vector2 vector = this.dragClickPos - Event.current.mousePosition; if (vector.magnitude > 10f) { this.isDragging = true; } Event.current.Use(); break; } default: if ((typeForControl == EventType.MouseUp) && (GUIUtility.hotControl == controlID)) { if (this.dropNode != null) { this.UndoStoreSelected(EditMode.Everything); TreeGroup g = this.dragNode.group; TreeGroup parent = this.dropNode.group; treeData.SetGroupParent(g, parent); this.m_WantCompleteUpdate = true; } else { base.Repaint(); } this.dragNode = null; this.dropNode = null; GUIUtility.hotControl = 0; Event.current.Use(); } break; } } }
private void DrawHierachyNodes(TreeData treeData, List<TreeEditor.HierachyNode> nodes, TreeGroup group, Vector2 offset, float alpha, float fade) { if (this.dragNode != null && this.isDragging && this.dragNode.group == group) { alpha = 0.5f; fade = 0.75f; } Vector3 b = new Vector3(0f, this.hierachyNodeSize.y * 0.5f, 0f); Vector3 b2 = new Vector3(offset.x, offset.y); Handles.color = new Color(0f, 0f, 0f, 0.5f * alpha); if (EditorGUIUtility.isProSkin) { Handles.color = new Color(0.4f, 0.4f, 0.4f, 0.5f * alpha); } TreeEditor.HierachyNode hierachyNode = null; for (int i = 0; i < nodes.Count; i++) { if (group == nodes[i].group) { hierachyNode = nodes[i]; break; } } if (hierachyNode == null) { return; } for (int j = 0; j < group.childGroupIDs.Length; j++) { TreeGroup group2 = treeData.GetGroup(group.childGroupIDs[j]); for (int k = 0; k < nodes.Count; k++) { if (nodes[k].group == group2) { Handles.DrawLine(hierachyNode.pos + b2 - b, nodes[k].pos + b2 + b); } } } Rect rect = hierachyNode.rect; rect.x += offset.x; rect.y += offset.y; int num = 0; if (hierachyNode == this.dropNode) { num = 1; } else { if (TreeEditor.s_SelectedGroup == hierachyNode.group) { if (TreeEditor.s_SelectedNode != null) { num = 1; } else { num = 1; } } } GUI.backgroundColor = new Color(1f, 1f, 1f, alpha); GUI.contentColor = new Color(1f, 1f, 1f, alpha); GUI.Label(rect, GUIContent.none, TreeEditor.styles.nodeBoxes[num]); Rect position = new Rect(rect.x + rect.width / 2f - 4f, rect.y - 2f, 0f, 0f); Rect position2 = new Rect(rect.x + rect.width / 2f - 4f, rect.y + rect.height - 2f, 0f, 0f); Rect position3 = new Rect(rect.x + 1f, rect.yMax - 36f, 32f, 32f); Rect position4 = new Rect(rect.xMax - 18f, rect.yMax - 18f, 16f, 16f); Rect position5 = new Rect(rect.x, rect.y, rect.width - 2f, 16f); bool flag = true; int num2 = 0; GUIContent gUIContent = new GUIContent(); Type type = group.GetType(); if (type == typeof(TreeGroupBranch)) { gUIContent = TreeEditorHelper.GetGUIContent("TreeEditor.Hierachy.TreeGroupBranch"); TreeGroupBranch treeGroupBranch = (TreeGroupBranch)group; switch (treeGroupBranch.geometryMode) { case TreeGroupBranch.GeometryMode.Branch: num2 = 1; break; case TreeGroupBranch.GeometryMode.BranchFrond: num2 = 0; break; case TreeGroupBranch.GeometryMode.Frond: num2 = 2; break; } } else { if (type == typeof(TreeGroupLeaf)) { gUIContent = TreeEditorHelper.GetGUIContent("TreeEditor.Hierachy.TreeGroupLeaf"); num2 = 3; } else { if (type == typeof(TreeGroupRoot)) { gUIContent = TreeEditorHelper.GetGUIContent("TreeEditor.Hierachy.TreeGroupRoot"); num2 = 4; flag = false; } } } if (flag) { Rect hierachyNodeVisRect = this.GetHierachyNodeVisRect(rect); GUIContent gUIContent2 = TreeEditorHelper.GetGUIContent("TreeEditor.Hierachy.ShowHide"); gUIContent2.image = TreeEditor.styles.visibilityIcons[(!group.visible) ? 1 : 0].image; GUI.contentColor = new Color(1f, 1f, 1f, 0.7f); if (GUI.Button(hierachyNodeVisRect, gUIContent2, GUIStyle.none)) { group.visible = !group.visible; GUI.changed = true; } GUI.contentColor = Color.white; } gUIContent.image = TreeEditor.styles.nodeIcons[num2].image; GUI.contentColor = new Color(1f, 1f, 1f, (!group.visible) ? 0.5f : 1f); if (GUI.Button(position3, gUIContent, GUIStyle.none) || this.dragNode == hierachyNode) { TreeGroup treeGroup = TreeEditor.s_SelectedGroup; this.SelectGroup(group); if (treeGroup == TreeEditor.s_SelectedGroup) { Tree tree = this.target as Tree; this.FrameSelected(tree); } } GUI.contentColor = Color.white; if (group.CanHaveSubGroups()) { GUI.Label(position, GUIContent.none, TreeEditor.styles.pinLabel); } if (flag) { GUIContent gUIContent3 = TreeEditorHelper.GetGUIContent("TreeEditor.Hierachy.NodeCount"); gUIContent3.text = group.nodeIDs.Length.ToString(); GUI.Label(position5, gUIContent3, TreeEditor.styles.nodeLabelTop); if (this.m_TreeEditorHelper.NodeHasWrongMaterial(group)) { GUI.DrawTexture(position4, ConsoleWindow.iconErrorSmall); } else { if (group.lockFlags != 0) { GUI.DrawTexture(position4, TreeEditor.styles.warningIcon.image); } } GUI.Label(position2, GUIContent.none, TreeEditor.styles.pinLabel); } for (int l = 0; l < group.childGroupIDs.Length; l++) { TreeGroup group3 = treeData.GetGroup(group.childGroupIDs[l]); this.DrawHierachyNodes(treeData, nodes, group3, offset, alpha * fade, fade); } GUI.backgroundColor = Color.white; GUI.contentColor = Color.white; }