修改水
This commit is contained in:
@@ -33,10 +33,6 @@ namespace Obi
|
||||
SerializedProperty plasticYield;
|
||||
SerializedProperty plasticCreep;
|
||||
|
||||
SerializedProperty aerodynamicsEnabled;
|
||||
SerializedProperty drag;
|
||||
SerializedProperty lift;
|
||||
|
||||
SerializedProperty fixRoot;
|
||||
SerializedProperty stretchBones;
|
||||
SerializedProperty ignored;
|
||||
@@ -73,9 +69,6 @@ namespace Obi
|
||||
plasticYield = serializedObject.FindProperty("_plasticYield");
|
||||
plasticCreep = serializedObject.FindProperty("_plasticCreep");
|
||||
|
||||
aerodynamicsEnabled = serializedObject.FindProperty("_aerodynamicsEnabled");
|
||||
drag = serializedObject.FindProperty("_drag");
|
||||
lift = serializedObject.FindProperty("_lift");
|
||||
}
|
||||
|
||||
public void OnDisable()
|
||||
@@ -151,12 +144,6 @@ namespace Obi
|
||||
EditorGUILayout.PropertyField(plasticCreep, new GUIContent("Plastic creep"));
|
||||
});
|
||||
|
||||
ObiEditorUtils.DoToggleablePropertyGroup(aerodynamicsEnabled, new GUIContent("Aerodynamics", Resources.Load<Texture2D>("Icons/ObiAerodynamicConstraints Icon")),
|
||||
() => {
|
||||
EditorGUILayout.PropertyField(drag, new GUIContent("Drag"));
|
||||
EditorGUILayout.PropertyField(lift, new GUIContent("Lift"));
|
||||
});
|
||||
|
||||
if (GUI.changed)
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
|
||||
@@ -2,38 +2,12 @@ using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.EditorTools;
|
||||
using System;
|
||||
using UnityEditor.Overlays;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
[EditorTool("Obi Path Editor Tool",typeof(ObiRopeBase))]
|
||||
public class ObiPathEditor : EditorTool
|
||||
{
|
||||
|
||||
[Overlay(typeof(SceneView), "Obi Path Editor", "Obi Path Editor", "Obi Path Editor", true)]
|
||||
[Icon("Assets/Obi/Editor/Resources/EditCurves.psd")]
|
||||
class PathEditorOverlay : Overlay, ITransientOverlay
|
||||
{
|
||||
public static ObiPathEditor editor;
|
||||
|
||||
public override VisualElement CreatePanelContent()
|
||||
{
|
||||
var root = new VisualElement();
|
||||
root.Add(new IMGUIContainer(editor.DrawToolPanel));
|
||||
return root;
|
||||
}
|
||||
|
||||
// Use the visible property to hide or show this instance from within the class.
|
||||
public bool visible
|
||||
{
|
||||
get
|
||||
{
|
||||
return ToolManager.activeToolType == typeof(ObiPathEditor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum PathEditorTool
|
||||
{
|
||||
TranslatePoints,
|
||||
@@ -90,7 +64,6 @@ namespace Obi
|
||||
{
|
||||
this.useOrientation = target is ObiRod;
|
||||
selectedStatus = new bool[0];
|
||||
PathEditorOverlay.editor = this;
|
||||
}
|
||||
|
||||
public void ResizeCPArrays()
|
||||
@@ -98,6 +71,7 @@ namespace Obi
|
||||
Array.Resize(ref selectedStatus, path.ControlPointCount);
|
||||
}
|
||||
|
||||
int windowId;
|
||||
public override void OnToolGUI(EditorWindow window)
|
||||
{
|
||||
needsRepaint = false;
|
||||
@@ -108,7 +82,11 @@ namespace Obi
|
||||
|
||||
ResizeCPArrays();
|
||||
|
||||
HandleUtility.AddDefaultControl(GUIUtility.GetControlID("PathEditor".GetHashCode(), FocusType.Passive));
|
||||
HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
|
||||
|
||||
// get a window ID:
|
||||
if (Event.current.type != EventType.Used)
|
||||
windowId = GUIUtility.GetControlID(FocusType.Passive);
|
||||
|
||||
Matrix4x4 prevMatrix = Handles.matrix;
|
||||
Handles.matrix = matrix;
|
||||
@@ -120,6 +98,9 @@ namespace Obi
|
||||
needsRepaint |= DrawControlPoint(i);
|
||||
}
|
||||
|
||||
// Control point selection handle:
|
||||
needsRepaint |= ObiPathHandles.SplineCPSelector(path, selectedStatus);
|
||||
|
||||
// Count selected and calculate average position:
|
||||
selectionAverage = GetControlPointAverage(out lastSelected, out selectedCount);
|
||||
|
||||
@@ -129,8 +110,10 @@ namespace Obi
|
||||
if (showThicknessHandles)
|
||||
needsRepaint |= DoThicknessHandles(thicknessScale);
|
||||
|
||||
// Control point selection handle:
|
||||
needsRepaint |= ObiPathHandles.SplineCPSelector(path, selectedStatus);
|
||||
// Sceneview GUI:
|
||||
Handles.BeginGUI();
|
||||
GUILayout.Window(windowId, new Rect(10, 28, 0, 0), DrawUIWindow, "Path editor");
|
||||
Handles.EndGUI();
|
||||
|
||||
Handles.matrix = prevMatrix;
|
||||
|
||||
@@ -562,7 +545,7 @@ namespace Obi
|
||||
return false;
|
||||
}
|
||||
|
||||
public void DrawToolPanel()
|
||||
public void DrawUIWindow(int windowID)
|
||||
{
|
||||
|
||||
DrawToolButtons();
|
||||
@@ -1073,7 +1056,7 @@ namespace Obi
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
color = EditorGUILayout.ColorField(new GUIContent("Color"), color, true, true, true, GUILayout.MinWidth(94));
|
||||
color = EditorGUILayout.ColorField("Color", color, GUILayout.MinWidth(94));
|
||||
EditorGUI.showMixedValue = false;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
@@ -1170,7 +1153,7 @@ namespace Obi
|
||||
|
||||
for (int index = 0; index < 4; ++index)
|
||||
{
|
||||
int controlId = GUIUtility.GetControlID("ObiPathThicknessHandle".GetHashCode(), FocusType.Passive);
|
||||
int controlId = GUIUtility.GetControlID("ObiPathThicknessHandle".GetHashCode(), FocusType.Keyboard);
|
||||
Vector3 position1 = position + radius * vector3Array[index];
|
||||
bool changed = GUI.changed;
|
||||
GUI.changed = false;
|
||||
@@ -1214,7 +1197,7 @@ namespace Obi
|
||||
Vector2 currentPoint = HandleUtility.WorldToGUIPoint(path.m_Points.Evaluate(_p, p, p_, p__, i * step));
|
||||
|
||||
float mu;
|
||||
float distance = Vector2.SqrMagnitude((Vector2)ObiUtils.ProjectPointLine(lastPoint, currentPoint, screenPoint, out mu) - screenPoint);
|
||||
float distance = Vector2.SqrMagnitude((Vector2)ObiUtils.ProjectPointLine(screenPoint, lastPoint, currentPoint, out mu) - screenPoint);
|
||||
|
||||
if (distance < minDistance)
|
||||
{
|
||||
|
||||
@@ -28,9 +28,27 @@ namespace Obi
|
||||
// select vertex on mouse click:
|
||||
switch (Event.current.GetTypeForControl(controlID))
|
||||
{
|
||||
case EventType.Layout:
|
||||
case EventType.MouseMove:
|
||||
|
||||
|
||||
case EventType.MouseDown:
|
||||
{
|
||||
|
||||
if ((Event.current.modifiers & EventModifiers.Control) == 0 &&
|
||||
(HandleUtility.nearestControl != controlID || Event.current.button != 0)) break;
|
||||
|
||||
startPos = Event.current.mousePosition;
|
||||
marquee.Set(0, 0, 0, 0);
|
||||
|
||||
// If the user is pressing shift, accumulate selection.
|
||||
if ((Event.current.modifiers & EventModifiers.Shift) == 0 && (Event.current.modifiers & EventModifiers.Alt) == 0)
|
||||
{
|
||||
for (int i = 0; i < selectionStatus.Length; i++)
|
||||
selectionStatus[i] = false;
|
||||
}
|
||||
|
||||
// If the user is holding down control, dont allow selection of other objects and use marquee tool.
|
||||
if ((Event.current.modifiers & EventModifiers.Control) != 0)
|
||||
GUIUtility.hotControl = controlID;
|
||||
|
||||
float minSqrDistance = System.Single.MaxValue;
|
||||
float sqrMinSelectionDistance = minSelectionDistance * minSelectionDistance;
|
||||
|
||||
@@ -41,94 +59,50 @@ namespace Obi
|
||||
Vector2 pos = HandleUtility.WorldToGUIPoint(path.points[i].position);
|
||||
|
||||
// get distance from mouse position to particle position:
|
||||
float sqrDistance = Vector2.SqrMagnitude(Event.current.mousePosition - pos);
|
||||
float sqrDistance = Vector2.SqrMagnitude(startPos - pos);
|
||||
|
||||
// check if this control point is closer to the cursor that any previously considered point.
|
||||
if (sqrDistance < sqrMinSelectionDistance && sqrDistance < minSqrDistance)
|
||||
{
|
||||
{
|
||||
minSqrDistance = sqrDistance;
|
||||
selectedCPIndex = i;
|
||||
}
|
||||
|
||||
}
|
||||
HandleUtility.AddControl(controlID, Mathf.Sqrt(minSqrDistance));
|
||||
|
||||
break;
|
||||
|
||||
case EventType.MouseDown:
|
||||
|
||||
marquee.Set(0, 0, 0, 0);
|
||||
startPos = Event.current.mousePosition;
|
||||
if (selectedCPIndex >= 0)
|
||||
{ // toggle particle selection status.
|
||||
|
||||
if (Event.current.button == 0)
|
||||
{
|
||||
selectionStatus[selectedCPIndex] = !selectionStatus[selectedCPIndex];
|
||||
selectionStatusChanged = true;
|
||||
|
||||
if (HandleUtility.nearestControl == controlID)
|
||||
{
|
||||
GUIUtility.hotControl = controlID;
|
||||
// Prevent spline deselection if we have selected a particle:
|
||||
GUIUtility.hotControl = controlID;
|
||||
Event.current.Use();
|
||||
|
||||
// If the user is pressing shift or ctrl, accumulate selection.
|
||||
if ((Event.current.modifiers & (EventModifiers.Shift | EventModifiers.Control)) == 0 && (Event.current.modifiers & EventModifiers.Alt) == 0)
|
||||
{
|
||||
for (int i = 0; i < selectionStatus.Length; i++)
|
||||
selectionStatus[i] = false;
|
||||
|
||||
selectionStatusChanged = true;
|
||||
}
|
||||
|
||||
minSqrDistance = System.Single.MaxValue;
|
||||
sqrMinSelectionDistance = minSelectionDistance * minSelectionDistance;
|
||||
|
||||
for (int i = 0; i < path.ControlPointCount; i++)
|
||||
{
|
||||
|
||||
// get particle position in gui space:
|
||||
Vector2 pos = HandleUtility.WorldToGUIPoint(path.points[i].position);
|
||||
|
||||
// get distance from mouse position to particle position:
|
||||
float sqrDistance = Vector2.SqrMagnitude(startPos - pos);
|
||||
|
||||
// check if this control point is closer to the cursor that any previously considered point.
|
||||
if (sqrDistance < sqrMinSelectionDistance && sqrDistance < minSqrDistance)
|
||||
{
|
||||
minSqrDistance = sqrDistance;
|
||||
selectedCPIndex = i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (selectedCPIndex >= 0)
|
||||
{ // toggle particle selection status.
|
||||
|
||||
selectionStatus[selectedCPIndex] = !selectionStatus[selectedCPIndex];
|
||||
selectionStatusChanged = true;
|
||||
|
||||
// Prevent spline deselection if we have selected a particle:
|
||||
Event.current.Use();
|
||||
|
||||
}
|
||||
}
|
||||
else if ((Event.current.modifiers & (EventModifiers.Shift | EventModifiers.Control)) == 0 && (Event.current.modifiers & EventModifiers.Alt) == 0)
|
||||
{
|
||||
for (int i = 0; i < selectionStatus.Length; i++)
|
||||
selectionStatus[i] = false;
|
||||
|
||||
selectionStatusChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
else if (Event.current.modifiers == EventModifiers.None)
|
||||
{ // deselect all particles:
|
||||
for (int i = 0; i < selectionStatus.Length; i++)
|
||||
selectionStatus[i] = false;
|
||||
|
||||
selectionStatusChanged = true;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case EventType.MouseDrag:
|
||||
|
||||
if (Event.current.button == 0 && (Event.current.modifiers & EventModifiers.Alt) == 0)
|
||||
if (GUIUtility.hotControl == controlID)
|
||||
{
|
||||
|
||||
currentPos = Event.current.mousePosition;
|
||||
if (!dragging && Vector2.Distance(startPos, currentPos) > 5)
|
||||
{
|
||||
dragging = true;
|
||||
}
|
||||
|
||||
if (dragging)
|
||||
else
|
||||
{
|
||||
GUIUtility.hotControl = controlID;
|
||||
Event.current.Use();
|
||||
@@ -187,6 +161,34 @@ namespace Obi
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case EventType.Layout:
|
||||
{
|
||||
|
||||
float minSqrDistance = System.Single.MaxValue;
|
||||
float sqrMinSelectionDistance = minSelectionDistance * minSelectionDistance;
|
||||
|
||||
for (int i = 0; i < path.ControlPointCount; i++)
|
||||
{
|
||||
|
||||
// get particle position in gui space:
|
||||
Vector2 pos = HandleUtility.WorldToGUIPoint(path.points[i].position);
|
||||
|
||||
// get distance from mouse position to particle position:
|
||||
float sqrDistance = Vector2.SqrMagnitude(Event.current.mousePosition - pos);
|
||||
|
||||
// check if this control point is closer to the cursor that any previously considered point.
|
||||
if (sqrDistance < sqrMinSelectionDistance && sqrDistance < minSqrDistance)
|
||||
{ //magic number 900 = 30*30, where 30 is min distance in pixels to select a particle.
|
||||
minSqrDistance = sqrDistance;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HandleUtility.AddControl(controlID, Mathf.Sqrt(minSqrDistance));
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return selectionStatusChanged;
|
||||
|
||||
@@ -17,8 +17,6 @@ namespace Obi
|
||||
static void CreateObiRod(MenuCommand menuCommand)
|
||||
{
|
||||
GameObject go = new GameObject("Obi Rod", typeof(ObiRod), typeof(ObiRopeExtrudedRenderer));
|
||||
var renderer = go.GetComponent<ObiRopeExtrudedRenderer>();
|
||||
renderer.material = ObiEditorUtils.GetDefaultMaterial();
|
||||
ObiEditorUtils.PlaceActorRoot(go, menuCommand);
|
||||
}
|
||||
|
||||
@@ -28,8 +26,7 @@ namespace Obi
|
||||
|
||||
SerializedProperty collisionMaterial;
|
||||
SerializedProperty selfCollisions;
|
||||
SerializedProperty surfaceCollisions;
|
||||
SerializedProperty massScale;
|
||||
SerializedProperty surfaceCollisions;
|
||||
|
||||
SerializedProperty stretchShearConstraintsEnabled;
|
||||
SerializedProperty stretchCompliance;
|
||||
@@ -43,10 +40,6 @@ namespace Obi
|
||||
SerializedProperty plasticYield;
|
||||
SerializedProperty plasticCreep;
|
||||
|
||||
SerializedProperty aerodynamicsEnabled;
|
||||
SerializedProperty drag;
|
||||
SerializedProperty lift;
|
||||
|
||||
SerializedProperty chainConstraintsEnabled;
|
||||
SerializedProperty tightness;
|
||||
|
||||
@@ -61,7 +54,6 @@ namespace Obi
|
||||
collisionMaterial = serializedObject.FindProperty("m_CollisionMaterial");
|
||||
selfCollisions = serializedObject.FindProperty("m_SelfCollisions");
|
||||
surfaceCollisions = serializedObject.FindProperty("m_SurfaceCollisions");
|
||||
massScale = serializedObject.FindProperty("m_MassScale");
|
||||
|
||||
stretchShearConstraintsEnabled = serializedObject.FindProperty("_stretchShearConstraintsEnabled");
|
||||
stretchCompliance = serializedObject.FindProperty("_stretchCompliance");
|
||||
@@ -75,10 +67,6 @@ namespace Obi
|
||||
plasticYield = serializedObject.FindProperty("_plasticYield");
|
||||
plasticCreep = serializedObject.FindProperty("_plasticCreep");
|
||||
|
||||
aerodynamicsEnabled = serializedObject.FindProperty("_aerodynamicsEnabled");
|
||||
drag = serializedObject.FindProperty("_drag");
|
||||
lift = serializedObject.FindProperty("_lift");
|
||||
|
||||
chainConstraintsEnabled = serializedObject.FindProperty("_chainConstraintsEnabled");
|
||||
tightness = serializedObject.FindProperty("_tightness");
|
||||
}
|
||||
@@ -122,30 +110,8 @@ namespace Obi
|
||||
|
||||
using (new EditorGUI.DisabledScope(ToolManager.activeToolType == typeof(ObiPathEditor)))
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
EditorGUILayout.PropertyField(rodBlueprint, new GUIContent("Blueprint"));
|
||||
|
||||
if (actor.rodBlueprint == null)
|
||||
{
|
||||
if (GUILayout.Button("Create", EditorStyles.miniButton, GUILayout.MaxWidth(80)))
|
||||
{
|
||||
string path = EditorUtility.SaveFilePanel("Save blueprint", "Assets/", "RodBlueprint", "asset");
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
path = FileUtil.GetProjectRelativePath(path);
|
||||
ObiRodBlueprint asset = ScriptableObject.CreateInstance<ObiRodBlueprint>();
|
||||
|
||||
AssetDatabase.CreateAsset(asset, path);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
actor.rodBlueprint = asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
foreach (var t in targets)
|
||||
@@ -157,12 +123,8 @@ namespace Obi
|
||||
foreach (var t in targets)
|
||||
(t as ObiRod).AddToSolver();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(massScale, new GUIContent("m_MassScale"));
|
||||
|
||||
DoEditButton();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
@@ -188,12 +150,6 @@ namespace Obi
|
||||
EditorGUILayout.PropertyField(plasticCreep, new GUIContent("Plastic creep"));
|
||||
});
|
||||
|
||||
ObiEditorUtils.DoToggleablePropertyGroup(aerodynamicsEnabled, new GUIContent("Aerodynamics", Resources.Load<Texture2D>("Icons/ObiAerodynamicConstraints Icon")),
|
||||
() => {
|
||||
EditorGUILayout.PropertyField(drag, new GUIContent("Drag"));
|
||||
EditorGUILayout.PropertyField(lift, new GUIContent("Lift"));
|
||||
});
|
||||
|
||||
ObiEditorUtils.DoToggleablePropertyGroup(chainConstraintsEnabled, new GUIContent("Chain Constraints", Resources.Load<Texture2D>("Icons/ObiChainConstraints Icon")),
|
||||
() => {
|
||||
EditorGUILayout.PropertyField(tightness, new GUIContent("Tightness"));
|
||||
|
||||
@@ -15,27 +15,8 @@ namespace Obi{
|
||||
public void OnEnable(){
|
||||
renderer = (ObiRopeChainRenderer)target;
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/ObiRopeChainRenderer/Bake mesh")]
|
||||
static void Bake(MenuCommand command)
|
||||
{
|
||||
ObiRopeChainRenderer renderer = (ObiRopeChainRenderer)command.context;
|
||||
|
||||
if (renderer.actor.isLoaded)
|
||||
{
|
||||
var system = renderer.actor.solver.GetRenderSystem<ObiRopeChainRenderer>() as ObiChainRopeRenderSystem;
|
||||
|
||||
if (system != null)
|
||||
{
|
||||
var mesh = new Mesh();
|
||||
system.BakeMesh(renderer, ref mesh, true);
|
||||
ObiEditorUtils.SaveMesh(mesh, "Save chain mesh", "chain mesh");
|
||||
GameObject.DestroyImmediate(mesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
|
||||
@@ -44,7 +25,12 @@ namespace Obi{
|
||||
// Apply changes to the serializedProperty
|
||||
if (GUI.changed){
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
renderer.ClearChainLinkInstances();
|
||||
renderer.CreateChainLinkInstances(renderer.GetComponent<ObiRopeBase>());
|
||||
renderer.UpdateRenderer(renderer.GetComponent<ObiRopeBase>());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -65,19 +65,17 @@ namespace Obi
|
||||
private static void DrawGizmos(ObiRopeCursor cursor, GizmoType gizmoType)
|
||||
{
|
||||
var rope = cursor.GetComponent<ObiRope>();
|
||||
if (rope.isLoaded)
|
||||
if (rope.solver != null)
|
||||
{
|
||||
Handles.matrix = rope.solver.transform.localToWorldMatrix;
|
||||
Handles.color = new Color(1, 0.5f, 0.2f, 1);
|
||||
Gizmos.color = new Color(1, 0.5f, 0, 0.75f);
|
||||
|
||||
// draw source particle:
|
||||
int sourceIndex = cursor.sourceParticleIndex;
|
||||
|
||||
if (sourceIndex >= 0 && rope.IsParticleActive(rope.solver.particleToActor[sourceIndex].indexInActor))
|
||||
{
|
||||
Vector3 pos = rope.solver.positions[sourceIndex];
|
||||
float size = HandleUtility.GetHandleSize(pos) * 0.15f;
|
||||
Handles.SphereHandleCap(0, pos, Quaternion.identity, size, EventType.Repaint);
|
||||
Vector3 pos = rope.GetParticlePosition(sourceIndex);
|
||||
Gizmos.DrawWireSphere(pos, HandleUtility.GetHandleSize(pos) * 0.4f);
|
||||
}
|
||||
|
||||
// draw cursor:
|
||||
@@ -85,12 +83,13 @@ namespace Obi
|
||||
|
||||
if (element != null && element.particle1 != element.particle2)
|
||||
{
|
||||
Vector3 pos = rope.solver.positions[cursor.direction ? element.particle1 : element.particle2];
|
||||
Vector3 pos2 = rope.solver.positions[cursor.direction ? element.particle2 : element.particle1];
|
||||
Vector3 pos = rope.GetParticlePosition(cursor.direction ? element.particle1 : element.particle2);
|
||||
Vector3 pos2 = rope.GetParticlePosition(cursor.direction ? element.particle2 : element.particle1);
|
||||
Vector3 direction = pos2 - pos;
|
||||
|
||||
float size = HandleUtility.GetHandleSize(pos) * 0.25f;
|
||||
Handles.ConeHandleCap(0, pos + Vector3.Normalize(direction)*size*0.5f, Quaternion.LookRotation(direction), size, EventType.Repaint);
|
||||
float size = HandleUtility.GetHandleSize(pos) * 0.4f;
|
||||
Gizmos.matrix = Matrix4x4.TRS(pos, Quaternion.LookRotation(direction), Vector3.one * size);
|
||||
DrawArrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
using UnityEditor;
|
||||
using UnityEditor.EditorTools;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
@@ -13,8 +18,6 @@ namespace Obi
|
||||
static void CreateObiRope(MenuCommand menuCommand)
|
||||
{
|
||||
GameObject go = new GameObject("Obi Rope", typeof(ObiRope), typeof(ObiRopeExtrudedRenderer));
|
||||
var renderer = go.GetComponent<ObiRopeExtrudedRenderer>();
|
||||
renderer.material = ObiEditorUtils.GetDefaultMaterial();
|
||||
ObiEditorUtils.PlaceActorRoot(go, menuCommand);
|
||||
}
|
||||
|
||||
@@ -25,7 +28,6 @@ namespace Obi
|
||||
SerializedProperty collisionMaterial;
|
||||
SerializedProperty selfCollisions;
|
||||
SerializedProperty surfaceCollisions;
|
||||
SerializedProperty massScale;
|
||||
|
||||
SerializedProperty distanceConstraintsEnabled;
|
||||
SerializedProperty stretchingScale;
|
||||
@@ -38,10 +40,6 @@ namespace Obi
|
||||
SerializedProperty plasticYield;
|
||||
SerializedProperty plasticCreep;
|
||||
|
||||
SerializedProperty aerodynamicsEnabled;
|
||||
SerializedProperty drag;
|
||||
SerializedProperty lift;
|
||||
|
||||
SerializedProperty tearingEnabled;
|
||||
SerializedProperty tearResistanceMultiplier;
|
||||
SerializedProperty tearRate;
|
||||
@@ -57,7 +55,6 @@ namespace Obi
|
||||
collisionMaterial = serializedObject.FindProperty("m_CollisionMaterial");
|
||||
selfCollisions = serializedObject.FindProperty("m_SelfCollisions");
|
||||
surfaceCollisions = serializedObject.FindProperty("m_SurfaceCollisions");
|
||||
massScale = serializedObject.FindProperty("m_MassScale");
|
||||
|
||||
distanceConstraintsEnabled = serializedObject.FindProperty("_distanceConstraintsEnabled");
|
||||
stretchingScale = serializedObject.FindProperty("_stretchingScale");
|
||||
@@ -70,10 +67,6 @@ namespace Obi
|
||||
plasticYield = serializedObject.FindProperty("_plasticYield");
|
||||
plasticCreep = serializedObject.FindProperty("_plasticCreep");
|
||||
|
||||
aerodynamicsEnabled = serializedObject.FindProperty("_aerodynamicsEnabled");
|
||||
drag = serializedObject.FindProperty("_drag");
|
||||
lift = serializedObject.FindProperty("_lift");
|
||||
|
||||
tearingEnabled = serializedObject.FindProperty("tearingEnabled");
|
||||
tearResistanceMultiplier = serializedObject.FindProperty("tearResistanceMultiplier");
|
||||
tearRate = serializedObject.FindProperty("tearRate");
|
||||
@@ -119,29 +112,8 @@ namespace Obi
|
||||
|
||||
using (new EditorGUI.DisabledScope(ToolManager.activeToolType == typeof(ObiPathEditor)))
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
EditorGUILayout.PropertyField(ropeBlueprint, new GUIContent("Blueprint"));
|
||||
|
||||
if (actor.ropeBlueprint == null)
|
||||
{
|
||||
if (GUILayout.Button("Create", EditorStyles.miniButton, GUILayout.MaxWidth(80)))
|
||||
{
|
||||
string path = EditorUtility.SaveFilePanel("Save blueprint", "Assets/", "RopeBlueprint", "asset");
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
path = FileUtil.GetProjectRelativePath(path);
|
||||
ObiRopeBlueprint asset = ScriptableObject.CreateInstance<ObiRopeBlueprint>();
|
||||
|
||||
AssetDatabase.CreateAsset(asset, path);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
actor.ropeBlueprint = asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
foreach (var t in targets)
|
||||
@@ -153,14 +125,8 @@ namespace Obi
|
||||
foreach (var t in targets)
|
||||
(t as ObiRope).AddToSolver();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUI.enabled = !Application.isPlaying;
|
||||
EditorGUILayout.PropertyField(massScale, new GUIContent("Mass scale"));
|
||||
GUI.enabled = true;
|
||||
|
||||
DoEditButton();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
@@ -193,11 +159,6 @@ namespace Obi
|
||||
EditorGUILayout.PropertyField(plasticCreep, new GUIContent("Plastic creep"));
|
||||
});
|
||||
|
||||
ObiEditorUtils.DoToggleablePropertyGroup(aerodynamicsEnabled, new GUIContent("Aerodynamics", Resources.Load<Texture2D>("Icons/ObiAerodynamicConstraints Icon")),
|
||||
() => {
|
||||
EditorGUILayout.PropertyField(drag, new GUIContent("Drag"));
|
||||
EditorGUILayout.PropertyField(lift, new GUIContent("Lift"));
|
||||
});
|
||||
|
||||
if (GUI.changed)
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
@@ -16,28 +16,22 @@ namespace Obi{
|
||||
renderer = (ObiRopeExtrudedRenderer)target;
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/ObiRopeExtrudedRenderer/Bake mesh")]
|
||||
static void Bake(MenuCommand command)
|
||||
private void BakeMesh()
|
||||
{
|
||||
ObiRopeExtrudedRenderer renderer = (ObiRopeExtrudedRenderer)command.context;
|
||||
|
||||
if (renderer.actor.isLoaded)
|
||||
if (renderer != null && renderer.extrudedMesh != null)
|
||||
{
|
||||
var system = renderer.actor.solver.GetRenderSystem<ObiRopeExtrudedRenderer>() as ObiExtrudedRopeRenderSystem;
|
||||
|
||||
if (system != null)
|
||||
{
|
||||
var mesh = new Mesh();
|
||||
system.BakeMesh(renderer, ref mesh, true);
|
||||
ObiEditorUtils.SaveMesh(mesh, "Save rope mesh", "rope mesh");
|
||||
GameObject.DestroyImmediate(mesh);
|
||||
}
|
||||
ObiEditorUtils.SaveMesh(renderer.extrudedMesh, "Save extruded mesh", "rope mesh");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
|
||||
if (GUILayout.Button("BakeMesh"))
|
||||
{
|
||||
BakeMesh();
|
||||
}
|
||||
|
||||
Editor.DrawPropertiesExcluding(serializedObject,"m_Script");
|
||||
|
||||
@@ -46,6 +40,8 @@ namespace Obi{
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
renderer.UpdateRenderer(renderer.GetComponent<ObiRopeBase>());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Obi{
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
//renderer.UpdateRenderer(null);
|
||||
renderer.UpdateRenderer(null);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Obi{
|
||||
|
||||
@@ -8,34 +11,28 @@ namespace Obi{
|
||||
{
|
||||
|
||||
ObiRopeMeshRenderer renderer;
|
||||
|
||||
[MenuItem("CONTEXT/ObiRopeMeshRenderer/Bake mesh")]
|
||||
static void Bake(MenuCommand command)
|
||||
{
|
||||
ObiRopeMeshRenderer renderer = (ObiRopeMeshRenderer)command.context;
|
||||
|
||||
if (renderer.actor.isLoaded)
|
||||
{
|
||||
var system = renderer.actor.solver.GetRenderSystem<ObiRopeMeshRenderer>() as ObiMeshRopeRenderSystem;
|
||||
|
||||
if (system != null)
|
||||
{
|
||||
var mesh = new Mesh();
|
||||
system.BakeMesh(renderer, ref mesh, true);
|
||||
ObiEditorUtils.SaveMesh(mesh, "Save rope mesh", "rope mesh");
|
||||
GameObject.DestroyImmediate(mesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEnable(){
|
||||
|
||||
public void OnEnable(){
|
||||
renderer = (ObiRopeMeshRenderer)target;
|
||||
}
|
||||
|
||||
private void BakeMesh()
|
||||
{
|
||||
if (renderer != null && renderer.deformedMesh != null)
|
||||
{
|
||||
ObiEditorUtils.SaveMesh(renderer.deformedMesh, "Save deformed mesh", "rope mesh");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
|
||||
if (GUILayout.Button("BakeMesh"))
|
||||
{
|
||||
BakeMesh();
|
||||
}
|
||||
|
||||
Editor.DrawPropertiesExcluding(serializedObject,"m_Script");
|
||||
|
||||
// Apply changes to the serializedProperty
|
||||
@@ -43,6 +40,8 @@ namespace Obi{
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
renderer.UpdateRenderer(renderer.GetComponent<ObiRopeBase>());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72e3dd3ad91bf485099095b5e59ff81b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,169 +0,0 @@
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
|
||||
[CustomEditor(typeof(ObiPinhole))]
|
||||
public class ObiPinholeEditor : Editor
|
||||
{
|
||||
|
||||
SerializedProperty targetTransform;
|
||||
SerializedProperty position;
|
||||
SerializedProperty limitRange;
|
||||
SerializedProperty range;
|
||||
SerializedProperty compliance;
|
||||
SerializedProperty friction;
|
||||
SerializedProperty motorSpeed;
|
||||
SerializedProperty motorForce;
|
||||
SerializedProperty clamp;
|
||||
SerializedProperty breakThreshold;
|
||||
|
||||
ObiPinhole pinhole;
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
|
||||
pinhole = target as ObiPinhole;
|
||||
targetTransform = serializedObject.FindProperty("m_Target");
|
||||
position = serializedObject.FindProperty("m_Position");
|
||||
limitRange = serializedObject.FindProperty("m_LimitRange");
|
||||
range = serializedObject.FindProperty("m_Range");
|
||||
friction = serializedObject.FindProperty("m_Friction");
|
||||
motorSpeed = serializedObject.FindProperty("m_MotorSpeed");
|
||||
motorForce = serializedObject.FindProperty("m_MotorForce");
|
||||
compliance = serializedObject.FindProperty("m_Compliance");
|
||||
clamp = serializedObject.FindProperty("m_ClampAtEnds");
|
||||
breakThreshold = serializedObject.FindProperty("breakThreshold");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
|
||||
// warn about incorrect setups:
|
||||
if (!targetTransform.hasMultipleDifferentValues)
|
||||
{
|
||||
var targetValue = targetTransform.objectReferenceValue as UnityEngine.Component;
|
||||
if (targetValue != null)
|
||||
{
|
||||
var collider = targetValue.GetComponent<ObiColliderBase>();
|
||||
if (collider == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Pinholes require the target object to have a ObiCollider component. Please add one.", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Transform trget = EditorGUILayout.ObjectField("Target", pinhole.target, typeof(Transform), true) as Transform;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(pinhole, "Set target");
|
||||
pinhole.target = trget;
|
||||
PrefabUtility.RecordPrefabInstancePropertyModifications(pinhole);
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(position, new GUIContent("Position"));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
pinhole.CalculateMu();
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(limitRange, new GUIContent("Limit Range"));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
pinhole.CalculateRange();
|
||||
}
|
||||
|
||||
if (limitRange.boolValue)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(range, new GUIContent("Range"));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
pinhole.CalculateRange();
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
EditorGUILayout.PropertyField(clamp, new GUIContent("Clamp at ends"));
|
||||
EditorGUILayout.PropertyField(friction, new GUIContent("Friction"));
|
||||
EditorGUILayout.PropertyField(motorSpeed, new GUIContent("Motor Target Speed"));
|
||||
EditorGUILayout.PropertyField(motorForce, new GUIContent("Motor Max Force"));
|
||||
EditorGUILayout.PropertyField(compliance, new GUIContent("Compliance"));
|
||||
EditorGUILayout.PropertyField(breakThreshold, new GUIContent("Break threshold"));
|
||||
|
||||
if (GUI.changed)
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
}
|
||||
|
||||
[DrawGizmo(GizmoType.Selected)]
|
||||
private static void DrawGizmos(ObiPinhole pinhole, GizmoType gizmoType)
|
||||
{
|
||||
var rope = pinhole.GetComponent<ObiRope>();
|
||||
|
||||
var ropeBlueprint = rope.sharedBlueprint as ObiRopeBlueprintBase;
|
||||
if (rope.isLoaded && ropeBlueprint != null && ropeBlueprint.deformableEdges != null)
|
||||
{
|
||||
Handles.color = new Color(1, 0.5f, 0.2f, 1);
|
||||
Handles.matrix = rope.solver.transform.localToWorldMatrix;
|
||||
|
||||
// draw limits:
|
||||
if (pinhole.limitRange)
|
||||
{
|
||||
for (int i = pinhole.firstEdge.edgeIndex; i <= pinhole.lastEdge.edgeIndex; ++i)
|
||||
{
|
||||
if (i >= 0 && i < ropeBlueprint.deformableEdges.Length)
|
||||
{
|
||||
int p1 = ropeBlueprint.deformableEdges[i * 2];
|
||||
int p2 = ropeBlueprint.deformableEdges[i * 2 + 1];
|
||||
var pos1 = rope.solver.positions[rope.solverIndices[p1]];
|
||||
var pos2 = rope.solver.positions[rope.solverIndices[p2]];
|
||||
|
||||
if (i == pinhole.firstEdge.edgeIndex)
|
||||
{
|
||||
pos1 = Vector4.Lerp(pos1, pos2, pinhole.firstEdge.coordinate);
|
||||
Handles.DrawSolidDisc(pos1, pos2 - pos1, HandleUtility.GetHandleSize(pos1) * 0.05f);
|
||||
}
|
||||
if (i == pinhole.lastEdge.edgeIndex)
|
||||
{
|
||||
pos2 = Vector4.Lerp(pos1, pos2, pinhole.lastEdge.coordinate);
|
||||
Handles.DrawSolidDisc(pos2, pos1 - pos2, HandleUtility.GetHandleSize(pos2) * 0.05f);
|
||||
}
|
||||
|
||||
Handles.DrawLine(pos1, pos2, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// draw source particle:
|
||||
int edgeIndex = pinhole.edgeIndex;
|
||||
|
||||
if (edgeIndex >= 0 && edgeIndex < ropeBlueprint.deformableEdges.Length)
|
||||
{
|
||||
int p1 = ropeBlueprint.deformableEdges[edgeIndex * 2];
|
||||
int p2 = ropeBlueprint.deformableEdges[edgeIndex * 2 + 1];
|
||||
var pos1 = rope.solver.positions[rope.solverIndices[p1]];
|
||||
var pos2 = rope.solver.positions[rope.solverIndices[p2]];
|
||||
Vector4 pos = Vector4.Lerp(pos1, pos2, pinhole.edgeCoordinate);
|
||||
Handles.DrawWireDisc(pos, pos1 - pos2, HandleUtility.GetHandleSize(pos) * 0.1f, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f58defb5faddb428ea91cd06eecd8729
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user