private void CopyFields(object n, object n2) { if (n.GetType() != n2.GetType()) { return; } FieldInfo[] fields = n.GetType().GetFields(); for (int i = 0; i < fields.Length; i++) { if (fields[i].IsPublic) { if (fields[i].FieldType == typeof(TreeSpline)) { TreeSpline o = fields[i].GetValue(n) as TreeSpline; fields[i].SetValue(n2, new TreeSpline(o)); } else { if (fields[i].FieldType == typeof(AnimationCurve)) { AnimationCurve animationCurve = fields[i].GetValue(n) as AnimationCurve; AnimationCurve animationCurve2 = new AnimationCurve(animationCurve.keys); animationCurve2.postWrapMode = animationCurve.postWrapMode; animationCurve2.preWrapMode = animationCurve.preWrapMode; fields[i].SetValue(n2, animationCurve2); } else { fields[i].SetValue(n2, fields[i].GetValue(n)); } } } } }
public TreeSpline(TreeSpline o) { this.nodes = new SplineNode[o.nodes.Length]; for (int i = 0; i < o.nodes.Length; i++) { this.nodes[i] = new SplineNode(o.nodes[i]); } this.tension = o.tension; }
public TreeSpline(TreeSpline o) { nodes = new SplineNode[o.nodes.Length]; for (int i = 0; i < o.nodes.Length; i++) { nodes[i] = new SplineNode(o.nodes[i]); } tension = o.tension; }
public TreeNode() { this.spline = null; this.parentID = 0; this.groupID = 0; this.parent = null; this.group = null; this.seed = 1234; this.breakOffset = 1f; this.visible = true; this.animSeed = 0f; this.scale = 1f; this.rotation = Quaternion.identity; this.matrix = Matrix4x4.identity; }
public TreeNode() { spline = null; parentID = 0; groupID = 0; parent = null; group = null; seed = 1234; breakOffset = 1.0f; visible = true; animSeed = 0.0f; scale = 1.0f; rotation = Quaternion.identity; matrix = Matrix4x4.identity; }
public void UpdateSpline(TreeNode node) { if (this.lockFlags != 0) { return; } UnityEngine.Random.seed = node.seed; if (node.spline == null) { TreeSpline spline = new TreeSpline(); node.spline = spline; } float num = this.height.y * node.GetScale(); float num2 = 1f; int num3 = (int)Mathf.Round(num / num2); float num4 = 0f; Quaternion quaternion = Quaternion.identity; Vector3 vector = new Vector3(0f, 0f, 0f); Matrix4x4 inverse = (node.matrix * base.GetRootMatrix()).inverse; Quaternion to = MathUtils.QuaternionFromMatrix(inverse) * Quaternion.Euler(0f, node.angle, 0f); Quaternion to2 = MathUtils.QuaternionFromMatrix(inverse) * Quaternion.Euler(-180f, node.angle, 0f); node.spline.Reset(); node.spline.AddPoint(vector, 0f); for (int i = 0; i < num3; i++) { float num5 = num2; if (i == num3 - 1) { num5 = num - num4; } num4 += num5; float num6 = num4 / num; float num7 = Mathf.Clamp(this.seekCurve.Evaluate(num6), -1f, 1f); float t = Mathf.Clamp01(num7) * this.seekBlend; float t2 = Mathf.Clamp01(-num7) * this.seekBlend; quaternion = Quaternion.Slerp(quaternion, to, t); quaternion = Quaternion.Slerp(quaternion, to2, t2); float t3 = this.crinklyness * Mathf.Clamp01(this.crinkCurve.Evaluate(num6)); Quaternion to3 = Quaternion.Euler(new Vector3(180f * (UnityEngine.Random.value - 0.5f), node.angle, 180f * (UnityEngine.Random.value - 0.5f))); quaternion = Quaternion.Slerp(quaternion, to3, t3); vector += quaternion * new Vector3(0f, num5, 0f); node.spline.AddPoint(vector, num6); } node.spline.UpdateTime(); node.spline.UpdateRotations(); }
public void UpdateSpline(TreeNode node) { if (base.lockFlags == 0) { UnityEngine.Random.InitState(node.seed); if (node.spline == null) { TreeSpline spline = new TreeSpline(); node.spline = spline; } float num = this.height.y * node.GetScale(); float num2 = 1f; int num3 = (int)Mathf.Round(num / num2); float num4 = 0f; Quaternion identity = Quaternion.identity; Vector3 pos = new Vector3(0f, 0f, 0f); Matrix4x4 matrixx2 = node.matrix * base.GetRootMatrix(); Matrix4x4 inverse = matrixx2.inverse; Quaternion b = MathUtils.QuaternionFromMatrix(inverse) * Quaternion.Euler(0f, node.angle, 0f); Quaternion quaternion3 = MathUtils.QuaternionFromMatrix(inverse) * Quaternion.Euler(-180f, node.angle, 0f); node.spline.Reset(); node.spline.AddPoint(pos, 0f); for (int i = 0; i < num3; i++) { float y = num2; if (i == (num3 - 1)) { y = num - num4; } num4 += y; float time = num4 / num; float num8 = Mathf.Clamp(this.seekCurve.Evaluate(time), -1f, 1f); float t = Mathf.Clamp01(num8) * this.seekBlend; float num10 = Mathf.Clamp01(-num8) * this.seekBlend; identity = Quaternion.Slerp(Quaternion.Slerp(identity, b, t), quaternion3, num10); float num11 = this.crinklyness * Mathf.Clamp01(this.crinkCurve.Evaluate(time)); Quaternion quaternion4 = Quaternion.Euler(new Vector3(180f * (UnityEngine.Random.value - 0.5f), node.angle, 180f * (UnityEngine.Random.value - 0.5f))); identity = Quaternion.Slerp(identity, quaternion4, num11); pos += identity * new Vector3(0f, y, 0f); node.spline.AddPoint(pos, time); } node.spline.UpdateTime(); node.spline.UpdateRotations(); } }
private void OnSceneGUI() { Tree target = this.target as Tree; TreeData treeData = GetTreeData(target); if (treeData != null) { this.VerifySelection(treeData); if (s_SelectedGroup != null) { this.OnCheckHotkeys(treeData, true); Transform transform = target.transform; Matrix4x4 localToWorldMatrix = target.transform.localToWorldMatrix; Event current = Event.current; if (s_SelectedGroup.GetType() == typeof(TreeGroupRoot)) { Tools.s_Hidden = false; Handles.color = s_NormalColor; Handles.DrawWireDisc(transform.position, transform.up, treeData.root.rootSpread); } else { Tools.s_Hidden = true; Handles.color = Handles.secondaryColor; Handles.DrawWireDisc(transform.position, transform.up, treeData.root.rootSpread); } if ((s_SelectedGroup != null) && (s_SelectedGroup.GetType() == typeof(TreeGroupBranch))) { EventType rawType = current.type; if ((current.type == EventType.Ignore) && (current.rawType == EventType.MouseUp)) { rawType = current.rawType; } Handles.DrawLine(Vector3.zero, Vector3.zero); GL.Begin(1); for (int i = 0; i < s_SelectedGroup.nodeIDs.Length; i++) { TreeNode node = treeData.GetNode(s_SelectedGroup.nodeIDs[i]); TreeSpline spline = node.spline; if (spline != null) { Handles.color = (node != s_SelectedNode) ? s_GroupColor : s_NormalColor; Matrix4x4 matrixx2 = localToWorldMatrix * node.matrix; Vector3 v = matrixx2.MultiplyPoint(spline.GetPositionAtTime(0f)); GL.Color(Handles.color); for (float k = 0.01f; k <= 1f; k += 0.01f) { Vector3 vector2 = matrixx2.MultiplyPoint(spline.GetPositionAtTime(k)); GL.Vertex(v); GL.Vertex(vector2); v = vector2; } } } GL.End(); for (int j = 0; j < s_SelectedGroup.nodeIDs.Length; j++) { TreeNode node2 = treeData.GetNode(s_SelectedGroup.nodeIDs[j]); TreeSpline spline2 = node2.spline; if (spline2 != null) { Handles.color = (node2 != s_SelectedNode) ? s_GroupColor : s_NormalColor; Matrix4x4 m = localToWorldMatrix * node2.matrix; for (int n = 0; n < spline2.nodes.Length; n++) { SplineNode node3 = spline2.nodes[n]; Vector3 position = m.MultiplyPoint(node3.point); float size = HandleUtility.GetHandleSize(position) * 0.08f; Handles.color = Handles.centerColor; int keyboardControl = GUIUtility.keyboardControl; switch (editMode) { case EditMode.MoveNode: if (n != 0) { break; } position = Handles.FreeMoveHandle(position, Quaternion.identity, size, Vector3.zero, new Handles.DrawCapFunction(Handles.CircleCap)); goto Label_0325; case EditMode.RotateNode: Handles.FreeMoveHandle(position, Quaternion.identity, size, Vector3.zero, new Handles.DrawCapFunction(Handles.CircleCap)); if (((rawType == EventType.MouseDown) && (current.type == EventType.Used)) && (keyboardControl != GUIUtility.keyboardControl)) { this.SelectNode(node2, treeData); s_SelectedPoint = n; this.m_GlobalToolRotation = Quaternion.identity; this.m_TempSpline = new TreeSpline(node2.spline); } GUI.changed = false; goto Label_0874; case EditMode.Freehand: Handles.FreeMoveHandle(position, Quaternion.identity, size, Vector3.zero, new Handles.DrawCapFunction(Handles.CircleCap)); if (((rawType == EventType.MouseDown) && (current.type == EventType.Used)) && (keyboardControl != GUIUtility.keyboardControl)) { Undo.RegisterCompleteObjectUndo(treeData, "Free Hand"); this.SelectNode(node2, treeData); s_SelectedPoint = n; s_StartPosition = position; int c = Mathf.Max(2, s_SelectedPoint + 1); node2.spline.SetNodeCount(c); current.Use(); } if (((s_SelectedPoint == n) && (s_SelectedNode == node2)) && (rawType == EventType.MouseDrag)) { Ray ray2 = HandleUtility.GUIPointToWorldRay(current.mousePosition); Vector3 forward = Camera.current.transform.forward; Plane plane2 = new Plane(forward, s_StartPosition); float enter = 0f; if (plane2.Raycast(ray2, out enter)) { Vector3 vector7 = ray2.origin + ((Vector3) (enter * ray2.direction)); if (s_SelectedPoint == 0) { s_SelectedPoint = 1; } s_SelectedGroup.Lock(); s_SelectedNode.spline.nodes[s_SelectedPoint].point = m.inverse.MultiplyPoint(vector7); Vector3 vector8 = s_SelectedNode.spline.nodes[s_SelectedPoint].point - s_SelectedNode.spline.nodes[s_SelectedPoint - 1].point; if (vector8.magnitude > 1f) { s_SelectedNode.spline.nodes[s_SelectedPoint].point = s_SelectedNode.spline.nodes[s_SelectedPoint - 1].point + vector8; s_SelectedPoint++; if (s_SelectedPoint >= s_SelectedNode.spline.nodes.Length) { s_SelectedNode.spline.AddPoint(m.inverse.MultiplyPoint(vector7), 1.1f); } } s_SelectedNode.spline.UpdateTime(); s_SelectedNode.spline.UpdateRotations(); current.Use(); PreviewMesh(target); } } goto Label_0874; default: goto Label_0874; } position = Handles.FreeMoveHandle(position, Quaternion.identity, size, Vector3.zero, new Handles.DrawCapFunction(Handles.RectangleCap)); Label_0325: if (((rawType == EventType.MouseDown) && (current.type == EventType.Used)) && (keyboardControl != GUIUtility.keyboardControl)) { this.SelectNode(node2, treeData); s_SelectedPoint = n; this.m_StartPointRotation = MathUtils.QuaternionFromMatrix(m) * node3.rot; } if (((rawType == EventType.MouseDown) || (rawType == EventType.MouseUp)) && (current.type == EventType.Used)) { this.m_StartPointRotation = MathUtils.QuaternionFromMatrix(m) * node3.rot; } if (((rawType == EventType.MouseUp) && (current.type == EventType.Used)) && treeData.isInPreviewMode) { UpdateMesh(target); } if (GUI.changed) { Undo.RegisterCompleteObjectUndo(treeData, "Move"); s_SelectedGroup.Lock(); float baseAngle = node2.baseAngle; if (n == 0) { TreeNode node4 = treeData.GetNode(s_SelectedNode.parentID); Ray mouseRay = HandleUtility.GUIPointToWorldRay(current.mousePosition); float num8 = 0f; if (node4 != null) { TreeGroup group = treeData.GetGroup(s_SelectedGroup.parentGroupID); if (group.GetType() == typeof(TreeGroupBranch)) { s_SelectedNode.offset = this.FindClosestOffset(treeData, localToWorldMatrix, node4, mouseRay, ref baseAngle); position = m.MultiplyPoint(Vector3.zero); } else if (group.GetType() == typeof(TreeGroupRoot)) { Vector3 inPoint = localToWorldMatrix.MultiplyPoint(Vector3.zero); Plane plane = new Plane(localToWorldMatrix.MultiplyVector(Vector3.up), inPoint); if (plane.Raycast(mouseRay, out num8)) { position = mouseRay.origin + ((Vector3) (mouseRay.direction * num8)); Vector3 vector5 = position - inPoint; vector5 = localToWorldMatrix.inverse.MultiplyVector(vector5); s_SelectedNode.offset = Mathf.Clamp01(vector5.magnitude / treeData.root.rootSpread); baseAngle = Mathf.Atan2(vector5.z, vector5.x) * 57.29578f; position = m.MultiplyPoint(Vector3.zero); } else { position = m.MultiplyPoint(node3.point); } } } } node2.baseAngle = baseAngle; node3.point = m.inverse.MultiplyPoint(position); spline2.UpdateTime(); spline2.UpdateRotations(); PreviewMesh(target); GUI.changed = false; } Label_0874: if (((s_SelectedPoint == n) && (s_SelectedNode == node2)) && this.m_StartPointRotationDirty) { spline2.UpdateTime(); spline2.UpdateRotations(); this.m_StartPointRotation = MathUtils.QuaternionFromMatrix(m) * node3.rot; this.m_GlobalToolRotation = Quaternion.identity; this.m_StartPointRotationDirty = false; } } } } if ((rawType == EventType.MouseUp) && (editMode == EditMode.Freehand)) { s_SelectedPoint = -1; if (treeData.isInPreviewMode) { UpdateMesh(target); } } if (((s_SelectedPoint > 0) && (editMode == EditMode.MoveNode)) && (s_SelectedNode != null)) { TreeNode node5 = s_SelectedNode; SplineNode node6 = node5.spline.nodes[s_SelectedPoint]; Matrix4x4 matrixx4 = localToWorldMatrix * node5.matrix; Vector3 vector9 = matrixx4.MultiplyPoint(node6.point); Quaternion identity = Quaternion.identity; if (Tools.pivotRotation == PivotRotation.Local) { switch (rawType) { case EventType.MouseUp: case EventType.MouseDown: this.m_StartPointRotation = MathUtils.QuaternionFromMatrix(matrixx4) * node6.rot; break; } identity = this.m_StartPointRotation; } vector9 = this.DoPositionHandle(vector9, identity, false); if (GUI.changed) { Undo.RegisterCompleteObjectUndo(treeData, "Move"); s_SelectedGroup.Lock(); node6.point = matrixx4.inverse.MultiplyPoint(vector9); node5.spline.UpdateTime(); node5.spline.UpdateRotations(); PreviewMesh(target); } if (((rawType == EventType.MouseUp) && (current.type == EventType.Used)) && treeData.isInPreviewMode) { UpdateMesh(target); } } if (((s_SelectedPoint >= 0) && (editMode == EditMode.RotateNode)) && (s_SelectedNode != null)) { TreeNode node7 = s_SelectedNode; SplineNode node8 = node7.spline.nodes[s_SelectedPoint]; Matrix4x4 matrixx5 = localToWorldMatrix * node7.matrix; if (this.m_TempSpline == null) { this.m_TempSpline = new TreeSpline(node7.spline); } Vector3 vector10 = matrixx5.MultiplyPoint(node8.point); Quaternion globalToolRotation = Quaternion.identity; this.m_GlobalToolRotation = Handles.RotationHandle(this.m_GlobalToolRotation, vector10); globalToolRotation = this.m_GlobalToolRotation; if (GUI.changed) { Undo.RegisterCompleteObjectUndo(treeData, "Move"); s_SelectedGroup.Lock(); for (int num11 = s_SelectedPoint + 1; num11 < this.m_TempSpline.nodes.Length; num11++) { Vector3 vector11 = this.m_TempSpline.nodes[num11].point - node8.point; vector11 = matrixx5.MultiplyVector(vector11); vector11 = (Vector3) (globalToolRotation * vector11); vector11 = matrixx5.inverse.MultiplyVector(vector11); Vector3 vector12 = node8.point + vector11; s_SelectedNode.spline.nodes[num11].point = vector12; } node7.spline.UpdateTime(); node7.spline.UpdateRotations(); PreviewMesh(target); } if (((rawType == EventType.MouseUp) && (current.type == EventType.Used)) && treeData.isInPreviewMode) { UpdateMesh(target); } } } if ((s_SelectedGroup != null) && (s_SelectedGroup.GetType() == typeof(TreeGroupLeaf))) { for (int num12 = 0; num12 < s_SelectedGroup.nodeIDs.Length; num12++) { TreeNode node9 = treeData.GetNode(s_SelectedGroup.nodeIDs[num12]); Matrix4x4 matrixx6 = localToWorldMatrix * node9.matrix; Vector3 vector13 = matrixx6.MultiplyPoint(Vector3.zero); float num13 = HandleUtility.GetHandleSize(vector13) * 0.08f; Handles.color = Handles.centerColor; EventType type = current.type; int num14 = GUIUtility.keyboardControl; switch (editMode) { case EditMode.MoveNode: Handles.FreeMoveHandle(vector13, Quaternion.identity, num13, Vector3.zero, new Handles.DrawCapFunction(Handles.CircleCap)); if (((type == EventType.MouseDown) && (current.type == EventType.Used)) && (num14 != GUIUtility.keyboardControl)) { this.SelectNode(node9, treeData); this.m_GlobalToolRotation = MathUtils.QuaternionFromMatrix(matrixx6); this.m_StartMatrix = matrixx6; this.m_StartPointRotation = node9.rotation; this.m_LockedWorldPos = new Vector3(this.m_StartMatrix.m03, this.m_StartMatrix.m13, this.m_StartMatrix.m23); } if (((type == EventType.MouseUp) && (current.type == EventType.Used)) && treeData.isInPreviewMode) { UpdateMesh(target); } if (GUI.changed) { s_SelectedGroup.Lock(); TreeNode node10 = treeData.GetNode(node9.parentID); TreeGroup group2 = treeData.GetGroup(s_SelectedGroup.parentGroupID); Ray ray3 = HandleUtility.GUIPointToWorldRay(current.mousePosition); float num15 = 0f; float rotation = node9.baseAngle; if (group2.GetType() == typeof(TreeGroupBranch)) { node9.offset = this.FindClosestOffset(treeData, localToWorldMatrix, node10, ray3, ref rotation); node9.baseAngle = rotation; PreviewMesh(target); break; } if (group2.GetType() == typeof(TreeGroupRoot)) { Vector3 vector14 = localToWorldMatrix.MultiplyPoint(Vector3.zero); Plane plane3 = new Plane(localToWorldMatrix.MultiplyVector(Vector3.up), vector14); if (plane3.Raycast(ray3, out num15)) { vector13 = ray3.origin + ((Vector3) (ray3.direction * num15)); Vector3 vector15 = vector13 - vector14; vector15 = localToWorldMatrix.inverse.MultiplyVector(vector15); node9.offset = Mathf.Clamp01(vector15.magnitude / treeData.root.rootSpread); rotation = Mathf.Atan2(vector15.z, vector15.x) * 57.29578f; } node9.baseAngle = rotation; PreviewMesh(target); } } break; case EditMode.RotateNode: Handles.FreeMoveHandle(vector13, Quaternion.identity, num13, Vector3.zero, new Handles.DrawCapFunction(Handles.CircleCap)); if (((type == EventType.MouseDown) && (current.type == EventType.Used)) && (num14 != GUIUtility.keyboardControl)) { this.SelectNode(node9, treeData); this.m_GlobalToolRotation = MathUtils.QuaternionFromMatrix(matrixx6); this.m_StartMatrix = matrixx6; this.m_StartPointRotation = node9.rotation; this.m_LockedWorldPos = new Vector3(matrixx6.m03, matrixx6.m13, matrixx6.m23); } if (s_SelectedNode == node9) { type = current.GetTypeForControl(GUIUtility.hotControl); this.m_GlobalToolRotation = Handles.RotationHandle(this.m_GlobalToolRotation, this.m_LockedWorldPos); if ((type == EventType.MouseUp) && (current.type == EventType.Used)) { this.m_LockedWorldPos = new Vector3(matrixx6.m03, matrixx6.m13, matrixx6.m23); if (treeData.isInPreviewMode) { UpdateMesh(target); } } if (GUI.changed) { s_SelectedGroup.Lock(); Quaternion quaternion3 = Quaternion.Inverse(MathUtils.QuaternionFromMatrix(this.m_StartMatrix)); node9.rotation = this.m_StartPointRotation * (quaternion3 * this.m_GlobalToolRotation); MathUtils.QuaternionNormalize(ref node9.rotation); PreviewMesh(target); } } break; } } } } } }
public void UpdateSpline(TreeNode node) { if (base.lockFlags == 0) { UnityEngine.Random.InitState(node.seed); if (node.spline == null) { TreeSpline spline = new TreeSpline(); node.spline = spline; } float num = this.height.y * node.GetScale(); float num2 = 1f; int num3 = (int) Mathf.Round(num / num2); float num4 = 0f; Quaternion identity = Quaternion.identity; Vector3 pos = new Vector3(0f, 0f, 0f); Matrix4x4 matrixx2 = node.matrix * base.GetRootMatrix(); Matrix4x4 inverse = matrixx2.inverse; Quaternion b = MathUtils.QuaternionFromMatrix(inverse) * Quaternion.Euler(0f, node.angle, 0f); Quaternion quaternion3 = MathUtils.QuaternionFromMatrix(inverse) * Quaternion.Euler(-180f, node.angle, 0f); node.spline.Reset(); node.spline.AddPoint(pos, 0f); for (int i = 0; i < num3; i++) { float y = num2; if (i == (num3 - 1)) { y = num - num4; } num4 += y; float time = num4 / num; float num8 = Mathf.Clamp(this.seekCurve.Evaluate(time), -1f, 1f); float t = Mathf.Clamp01(num8) * this.seekBlend; float num10 = Mathf.Clamp01(-num8) * this.seekBlend; identity = Quaternion.Slerp(Quaternion.Slerp(identity, b, t), quaternion3, num10); float num11 = this.crinklyness * Mathf.Clamp01(this.crinkCurve.Evaluate(time)); Quaternion quaternion4 = Quaternion.Euler(new Vector3(180f * (UnityEngine.Random.value - 0.5f), node.angle, 180f * (UnityEngine.Random.value - 0.5f))); identity = Quaternion.Slerp(identity, quaternion4, num11); pos += identity * new Vector3(0f, y, 0f); node.spline.AddPoint(pos, time); } node.spline.UpdateTime(); node.spline.UpdateRotations(); } }
public void UpdateSpline(TreeNode node) { // locked due to user editing... if (lockFlags != 0) { return; } Random.InitState(node.seed); if (node.spline == null) { TreeSpline spline = new TreeSpline(); node.spline = spline; // Add asset to database.. // UnityEditor.AssetDatabase.AddObjectToAsset(spline, this); } float totalHeight = height.y * node.GetScale(); float stepSize = 1.0f; int count = (int)Mathf.Round(totalHeight / stepSize); float curHeight = 0.0f; Quaternion r = Quaternion.identity; Vector3 p = new Vector3(0, 0, 0); Matrix4x4 worldUp = (node.matrix * GetRootMatrix()).inverse; Quaternion rotPhotropism = MathUtils.QuaternionFromMatrix(worldUp) * Quaternion.Euler(0.0f, node.angle, 0.0f); Quaternion rotGravitropism = MathUtils.QuaternionFromMatrix(worldUp) * Quaternion.Euler(-180.0f, node.angle, 0.0f); node.spline.Reset(); node.spline.AddPoint(p, 0.0f); for (int i = 0; i < count; i++) { float stepPos = stepSize; if (i == (count - 1)) { stepPos = totalHeight - curHeight; } curHeight += stepPos; float curTime = curHeight / totalHeight; // seek towards sun or ground.. float seekValue = Mathf.Clamp(seekCurve.Evaluate(curTime), -1.0f, 1.0f); float seekSun = Mathf.Clamp01(seekValue) * seekBlend; float seekGround = Mathf.Clamp01(-seekValue) * seekBlend; r = Quaternion.Slerp(r, rotPhotropism, seekSun); r = Quaternion.Slerp(r, rotGravitropism, seekGround); // crinkle float crinkle = crinklyness * Mathf.Clamp01(crinkCurve.Evaluate(curTime)); Quaternion c = Quaternion.Euler(new Vector3(180.0f * (Random.value - 0.5f), node.angle, 180.0f * (Random.value - 0.5f))); r = Quaternion.Slerp(r, c, crinkle); // advance position p += r * (new Vector3(0.0f, stepPos, 0.0f)); node.spline.AddPoint(p, curTime); } // Rethink time and rotations node.spline.UpdateTime(); node.spline.UpdateRotations(); }
private void OnSceneGUI() { Tree tree = this.target as Tree; TreeData treeData = TreeEditor.GetTreeData(tree); if (!treeData) { return; } this.VerifySelection(treeData); if (TreeEditor.s_SelectedGroup == null) { return; } this.OnCheckHotkeys(treeData, true); Transform transform = tree.transform; Matrix4x4 localToWorldMatrix = tree.transform.localToWorldMatrix; Event current = Event.current; if (TreeEditor.s_SelectedGroup.GetType() == typeof(TreeGroupRoot)) { Tools.s_Hidden = false; Handles.color = TreeEditor.s_NormalColor; Handles.DrawWireDisc(transform.position, transform.up, treeData.root.rootSpread); } else { Tools.s_Hidden = true; Handles.color = Handles.secondaryColor; Handles.DrawWireDisc(transform.position, transform.up, treeData.root.rootSpread); } if (TreeEditor.s_SelectedGroup != null && TreeEditor.s_SelectedGroup.GetType() == typeof(TreeGroupBranch)) { EventType eventType = current.type; if (current.type == EventType.Ignore && current.rawType == EventType.MouseUp) { eventType = current.rawType; } Handles.DrawLine(Vector3.zero, Vector3.zero); GL.Begin(1); for (int i = 0; i < TreeEditor.s_SelectedGroup.nodeIDs.Length; i++) { TreeNode node = treeData.GetNode(TreeEditor.s_SelectedGroup.nodeIDs[i]); TreeSpline spline = node.spline; if (spline != null) { Handles.color = ((node != TreeEditor.s_SelectedNode) ? TreeEditor.s_GroupColor : TreeEditor.s_NormalColor); Matrix4x4 matrix4x = localToWorldMatrix * node.matrix; Vector3 v = matrix4x.MultiplyPoint(spline.GetPositionAtTime(0f)); GL.Color(Handles.color); for (float num = 0.01f; num <= 1f; num += 0.01f) { Vector3 vector = matrix4x.MultiplyPoint(spline.GetPositionAtTime(num)); GL.Vertex(v); GL.Vertex(vector); v = vector; } } } GL.End(); for (int j = 0; j < TreeEditor.s_SelectedGroup.nodeIDs.Length; j++) { TreeNode node2 = treeData.GetNode(TreeEditor.s_SelectedGroup.nodeIDs[j]); TreeSpline spline2 = node2.spline; if (spline2 != null) { Handles.color = ((node2 != TreeEditor.s_SelectedNode) ? TreeEditor.s_GroupColor : TreeEditor.s_NormalColor); Matrix4x4 m = localToWorldMatrix * node2.matrix; for (int k = 0; k < spline2.nodes.Length; k++) { SplineNode splineNode = spline2.nodes[k]; Vector3 vector2 = m.MultiplyPoint(splineNode.point); float size = HandleUtility.GetHandleSize(vector2) * 0.08f; Handles.color = Handles.centerColor; int keyboardControl = GUIUtility.keyboardControl; switch (TreeEditor.editMode) { case TreeEditor.EditMode.MoveNode: if (k == 0) { vector2 = Handles.FreeMoveHandle(vector2, Quaternion.identity, size, Vector3.zero, new Handles.DrawCapFunction(Handles.CircleCap)); } else { vector2 = Handles.FreeMoveHandle(vector2, Quaternion.identity, size, Vector3.zero, new Handles.DrawCapFunction(Handles.RectangleCap)); } if (eventType == EventType.MouseDown && current.type == EventType.Used && keyboardControl != GUIUtility.keyboardControl) { this.SelectNode(node2, treeData); TreeEditor.s_SelectedPoint = k; this.m_StartPointRotation = MathUtils.QuaternionFromMatrix(m) * splineNode.rot; } if ((eventType == EventType.MouseDown || eventType == EventType.MouseUp) && current.type == EventType.Used) { this.m_StartPointRotation = MathUtils.QuaternionFromMatrix(m) * splineNode.rot; } if (eventType == EventType.MouseUp && current.type == EventType.Used && treeData.isInPreviewMode) { TreeEditor.UpdateMesh(tree); } if (GUI.changed) { Undo.RegisterCompleteObjectUndo(treeData, "Move"); TreeEditor.s_SelectedGroup.Lock(); float baseAngle = node2.baseAngle; if (k == 0) { TreeNode node3 = treeData.GetNode(TreeEditor.s_SelectedNode.parentID); Ray ray = HandleUtility.GUIPointToWorldRay(current.mousePosition); float d = 0f; if (node3 != null) { TreeGroup group = treeData.GetGroup(TreeEditor.s_SelectedGroup.parentGroupID); if (group.GetType() == typeof(TreeGroupBranch)) { TreeEditor.s_SelectedNode.offset = this.FindClosestOffset(treeData, localToWorldMatrix, node3, ray, ref baseAngle); vector2 = m.MultiplyPoint(Vector3.zero); } else { if (group.GetType() == typeof(TreeGroupRoot)) { Vector3 vector3 = localToWorldMatrix.MultiplyPoint(Vector3.zero); Plane plane = new Plane(localToWorldMatrix.MultiplyVector(Vector3.up), vector3); if (plane.Raycast(ray, out d)) { vector2 = ray.origin + ray.direction * d; Vector3 v2 = vector2 - vector3; v2 = localToWorldMatrix.inverse.MultiplyVector(v2); TreeEditor.s_SelectedNode.offset = Mathf.Clamp01(v2.magnitude / treeData.root.rootSpread); baseAngle = Mathf.Atan2(v2.z, v2.x) * 57.29578f; vector2 = m.MultiplyPoint(Vector3.zero); } else { vector2 = m.MultiplyPoint(splineNode.point); } } } } } node2.baseAngle = baseAngle; splineNode.point = m.inverse.MultiplyPoint(vector2); spline2.UpdateTime(); spline2.UpdateRotations(); TreeEditor.PreviewMesh(tree); GUI.changed = false; } break; case TreeEditor.EditMode.RotateNode: Handles.FreeMoveHandle(vector2, Quaternion.identity, size, Vector3.zero, new Handles.DrawCapFunction(Handles.CircleCap)); if (eventType == EventType.MouseDown && current.type == EventType.Used && keyboardControl != GUIUtility.keyboardControl) { this.SelectNode(node2, treeData); TreeEditor.s_SelectedPoint = k; this.m_GlobalToolRotation = Quaternion.identity; this.m_TempSpline = new TreeSpline(node2.spline); } GUI.changed = false; break; case TreeEditor.EditMode.Freehand: Handles.FreeMoveHandle(vector2, Quaternion.identity, size, Vector3.zero, new Handles.DrawCapFunction(Handles.CircleCap)); if (eventType == EventType.MouseDown && current.type == EventType.Used && keyboardControl != GUIUtility.keyboardControl) { Undo.RegisterCompleteObjectUndo(treeData, "Free Hand"); this.SelectNode(node2, treeData); TreeEditor.s_SelectedPoint = k; TreeEditor.s_StartPosition = vector2; int nodeCount = Mathf.Max(2, TreeEditor.s_SelectedPoint + 1); node2.spline.SetNodeCount(nodeCount); current.Use(); } if (TreeEditor.s_SelectedPoint == k && TreeEditor.s_SelectedNode == node2 && eventType == EventType.MouseDrag) { Ray ray2 = HandleUtility.GUIPointToWorldRay(current.mousePosition); Vector3 forward = Camera.current.transform.forward; Plane plane2 = new Plane(forward, TreeEditor.s_StartPosition); float d2 = 0f; if (plane2.Raycast(ray2, out d2)) { Vector3 v3 = ray2.origin + d2 * ray2.direction; if (TreeEditor.s_SelectedPoint == 0) { TreeEditor.s_SelectedPoint = 1; } TreeEditor.s_SelectedGroup.Lock(); TreeEditor.s_SelectedNode.spline.nodes[TreeEditor.s_SelectedPoint].point = m.inverse.MultiplyPoint(v3); Vector3 b = TreeEditor.s_SelectedNode.spline.nodes[TreeEditor.s_SelectedPoint].point - TreeEditor.s_SelectedNode.spline.nodes[TreeEditor.s_SelectedPoint - 1].point; if (b.magnitude > 1f) { TreeEditor.s_SelectedNode.spline.nodes[TreeEditor.s_SelectedPoint].point = TreeEditor.s_SelectedNode.spline.nodes[TreeEditor.s_SelectedPoint - 1].point + b; TreeEditor.s_SelectedPoint++; if (TreeEditor.s_SelectedPoint >= TreeEditor.s_SelectedNode.spline.nodes.Length) { TreeEditor.s_SelectedNode.spline.AddPoint(m.inverse.MultiplyPoint(v3), 1.1f); } } TreeEditor.s_SelectedNode.spline.UpdateTime(); TreeEditor.s_SelectedNode.spline.UpdateRotations(); current.Use(); TreeEditor.PreviewMesh(tree); } } break; } if (TreeEditor.s_SelectedPoint == k && TreeEditor.s_SelectedNode == node2 && this.m_StartPointRotationDirty) { spline2.UpdateTime(); spline2.UpdateRotations(); this.m_StartPointRotation = MathUtils.QuaternionFromMatrix(m) * splineNode.rot; this.m_GlobalToolRotation = Quaternion.identity; this.m_StartPointRotationDirty = false; } } } } if (eventType == EventType.MouseUp && TreeEditor.editMode == TreeEditor.EditMode.Freehand) { TreeEditor.s_SelectedPoint = -1; if (treeData.isInPreviewMode) { TreeEditor.UpdateMesh(tree); } } if (TreeEditor.s_SelectedPoint > 0 && TreeEditor.editMode == TreeEditor.EditMode.MoveNode && TreeEditor.s_SelectedNode != null) { TreeNode treeNode = TreeEditor.s_SelectedNode; SplineNode splineNode2 = treeNode.spline.nodes[TreeEditor.s_SelectedPoint]; Matrix4x4 m2 = localToWorldMatrix * treeNode.matrix; Vector3 vector4 = m2.MultiplyPoint(splineNode2.point); Quaternion rotation = Quaternion.identity; if (Tools.pivotRotation == PivotRotation.Local) { if (eventType == EventType.MouseUp || eventType == EventType.MouseDown) { this.m_StartPointRotation = MathUtils.QuaternionFromMatrix(m2) * splineNode2.rot; } rotation = this.m_StartPointRotation; } vector4 = this.DoPositionHandle(vector4, rotation, false); if (GUI.changed) { Undo.RegisterCompleteObjectUndo(treeData, "Move"); TreeEditor.s_SelectedGroup.Lock(); splineNode2.point = m2.inverse.MultiplyPoint(vector4); treeNode.spline.UpdateTime(); treeNode.spline.UpdateRotations(); TreeEditor.PreviewMesh(tree); } if (eventType == EventType.MouseUp && current.type == EventType.Used && treeData.isInPreviewMode) { TreeEditor.UpdateMesh(tree); } } if (TreeEditor.s_SelectedPoint >= 0 && TreeEditor.editMode == TreeEditor.EditMode.RotateNode && TreeEditor.s_SelectedNode != null) { TreeNode treeNode2 = TreeEditor.s_SelectedNode; SplineNode splineNode3 = treeNode2.spline.nodes[TreeEditor.s_SelectedPoint]; Matrix4x4 matrix4x2 = localToWorldMatrix * treeNode2.matrix; if (this.m_TempSpline == null) { this.m_TempSpline = new TreeSpline(treeNode2.spline); } Vector3 position = matrix4x2.MultiplyPoint(splineNode3.point); Quaternion rotation2 = Quaternion.identity; this.m_GlobalToolRotation = Handles.RotationHandle(this.m_GlobalToolRotation, position); rotation2 = this.m_GlobalToolRotation; if (GUI.changed) { Undo.RegisterCompleteObjectUndo(treeData, "Move"); TreeEditor.s_SelectedGroup.Lock(); for (int l = TreeEditor.s_SelectedPoint + 1; l < this.m_TempSpline.nodes.Length; l++) { Vector3 vector5 = this.m_TempSpline.nodes[l].point - splineNode3.point; vector5 = matrix4x2.MultiplyVector(vector5); vector5 = rotation2 * vector5; vector5 = matrix4x2.inverse.MultiplyVector(vector5); Vector3 point = splineNode3.point + vector5; TreeEditor.s_SelectedNode.spline.nodes[l].point = point; } treeNode2.spline.UpdateTime(); treeNode2.spline.UpdateRotations(); TreeEditor.PreviewMesh(tree); } if (eventType == EventType.MouseUp && current.type == EventType.Used && treeData.isInPreviewMode) { TreeEditor.UpdateMesh(tree); } } } if (TreeEditor.s_SelectedGroup != null && TreeEditor.s_SelectedGroup.GetType() == typeof(TreeGroupLeaf)) { for (int n = 0; n < TreeEditor.s_SelectedGroup.nodeIDs.Length; n++) { TreeNode node4 = treeData.GetNode(TreeEditor.s_SelectedGroup.nodeIDs[n]); Matrix4x4 matrix4x3 = localToWorldMatrix * node4.matrix; Vector3 vector6 = matrix4x3.MultiplyPoint(Vector3.zero); float size2 = HandleUtility.GetHandleSize(vector6) * 0.08f; Handles.color = Handles.centerColor; EventType eventType2 = current.type; int keyboardControl2 = GUIUtility.keyboardControl; TreeEditor.EditMode editMode = TreeEditor.editMode; if (editMode != TreeEditor.EditMode.MoveNode) { if (editMode == TreeEditor.EditMode.RotateNode) { Handles.FreeMoveHandle(vector6, Quaternion.identity, size2, Vector3.zero, new Handles.DrawCapFunction(Handles.CircleCap)); if (eventType2 == EventType.MouseDown && current.type == EventType.Used && keyboardControl2 != GUIUtility.keyboardControl) { this.SelectNode(node4, treeData); this.m_GlobalToolRotation = MathUtils.QuaternionFromMatrix(matrix4x3); this.m_StartMatrix = matrix4x3; this.m_StartPointRotation = node4.rotation; this.m_LockedWorldPos = new Vector3(matrix4x3.m03, matrix4x3.m13, matrix4x3.m23); } if (TreeEditor.s_SelectedNode == node4) { eventType2 = current.GetTypeForControl(GUIUtility.hotControl); this.m_GlobalToolRotation = Handles.RotationHandle(this.m_GlobalToolRotation, this.m_LockedWorldPos); if (eventType2 == EventType.MouseUp && current.type == EventType.Used) { this.m_LockedWorldPos = new Vector3(matrix4x3.m03, matrix4x3.m13, matrix4x3.m23); if (treeData.isInPreviewMode) { TreeEditor.UpdateMesh(tree); } } if (GUI.changed) { TreeEditor.s_SelectedGroup.Lock(); Quaternion lhs = Quaternion.Inverse(MathUtils.QuaternionFromMatrix(this.m_StartMatrix)); node4.rotation = this.m_StartPointRotation * (lhs * this.m_GlobalToolRotation); MathUtils.QuaternionNormalize(ref node4.rotation); TreeEditor.PreviewMesh(tree); } } } } else { Handles.FreeMoveHandle(vector6, Quaternion.identity, size2, Vector3.zero, new Handles.DrawCapFunction(Handles.CircleCap)); if (eventType2 == EventType.MouseDown && current.type == EventType.Used && keyboardControl2 != GUIUtility.keyboardControl) { this.SelectNode(node4, treeData); this.m_GlobalToolRotation = MathUtils.QuaternionFromMatrix(matrix4x3); this.m_StartMatrix = matrix4x3; this.m_StartPointRotation = node4.rotation; this.m_LockedWorldPos = new Vector3(this.m_StartMatrix.m03, this.m_StartMatrix.m13, this.m_StartMatrix.m23); } if (eventType2 == EventType.MouseUp && current.type == EventType.Used && treeData.isInPreviewMode) { TreeEditor.UpdateMesh(tree); } if (GUI.changed) { TreeEditor.s_SelectedGroup.Lock(); TreeNode node5 = treeData.GetNode(node4.parentID); TreeGroup group2 = treeData.GetGroup(TreeEditor.s_SelectedGroup.parentGroupID); Ray ray3 = HandleUtility.GUIPointToWorldRay(current.mousePosition); float d3 = 0f; float baseAngle2 = node4.baseAngle; if (group2.GetType() == typeof(TreeGroupBranch)) { node4.offset = this.FindClosestOffset(treeData, localToWorldMatrix, node5, ray3, ref baseAngle2); node4.baseAngle = baseAngle2; TreeEditor.PreviewMesh(tree); } else { if (group2.GetType() == typeof(TreeGroupRoot)) { Vector3 vector7 = localToWorldMatrix.MultiplyPoint(Vector3.zero); Plane plane3 = new Plane(localToWorldMatrix.MultiplyVector(Vector3.up), vector7); if (plane3.Raycast(ray3, out d3)) { vector6 = ray3.origin + ray3.direction * d3; Vector3 v4 = vector6 - vector7; v4 = localToWorldMatrix.inverse.MultiplyVector(v4); node4.offset = Mathf.Clamp01(v4.magnitude / treeData.root.rootSpread); baseAngle2 = Mathf.Atan2(v4.z, v4.x) * 57.29578f; } node4.baseAngle = baseAngle2; TreeEditor.PreviewMesh(tree); } } } } } } }