コード例 #1
0
ファイル: RigidBody.cpp プロジェクト: realXtend/tundra-urho3d
    /// btMotionState override. Called when Bullet wants to tell us the body's current transform
    void setWorldTransform(const btTransform &worldTrans)
    {
        /// \todo For a large scene, applying the changed transforms of rigid bodies is slow (slower than the physics simulation itself,
        /// or handling collisions) due to the large number of signals being fired.
    
        // Cannot modify server-authoritative physics object, rather get the transform changes through placeable attributes
        const bool hasAuthority = rigidBody->HasAuthority();
        if (!hasAuthority && !clientExtrapolating)
            return;
    
        if (placeable.Expired())
            return;
        Placeable* p = placeable;
        // Important: disconnect our own response to attribute changes to not create an endless loop!
        disconnected = true;
    
        AttributeChange::Type changeType = hasAuthority ? AttributeChange::Default : AttributeChange::LocalOnly;

        // Set transform
        float3 position = worldTrans.getOrigin();
        Quat orientation = worldTrans.getRotation();
    
        // Non-parented case
        if (p->parentRef.Get().IsEmpty())
        {
            Transform newTrans = p->transform.Get();
            newTrans.SetPos(position.x, position.y, position.z);
            newTrans.SetOrientation(orientation);
            p->transform.Set(newTrans, changeType);
        }
        else
        // The placeable has a parent itself
        {
            Urho3D::Node* parent = p->UrhoSceneNode()->GetParent();
            if (parent)
            {
                position = parent->WorldToLocal(position);
                orientation = parent->GetWorldRotation().Inverse() * orientation;
                Transform newTrans = p->transform.Get();
                newTrans.SetPos(position);
                newTrans.SetOrientation(orientation);
                p->transform.Set(newTrans, changeType);
            }
        }
        // Set linear & angular velocity
        if (body)
        {
            // Performance optimization: because applying each attribute causes signals to be fired, which is slow in a large scene
            // (and furthermore, on a server, causes each connection's sync state to be accessed), do not set the linear/angular
            // velocities if they haven't changed
            float3 linearVel = body->getLinearVelocity();
            float3 angularVel = RadToDeg(body->getAngularVelocity());
            if (!linearVel.Equals(rigidBody->linearVelocity.Get()))
                rigidBody->linearVelocity.Set(linearVel, changeType);
            if (!angularVel.Equals(rigidBody->angularVelocity.Get()))
                rigidBody->angularVelocity.Set(angularVel, changeType);
        }
    
        disconnected = false;
    }