/// <summary> /// Create a new constraint given type and constraint frames. /// </summary> /// <param name="type">Constraint type.</param> /// <param name="referenceFrame">Reference frame.</param> /// <param name="connectedFrame">Connected frame.</param> /// <returns>Constraint component, added to a new game object - null if unsuccessful.</returns> public static Constraint Create(ConstraintType type, ConstraintFrame referenceFrame, ConstraintFrame connectedFrame) { GameObject constraintGameObject = new GameObject(Factory.CreateName("AGXUnity." + type)); try { Constraint constraint = constraintGameObject.AddComponent <Constraint>(); constraint.Type = type; constraint.AttachmentPair.ReferenceFrame = referenceFrame ?? new ConstraintFrame(); constraint.AttachmentPair.ConnectedFrame = connectedFrame ?? new ConstraintFrame(); // Creating a temporary native instance of the constraint, including a rigid body and frames. // Given this native instance we copy the default configuration. using (var tmpNative = new TemporaryNative(constraint.NativeType, constraint.AttachmentPair)) constraint.TryAddElementaryConstraints(tmpNative.Instance); return(constraint); } catch (System.Exception e) { Debug.LogException(e); DestroyImmediate(constraintGameObject); return(null); } }
/// <summary> /// Change constraint type. Note that all values will be default /// when the type has changed. /// </summary> /// <param name="type">New type of the constraint.</param> /// <param name="onObjectCreated">Optional callback when an object has been created.</param> /// <param name="destroyObject"> /// Optional callback to destroy an object - Object.DestroyImmediate /// is used by default. /// </param> public void ChangeType(ConstraintType type, Action <UnityEngine.Object> onObjectCreated = null, Action <UnityEngine.Object> destroyObject = null) { if (Native != null) { Debug.LogWarning("Invalid to change type of an initialized constraint.", this); return; } foreach (var elementaryConstraint in m_elementaryConstraints) { if (destroyObject != null) { destroyObject(elementaryConstraint); } else { DestroyImmediate(elementaryConstraint); } } m_elementaryConstraints.Clear(); SetType(type, true); if (type == ConstraintType.Unknown) { return; } using (var tempNative = new TemporaryNative(NativeType, AttachmentPair)) TryAddElementaryConstraints(tempNative.Instance, onObjectCreated); }
/// <summary> /// Patches primary and secondary elementary constraints to the current version of AGX. /// </summary> /// <param name="native">If given, the native configuration may be used.</param> /// <returns>True if modification were applied - otherwise false.</returns> public bool VerifyImplementation() { if (Type == ConstraintType.Hinge) { var swing = m_elementaryConstraints.FirstOrDefault(ec => ec.NativeName == "SW"); // Already created with swing - hinge is up to date. if (swing != null) { return(false); } var ecUn = m_elementaryConstraints.FirstOrDefault(ec => ec.NativeName == "D1_UN"); var ecVn = m_elementaryConstraints.FirstOrDefault(ec => ec.NativeName == "D1_VN"); // Not swing nor dot1's - this is an unknown configuration. if (ecUn == null || ecVn == null) { Debug.LogWarning("Trying to patch hinge but the elementary constraint configuration is undefined.", this); return(false); } using (var nativeHinge = new TemporaryNative(NativeType)) { swing = ElementaryConstraint.Create(gameObject, nativeHinge.Instance.getElementaryConstraintGivenName("SW")); } if (swing == null) { Debug.LogWarning("Unable to find elementary constraint \"SW\" in native hinge implementation.", this); return(false); } swing.Enable = ecUn.Enable || ecVn.Enable; swing.RowData[0].CopyFrom(ecUn.RowData[0]); swing.RowData[1].CopyFrom(ecVn.RowData[0]); m_elementaryConstraints.Insert(m_elementaryConstraints.IndexOf(ecUn), swing); m_elementaryConstraints.Remove(ecUn); m_elementaryConstraints.Remove(ecVn); DestroyImmediate(ecUn); DestroyImmediate(ecVn); return(true); } return(false); }
/// <summary> /// Create a new constraint component given constraint type. /// </summary> /// <param name="type">Type of constraint.</param> /// <param name="givenAttachmentPair">Optional initial attachment pair. When given, values and fields will be copied to this objects attachment pair.</param> /// <returns>Constraint component, added to a new game object - null if unsuccessful.</returns> public static Constraint Create(ConstraintType type, AttachmentPair givenAttachmentPair = null) { GameObject constraintGameObject = new GameObject(Factory.CreateName("AGXUnity." + type)); try { Constraint constraint = constraintGameObject.AddComponent <Constraint>(); constraint.Type = type; // Property AttachmentPair will create a new one if it doesn't exist. constraint.AttachmentPair.CopyFrom(givenAttachmentPair); // Creating a temporary native instance of the constraint, including a rigid body and frames. // Given this native instance we copy the default configuration. using (var tmpNative = new TemporaryNative(constraint.NativeType, constraint.AttachmentPair)) constraint.TryAddElementaryConstraints(tmpNative.Instance); return(constraint); } catch (System.Exception e) { Debug.LogException(e); DestroyImmediate(constraintGameObject); return(null); } }