btDefaultMotionState的多个实例都被忽略,但只有一个

时间:2016-12-21 20:21:35

标签: c++ game-engine game-physics bulletphysics

总结问题:

到目前为止,我的世界里有两具尸体,一只是地面,另一只是一个叫做“坠落的星星”的坠落的盒子。

1)我不明白为什么我的子弹世界与我绘制的世界不对齐,除非我将btVector3(2,2,2)的偏移量设置为(btDefault)MotionState。 在代码中的任何地方都没有花哨的魔法可以解释偏移。或者至少我找不到任何理由,不是在着色器中,而是在任何地方。

2)我希望能够使用btDefaultMotionState的多个实例,确切地说,我想为下降实体使用一个实例并将其放置在地面上的某个位置,然后为地面创建另一个实例应该简单地与我的图形对齐,永远不动。

我在2)方面遇到的问题是,无论出于何种原因,下降实体的btDefaultMotionState实例总是也会影响地面的实例,而没有任何参考。< / p>

现在代码:

创建fallingBox:

btCollisionShape *fallingBoxShape = new btBoxShape(btVector3(1,1,1));
btScalar fallingBoxMass = 1;
btVector3 fallingBoxInertia(0,0,0);
fallingBoxShape->calculateLocalInertia(fallingBoxMass, fallingBoxInertia);

// TODO this state somehow defines where exactly _ALL_ of the physicsWorld is...
btDefaultMotionState *fallMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(2,2,2)));
//btDefaultMotionState *fallMotionState = new btDefaultMotionState();
btRigidBody::btRigidBodyConstructionInfo fallingBoxBodyCI(fallingBoxMass, fallMotionState, fallingBoxShape, fallingBoxInertia);
/*btTransform initialTransform;
initialTransform.setOrigin(btVector3(0,5,0));*/
this->fallingBoxBody = new btRigidBody(fallingBoxBodyCI);
/*fallMotionState->setWorldTransform(initialTransform);
this->fallingBoxBody->setWorldTransform(initialTransform);*/
this->physicsWorld->addBody(*fallingBoxBody);

现在我感兴趣的部分是btVector3(2,2,2)必要的偏移量,以便与我绘制的世界保持一致,并且:

btTransform initialTransform;
initialTransform.setOrigin(btVector3(0,5,0));
this->fallingStarBody = new btRigidBody(fallingStarBodyCI);
fallMotionState->setWorldTransform(initialTransform);

如果我重新启用代码 ALL 的这部分,那么这些实体会再次显示一个偏移量,但是 NOT 只需要5,这样,无论出于何种原因,我都可以理解为worldTransform会对每个实体产生影响,但是大约2,2,2个关闭......我完全无法理解。

我猜这行无用:

fallMotionState->setWorldTransform(initialTransform);因为它不会改变任何东西,无论它是否存在。

现在到地面创作的代码:

btCompoundShape *shape = new btCompoundShape();

... just some logic, nothing to do with bullet

btTransform transform;
transform.setIdentity();

transform.setOrigin(btVector3(x + (this->x * Ground::width),
                          y + (this->y * Ground::height),
                          z + (this->z * Ground::depth)));

btBoxShape *boxShape = new btBoxShape(btVector3(1,0,1)); // flat surface, no box

shape->addChildShape(transform, boxShape);

(此部分只为每个表面贴砖创建一个复合形状:)

btRigidBody::btRigidBodyConstructionInfo info(0, nullptr, shape);
return new btRigidBody(info); 

这里我故意将运动状态设置为nullptr,但这并没有改变任何内容。

现在我真的好奇......我想也许btDefaultMotionState的实现是一个单身,但它看起来不那么,所以...为什么地狱设置一个身体的运动状态影响全世界?

offset without btVector3(2,2,2) for btDefaultMotionState

offset with btVector3(2,2,2) for btDefaultMotionState

The position of my box and it's body, also an offset

3 个答案:

答案 0 :(得分:3)

Bullet是一个很好的图书馆,但只有少数人花时间写好文档。

要设置btRigidBody的位置,请尝试以下操作: -

btTransform transform = body -> getCenterOfMassTransform();
transform.setOrigin(aNewPosition); //<- set orientation / position that you like
body -> setCenterOfMassTransform(transform);  

如果您的代码错误在设置的转换部分(这是我从略读代码中猜到的),它应该被解决。

请注意,此代码段仅适用于动态正文,而不适用于静态正文。

关于CompoundBody: -

如果是复合体,例如形状B包含形状C 设置B的转换可行(设置B的正文),但不适用于C
 (因为C只是一个形状,转换只支持体。)

如果我想改变CB的相对转换,我会创建一个全新的复合形状和一个新的刚体。不要忘记删除旧的身体&amp;形状

这是图书馆限制。

<强> P.S。

我无法回答您的一些疑问/问题,这些信息是我在Bullet论坛中跟踪一段时间后收集到的信息,并由我自己进行测试。

(我还使用Bullet和其他开源来从头开始编写游戏+游戏库。)

编辑:(关于新问题)

  它只是慢慢地下降(与地面本身一起,应该   不要动,因为我给它的质量为0)

我会尝试按此顺序解决它。

想法A

  • 设置为复合质量= 0,因为设置子形状的质量没有意义。

想法B

  • 首先检查-> getCenterOfMassTransform()每一个步骤,它真的下降了吗?
  • 如果确实在下降,请务必尝试dynamicsWorld->setGravity(btVector3(0,0,0));
  • 如果仍然不起作用,请尝试使用非常简单的世界(1个简单的对象,没有化合物)并查看。

想法C (现在我开始绝望了)

  • 确保您的相机位置恒定。
  • 如果问题仍然存在,我认为您现在可以创建一个简单的测试用例并在Bullet论坛中发布它而不需要太多努力。
  • 较少的代码行=更好的反馈

答案 1 :(得分:1)

您所描述的不是正常的子弹行为。您对图书馆的理解是正确的。

您最有可能处理的是缓冲区溢出或悬空指针。您发布的代码中没有明显的代码,因此它将来自您的代码库中的其他位置。您可以使用放置良好的内存断点来跟踪它。

你&#34;可能&#34;正在处理标题/二进制版本不一致问题,但这可能不太可能,因为您可能会看到其他主要问题。

答案 2 :(得分:0)

在DebugDrawer悬浮在世界之巅时,只有完全相同的行为。通过传递给Bullet Physics单独的投影视图矩阵来解决它,没有他已经拥有的模型矩阵并且已经成倍增加:

glUseProgram(shaderID);

m_MVP = m_camera->getProjectionViewMatrix();
glUniformMatrix4fv(shaderIDMVP, 1, GL_FALSE, &m_MVP[0][0]);
if (m_dynamicWorld) m_dynamicWorld->debugDrawWorld();