void RigidBody::setWorldTransform(const btTransform& worldTrans) { Quaternion newWorldRotation = ToQuaternion(worldTrans.getRotation()); Vector3 newWorldPosition = ToVector3(worldTrans.getOrigin()) - newWorldRotation * centerOfMass_; RigidBody* parentRigidBody = 0; // It is possible that the RigidBody component has been kept alive via a shared pointer, // while its scene node has already been destroyed if (node_) { // If the rigid body is parented to another rigid body, can not set the transform immediately. // In that case store it to PhysicsWorld for delayed assignment Node* parent = node_->GetParent(); if (parent != GetScene() && parent) parentRigidBody = parent->GetComponent<RigidBody>(); if (!parentRigidBody) ApplyWorldTransform(newWorldPosition, newWorldRotation); else { DelayedWorldTransform delayed; delayed.rigidBody_ = this; delayed.parentRigidBody_ = parentRigidBody; delayed.worldPosition_ = newWorldPosition; delayed.worldRotation_ = newWorldRotation; physicsWorld_->AddDelayedWorldTransform(delayed); } MarkNetworkUpdate(); } }
void RigidBody2D::ApplyWorldTransform() { if (!body_ || !node_) return; // If the rigid body is parented to another rigid body, can not set the transform immediately. // In that case store it to PhysicsWorld2D for delayed assignment RigidBody2D* parentRigidBody = 0; Node* parent = node_->GetParent(); if (parent != GetScene() && parent) parentRigidBody = parent->GetComponent<RigidBody2D>(); // If body is not parented and is static or sleeping, no need to update if (!parentRigidBody && (!body_->IsActive() || body_->GetType() == b2_staticBody || !body_->IsAwake())) return; const b2Transform& transform = body_->GetTransform(); Vector3 newWorldPosition = node_->GetWorldPosition(); newWorldPosition.x_ = transform.p.x; newWorldPosition.y_ = transform.p.y; Quaternion newWorldRotation(transform.q.GetAngle() * M_RADTODEG, Vector3::FORWARD); if (parentRigidBody) { DelayedWorldTransform2D delayed; delayed.rigidBody_ = this; delayed.parentRigidBody_ = parentRigidBody; delayed.worldPosition_ = newWorldPosition; delayed.worldRotation_ = newWorldRotation; physicsWorld_->AddDelayedWorldTransform(delayed); } else ApplyWorldTransform(newWorldPosition, newWorldRotation); }