如何防止 OgreBullet 胶囊翻倒?

发布于 2024-12-17 09:48:26 字数 2590 浏览 1 评论 0原文

我刚刚开始在我的 Ogre 项目中实施项目符号。我按照此处的安装说明进行操作: http://www.ogre3d.org/tikiwiki/OgreBullet+教程+1

其余的教程在这里: http://www.ogre3d.org/tikiwiki/OgreBullet+Tutorial+2

我让它工作得很好,但现在我想将它扩展到第一人称相机的手柄。我创建了一个 CapsuleShape 和一个刚体(就像教程中为盒子所做的那样),但是当我运行游戏时,胶囊会翻倒并在地板上滚动,导致相机剧烈摆动。

我需要一种方法来固定胶囊以使其始终保持直立,但我不知道

下面是我正在使用的代码。

(部分)头文件

OgreBulletDynamics::DynamicsWorld *mWorld;   // OgreBullet World
OgreBulletCollisions::DebugDrawer *debugDrawer;
std::deque<OgreBulletDynamics::RigidBody *>         mBodies;
std::deque<OgreBulletCollisions::CollisionShape *>  mShapes;

OgreBulletCollisions::CollisionShape *character;
OgreBulletDynamics::RigidBody *characterBody;
Ogre::SceneNode *charNode;

Ogre::Camera* mCamera;
Ogre::SceneManager* mSceneMgr;
Ogre::RenderWindow* mWindow;

主文件

bool MinimalOgre::go(void)
{
    ...

     mCamera = mSceneMgr->createCamera("PlayerCam");
     mCamera->setPosition(Vector3(0,0,0));
     mCamera->lookAt(Vector3(0,0,300));
     mCamera->setNearClipDistance(5);
     mCameraMan = new OgreBites::SdkCameraMan(mCamera);


    OgreBulletCollisions::CollisionShape *Shape;
    Shape = new OgreBulletCollisions::StaticPlaneCollisionShape(Vector3(0,1,0), 0); // (normal vector, distance)
    OgreBulletDynamics::RigidBody *defaultPlaneBody = new OgreBulletDynamics::RigidBody(
            "BasePlane",
            mWorld);
    defaultPlaneBody->setStaticShape(Shape, 0.1, 0.8); // (shape, restitution, friction)
    // push the created objects to the deques
    mShapes.push_back(Shape);
    mBodies.push_back(defaultPlaneBody);

    character = new OgreBulletCollisions::CapsuleCollisionShape(1.0f, 1.0f, Vector3(0, 1, 0));

    charNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    charNode->attachObject(mCamera);
    charNode->setPosition(mCamera->getPosition());

    characterBody = new OgreBulletDynamics::RigidBody("character", mWorld);
    characterBody->setShape(   charNode,
                    character,
                    0.0f,         // dynamic body restitution
                    10.0f,         // dynamic body friction
                    10.0f,          // dynamic bodymass
                    Vector3(0,0,0),     
                    Quaternion(0, 0, 1, 0));


    mShapes.push_back(character);
    mBodies.push_back(characterBody);

    ...
}

I've just started implementing bullet into my Ogre project. I follows the install instructions here: http://www.ogre3d.org/tikiwiki/OgreBullet+Tutorial+1

And the rest if the tutorial here:
http://www.ogre3d.org/tikiwiki/OgreBullet+Tutorial+2

I got that to work fine however now I wanted to extend it to a handle a first person camera. I created a CapsuleShape and a Rigid Body (like the tutorial did for the boxes) however when I run the game the capsule falls over and rolls around on the floor, causing the camera swing wildly around.

I need a way to fix the capsule to always stay upright, but I have no idea how

Below is the code I'm using.

(part of) Header File

OgreBulletDynamics::DynamicsWorld *mWorld;   // OgreBullet World
OgreBulletCollisions::DebugDrawer *debugDrawer;
std::deque<OgreBulletDynamics::RigidBody *>         mBodies;
std::deque<OgreBulletCollisions::CollisionShape *>  mShapes;

OgreBulletCollisions::CollisionShape *character;
OgreBulletDynamics::RigidBody *characterBody;
Ogre::SceneNode *charNode;

Ogre::Camera* mCamera;
Ogre::SceneManager* mSceneMgr;
Ogre::RenderWindow* mWindow;

main file

bool MinimalOgre::go(void)
{
    ...

     mCamera = mSceneMgr->createCamera("PlayerCam");
     mCamera->setPosition(Vector3(0,0,0));
     mCamera->lookAt(Vector3(0,0,300));
     mCamera->setNearClipDistance(5);
     mCameraMan = new OgreBites::SdkCameraMan(mCamera);


    OgreBulletCollisions::CollisionShape *Shape;
    Shape = new OgreBulletCollisions::StaticPlaneCollisionShape(Vector3(0,1,0), 0); // (normal vector, distance)
    OgreBulletDynamics::RigidBody *defaultPlaneBody = new OgreBulletDynamics::RigidBody(
            "BasePlane",
            mWorld);
    defaultPlaneBody->setStaticShape(Shape, 0.1, 0.8); // (shape, restitution, friction)
    // push the created objects to the deques
    mShapes.push_back(Shape);
    mBodies.push_back(defaultPlaneBody);

    character = new OgreBulletCollisions::CapsuleCollisionShape(1.0f, 1.0f, Vector3(0, 1, 0));

    charNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    charNode->attachObject(mCamera);
    charNode->setPosition(mCamera->getPosition());

    characterBody = new OgreBulletDynamics::RigidBody("character", mWorld);
    characterBody->setShape(   charNode,
                    character,
                    0.0f,         // dynamic body restitution
                    10.0f,         // dynamic body friction
                    10.0f,          // dynamic bodymass
                    Vector3(0,0,0),     
                    Quaternion(0, 0, 1, 0));


    mShapes.push_back(character);
    mBodies.push_back(characterBody);

    ...
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

兲鉂ぱ嘚淚 2024-12-24 09:48:26

您可以锁定胶囊的角运动以防止其翻倒。 Ogre 不会直接公开此功能,但您应该能够访问底层的子弹刚体来完成您需要的操作:

characterBody->getBulletRigidBody()->setAngularFactor(btVector3(0.0f,1.0f,0.0f));

这将锁定 x 轴和 z 轴上的旋转,防止胶囊翻倒,但允许绕 y 轴旋转,这样角色仍然可以转动。

在某些时候,您可能想考虑使用运动学角色控制器,但这是另一个问题的答案。

You can lock the angular motion of the capsule in order to prevent it from tipping over. Ogre doesn't expose this functionality directly, but you should be able to access the underlying bullet rigid body to accomplish what you need:

characterBody->getBulletRigidBody()->setAngularFactor(btVector3(0.0f,1.0f,0.0f));

This would lock rotation on the xaxis and zaxis, preventing the capsule from tipping over, but allowing rotation around the yaxis, so that the character can still turn.

At some point you may want to looking into using a kinematic character controller, but that's an answer to a different question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文