Browse Source

Before rigidbody has simulated at least once, allow also setting the interpolation transform. Possible fix for #1128.

Lasse Öörni 10 years ago
parent
commit
05cd6f4346
2 changed files with 15 additions and 5 deletions
  1. 13 5
      Source/Urho3D/Physics/RigidBody.cpp
  2. 2 0
      Source/Urho3D/Physics/RigidBody.h

+ 13 - 5
Source/Urho3D/Physics/RigidBody.cpp

@@ -79,7 +79,8 @@ RigidBody::RigidBody(Context* context) :
     useGravity_(true),
     readdBody_(false),
     inWorld_(false),
-    enableMassUpdate_(true)
+    enableMassUpdate_(true),
+    hasSimulated_(false)
 {
     compoundShape_ = new btCompoundShape();
     shiftedCompoundShape_ = new btCompoundShape();
@@ -171,6 +172,9 @@ void RigidBody::getWorldTransform(btTransform& worldTrans) const
         worldTrans.setOrigin(ToBtVector3(lastPosition_ + lastRotation_ * centerOfMass_));
         worldTrans.setRotation(ToBtQuaternion(lastRotation_));
     }
+
+    if (kinematic_)
+        hasSimulated_ = true;
 }
 
 void RigidBody::setWorldTransform(const btTransform& worldTrans)
@@ -203,6 +207,8 @@ void RigidBody::setWorldTransform(const btTransform& worldTrans)
 
         MarkNetworkUpdate();
     }
+
+    hasSimulated_ = true;
 }
 
 void RigidBody::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
@@ -241,8 +247,9 @@ void RigidBody::SetPosition(const Vector3& position)
 
         // When forcing the physics position, set also interpolated position so that there is no jitter
         // When not inside the simulation loop, this may lead to erratic movement of parented rigidbodies
-        // so skip in that case
-        if (physicsWorld_->IsSimulating())
+        // so skip in that case. Exception made before first simulation tick so that interpolation position
+        // of e.g. instantiated prefabs will be correct from the start
+        if (!hasSimulated_ || physicsWorld_->IsSimulating())
         {
             btTransform interpTrans = body_->getInterpolationWorldTransform();
             interpTrans.setOrigin(worldTrans.getOrigin());
@@ -264,7 +271,7 @@ void RigidBody::SetRotation(const Quaternion& rotation)
         if (!centerOfMass_.Equals(Vector3::ZERO))
             worldTrans.setOrigin(ToBtVector3(oldPosition + rotation * centerOfMass_));
 
-        if (physicsWorld_->IsSimulating())
+        if (!hasSimulated_ || physicsWorld_->IsSimulating())
         {
             btTransform interpTrans = body_->getInterpolationWorldTransform();
             interpTrans.setRotation(worldTrans.getRotation());
@@ -288,7 +295,7 @@ void RigidBody::SetTransform(const Vector3& position, const Quaternion& rotation
         worldTrans.setRotation(ToBtQuaternion(rotation));
         worldTrans.setOrigin(ToBtVector3(position + rotation * centerOfMass_));
 
-        if (physicsWorld_->IsSimulating())
+        if (!hasSimulated_ || physicsWorld_->IsSimulating())
         {
             btTransform interpTrans = body_->getInterpolationWorldTransform();
             interpTrans.setOrigin(worldTrans.getOrigin());
@@ -1012,6 +1019,7 @@ void RigidBody::AddBodyToWorld()
     world->addRigidBody(body_, (short)collisionLayer_, (short)collisionMask_);
     inWorld_ = true;
     readdBody_ = false;
+    hasSimulated_ = false;
 
     if (mass_ > 0.0f)
         Activate();

+ 2 - 0
Source/Urho3D/Physics/RigidBody.h

@@ -305,6 +305,8 @@ private:
     bool inWorld_;
     /// Mass update enable flag.
     bool enableMassUpdate_;
+    /// Internal flag whether has simulated at least once.
+    mutable bool hasSimulated_;
 };
 
 }