/// <summary> /// Creates a wheel and attaches it to the parent BRaycastVehicle. /// </summary> /// <param name="node"></param> public void CreateWheel(RigidNode node) { this.node = node; RigidNode parent = (RigidNode)node.GetParent(); robot = parent.MainObject.GetComponent <BRaycastRobot>(); if (robot == null) { Debug.LogError("Could not add BRaycastWheel because its parent does not have a BRaycastVehicle!"); Destroy(this); } RotationalJoint_Base joint = (RotationalJoint_Base)node.GetSkeletalJoint(); joint.basePoint.x *= -1; node.OrientWheelNormals(); axis = joint.axis.AsV3(); WheelDriverMeta driverMeta = node.GetDriverMeta <WheelDriverMeta>(); radius = driverMeta.radius * 0.01f; Vector3 localPosition = parent.MainObject.transform.InverseTransformPoint(node.MainObject.transform.position); basePoint = localPosition.ToBullet() + new BulletSharp.Math.Vector3(0f, VerticalOffset, 0f); wheelIndex = robot.AddWheel(driverMeta.type, basePoint, axis.normalized.ToBullet(), VerticalOffset, radius); }
// Generation Methods private RigidNode_Base CreateNodeWithChild() { RotationalJoint_Base joint = new RotationalJoint_Base(); joint.axis = new BXDVector3(2, 2, 2); joint.basePoint = new BXDVector3(3, 131, 3); JointDriver driver = new JointDriver(JointDriverType.MOTOR); driver.SetPort(414); driver.isCan = true; WheelDriverMeta wheelDriverMeta = new WheelDriverMeta(); wheelDriverMeta.radius = 9.4F; wheelDriverMeta.center = new BXDVector3(1, 1, 1); driver.AddInfo(wheelDriverMeta); joint.cDriver = driver; Guid childID = new Guid(); RigidNode_Base baseNode = new RigidNode_Base(id); RigidNode_Base childNode = new RigidNode_Base(childID); baseNode.AddChild(joint, childNode); return(baseNode); }
/// <summary> /// Creates the joint data /// </summary> public void CreateJoint() { if (joint != null || GetSkeletalJoint() == null) { return; } switch (GetSkeletalJoint().GetJointType()) { case SkeletalJointType.ROTATIONAL: RotationalJoint_Base nodeR = (RotationalJoint_Base)GetSkeletalJoint(); CollisionObject parentObject = ((BulletRigidNode)GetParent()).BulletObject; WheelDriverMeta wheel = GetSkeletalJoint().cDriver.GetInfo <WheelDriverMeta>(); Vector3 pivot = nodeR.basePoint.Convert(); Matrix4 locJ, locP; //Local Joint Pivot, Local Parent Pivot BulletObject.WorldTransform = parentObject.WorldTransform * Matrix4.CreateTranslation(pivot); if (debug) { Console.WriteLine("Pivot at " + pivot); } GetFrames(nodeR.basePoint.Convert(), parentObject.WorldTransform, BulletObject.WorldTransform, out locP, out locJ); //HingeConstraint temp = new HingeConstraint((RigidBody)parentObject, /*(RigidBody)*/BulletObject, locP, locJ); HingeConstraint temp = new HingeConstraint((RigidBody)parentObject, BulletObject, pivot, Vector3.Zero, nodeR.axis.Convert(), nodeR.axis.Convert()); joint = temp; temp.SetAxis(nodeR.axis.Convert()); if (nodeR.hasAngularLimit) { temp.SetLimit(nodeR.angularLimitLow, nodeR.angularLimitHigh); } //also need to find a less screwy way to do this Update = (f) => { (/*(RigidBody)*/ BulletObject).ApplyTorque(nodeR.axis.Convert() * f * 25); }; if (debug) { Console.WriteLine("{0} joint made", wheel == null ? "Rotational" : "Wheel"); } break; default: if (debug) { Console.WriteLine("Received joint of type {0}", GetSkeletalJoint().GetJointType()); } break; } }
/// <summary> /// Orients drive wheel normals so they face away from the center of mass. /// </summary> /// <remarks> /// Implemented so that the joint's axis is negated when the angle between the joint's axis and the vector from /// the wheel to the center of mass is greater than 90 degrees. /// </remarks> private void OrientWheelNormals() { if (GetSkeletalJoint() is RotationalJoint_Base && this.HasDriverMeta <WheelDriverMeta>()) { Vector3 com = ((UnityRigidNode)GetParent()).bxdPhysics.centerOfMass.AsV3(); RotationalJoint_Base rJoint = (RotationalJoint_Base)GetSkeletalJoint(); Vector3 diff = rJoint.basePoint.AsV3() - com; double dot = Vector3.Dot(diff, rJoint.axis.AsV3()); if (dot < 0) { rJoint.axis = rJoint.axis.Multiply(-1); } } }
public void OrientWheelNormals() { if (GetSkeletalJoint() is RotationalJoint_Base) { Vector3 com = ((RigidNode)GetParent()).PhysicalProperties.centerOfMass.AsV3(); RotationalJoint_Base rJoint = (RotationalJoint_Base)GetSkeletalJoint(); Vector3 diff = rJoint.basePoint.AsV3() - com; double dot = Vector3.Dot(diff, rJoint.axis.AsV3()); if (dot > 0) { rJoint.axis = rJoint.axis.Multiply(-1f); } } }
/// <summary> /// Reads a RotationalJoint_Base from the given XmlReader. /// </summary> /// <param name="reader"></param> /// <returns></returns> private static RotationalJoint_Base ReadRotationalJoint_3_0(XmlReader reader) { // Create a new RotationalJoint_Base. RotationalJoint_Base rotationalJoint = (RotationalJoint_Base)SkeletalJoint_Base.JOINT_FACTORY(SkeletalJointType.ROTATIONAL); foreach (string name in IOUtilities.AllElements(reader)) { switch (name) { case "BXDVector3": switch (reader["VectorID"]) { case "BasePoint": // Read the BXDVector3 as the basePoint. rotationalJoint.basePoint = ReadBXDVector3_3_0(reader.ReadSubtree()); break; case "Axis": // Read the BXDVector3 as the axis. rotationalJoint.axis = ReadBXDVector3_3_0(reader.ReadSubtree()); break; } break; case "AngularLowLimit": // Assign the current element value to angularLimitLow. rotationalJoint.hasAngularLimit = true; rotationalJoint.angularLimitLow = float.Parse(reader.ReadElementContentAsString()); break; case "AngularHighLimit": // Assign the current element value to angularLimitHigh. rotationalJoint.angularLimitHigh = float.Parse(reader.ReadElementContentAsString()); break; case "CurrentAngularPosition": // Assign the current element value to currentAngularPosition. rotationalJoint.currentAngularPosition = float.Parse(reader.ReadElementContentAsString()); break; } } return(rotationalJoint); }
/// <summary> /// Used for writing the data of a RotationalJoint_Base. /// </summary> /// <param name="joint"></param> /// <param name="writer"></param> private static void WriteRotationalJoint(RotationalJoint_Base joint, XmlWriter writer) { writer.WriteStartElement("RotationalJoint"); joint.EnforceOrder(); WriteBXDVector3(joint.basePoint, writer, "BasePoint"); WriteBXDVector3(joint.axis, writer, "Axis"); if (joint.hasAngularLimit) { writer.WriteElementString("AngularLowLimit", joint.angularLimitLow.ToString("F4")); writer.WriteElementString("AngularHighLimit", joint.angularLimitHigh.ToString("F4")); } writer.WriteElementString("CurrentAngularPosition", joint.currentAngularPosition.ToString("F4")); writer.WriteEndElement(); }
/// <summary> /// Used for writing the data of a RotationalJoint_Base. /// </summary> /// <param name="joint"></param> /// <param name="writer"></param> private static void WriteRotationalJoint(RotationalJoint_Base joint, XmlWriter writer) { writer.WriteStartElement("RotationalJoint"); joint.EnforceOrder(); WriteBXDVector3(joint.basePoint, writer, "BasePoint"); WriteBXDVector3(joint.axis, writer, "Axis"); if (joint.hasAngularLimit) { writer.WriteElementString("AngularLowLimit", joint.angularLimitLow.ToString("F4")); writer.WriteElementString("AngularHighLimit", joint.angularLimitHigh.ToString("F4")); } // writer.WriteElementString("CurrentAngularPosition", joint.currentAngularPosition.ToString("F4")); writer.WriteElementString("CurrentAngularPosition", joint.currentAngularPosition.ToString("F4"));// writes the lowest point of the joint to the file as the positon so the joint starts at the bottom, hopefully prevents any weird issues with the joint limits being messed up do to being relative to the start of the joint writer.WriteEndElement(); }
/// <summary> /// Creates node_0 of a manipulator for QuickSwap mode. Node_0 is used to attach the manipulator to the robot. /// </summary> public void CreateManipulatorJoint() { //Ignore physics/collisions between the manipulator and the robot. Currently not working. foreach (BRigidBody rb in GameObject.Find("Robot").GetComponentsInChildren <BRigidBody>()) { MainObject.GetComponent <BRigidBody>().GetCollisionObject().SetIgnoreCollisionCheck(rb.GetCollisionObject(), true); } if (joint != null || GetSkeletalJoint() == null) { RotationalJoint_Base rNode = new RotationalJoint_Base(); B6DOFConstraint hc = MainObject.AddComponent <B6DOFConstraint>(); hc.thisRigidBody = MainObject.GetComponent <BRigidBody>(); hc.otherRigidBody = GameObject.Find("Robot").GetComponentInChildren <BRigidBody>(); hc.localConstraintPoint = ComOffset; //Put this after everything else hc.constraintType = BTypedConstraint.ConstraintType.constrainToAnotherBody; } }
/// <summary> /// Compute the positions and rotations of this node and its children /// </summary> /// <param name="moveJoints">Whether or not to move the node on its joints</param> public void compute(bool moveJoints) { if (moveJoints) { timeStep += 0.005f; } else { timeStep = 0.0f; } #region INIT_POSITION if (!initialPositions && GetSkeletalJoint() != null) { initialPositions = true; switch (GetSkeletalJoint().GetJointType()) { case SkeletalJointType.CYLINDRICAL: CylindricalJoint_Base cjb = (CylindricalJoint_Base)GetSkeletalJoint(); requestedRotation = cjb.currentAngularPosition; requestedTranslation = cjb.currentLinearPosition; break; case SkeletalJointType.ROTATIONAL: RotationalJoint_Base rjb = (RotationalJoint_Base)GetSkeletalJoint(); requestedRotation = rjb.currentAngularPosition; requestedTranslation = 0; break; case SkeletalJointType.LINEAR: LinearJoint_Base ljb = (LinearJoint_Base)GetSkeletalJoint(); requestedRotation = 0; requestedTranslation = ljb.currentLinearPosition; break; } } #endregion myTrans = Matrix4.Identity; if (GetSkeletalJoint() != null) { foreach (AngularDOF dof in GetSkeletalJoint().GetAngularDOF()) { BXDVector3 axis = dof.rotationAxis; BXDVector3 basePoint = dof.basePoint; if (GetParent() != null) { basePoint = ((OGL_RigidNode)GetParent()).myTrans.Multiply(basePoint); axis = ((OGL_RigidNode)GetParent()).myTrans.Rotate(axis); } requestedRotation = (float)(Math.Sin(timeStep) + 0.9f) * 1.2f * (dof.hasAngularLimits() ? (dof.upperLimit - dof.lowerLimit) / 2.0f : 3.14f) + (dof.hasAngularLimits() ? dof.lowerLimit : 0); requestedRotation = Math.Max(dof.lowerLimit, Math.Min(dof.upperLimit, requestedRotation)); myTrans *= Matrix4.CreateTranslation(-dof.basePoint.ToTK()); myTrans *= Matrix4.CreateFromAxisAngle(dof.rotationAxis.ToTK(), requestedRotation - dof.currentPosition); myTrans *= Matrix4.CreateTranslation(dof.basePoint.ToTK()); } foreach (LinearDOF dof in GetSkeletalJoint().GetLinearDOF()) { requestedTranslation = (float)(Math.Cos(timeStep) + 0.9f) * 1.2f * (dof.hasLowerLinearLimit() && dof.hasUpperLinearLimit() ? (dof.upperLimit - dof.lowerLimit) / 2.0f : 3.14f) + (dof.hasLowerLinearLimit() ? dof.lowerLimit : 0); requestedTranslation = Math.Max(dof.lowerLimit, Math.Min(dof.upperLimit, requestedTranslation)); myTrans *= Matrix4.CreateTranslation(dof.translationalAxis.ToTK() * (requestedTranslation - dof.currentPosition)); } } if (GetParent() != null) { myTrans = myTrans * ((OGL_RigidNode)GetParent()).myTrans; } foreach (KeyValuePair <SkeletalJoint_Base, RigidNode_Base> pair in Children) { OGL_RigidNode child = ((OGL_RigidNode)pair.Value); child.compute(moveJoints); } }
/// <summary> /// Crenates the proper joint type for this node. /// </summary> public void CreateJoint() { if (joint != null || GetSkeletalJoint() == null) { return; } //this is the conditional for Identifying wheels if (GetSkeletalJoint().GetJointType() == SkeletalJointType.ROTATIONAL) { if (this.HasDriverMeta <WheelDriverMeta>()) { OrientWheelNormals(); } RotationalJoint_Base nodeR = (RotationalJoint_Base)GetSkeletalJoint(); //takes the x, y, and z axis information from a custom vector class to unity's vector class joint = ConfigJointInternal <HingeJoint>(nodeR.basePoint.AsV3(), nodeR.axis.AsV3(), delegate(HingeJoint jointSub) { jointSub.useLimits = nodeR.hasAngularLimit; if (nodeR.hasAngularLimit) { AngularLimit(jointSub, MathfExt.ToDegrees(nodeR.currentAngularPosition), MathfExt.ToDegrees(nodeR.angularLimitLow), MathfExt.ToDegrees(nodeR.angularLimitHigh)); } }); //don't worry, I'm a doctor if (this.HasDriverMeta <WheelDriverMeta>()) { CreateWheel(); } } else if (GetSkeletalJoint().GetJointType() == SkeletalJointType.CYLINDRICAL) { CylindricalJoint_Base nodeC = (CylindricalJoint_Base)GetSkeletalJoint(); joint = ConfigJointInternal <ConfigurableJoint>(nodeC.basePoint.AsV3(), nodeC.axis.AsV3(), delegate(ConfigurableJoint jointSub) { jointSub.xMotion = ConfigurableJointMotion.Limited; jointSub.angularXMotion = !nodeC.hasAngularLimit ? ConfigurableJointMotion.Free : ConfigurableJointMotion.Limited; LinearLimit(jointSub, nodeC.currentLinearPosition, nodeC.linearLimitStart, nodeC.linearLimitEnd); if (GetSkeletalJoint().cDriver != null && GetSkeletalJoint().cDriver.GetDriveType().IsPneumatic()) { JointDrive drMode = new JointDrive(); drMode.mode = JointDriveMode.Velocity; drMode.maximumForce = 100.0f; jointSub.xDrive = drMode; } if (jointSub.angularXMotion == ConfigurableJointMotion.Limited) { AngularLimit(jointSub, MathfExt.ToDegrees(nodeC.currentAngularPosition), MathfExt.ToDegrees(nodeC.angularLimitLow), MathfExt.ToDegrees(nodeC.angularLimitHigh)); } }); } else if (GetSkeletalJoint().GetJointType() == SkeletalJointType.LINEAR) { LinearJoint_Base nodeL = (LinearJoint_Base)GetSkeletalJoint(); joint = ConfigJointInternal <ConfigurableJoint>(nodeL.basePoint.AsV3(), nodeL.axis.AsV3(), delegate(ConfigurableJoint jointSub) { jointSub.xMotion = ConfigurableJointMotion.Limited; LinearLimit(jointSub, nodeL.currentLinearPosition, nodeL.linearLimitLow, nodeL.linearLimitHigh); }); //TODO make code good if (GetSkeletalJoint().cDriver != null) { if (GetSkeletalJoint().cDriver.GetDriveType().IsElevator()) { Debug.Log(GetSkeletalJoint().cDriver.portA); unityObject.AddComponent <ElevatorScript>(); unityObject.GetComponent <ElevatorScript>().eType = (ElevatorType)this.GetDriverMeta <ElevatorDriverMeta>().type; Debug.Log("added"); } } } SetXDrives(); }
public AngularDOF_Impl(RotationalJoint_Base rjb) { this.rjb = rjb; }
public void CreateJoint(RobotBase robotBase, float wheelFriction = 1f, float lateralFriction = 1f) { if (joint != null || GetSkeletalJoint() == null) { return; } switch (GetSkeletalJoint().GetJointType()) { case SkeletalJointType.ROTATIONAL: if (this.HasDriverMeta <WheelDriverMeta>() && this.GetDriverMeta <WheelDriverMeta>().type != WheelType.NOT_A_WHEEL) { RigidNode parent = (RigidNode)GetParent(); if (parent.MainObject.GetComponent <BRaycastRobot>() == null) { parent.MainObject.AddComponent <BRaycastRobot>().RootNode = RootNode; } WheelType wheelType = this.GetDriverMeta <WheelDriverMeta>().type; BRaycastWheel wheel = MainObject.AddComponent <BRaycastWheel>(); wheel.CreateWheel(this); if (robotBase is MaMRobot) { wheel.Friction = wheelFriction; wheel.SlidingFriction = lateralFriction; } MainObject.transform.parent = parent.MainObject.transform; } else { RotationalJoint_Base rNode = (RotationalJoint_Base)GetSkeletalJoint(); BHingedConstraintEx hc = (BHingedConstraintEx)(joint = ConfigJoint <BHingedConstraintEx>(rNode.basePoint.AsV3() - ComOffset, rNode.axis.AsV3(), AxisType.X)); Vector3 rAxis = rNode.axis.AsV3().normalized; hc.axisInA = rAxis; hc.axisInB = rAxis; if (hc.setLimit = rNode.hasAngularLimit) { hc.lowLimitAngleRadians = rNode.currentAngularPosition - rNode.angularLimitHigh; hc.highLimitAngleRadians = rNode.currentAngularPosition - rNode.angularLimitLow; } hc.constraintType = BTypedConstraint.ConstraintType.constrainToAnotherBody; } break; case SkeletalJointType.CYLINDRICAL: CylindricalJoint_Base cNode = (CylindricalJoint_Base)GetSkeletalJoint(); Vector3 cAxis = cNode.axis.AsV3().normalized; B6DOFConstraint bc = (B6DOFConstraint)(joint = ConfigJoint <B6DOFConstraint>(cNode.basePoint.AsV3() - ComOffset, cAxis, AxisType.X)); bc.localConstraintAxisX = cAxis; bc.localConstraintAxisY = new Vector3(cAxis.y, cAxis.z, cAxis.x); bc.linearLimitLower = new Vector3((cNode.linearLimitStart - cNode.currentLinearPosition) * 0.01f, 0f, 0f); bc.linearLimitUpper = new Vector3((cNode.linearLimitEnd - cNode.currentLinearPosition) * 0.01f, 0f, 0f); // TODO: Implement angular cylinder limits bc.constraintType = BTypedConstraint.ConstraintType.constrainToAnotherBody; break; case SkeletalJointType.LINEAR: LinearJoint_Base lNode = (LinearJoint_Base)GetSkeletalJoint(); Vector3 lAxis = lNode.axis.AsV3().normalized; BSliderConstraint sc = (BSliderConstraint)(joint = ConfigJoint <BSliderConstraint>(lNode.basePoint.AsV3() - ComOffset, lAxis, AxisType.X)); sc.localConstraintAxisX = lAxis; sc.localConstraintAxisY = new Vector3(lAxis.y, lAxis.z, lAxis.x); sc.lowerLinearLimit = (lNode.linearLimitLow - lNode.currentLinearPosition) * 0.01f; sc.upperLinearLimit = (lNode.linearLimitHigh - lNode.currentLinearPosition) * 0.01f; sc.lowerAngularLimitRadians = 0f; sc.upperAngularLimitRadians = 0f; sc.constraintType = BTypedConstraint.ConstraintType.constrainToAnotherBody; bool b = this.HasDriverMeta <ElevatorDriverMeta>(); if (GetSkeletalJoint().cDriver != null) { if (GetSkeletalJoint().cDriver.GetDriveType().IsElevator()) { MainObject.GetComponent <BRigidBody>().mass *= 2f; } } break; } }
public void CreateJoint() { if (joint != null || GetSkeletalJoint() == null) { return; } switch (GetSkeletalJoint().GetJointType()) { case SkeletalJointType.ROTATIONAL: WheelType wheelType = WheelType.NOT_A_WHEEL; if (this.HasDriverMeta <WheelDriverMeta>()) { OrientWheelNormals(); wheelType = this.GetDriverMeta <WheelDriverMeta>().type; } RotationalJoint_Base rNode = (RotationalJoint_Base)GetSkeletalJoint(); BHingedConstraintEx hc = (BHingedConstraintEx)(joint = ConfigJoint <BHingedConstraintEx>(rNode.basePoint.AsV3() - ComOffset, rNode.axis.AsV3(), AxisType.X)); Vector3 rAxis = rNode.axis.AsV3().normalized; hc.axisInA = rAxis; hc.axisInB = rAxis; if (hc.setLimit = rNode.hasAngularLimit) { hc.lowLimitAngleRadians = rNode.currentAngularPosition - rNode.angularLimitHigh; hc.highLimitAngleRadians = rNode.currentAngularPosition - rNode.angularLimitLow; } hc.constraintType = BTypedConstraint.ConstraintType.constrainToAnotherBody; break; case SkeletalJointType.CYLINDRICAL: CylindricalJoint_Base cNode = (CylindricalJoint_Base)GetSkeletalJoint(); B6DOFConstraint bc = (B6DOFConstraint)(joint = ConfigJoint <B6DOFConstraint>(cNode.basePoint.AsV3() - ComOffset, cNode.axis.AsV3(), AxisType.X)); bc.linearLimitLower = new Vector3(cNode.linearLimitStart * 0.01f, 0f, 0f); bc.linearLimitUpper = new Vector3(cNode.linearLimitEnd * 0.01f, 0f, 0f); bc.constraintType = BTypedConstraint.ConstraintType.constrainToAnotherBody; break; case SkeletalJointType.LINEAR: LinearJoint_Base lNode = (LinearJoint_Base)GetSkeletalJoint(); Vector3 lAxis = lNode.axis.AsV3().normalized; // TODO: Figure out how to make a vertical slider? BSliderConstraint sc = (BSliderConstraint)(joint = ConfigJoint <BSliderConstraint>(lNode.basePoint.AsV3() - ComOffset, lNode.axis.AsV3(), AxisType.X)); if (lAxis.x < 0) { lAxis.x *= -1f; } if (lAxis.y < 0) { lAxis.y *= -1f; } if (lAxis.z < 0) { lAxis.z *= -1f; } sc.localConstraintAxisX = lAxis; sc.localConstraintAxisY = new Vector3(lAxis.y, lAxis.z, lAxis.x); sc.lowerLinearLimit = lNode.linearLimitLow * 0.01f; sc.upperLinearLimit = lNode.linearLimitHigh * 0.01f; sc.lowerAngularLimitRadians = 0f; sc.upperAngularLimitRadians = 0f; sc.constraintType = BTypedConstraint.ConstraintType.constrainToAnotherBody; bool b = this.HasDriverMeta <ElevatorDriverMeta>(); if (GetSkeletalJoint().cDriver != null) { if (GetSkeletalJoint().cDriver.GetDriveType().IsElevator()) { MainObject.GetComponent <BRigidBody>().mass *= 2f; } } break; } }
public void CreateJoint(int numWheels, bool mixAndMatch, float wheelFriction = 1f, float lateralFriction = 1f) { if (joint != null || GetSkeletalJoint() == null) { return; } switch (GetSkeletalJoint().GetJointType()) { case SkeletalJointType.ROTATIONAL: if (this.HasDriverMeta <WheelDriverMeta>() && this.GetDriverMeta <WheelDriverMeta>().type != WheelType.NOT_A_WHEEL) { RigidNode parent = (RigidNode)GetParent(); if (parent.MainObject.GetComponent <BRaycastRobot>() == null) { BRaycastRobot robot = parent.MainObject.AddComponent <BRaycastRobot>(); robot.NumWheels = numWheels; } WheelType wheelType = this.GetDriverMeta <WheelDriverMeta>().type; BRaycastWheel wheel = MainObject.AddComponent <BRaycastWheel>(); wheel.CreateWheel(this); if (mixAndMatch) { wheel.Friction = wheelFriction; wheel.SlidingFriction = lateralFriction; } MainObject.transform.parent = parent.MainObject.transform; } else { RotationalJoint_Base rNode = (RotationalJoint_Base)GetSkeletalJoint(); rNode.basePoint.x *= -1; BHingedConstraintEx hc = (BHingedConstraintEx)(joint = ConfigJoint <BHingedConstraintEx>(rNode.basePoint.AsV3() - ComOffset, rNode.axis.AsV3(), AxisType.X)); Vector3 rAxis = rNode.axis.AsV3().normalized; rAxis.x *= -1f; hc.axisInA = rAxis; hc.axisInB = rAxis; if (hc.setLimit = rNode.hasAngularLimit) { hc.lowLimitAngleRadians = rNode.currentAngularPosition - rNode.angularLimitHigh; hc.highLimitAngleRadians = rNode.currentAngularPosition - rNode.angularLimitLow; } hc.constraintType = BTypedConstraint.ConstraintType.constrainToAnotherBody; } break; case SkeletalJointType.CYLINDRICAL: CylindricalJoint_Base cNode = (CylindricalJoint_Base)GetSkeletalJoint(); B6DOFConstraint bc = (B6DOFConstraint)(joint = ConfigJoint <B6DOFConstraint>(cNode.basePoint.AsV3() - ComOffset, cNode.axis.AsV3(), AxisType.X)); bc.linearLimitLower = new Vector3(cNode.linearLimitStart * 0.01f, 0f, 0f); bc.linearLimitUpper = new Vector3(cNode.linearLimitEnd * 0.01f, 0f, 0f); bc.constraintType = BTypedConstraint.ConstraintType.constrainToAnotherBody; break; case SkeletalJointType.LINEAR: LinearJoint_Base lNode = (LinearJoint_Base)GetSkeletalJoint(); lNode.basePoint.x *= -1; Vector3 lAxis = lNode.axis.AsV3().normalized; // TODO: Figure out how to make a vertical slider? BSliderConstraint sc = (BSliderConstraint)(joint = ConfigJoint <BSliderConstraint>(lNode.basePoint.AsV3() - ComOffset, lNode.axis.AsV3(), AxisType.X)); if (lAxis.x < 0) { lAxis.x *= -1f; } if (lAxis.y < 0) { lAxis.y *= -1f; } if (lAxis.z < 0) { lAxis.z *= -1f; } sc.localConstraintAxisX = lAxis; sc.localConstraintAxisY = new Vector3(lAxis.y, lAxis.z, lAxis.x); sc.lowerLinearLimit = lNode.linearLimitLow * 0.01f; sc.upperLinearLimit = lNode.linearLimitHigh * 0.01f; sc.lowerAngularLimitRadians = 0f; sc.upperAngularLimitRadians = 0f; sc.constraintType = BTypedConstraint.ConstraintType.constrainToAnotherBody; bool b = this.HasDriverMeta <ElevatorDriverMeta>(); if (GetSkeletalJoint().cDriver != null) { if (GetSkeletalJoint().cDriver.GetDriveType().IsElevator()) { MainObject.GetComponent <BRigidBody>().mass *= 2f; } } break; } }