Ich habe eine First-Person-Kamera mit Bullet implementiert - es ist ein starrer Körper mit einer Kapselform. Ich benutze Bullet erst seit ein paar Tagen und Physik-Engines sind für mich neu. Ich btRigidBody::setLinearVelocity()
bewege es und es kollidiert perfekt mit der Welt. Das einzige Problem ist, dass sich der Y-Wert frei bewegt, was ich vorübergehend gelöst habe, indem ich den Y-Wert des Translationsvektors auf Null gesetzt habe, bevor der Körper bewegt wird. Dies funktioniert in allen Fällen, außer wenn Sie aus großer Höhe fallen.
Wenn der Körper von einem hohen Objekt abfällt, können Sie immer noch herumgleiten, da der Y-Wert des Übersetzungsvektors auf Null gesetzt wird, bis Sie aufhören, sich zu bewegen und auf den Boden fallen (die Geschwindigkeit wird nur beim Bewegen eingestellt). Um dies zu lösen, möchte ich versuchen, einen Strahl vom Körper herabzuwerfen, um den Y-Wert der Welt zu bestimmen, die Differenz zwischen diesem Wert und dem Y-Wert des Kameragehäuses zu überprüfen und die Bewegung zu deaktivieren oder zu verlangsamen, wenn Der Unterschied ist groß genug.
Ich bin ein bisschen festgefahren, einfach einen Strahl zu werfen und den Y-Wert der Welt zu bestimmen, in der er getroffen hat. Ich habe diesen Rückruf implementiert:
struct AllRayResultCallback : public btCollisionWorld::RayResultCallback{
AllRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld)
: m_rayFromWorld(rayFromWorld), m_rayToWorld(rayToWorld), m_closestHitFraction(1.0){}
btVector3 m_rayFromWorld;
btVector3 m_rayToWorld;
btVector3 m_hitNormalWorld;
btVector3 m_hitPointWorld;
float m_closestHitFraction;
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
{
if(rayResult.m_hitFraction < m_closestHitFraction)
m_closestHitFraction = rayResult.m_hitFraction;
m_collisionObject = rayResult.m_collisionObject;
if(normalInWorldSpace){
m_hitNormalWorld = rayResult.m_hitNormalLocal;
}
else{
m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal;
}
m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, m_closestHitFraction);
return 1.0f;
}
};
Und in der Bewegungsfunktion habe ich diesen Code:
btVector3 from(pos.x, pos.y + 1000, pos.z); // pos is the camera's rigid body position
btVector3 to(pos.x, 0, pos.z); // not sure if 0 is correct for Y
AllRayResultCallback callback(from, to);
Base::getSingletonPtr()->m_btWorld->rayTest(from, to, callback);
Ich habe also den callback.m_hitPointWorld
Vektor, der nur die Position der Kamera in jedem Bild zu zeigen scheint. Ich habe Google nach Beispielen für das Strahlen von Strahlen sowie nach der Bullet-Dokumentation durchsucht, und es war schwierig, nur ein Beispiel zu finden. Ein Beispiel ist wirklich alles was ich brauche.
Oder gibt es in Bullet eine Methode, um den starren Körper auf dem Boden zu halten?
Ich verwende Ogre3D als Rendering-Engine, und das Abwerfen eines Strahls ist damit recht einfach. Der Einfachheit halber möchte ich jedoch das gesamte Strahlen-Casting in Bullet beibehalten.
Könnte mich jemand in die richtige Richtung weisen? Vielen Dank.