public void SetPhysics(bool enabled) { if (!model.part.root) { return; } PuppetReprModel root = model.part.root.reprs[PuppetModel.key] as PuppetReprModel; if (!root.usePhysics) { return; } model.kinematic = !enabled; if (enabled) { // Teleport root.pheasy.TeleportToDestination(root.constraint); } // Physics SetPartPhysics(model.part, enabled, new List <PartModel>()); }
void UpdatePhysicsSettings(PuppetReprModel slave, PuppetBoneConfiguration conf) { if (!slave.usePhysics) { return; } // Joint drives slave.constraint.settings.motionDrive = conf.positionDrive; slave.constraint.settings.angularDrive = conf.rotationDrive; // Joint mass scales slave.constraint.joint.massScale = conf.jointMassScale; slave.constraint.joint.connectedMassScale = conf.jointConnectedMassScale; // Rb slave.pheasy.rb.mass = conf.rigidbodyMass; slave.pheasy.rb.drag = conf.rigidbodyDrag; slave.pheasy.rb.angularDrag = conf.rigidbodyAngularDrag; slave.pheasy.rb.useGravity = conf.useGravity; // Stability slave.pheasy.safeMode = conf.safeMode; slave.pheasy.maxVelocity = conf.maxLinearVelocity; slave.pheasy.maxAngularVelocity = conf.maxAngularVelocity; slave.pheasy.maxDepenetrationVelocity = conf.maxDepenetrationVelocity; slave.pheasy.maxErrorAllowed = conf.maxErrorAllowed; // Debug slave.constraint.force = conf.force; }
void LateBoneStart(BoneModel bone) { if (!bone.reprs.ContainsKey(PuppetModel.key)) { Debug.Log("Bone " + bone + " does not have a " + PuppetModel.key + " representation"); return; } PuppetReprModel slave = bone.reprs[PuppetModel.key] as PuppetReprModel; if (!slave.usePhysics) { return; } if (bone.parent != null) { // Ignore part-parent collisions for (int b = 0; b < bone.part.parent.bones.Count; b++) { BoneModel parentBone = bone.part.parent.bones[b]; if (parentBone.reprs.ContainsKey(PuppetModel.key)) { PuppetReprModel parentSlave = parentBone.reprs[PuppetModel.key] as PuppetReprModel; slave.pheasy.IgnoreCollisions(parentSlave.pheasy, true, true); } } } slave.specificView.onPhysicsReady.Invoke(); slave.ready = true; }
void BoneUpdate(BoneModel bone) { if (bone.point.master == null || !bone.point.reprs.ContainsKey(PuppetModel.key)) { return; } ReprModel master; PuppetReprModel slave = bone.point.reprs[PuppetModel.key] as PuppetReprModel; if (!slave.usePhysics) { return; } if (!bone.reprs.ContainsKey(model.mimicRepr)) { Debug.LogWarning("Bone " + bone.name + " does not have a " + model.mimicRepr + " representation. Puppet goal cannot be updated for this bone"); return; } if (slave.constraint.connectedBody) { master = bone.point.reprs[model.mimicRepr]; if (master.localRotZ < slave.maxLocalRotZ && master.localRotZ > slave.minLocalRotZ) { slave.goal.rotation = slave.goal.parent.rotation * master.localRotation; } else { slave.goal.localRotation = slave.fixedLocalRot; } } else { master = bone.point.reprs[model.mimicRepr]; slave.goal.rotation = master.transformRef.rotation; slave.goal.position = master.transformRef.position; if (model.forceUnconnected) { slave.pheasy.rb.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative; } else { slave.pheasy.rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic; } slave.pheasy.rb.isKinematic = model.forceUnconnected; slave.constraint.force = model.forceUnconnected; } }
public void SetSlavePhysics(PuppetReprModel slave, bool enabled) { if (!slave.usePhysics) { return; } if (enabled) { slave.pheasy.rb.isKinematic = false; slave.pheasy.rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic; } else { slave.pheasy.rb.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative; slave.pheasy.rb.isKinematic = true; } // Enable/Disable colliders slave.pheasy.colliders.ForEach(c => c.enabled = enabled); }
void BoneStart(BoneModel bone, BoneModel mainRoot) { if (!bone.reprs.ContainsKey(PuppetModel.key)) { Debug.LogWarning("Bone " + bone.name + " does not have any " + PuppetModel.key + " representation. PuppetController cannot start this bone"); return; } PuppetReprModel slave = bone.reprs[PuppetModel.key] as PuppetReprModel; // Set puppet model for each puppet representation slave.puppet = model; // Set thumb bones as special if (bone.part is FingerModel) { FingerModel finger = bone.part as FingerModel; if (finger == finger.hand.thumb) { slave.isSpecial = true; } } if (!slave.usePhysics) { Debug.LogWarning("Bone " + bone.name + " has slave representation but it won't use physics"); return; } // Set pheasy if needed if (slave.pheasy == null) { Pheasy pheasy = slave.transformRef.GetComponent <Pheasy>(); if (pheasy == null) { pheasy = slave.transformRef.gameObject.AddComponent <Pheasy>(); } pheasy.rb.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative; pheasy.rb.isKinematic = true; pheasy.axis = model.axisPrefab; slave.pheasy = pheasy; } // Get connected body Rigidbody connectedBody = null; if (bone.parent != null) { if (bone.parent.reprs.ContainsKey(PuppetModel.key)) { PuppetReprModel parentSlave = bone.parent.reprs[PuppetModel.key] as PuppetReprModel; if (parentSlave.usePhysics && !parentSlave.pheasy) { // Debug.LogWarning("Bone " + bone.parent.name + " has a " + PuppetModel.key + " representation and it use physics but it has no Pheasy component. Forcing initialization"); BoneStart(bone.parent, mainRoot); } if (parentSlave.pheasy) { connectedBody = parentSlave.pheasy.rb; } } else { Debug.LogWarning("Parent of bone " + bone.name + ", " + bone.parent.name + ", does not have a " + PuppetModel.key + " representation"); } } // Add and save pheasy.constraint if (slave.constraint == null || slave.constraint.pheasy == null) { slave.constraint = slave.pheasy.AddTargetConstraint("PuppetBone", connectedBody, false, null); } // Replace or instantiate goal if (slave.goal == null) { slave.goal = slave.constraint.connectedAnchor; } else { slave.constraint.connectedAnchor = slave.goal; } // Set freedom slave.constraint.settings.angularMotion = ConfigurableJointMotion.Free; if (connectedBody != null) { slave.constraint.settings.linearMotion = ConfigurableJointMotion.Locked; } else { slave.constraint.settings.linearMotion = ConfigurableJointMotion.Free; } // Replace connected body by parent if (bone.parent == null || slave.point.bone == mainRoot || slave.constraint.connectedBody == null) // Wrist { UpdatePhysicsSettings(slave, model.configuration.root); } else if (slave.isSpecial) // Special bones { UpdatePhysicsSettings(slave, model.configuration.special); } else // Common bones { UpdatePhysicsSettings(slave, model.configuration.standard); } if (slave.constraint != null) { // Stability slave.constraint.settings.collideWithConnectedRb = false; slave.pheasy.safeMode = true; slave.pheasy.gradualMode = false; // Forced values slave.constraint.enabled = true; slave.constraint.keepAxisRelativeToObject = true; slave.pheasy.rb.isKinematic = false; slave.pheasy.rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic; // Performance slave.pheasy.editMode = true; AsyncHelpers.DoAfterFrames(this, 1, () => slave.pheasy.editMode = false); } // Find colliders and triggers. Children colliders are updated before their parents slave.pheasy.UpdateCollidersAndTriggerNotifiers(); }