public void SetLimitCone() { using (var core = CreatePhysicsAndScene()) { var box1 = CreateBoxActor(core.Scene, new Vector3(5, 5, 5), new Vector3(0, 10, 0)); var box2 = CreateBoxActor(core.Scene, new Vector3(5, 5, 5), new Vector3(0, 20, 0)); SphericalJoint joint = core.Scene.CreateJoint <SphericalJoint>(box1, Matrix4x4.Identity, box2, Matrix4x4.Identity); // Set the limit cone var limit = new JointLimitCone() { YLimitAngle = 0.5f, // [0 - PI/2] ZLimitAngle = 0.6f, // [0 - PI/2] Stiffness = 3, Damping = 4, Restitution = 0.7f // [0 - 1] }; joint.SetLimitCone(limit); // Get the limit cone back and compare the values to make sure they've been stored var retrievedLimitCone = joint.GetLimitCone(); Assert.AreEqual(0.5f, retrievedLimitCone.YLimitAngle); Assert.AreEqual(0.6f, retrievedLimitCone.ZLimitAngle); Assert.AreEqual(3, retrievedLimitCone.Stiffness); Assert.AreEqual(4, retrievedLimitCone.Damping); Assert.AreEqual(0.7f, retrievedLimitCone.Restitution); } }
/// <summary> /// Creates GUI elements for fields specific to the spherical joint. /// </summary> protected void BuildGUI(SphericalJoint joint) { enableLimitField.OnChanged += x => { joint.SetFlag(SphericalJointFlag.Limit, x); MarkAsModified(); ConfirmModify(); ToggleLimitFields(x); }; Layout.AddElement(enableLimitField); limitLayout = Layout.AddLayoutX(); { limitLayout.AddSpace(10); GUILayoutY limitContentsLayout = limitLayout.AddLayoutY(); limitGUI = new LimitConeRangeGUI(joint.Limit, limitContentsLayout, Persistent); limitGUI.OnChanged += (x, y) => { joint.Limit = x; joint.Limit.SetBase(y); MarkAsModified(); }; limitGUI.OnConfirmed += ConfirmModify; } ToggleLimitFields(joint.HasFlag(SphericalJointFlag.Limit)); base.BuildGUI(joint, true); }
/// <inheritdoc/> protected internal override void Initialize() { SphericalJoint joint = InspectedObject as SphericalJoint; if (joint != null) { BuildGUI(joint); } }
/// <summary> /// Updates all GUI elements from current values in the joint. /// </summary> /// <param name="joint">Joint to update the GUI from.</param> protected void Refresh(SphericalJoint joint) { if (enableLimitField.Value != joint.EnableLimit) { enableLimitField.Value = joint.EnableLimit; ToggleLimitFields(joint.EnableLimit); } limitGUI.Limit = joint.Limit; base.Refresh(joint); }
/// <inheritdoc/> protected internal override void Initialize() { SphericalJoint joint = (SphericalJoint)InspectedObject; BuildGUI(joint, true); drawer.AddDefault(joint, typeof(SphericalJoint)); drawer.AddField("Enable limit", () => joint.HasFlag(SphericalJointFlag.Limit), x => joint.SetFlag(SphericalJointFlag.Limit, x)); drawer.AddConditional("Limit", () => joint.HasFlag(SphericalJointFlag.Limit)); }
private static void DrawSphericalJoint(SphericalJoint joint) { Vector3 target = GetAnchor(joint, JointBody.Target); Vector3 anchor = GetAnchor(joint, JointBody.Anchor); Vector3 center = target; Rigidbody rigidbody = joint.GetBody(JointBody.Target); if (rigidbody != null) { center = rigidbody.SceneObject.Position; } Gizmos.Color = Color.White; Gizmos.DrawSphere(center, 0.05f); Gizmos.Color = Color.Yellow; Gizmos.DrawSphere(target, 0.05f); Gizmos.DrawSphere(anchor, 0.05f); Gizmos.Color = Color.Green; Gizmos.DrawLine(target, center); Gizmos.Color = Color.Green; if (joint.HasFlag(SphericalJointFlag.Limit)) { LimitConeRange limit = joint.Limit; Radian zAngle = MathEx.Min(new Degree(360), limit.zLimitAngle * 2.0f); Radian yAngle = MathEx.Min(new Degree(360), limit.yLimitAngle * 2.0f); Gizmos.Transform = joint.SceneObject.WorldTransform; Gizmos.DrawWireArc(Vector3.Zero, Vector3.ZAxis, 0.25f, zAngle * -0.5f + new Degree(90), zAngle); Gizmos.DrawWireArc(Vector3.Zero, Vector3.YAxis, 0.25f, yAngle * -0.5f + new Degree(90), yAngle); Gizmos.Color = Color.Red; Radian remainingZAngle = new Degree(360) - zAngle; Radian remainingYAngle = new Degree(360) - yAngle; Gizmos.DrawWireArc(Vector3.Zero, Vector3.ZAxis, 0.25f, zAngle * 0.5f + new Degree(90), remainingZAngle); Gizmos.DrawWireArc(Vector3.Zero, Vector3.YAxis, 0.25f, yAngle * 0.5f + new Degree(90), remainingYAngle); } else { Gizmos.Color = Color.Green; Gizmos.Transform = joint.SceneObject.WorldTransform; Gizmos.DrawWireDisc(Vector3.Zero, Vector3.ZAxis, 0.25f); Gizmos.DrawWireDisc(Vector3.Zero, Vector3.YAxis, 0.25f); } }
/// <summary> /// Updates all GUI elements from current values in the joint. /// </summary> /// <param name="joint">Joint to update the GUI from.</param> protected void Refresh(SphericalJoint joint) { bool enableLimit = joint.HasFlag(SphericalJointFlag.Limit); if (enableLimitField.Value != enableLimit) { enableLimitField.Value = enableLimit; ToggleLimitFields(enableLimit); } limitGUI.Limit = joint.Limit; base.Refresh(joint); }
/// <inheritdoc/> protected internal override InspectableState Refresh() { SphericalJoint joint = InspectedObject as SphericalJoint; if (joint == null) { return(InspectableState.NotModified); } Refresh(joint); InspectableState oldState = modifyState; if (modifyState.HasFlag(InspectableState.Modified)) { modifyState = InspectableState.NotModified; } return(oldState); }