private FABRIKChain LoadSystem(Transform transform, FABRIKChain parent = null, int layer = 0) { List <FABRIKEffector> effectors = new List <FABRIKEffector>(); // Use parent chain's end effector as our sub-base effector, e.g: // [D]---[E] // 1 / 2 1 = [A, B, C] // [A]---[B]---[C] 2 = [C, D, E] // \ 3 3 = [C, F, G] // [F]---[G] if (parent != null) { effectors.Add(parent.EndEffector); } // childCount > 1 is a new sub-base // childCount = 0 is an end chain (added to our list below) // childCount = 1 is continuation of chain while (transform != null) { FABRIKEffector effector = transform.gameObject.GetComponent <FABRIKEffector>(); if (effector == null) { break; } effectors.Add(effector); if (transform.childCount != 1) { break; } transform = transform.GetChild(0); } FABRIKChain chain = new FABRIKChain(parent, effectors, layer); chains.Add(chain); // Add to our end chain list if it is an end chain if (chain.IsEndChain) { endChains.Add(transform.gameObject.name, chain); } // Else iterate over each of the end effector's children to create a new chain in the layer above else { foreach (Transform child in transform) { LoadSystem(child, chain, layer + 1); } } return(chain); }
static public FABRIKEffector FetchComponent(GameObject gameObject) { FABRIKEffector effector = gameObject.GetComponent <FABRIKEffector>(); if (effector == null) { effector = gameObject.AddComponent <FABRIKEffector>(); } return(effector); }
public FABRIKEffector Constructor(FABRIKEffector parent = null) { position = transform.position; if (parent != null) { distance = Vector3.Distance(parent.position, position); } return(this); }
public FABRIKEffector Constructor(FABRIKEffector parent = null) { position = transform.position; if(parent != null) { distance = Vector3.Distance(parent.position, position); } return this; }
public void OnEnable() { FABRIKEffector effector = target as FABRIKEffector; Transform transform = effector.transform; SerializedObject serializedObject = new SerializedObject(target); SerializedProperty upAxisConstraintProperty = serializedObject.FindProperty("upAxisConstraint"); SerializedProperty forwardAxisConstraintProperty = serializedObject.FindProperty("forwardAxisConstraint"); rotation = transform.rotation * Quaternion.LookRotation(forwardAxisConstraintProperty.vector3Value, upAxisConstraintProperty.vector3Value); editingAxis = false; }
protected void CreateSystem(Transform transform) { if (transform.gameObject.GetComponent <FABRIKEffector>() == null) { FABRIKEffector effector = transform.gameObject.AddComponent <FABRIKEffector>(); if (transform.parent != null) { effector.forwardAxisConstraint = transform.localPosition; effector.upAxisConstraint = Vector3.up; } Debug.Log(transform.gameObject.name + ": FABRIKEffector added."); } else { Debug.Log(transform.gameObject.name + ": FABRIKEffector already exists!"); } if (transform.childCount == 0 && !transform.gameObject.name.Contains("_end_effector")) { GameObject gameObject = new GameObject(transform.gameObject.name + "_end_effector"); gameObject.transform.parent = transform; MeshFilter meshFilter = transform.gameObject.GetComponent <MeshFilter>(); if (meshFilter != null) { Bounds bounds = meshFilter.mesh.bounds; //gameObject.transform.localPosition = bounds.center + bounds.extents; //gameObject.transform.localPosition = Vector3.forward; } else { gameObject.transform.position = transform.position; } Debug.Log(transform.gameObject.name + ": end effector added as " + gameObject.name); } foreach (Transform child in transform) { CreateSystem(child); } }
private FABRIKChain CreateSystem(Transform transform, FABRIKChain parent = null, int layer = 0) { List <FABRIKEffector> effectors = new List <FABRIKEffector>(); FABRIKEffector effector = null; // Use parent chain's end effector as our sub-base effector if (parent != null) { effector = parent.EndEffector; effectors.Add(effector); } // childCount > 1 is a new sub-base, childCount = 0 is an end chain (added to our list below), childCount = 1 is continuation of chain while (transform) { effector = FABRIKEffector.FetchComponent(transform.gameObject).Constructor(effector); effectors.Add(effector); if (transform.childCount != 1) { break; } transform = transform.GetChild(0); } FABRIKChain chain = new FABRIKChain(layer, parent, effectors.ToArray()); chains.Add(chain); if (transform.childCount == 0) { endChains.Add(chain); } else { foreach (Transform child in transform) { CreateSystem(child, chain, layer + 1); } } return(chain); }
public void OnSceneGUI() { if (editingAxis) { if (Tools.current != Tool.None) { editingAxis = false; } else { FABRIKEffector effector = target as FABRIKEffector; Transform transform = effector.transform; EditorGUI.BeginChangeCheck(); Quaternion new_rotation = Handles.RotationHandle(rotation, transform.position); Handles.color = Handles.yAxisColor; Handles.ArrowHandleCap(0, transform.position, Quaternion.LookRotation(new_rotation * Vector3.up), 0.5F, EventType.Repaint); Handles.color = Handles.zAxisColor; Handles.ArrowHandleCap(0, transform.position, new_rotation, 1.0F, EventType.Repaint); if (EditorGUI.EndChangeCheck()) { rotation = new_rotation; SerializedObject serializedObject = new SerializedObject(target); SerializedProperty upAxisConstraintProperty = serializedObject.FindProperty("upAxisConstraint"); SerializedProperty forwardAxisConstraintProperty = serializedObject.FindProperty("forwardAxisConstraint"); upAxisConstraintProperty.vector3Value = Quaternion.Inverse(transform.rotation) * new_rotation * Vector3.up; forwardAxisConstraintProperty.vector3Value = Quaternion.Inverse(transform.rotation) * new_rotation * Vector3.forward; serializedObject.ApplyModifiedProperties(); AssetDatabase.SaveAssets(); } } } }
public void OnSceneGUI() { FABRIKEffector effector = target as FABRIKEffector; Transform transform = effector.transform; if (transform.parent != null && transform.parent.parent != null) { // Take our world-space direction and world-space up vector of the constraining rotation // Multiply this by the inverse of the constraining rotation to derive a local rotation Quaternion rotation = Quaternion.Inverse(transform.parent.parent.rotation) * Quaternion.LookRotation(transform.localPosition, transform.parent.rotation * Vector3.up); Quaternion swing, twist; // Decompose our local rotation to swing-twist about the forward vector of the constraining rotation rotation.Decompose(transform.parent.rotation * Vector3.forward, out swing, out twist); Handles.color = new Color(1.0f, 0.8f, 0.6f, 0.2f); Handles.DrawSolidArc(transform.parent.position, transform.parent.parent.rotation * swing * Vector3.right, transform.parent.parent.rotation * swing * Quaternion.AngleAxis(-effector.swingConstraint * 0.5F, swing * Vector3.right) * Vector3.forward, effector.swingConstraint, 5.0f); Handles.color = new Color(0.6f, 0.8f, 1.0f, 0.2f); Handles.DrawSolidArc(transform.parent.position, transform.parent.parent.rotation * twist * Vector3.right, transform.parent.parent.rotation * twist * Quaternion.AngleAxis(-effector.twistConstraint * 0.5F, twist * Vector3.right) * Vector3.forward, effector.twistConstraint, 5.0f); // Constrain the swing and twist quaternions if (effector.SwingConstrained) { swing = swing.Constrain(effector.swingConstraint * Mathf.Deg2Rad); } if (effector.TwistConstrained) { twist = twist.Constrain(effector.twistConstraint * Mathf.Deg2Rad); } // Multiply the constrained swing-twist by our constraining rotation to get a world-space rotation //transform.position = transform.parent.position + transform.parent.parent.rotation * swing * twist * Vector3.forward * transform.localPosition.magnitude; } }
private FABRIKEffector CreateEndEffector(FABRIKEffector parent) { MeshFilter meshFilter = parent.gameObject.GetComponent <MeshFilter>(); Bounds bounds = meshFilter.mesh.bounds; GameObject gameObject = new GameObject(); gameObject.hideFlags = HideFlags.DontSave; gameObject.transform.parent = parent.transform; gameObject.transform.localPosition = bounds.center + Vector3.Scale(bounds.extents, parent.offset); foreach (Transform child in parent.transform) { if (child != gameObject.transform) { child.parent = gameObject.transform; } } return(gameObject.AddComponent <FABRIKEffector>()); }
void Awake() { parent = transform.parent.gameObject.GetComponent <FABRIKEffector>(); Position = transform.position; }