public static bool RayCast(Vector3 _origin, Vector3 _direction, float _distance, TxBody _skip, out TxBody _body, out Vector3 _point, out Vector3 _normal, out int _face) { if (sm_world != null) { return(sm_world.RayCast(_origin, _direction, _distance, _skip, out _body, out _point, out _normal, out _face)); } _body = null; _point = Vector3.zero; _normal = Vector3.zero; _face = -1; return(false); }
void GroupCollisionUI(TxBody _rootBody) { string[] groupLayers = _rootBody.groupLayers; List <GUIContent> layerNames = new List <GUIContent>(); List <int> layerIndices = new List <int>(); GUIStyle lableStyle = EditorStyles.label; float maxLength = 0; for (int i = 0; i < groupLayers.Length; ++i) { string layerName = groupLayers[i]; if (layerName != string.Empty) { layerNames.Add(new GUIContent(layerName)); layerIndices.Add(i); maxLength = Mathf.Max(maxLength, lableStyle.CalcSize(new GUIContent(layerName)).x); } } int num = layerNames.Count; sm_showCollision = EditorGUILayout.Foldout(sm_showCollision, "Collision"); if (sm_showCollision) { Rect rect = GUILayoutUtility.GetRect(EditorGUIUtility.labelWidth, maxLength); for (int j = 0; j < num; j++) { Vector3 pos = new Vector3(EditorGUIUtility.labelWidth + (num - j + 1) * 15f - 1f, rect.y - 9f, 0f); GUI.matrix = Matrix4x4.identity; GUIUtility.RotateAroundPivot(90.0f, pos); if (SystemInfo.graphicsDeviceVersion.StartsWith("Direct3D 9.0")) { GUI.matrix *= Matrix4x4.TRS(new Vector3(-0.5f, -0.5f, 0f), Quaternion.identity, Vector3.one); } GUI.Label(new Rect(pos.x, pos.y, maxLength, 15f), layerNames[j], "RightLabel"); } GUI.matrix = Matrix4x4.identity; for (int k = 0; k < num; k++) { GUILayoutUtility.GetRect((float)(30 + 15 * num + 100), 15f); GUI.Label(new Rect(15f, rect.y + maxLength + k * 15f - 10f, EditorGUIUtility.labelWidth, 15f), layerNames[k], "RightLabel"); for (int l = k; l < num; l++) { GUIContent content = new GUIContent(string.Empty, layerNames[k].text + "/" + layerNames[l].text); int ki = layerIndices[k], li = layerIndices[l]; int index = ki * 8 - ki * (ki + 1) / 2 + li; SerializedProperty collision = groupCollision.GetArrayElementAtIndex(index); bool flag = collision.boolValue; bool flag2 = GUI.Toggle(new Rect(EditorGUIUtility.labelWidth + (num - l) * 15f, rect.y + maxLength + k * 15f - 10f, 15f, 15f), flag, content); if (flag2 != flag) { collision.boolValue = flag2; } } } } }
protected override void RegisterDependencies() { TxBody parentBody = FindParentBody(); if (parentBody) { AddDependency(parentBody); } base.RegisterDependencies(); }
public bool RayCast(Vector3 _origin, Vector3 _direction, float _distance, TxBody _skip, out TxBody _body, out Vector3 _point, out Vector3 _normal, out int _face) { _body = null; int hitObjectID = -1; _point = Vector3.zero; _normal = Vector3.zero; _face = -1; if (TxNative.WorldRayCast(m_worldID, _origin, _direction, _distance, _skip ?_skip.objectID : -1, ref hitObjectID, ref _point, ref _normal, ref _face)) { _body = TxBody.Find(hitObjectID); return(true); } return(false); }
int InSameGroup(ref TxBody _rootBody) { foreach (var b in m_targets) { int inGroup = InGroup(b, ref _rootBody); if (inGroup != 1) { return(inGroup); } } return(1); }
protected void CreateBody() { m_worldID = TxWorld.instance.worldID; if (!TxNative.WorldObjectExists(m_worldID, m_objectID)) { m_objectID = TxNative.WorldCreateObject(m_worldID, transform.localToWorldMatrix); sm_bodies.Add(m_objectID, this); TxNative.WorldObjectSetEnabled(m_worldID, m_objectID, m_spawnEnabled); if (m_groupRoot) { m_groupID = TxNative.WorldCreateGroup(m_worldID); TxNative.WorldObjectSetGroup(m_worldID, m_objectID, m_groupID); for (int i = 0; i < 8; ++i) { for (int j = i; j < 8; ++j) { int index = i * 8 - i * (i + 1) / 2 + j; bool yes = m_groupCollision[index]; TxNative.WorldGroupSetColliding(m_worldID, m_groupID, i, j, yes); } } } else { m_groupID = -1; Transform parent = transform; while (parent != null) { TxBody parentBody = parent.GetComponent <TxBody>(); if (parentBody != null && parentBody.groupRoot) { if (!parentBody.isValid) { parentBody.Create(); } m_groupID = parentBody.groupID; break; } parent = parent.parent; } TxNative.WorldObjectSetGroup(m_worldID, m_objectID, m_groupID); } TxNative.WorldObjectSetWorldLayer(m_worldID, m_objectID, gameObject.layer); TxNative.WorldObjectSetGroupLayer(m_worldID, m_objectID, m_groupLayer); } }
public TxBody FindParentBody() { Transform parent = transform.parent; while (parent != null) { TxBody body = parent.GetComponent <TxBody>(); if (body != null) { return(body); } parent = parent.parent; } return(null); }
void GroupLayerUI(TxBody _rootBody) { string[] groupLayers = _rootBody.groupLayers; List <GUIContent> layerNames = new List <GUIContent>(); List <int> layerIndices = new List <int>(); for (int i = 0; i < groupLayers.Length; ++i) { string layerName = groupLayers[i]; if (layerName != string.Empty) { layerNames.Add(new GUIContent(layerName)); layerIndices.Add(i); } } EditorGUILayout.IntPopup(groupLayer, layerNames.ToArray(), layerIndices.ToArray(), new GUIContent("Layer")); }
protected override void OnAfterStep() { if (onCollision != null) { int contactID = TxNative.WorldObjectFirstContact(m_worldID, m_objectID); while (TxNative.WorldContactExists(m_worldID, contactID)) { Contact c = new Contact(); int objectA = -1, objectB = -1; if (TxNative.WorldContactGetInfo(m_worldID, contactID, ref objectA, ref objectB, ref c.averagePosition, ref c.averageNormal, ref c.minimumDistance, ref c.totalImpulse, ref c.relativeVelocity)) { c.bodyA = TxBody.Find(objectA); c.bodyB = TxBody.Find(objectB); onCollision(c); } contactID = TxNative.WorldObjectNextContact(m_worldID, m_objectID, contactID); } } base.OnAfterStep(); }
protected void BodyGroupUI() { bool isPlaying = Application.isPlaying; sm_showGroup = EditorGUILayout.Foldout(sm_showGroup, "Group"); if (sm_showGroup) { EditorGUI.indentLevel++; GUI.enabled = !isPlaying; EditorGUILayout.PropertyField(groupRoot, new GUIContent("Root")); TxBody rootBody = null; int inGroup = InSameGroup(ref rootBody); switch (inGroup) { case 0: GUI.enabled = false; EditorGUILayout.LabelField("Different groups"); break; case -1: GUI.enabled = false; EditorGUILayout.LabelField("Not in a group"); break; case 1: GUI.enabled = !isPlaying; if (m_targets.Length == 1 && m_targets[0] == rootBody) { EditorGUI.indentLevel++; GroupLayersUI(); GroupCollisionUI(rootBody); EditorGUI.indentLevel--; } GroupLayerUI(rootBody); break; } EditorGUI.indentLevel--; } }
int InGroup(TxBody _target, ref TxBody _rootBody) { Transform parent = _target.transform; while (parent != null) { TxBody parentBody = parent.GetComponent <TxBody>(); if (parentBody != null && parentBody.groupRoot) { if (_rootBody == null) { _rootBody = parentBody; } else if (_rootBody != parentBody) { return(0); } return(1); } parent = parent.parent; } return(-1); }
public virtual void Destroy() { if (onBeforeDestroy != null) { onBeforeDestroy(this); } TxBody parentBody = (this is TxBody) ? (this as TxBody).FindParentBody() : (this is TxConstraint) ? (this as TxConstraint).attachedBody : null; if (parentBody != null) { parentBody.onBeforeStep -= OnBeforeStep; parentBody.onAfterStep -= OnAfterStep; parentBody.onAfterUpdate -= OnAfterUpdate; } else { TxPhysics.onBeforeStep -= OnBeforeStep; TxPhysics.onAfterStep -= OnAfterStep; TxPhysics.onAfterUpdate -= OnAfterUpdate; } m_valid = false; }
public virtual void Create() { TxBody parentBody = (this is TxBody) ? (this as TxBody).FindParentBody() : (this is TxConstraint) ? (this as TxConstraint).attachedBody : null; if (parentBody != null) { parentBody.onBeforeStep += OnBeforeStep; parentBody.onAfterStep += OnAfterStep; parentBody.onAfterUpdate += OnAfterUpdate; } else { TxPhysics.onBeforeStep += OnBeforeStep; TxPhysics.onAfterStep += OnAfterStep; TxPhysics.onAfterUpdate += OnAfterUpdate; } m_valid = true; if (onAfterCreate != null) { onAfterCreate(this); } }
protected override TxComponent GetComponentMaster() { TxBody parent = FindParentBody(); return(parent != null ? (TxComponent)parent : (TxComponent)TxWorld.instance); }
void OnSceneGUI() { Color yellow = new Color(1.0f, 0.5f, 0.0f); Color green = new Color(0.0f, 0.5f, 0.0f); Color blue = new Color(0.0f, 0.5f, 1.0f); Color red = new Color(0.5f, 0.0f, 0.0f); float size = 0.1f; foreach (TxConstraint constraint in m_targets) { if (!constraint.enabled || constraint.isBroken) { continue; } TxSoftBody bodyA = constraint.attachedBody; TxTruss trussA = bodyA.truss; if (trussA == null) { continue; } if (constraint.enableMotor) { int[] motorAxis = trussA.FindNodeSet(constraint.motorAxis); if (motorAxis != null && motorAxis.Length == 2) { Vector3 axis0 = bodyA.nodePosition[motorAxis[0]]; Vector3 axis1 = bodyA.nodePosition[motorAxis[1]]; Handles.color = red; Handles.DrawLine(axis0, axis1); } } if (constraint.baseBody is TxSoftBody) { Handles.color = yellow; TxSoftBody bodyB = constraint.baseBody as TxSoftBody; TxTruss trussB = bodyB.truss; if (trussB == null) { continue; } TxConstraint.Snap[] snaps = constraint.snaps; foreach (var s in snaps) { if (!s.show) { continue; } int[] indicesA = trussA.FindNodeSet(s.node); if (indicesA != null && indicesA.Length == 1) { Vector3 positionA = bodyA.nodePosition[indicesA[0]]; int[] indicesB = trussB.FindNodeSet(s.featureB); if (indicesB != null) { switch (s.type) { case TxConstraint.SnapType.Node: if (indicesB.Length == 1) { Matrix4x4 matrixB = bodyB.transform.localToWorldMatrix; Vector3 positionB = bodyB.nodePosition[indicesB[0]]; if (Vector3.Distance(positionA, positionB) > 0.001f) { Handles.color = yellow; size = HandleUtility.GetHandleSize(positionA) * 0.08f; Handles.SphereCap(-1, positionA, Quaternion.identity, size); Handles.color = blue; size = HandleUtility.GetHandleSize(positionB) * 0.08f; Handles.SphereCap(-1, positionB, Quaternion.identity, size); Handles.color = green; Handles.DrawLine(positionA, positionB); } else { Handles.color = green; size = HandleUtility.GetHandleSize(positionA) * 0.08f; Handles.SphereCap(-1, positionA, Quaternion.identity, size); } if (s.maxLimit > 0.001f) { if (s.minLimit < s.maxLimit - 0.001f) { Handles.color = blue; Handles.DrawWireDisc(positionB, matrixB.GetColumn(0), s.minLimit); Handles.DrawWireDisc(positionB, matrixB.GetColumn(1), s.minLimit); Handles.DrawWireDisc(positionB, matrixB.GetColumn(2), s.minLimit); Handles.color = yellow; Handles.DrawWireDisc(positionB, matrixB.GetColumn(0), s.maxLimit); Handles.DrawWireDisc(positionB, matrixB.GetColumn(1), s.maxLimit); Handles.DrawWireDisc(positionB, matrixB.GetColumn(2), s.maxLimit); } else { Handles.color = green; Handles.DrawWireDisc(positionB, matrixB.GetColumn(0), s.maxLimit); Handles.DrawWireDisc(positionB, matrixB.GetColumn(1), s.maxLimit); Handles.DrawWireDisc(positionB, matrixB.GetColumn(2), s.maxLimit); } } } break; case TxConstraint.SnapType.Edge: if (indicesB.Length == 2) { Vector3 positionB0 = bodyB.nodePosition[indicesB[0]]; Vector3 positionB1 = bodyB.nodePosition[indicesB[1]]; Handles.color = blue; size = HandleUtility.GetHandleSize(positionB0) * 0.08f; Handles.SphereCap(-1, positionB0, Quaternion.identity, size); size = HandleUtility.GetHandleSize(positionB1) * 0.08f; Handles.SphereCap(-1, positionB1, Quaternion.identity, size); Handles.DrawLine(positionB0, positionB1); Vector3 positionB = positionB0 + (positionB1 - positionB0) * Vector3.Dot(positionB1 - positionB0, positionA - positionB0) / (positionB1 - positionB0).sqrMagnitude; if (Vector3.Distance(positionA, positionB) > 0.001f) { Handles.color = yellow; size = HandleUtility.GetHandleSize(positionA) * 0.08f; Handles.SphereCap(-1, positionA, Quaternion.identity, size); Handles.color = blue; size = HandleUtility.GetHandleSize(positionB) * 0.08f; Handles.SphereCap(-1, positionB, Quaternion.identity, size); Handles.color = green; Handles.DrawLine(positionA, positionB); } else { Handles.color = green; size = HandleUtility.GetHandleSize(positionA) * 0.08f; Handles.SphereCap(-1, positionA, Quaternion.identity, size); } if (s.maxLimit > 0.001f) { Vector3 normal = (positionB1 - positionB0).normalized; if (s.minLimit < s.maxLimit - 0.001f) { Handles.color = blue; Handles.DrawWireDisc(positionB0, normal, s.minLimit); Handles.DrawWireDisc((positionB0 + positionB1) * 0.5f, normal, s.minLimit); Handles.DrawWireDisc(positionB1, normal, s.minLimit); Handles.color = yellow; Handles.DrawWireDisc(positionB0, normal, s.maxLimit); Handles.DrawWireDisc((positionB0 + positionB1) * 0.5f, normal, s.maxLimit); Handles.DrawWireDisc(positionB1, normal, s.maxLimit); } else { Handles.color = green; Handles.DrawWireDisc(positionB0, normal, s.maxLimit); Handles.DrawWireDisc((positionB0 + positionB1) * 0.5f, normal, s.maxLimit); Handles.DrawWireDisc(positionB1, normal, s.maxLimit); } } } break; } } } } } else { TxBody bodyB = constraint.baseBody; Matrix4x4 matrixA = Application.isPlaying ? constraint.startMatrix : bodyB ? bodyB.transform.worldToLocalMatrix * bodyA.transform.localToWorldMatrix : bodyA.transform.localToWorldMatrix; Matrix4x4 matrixB = bodyB ? bodyB.transform.localToWorldMatrix : Matrix4x4.identity; TxConstraint.Snap[] snaps = constraint.snaps; foreach (var s in snaps) { if (!s.show) { continue; } int[] indices = trussA.FindNodeSet(s.node); if (indices != null) { foreach (var i in indices) { if (s.maxLimit > 0.001f) { Vector3 positionA = bodyA.nodePosition[i]; Vector3 positionB = matrixB.MultiplyPoint(matrixA.MultiplyPoint(trussA.nodePosition[i])); if (Vector3.Distance(positionA, positionB) > 0.001f) { Handles.color = yellow; size = HandleUtility.GetHandleSize(positionA) * 0.08f; Handles.SphereCap(-1, positionA, Quaternion.identity, size); Handles.color = blue; size = HandleUtility.GetHandleSize(positionB) * 0.08f; Handles.SphereCap(-1, positionB, Quaternion.identity, size); } else { Handles.color = green; size = HandleUtility.GetHandleSize(positionA) * 0.08f; Handles.SphereCap(-1, positionA, Quaternion.identity, size); } Handles.color = green; Handles.DrawWireDisc(positionB, matrixB.GetColumn(0), s.maxLimit); Handles.DrawWireDisc(positionB, matrixB.GetColumn(1), s.maxLimit); Handles.DrawWireDisc(positionB, matrixB.GetColumn(2), s.maxLimit); } else { Vector3 position = matrixB.MultiplyPoint(matrixA.MultiplyPoint(trussA.nodePosition[i])); Handles.color = green; size = HandleUtility.GetHandleSize(position) * 0.08f; Handles.SphereCap(-1, position, Quaternion.identity, size); } } } } } } Handles.color = Color.white; }