void LateUpdate() { if (invert) { joint.SetTargetRotationLocal(Quaternion.Inverse(target.localRotation), Quaternion.Inverse(startingRotation)); } //joint.targetRotation = Quaternion.Inverse(target.localRotation * startingRotation); else { joint.SetTargetRotationLocal(target.localRotation, startingRotation); } //joint.targetRotation = target.rotation * startingRotation; }
public void SetGrabJointTargetRotation(Quaternion targetRotation) { //grabJoint.SetTargetRotationLocal(grabJoint.connectedBody.rotation, MyRigidbody.rotation); //grabJoint.configuredInWorldSpace = false; grabJoint.SetTargetRotationLocal(targetRotation, grabJointStartRotation); }
void UpdateJoint(LimbGene gene, ConfigurableJoint joint, Vector3 targetRotation, Quaternion initialRotation) { float t = totalTime / gene.rotationTime; Quaternion target = Quaternion.Euler(targetRotation + initialRotation.eulerAngles); Quaternion t1 = Quaternion.Lerp(initialRotation, target, t); joint.SetTargetRotationLocal(t1, initialRotation); }
void UpdateJoints(BasicGene gene, ConfigurableJoint joint) { float t = totalTime / 5.0f; Quaternion target = Quaternion.Euler(new Vector3( 0, 45, 0 ) + initialRotation.eulerAngles); Quaternion t1 = Quaternion.Lerp(initialRotation, target, t); joint.SetTargetRotationLocal(t1, initialRotation); }
void SetTargetRotation(AnimatedPair pair) { ConfigurableJoint joint = pair.RagdollBone.Joint; if (joint.configuredInWorldSpace) { joint.SetTargetRotation(pair.currentPose.worldRotation, pair.RagdollBone.StartingJointRotation); } else { joint.SetTargetRotationLocal(pair.currentPose.localRotation, pair.RagdollBone.StartingJointRotation); } }
void UpdateJoint(ConfigurableJoint joint, Quaternion targetRotation, Quaternion initialRotation, int phase, int index) { float t = Mathf.Lerp(0, dNA.genes.Count, (1 - (joint.transform.position.y / initialHeights[index]))) - phase; //if (joint.gameObject.name == "CatGirl2:Tail0_M") // Debug.Log($"{index}: {Mathf.Lerp(0, dNA.genes.Count, (1 - (joint.transform.position.y / initialHeight)))}, {t}"); Quaternion target = Quaternion.Euler(targetRotation.eulerAngles + initialRotation.eulerAngles); Quaternion rotation = Quaternion.Lerp(initialRotation, target, t); joint.SetTargetRotationLocal(rotation, initialRotation); }
void Update() { // pos = transform.InverseTransformPoint(joint.connectedBody.transform.position); // joint.targetRotation = Quaternion.Euler(new Vector3(target, // 1f, // 1f)); joint.SetTargetRotationLocal(Quaternion.Euler(90f, 0f, 0f), startRotation); // Debug.Log(joint.velocity + " " + tooMuchResistance()); // if(tooMuchResistance() || isFullyExtended()){ // contract(); // }else if(tooMuchResistance() || isFullyContracted()){ // extend(); // } }
void UpdateJoints(BasicGene gene, ConfigurableJoint joint, Quaternion initialRotation) { if (totalTime > gene.rotationTime) { return; } float t = totalTime / gene.rotationTime; Quaternion target = Quaternion.Euler((gene.rotation * 360.0f) + initialRotation.eulerAngles); Quaternion rotation = Quaternion.Lerp(initialRotation, target, t); joint.SetTargetRotationLocal(rotation, initialRotation); }
void UpdateJoints(BasicGene gene, ConfigurableJoint joint) { Quaternion currentRotation = joint.transform.localRotation; Quaternion totalRotation = Quaternion.Euler( // assuming low and high x limit is the same gene.rotation.x * joint.highAngularXLimit.limit, gene.rotation.y * joint.angularYLimit.limit, gene.rotation.z * joint.angularZLimit.limit ); if (joint.gameObject.name == "CatGirl2:Chest_M") { Debug.Log("Rotating joint " + joint + " by " + totalRotation.eulerAngles + " total rot " + new Vector3(gene.rotation.x * joint.highAngularXLimit.limit, gene.rotation.y * joint.angularYLimit.limit, gene.rotation.z * joint.angularZLimit.limit)); } joint.SetTargetRotationLocal(totalRotation, currentRotation); }
void UpdateJoints(BasicGene gene, ConfigurableJoint joint, Quaternion initialRotation) { if (totalTime > gene.rotationTime) { return; } float t = totalTime / gene.rotationTime; Vector3 limit = new Vector3(joint.highAngularXLimit.limit, joint.angularYLimit.limit, joint.angularZLimit.limit); limit.Scale(gene.rotation); Quaternion target = Quaternion.Euler(limit + initialRotation.eulerAngles); Quaternion rotation = Quaternion.Lerp(initialRotation, target, t); joint.SetTargetRotationLocal(rotation, initialRotation); // joint.SetTargetRotationLocal(partialRotation, currentRotation); }
void CreateJoint(GameObject obj) { grabJoint = gameObject.AddComponent <ConfigurableJoint>(); // from fixedjoint grabJoint.breakForce = 1500f; grabJoint.connectedBody = obj.GetComponent <Rigidbody>(); // configurablejoint additions - make it behave like a fixed joint grabJoint.xMotion = ConfigurableJointMotion.Locked; grabJoint.yMotion = ConfigurableJointMotion.Locked; grabJoint.zMotion = ConfigurableJointMotion.Locked; grabJoint.angularXMotion = ConfigurableJointMotion.Locked; grabJoint.angularYMotion = ConfigurableJointMotion.Locked; grabJoint.angularZMotion = ConfigurableJointMotion.Locked; if (!HeldObjectInteractable.RelativeAnchor) { grabJoint.autoConfigureConnectedAnchor = false; grabJoint.connectedAnchor = Vector3.zero; grabJoint.anchor = Vector3.zero; grabJoint.angularXMotion = ConfigurableJointMotion.Free; grabJoint.angularYMotion = ConfigurableJointMotion.Free; grabJoint.angularZMotion = ConfigurableJointMotion.Free; JointDrive drive = new JointDrive(); drive.positionSpring = 100f; drive.positionDamper = 15f; drive.maximumForce = Mathf.Infinity; grabJoint.slerpDrive = drive; grabJoint.rotationDriveMode = RotationDriveMode.Slerp; grabJoint.configuredInWorldSpace = false; grabJointStartRotation = MyRigidbody.rotation; grabJoint.SetTargetRotationLocal(grabJoint.connectedBody.rotation, grabJointStartRotation); } }
public void UpdateAttachments(State flightState, bool debug, bool debugPeriodic) { // If the is no actual part attached to the attach node, then we can bail out. // Part attachedPart = GetAttachedPart(); if (debugPeriodic) { printf("UA: %s %s %s %s", attachedPart != null ? attachedPart.name : null, nodeType, stackAttachNode != null ? stackAttachNode.id : "null", stackAttachNode != null ? stackAttachNode.attachedPartId.ToString() : "null"); } // We don't want to mess with the joint attaching this part to its parent. // Also, take of the special case where they are both null, otherwise we // will incorrectly get a match between them, resulting in loss of function // if the animated part is the root part. if ((attachedPart == animatedAttachment.part.parent) && (attachedPart != null)) { if (debugPeriodic) { printf("Skipping parent"); } return; } switch (nodeType) { case AttachNode.NodeType.Surface: if (collider == null) { SetCollider(); if (debug) { printf("Setting collider to %s", collider.name); } } break; case AttachNode.NodeType.Stack: if (stackAttachNode == null) { stackAttachNode = animatedAttachment.part.FindAttachNodeByPart(attachedPart); // Sometimes life throws lemons at you, like when the user actvated attachments in flight if (stackAttachNode == null) { // Try again as surface attached nodeType = AttachNode.NodeType.Surface; return; } if (debug) { printf("Setting attach node to %s", stackAttachNode.id); } } break; } Transform referenceTransform = GetReferenceTransform(); // If this attach node is defined in the cfg, then bail out now, it will not be movable if (referenceTransform == null) { if (debugPeriodic) { printf("Skipping cfg based node: %s", stackAttachNode.id); } return; } // Get the position and rotation of the node transform relative to the part. // The nodeTransform itself will only contain its positions and rotation // relative to the immediate parent in the model PosRot referencePosRot = PosRot.GetPosRot(referenceTransform, animatedAttachment.part); // We can't animate decoupling shrouds if (referencePosRot == null) { if (debugPeriodic) { printf("Skipping decoupler shroud"); } return; } bool active = animatedAttachment.activated; if (EditorLogic.fetch && (EditorLogic.fetch.EditorConstructionMode != ConstructionMode.Place)) { active = false; } // Take note of newly attached parts, including at initial ship load if (attachedPart == null || !active) { if (debugPeriodic) { if (attachedPart == null) { printf("No part attached"); } } attachedPartOffset = null; return; } if (attachedPartOffset == null || attachedPartOriginal == null) { // Get attached part position relative to this part PosRot localPosRot = new PosRot(); Transform parent = attachedPart.transform.parent; // Let the engine calculate the local position instead of doing the calculation ourselves.. attachedPart.transform.parent = animatedAttachment.part.transform; localPosRot.position = attachedPart.transform.localPosition; localPosRot.rotation = attachedPart.transform.localRotation; attachedPart.transform.parent = parent; // We could do parenting trick for this too, but seems we loose the scaling if (attachedPartOffset == null) { printf("Recording attachedPartOffset"); attachedPartOffset = new PosRot(); attachedPartOffset.rotation = referencePosRot.rotation.Inverse() * localPosRot.rotation; attachedPartOffset.position = referencePosRot.rotation.Inverse() * (localPosRot.position - referencePosRot.position); } if (attachedPartOriginal == null) { printf("Recording attachedPartOriginal"); attachedPartOriginal = new PosRot(); attachedPartOriginal.rotation = localPosRot.rotation; } } // Calculate the attached parts position in the frame of reference of this part PosRot attachedPartPosRot = new PosRot { rotation = referencePosRot.rotation * attachedPartOffset.rotation, position = referencePosRot.position + referencePosRot.rotation * attachedPartOffset.position }; /* A sub part can either be connected directly by their transform having a parent transform, * or be connected through a joint. In the first case, the sub part will directly move with * their parent as their position is in in the reference frame of the parent local space. * In the latter case, the sub part lacks a parent transform, and the position is in the vessel * space instead, and parts are held together by forces working through the joints. * The first case occurs in two situations. In the VAB editor, all parts are connected by * parent transforms. And, during flight, a physicsless part will also be connected to the parent * this way - for example some science parts. * Joints are used for normal physics based parts during flight. */ if (attachedPart.transform.parent != null) { // If a parent was found, we will just update the position of the part directly since no physics is involved attachedPart.transform.localRotation = attachedPartPosRot.rotation; attachedPart.transform.localPosition = attachedPartPosRot.position; if (debugPeriodic) { printf("Updated pos without physics"); } // There is nothing more to do, so bail out return; } // In the editor, while changing action groups, the parent will be null for some reason. // We can catch that here by making sure there exists a joint if (attachedPart.attachJoint == null) { if (debugPeriodic) { printf("No attach joint found"); } return; } // Things get tricker if the parts are connected by joints. We need to setup the joint // to apply forces to the sub part. ConfigurableJoint joint = attachedPart.attachJoint.Joint; // It is not possible to change values of a JointDrive after creation, so we must create a // new one and apply it to the joint. Seems we can't only create it at startup either. switch (joint.name) { case "AnimatedAttachment": if (joint.xMotion != ConfigurableJointMotion.Free && flightState == State.STARTED) { animatedAttachment.initJointDrive = true; } break; case "MechanicsToolkit": break; default: animatedAttachment.initJointDrive = true; break; } if (animatedAttachment.initJointDrive) { animatedAttachment.initJointDrive = false; joint.name = "AnimatedAttachment"; jointDrive = new JointDrive(); printf("Creating a new drive mode. Previous: %s, %s, %s, %s, %s", joint.name, joint.xDrive.positionSpring, animatedAttachment.part.name, animatedAttachment.part.started, joint.angularXMotion); /* * printf(string.Format("maximumForce: {0}", animatedAttachment.maximumForce)); * printf(string.Format("positionDamper: {0}", animatedAttachment.positionDamper)); * printf(string.Format("positionSpring: {0}", animatedAttachment.positionSpring)); */ // The joint will not respond to changes to targetRotation/Position in locked mode, // so change it to free in all directions joint.xMotion = ConfigurableJointMotion.Free; joint.yMotion = ConfigurableJointMotion.Free; joint.zMotion = ConfigurableJointMotion.Free; joint.angularXMotion = ConfigurableJointMotion.Free; joint.angularYMotion = ConfigurableJointMotion.Free; joint.angularZMotion = ConfigurableJointMotion.Free; // Create a new joint with settings from the cfg file or user selection jointDrive.maximumForce = animatedAttachment.maximumForce; jointDrive.positionDamper = animatedAttachment.positionDamper; jointDrive.positionSpring = animatedAttachment.positionSpring; // Same drive in all directions.. is there benefits of separating them? joint.angularXDrive = jointDrive; joint.angularYZDrive = jointDrive; joint.xDrive = jointDrive; joint.yDrive = jointDrive; joint.zDrive = jointDrive; //} if (debug) { printf("%s", joint); } } if (debug) { printf("%s", attachedPartPosRot); } if (debug) { printf("%s", attachedPartOriginal); } // Update the joint.targetRotation using this convenience function, since the joint // reference frame has weird axes. Arguments are current and original rotation. joint.SetTargetRotationLocal( attachedPartPosRot.rotation, attachedPartOriginal.rotation); /* Move the attached part by updating the connectedAnchor instead of the joint.targetPosition. * This is easier since the anchor is in the reference frame of this part, and we already have the * position in that reference frame. It also makes sense from the view that since it really is the * attachment point of the attached part that is moving. There might be benefits of using the targetPosition * though, and should be possible to calculate it fairly easily if needed. */ joint.connectedAnchor = referencePosRot.position; // Make sure the target position is zero joint.targetPosition = Vector3.zero; // This scaling and rotation is to convert to joint space... maybe? // Determined by random tinkering and is magical as far as I am concerned joint.anchor = attachedPartOffset.rotation.Inverse() * Vector3.Scale( new Vector3(-1, -1, -1), attachedPartOffset.position); if (debugPeriodic) { printf("%s; %s; %s -> %s; %s -> %s; %s", referencePosRot, attachedPartPosRot, attachedPartOffset, attachedPartOriginal.rotation.eulerAngles, joint.targetRotation.eulerAngles, joint.anchor, joint.connectedAnchor ); } // Debug info if (debug) { // Show debug vectors for the child part if (axisJoint == null) { axisJoint = new AxisInfo(joint.transform); } if (lineAnchor == null) { lineAnchor = new LineInfo(animatedAttachment.part.transform, Color.cyan); } lineAnchor.Update(Vector3.zero, joint.connectedAnchor); if (lineNodeToPart == null) { lineNodeToPart = new LineInfo(animatedAttachment.part.transform, Color.magenta); } lineNodeToPart.Update( referencePosRot.position, attachedPartPosRot.position); } else { if (axisJoint != null) { axisJoint = null; } } // Debug info if (debug) { // Show debug vectors for the attachNodes if (orientationAttachNode == null) { orientationAttachNode = new OrientationInfo(animatedAttachment.part.transform, referencePosRot.position, referencePosRot.position + attachedPartOffset.orientation); } if (stackAttachNode != null) { orientationAttachNode.Update(referencePosRot.position, referencePosRot.position + stackAttachNode.orientation); } } else { if (orientationAttachNode != null) { orientationAttachNode = null; } } }
void Update() { //if(!collided) myJoint.SetTargetRotationLocal(target.localRotation, initialRotation); }
public void setTargetOrientation(Quaternion qua) { joint.SetTargetRotationLocal(qua, initialLocalRotation); }
public static void SetTargetRotationLocal(this ConfigurableJoint joint, Quaternion targetLocalRotation) { joint.SetTargetRotationLocal(targetLocalRotation, joint.transform.localRotation); }