//********************************** Banshee Engine (www.banshee3d.com) **************************************************// //**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************// namespace BansheeEngine { /** @addtogroup Physics * @{ */ /// /// Represents the most customizable type of joint. This joint type can be used to create all other built-in joint /// types, and to design your own custom ones, but is less intuitive to use. Allows a specification of a linear /// constraint (for example for slider), twist constraint(rotating around X) and swing constraint(rotating around Y and /// Z). It also allows you to constrain limits to only specific axes or completely lock specific axes. /// public sealed class D6Joint : Joint { [SerializeField] private SerializableData data = new SerializableData(); /// /// Returns the current rotation of the joint around the X axis. /// public Radian Twist { get { if (Native != null) return Native.Twist; return new Radian(0.0f); } } /// /// Returns the current rotation of the joint around the Y axis. /// public Radian SwingY { get { if (Native != null) return Native.SwingY; return new Radian(0.0f); } } /// /// Returns the current rotation of the joint around the Z axis. /// public Radian SwingZ { get { if (Native != null) return Native.SwingZ; return new Radian(0.0f); } } /// /// Linear limit used for constraining translation degrees of freedom. /// public LimitLinear LimitLinear { get { return data.@internal.linearLimit; } set { if (data.@internal.linearLimit == value) return; data.@internal.linearLimit = value; if (Native != null) Native.LimitLinear = value; } } /// /// Angular limit used for constraining the twist (rotation around X) degree of freedom. /// public LimitAngularRange LimitTwist { get { return data.@internal.twistLimit; } set { if (data.@internal.twistLimit == value) return; data.@internal.twistLimit = value; if (Native != null) Native.LimitTwist = value; } } /// /// Cone limit used for constraining the swing (rotation around Y and Z) degree of freedom. /// public LimitConeRange LimitSwing { get { return data.@internal.swingLimit; } set { if (data.@internal.swingLimit == value) return; data.@internal.swingLimit = value; if (Native != null) Native.LimitSwing = value; } } /// /// Determines the drive's target position relative to the joint's first body. This is the position the drive will /// attempt to reach if enabled. /// public Vector3 DrivePosition { get { return data.@internal.drivePosition; } set { if (data.@internal.drivePosition == value) return; data.@internal.drivePosition = value; if (Native != null) Native.DrivePosition = value; } } /// /// Determines the drive's target orientation relative to the joint's first body. This is the orientation the drive /// will attempt to reach if enabled. /// public Quaternion DriveRotation { get { return data.@internal.driveRotation; } set { if (data.@internal.driveRotation == value) return; data.@internal.driveRotation = value; if (Native != null) Native.DriveRotation = value; } } /// /// Determines the drive's target linear velocity. This is the velocity the drive will attempt to reach if enabled. /// public Vector3 DriveLinearVelocity { get { return data.@internal.driveLinearVelocity; } set { if (data.@internal.driveLinearVelocity == value) return; data.@internal.driveLinearVelocity = value; if (Native != null) Native.DriveLinearVelocity = value; } } /// /// Determines the drive's target angular velocity. This is the velocity the drive will attempt to reach if enabled. /// public Vector3 DriveAngularVelocity { get { return data.@internal.driveAngularVelocity; } set { if (data.@internal.driveAngularVelocity == value) return; data.@internal.driveAngularVelocity = value; if (Native != null) Native.DriveAngularVelocity = value; } } /// /// Returns the type of motion constrain for the specified axis. /// /// Axis to retrieve the motion constrain for. /// Motion constrain type for the axis. public D6JointMotion GetMotion(D6JointAxis axis) { return data.@internal.motion[(int) axis]; } /// /// Allows you to constrain motion of the specified axis. Be aware that when setting drives for a specific axis /// you must also take care not to constrain its motion in a conflicting way(for example you cannot add a drive /// that moves the joint on X axis, and then lock the X axis). /// /// Unlocking translations degrees of freedom allows the bodies to move along the subset of the unlocked axes. /// (for example unlocking just one translational axis is the equivalent of a slider joint.) /// /// Angular degrees of freedom are partitioned as twist(around X axis) and swing(around Y and Z axes). Different /// effects can be achieves by unlocking their various combinations: /// - If a single degree of angular freedom is unlocked it should be the twist degree as it has extra options for /// that case (for example for a hinge joint). /// - If both swing degrees are unlocked but twist is locked the result is a zero-twist joint. /// - If one swing and one twist degree of freedom are unlocked the result is a zero-swing joint (for example an /// arm attached at the elbow) /// - If all angular degrees of freedom are unlocked the result is the same as the spherical joint. /// /// Axis to change the motion type for. /// Type of motion for the axis. public void SetMotion(D6JointAxis axis, D6JointMotion motion) { if (data.@internal.motion[(int)axis] == motion) return; data.@internal.motion[(int)axis] = motion; if (Native != null) Native.SetMotion(axis, motion); } /// /// Returns properties for the specified drive type. /// /// Type of drive to retrieve properties for. /// Properties for the requested drive type. public D6JointDrive GetDrive(D6JointDriveType type) { return data.@internal.drives[(int) type]; } /// /// Sets a drive that will attempt to move the specified degree(s) of freedom to the wanted position and velocity. /// /// Type of the drive. /// Drive properties. public void SetDrive(D6JointDriveType type, D6JointDrive drive) { if (data.@internal.drives[(int)type] == drive) return; data.@internal.drives[(int)type] = drive; if (Native != null) Native.SetDrive(type, drive); } /// /// Returns the native joint wrapped by this component. /// private NativeD6Joint Native { get { return (NativeD6Joint)native; } } /// internal override NativeJoint CreateNative() { NativeD6Joint joint = new NativeD6Joint(commonData.@internal, data.@internal); return joint; } /// /// Holds all data the joint component needs to persist through serialization. /// [SerializeObject] internal new class SerializableData { public ScriptD6JointData @internal; public SerializableData() { @internal.linearLimit = new LimitLinear(); @internal.twistLimit = new LimitAngularRange(); @internal.swingLimit = new LimitConeRange(); @internal.motion = new D6JointMotion[(int)D6JointAxis.Count]; @internal.drives = new D6JointDrive[(int)D6JointDriveType.Count]; @internal.drivePosition = Vector3.Zero; @internal.driveRotation = Quaternion.Identity; @internal.driveLinearVelocity = Vector3.Zero; @internal.driveAngularVelocity = Vector3.Zero; for (int i = 0; i < (int) D6JointAxis.Count; i++) @internal.drives[i] = new D6JointDrive(); } } } /** @} */ }