多个btDefaultMotionState实例,所有的都被忽略了,但其中一个没有。

7
总结问题如下: 我目前的世界中有两个物体,一个是地面,另一个是名为“fallingStar”的下落物体。 1)如果不将(btDefault) MotionState的偏移量设置为btVector3(2,2,2),则我不明白为什么我的子弹世界与我的绘制世界不对齐。 在代码中没有任何神奇的魔法可以解释这种偏移量。至少我找不到任何原因,无论是在着色器中还是其他任何地方。 2)我希望能够使用多个btDefaultMotionState实例,确切地说,我想为下落物体使用一个实例,并将其放置在地面上方的某个位置,然后为地面创建另一个实例,应该简单地与我的图形地面对齐,永远保持不动。 关于2),我所经历的是btDefaultMotionState实例始终影响地面的实例,而没有参考。 现在来看一下代码: 创建下落物体:
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);

如果我重新启用代码的这部分,所有物体都会再次显示出偏移量,但不只是上移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 的实现是一个单例,但看起来并不是这样,那么... 为什么设置一个物体的运动状态会影响整个世界呢?

未使用 btVector3(2,2,2) 偏移量的 btDefaultMotionState

使用 btVector3(2,2,2) 偏移量的 btDefaultMotionState

我的盒子和它的身体位置,还有一个偏移量


1
你是否在创建 fallingBoxBody 刚体后删除了 fallMotionState?这将导致刚体中的悬空指针,可能会与下一个相同大小的分配别名,从而导致你所看到的问题。或者,你有一些其他之前的悬空指针被 fallMotionState 覆盖。 - user4442671
@Frank,这发生在构造函数中,稍后就会超出范围,但我这里没有手动释放任何东西。(是的,可能会导致泄漏) - user4063815
已经将所有内容切换为使用智能指针,但仍然没有运气。 - user4063815
3个回答

2
是一个很好的库,但只有少数人花时间编写良好的文档。 <要设置btRigidBody的位置,请尝试以下方法:>btRigidBody的位置,请尝试以下方法:>
btTransform transform = body -> getCenterOfMassTransform();
transform.setOrigin(aNewPosition); //<- set orientation / position that you like
body -> setCenterOfMassTransform(transform);  

如果你的代码只在设置转换部分出错(根据我浏览代码所猜测),那么应该可以解决。

请注意,此代码片段仅适用于动态物体,不适用于静态物体。

关于复合体:

如果它是一个复合体,例如形状B包含形状C
设置B的变换会起作用(设置B的主体),但对于C则无效。(因为C只是一个形状,变换仅支持主体。)

如果我想改变C相对于B的变换,则需要创建一个全新的复合形状和一个新的刚体。别忘了删除旧的主体和形状。

这是库的限制。

P.S.

我无法回答您的一些疑问,这些信息是我在Bullet论坛上偷窥一段时间后收集到的,并由我自己测试。

(我也正在从头开始编写游戏和游戏库,使用Bullet和其他开放源代码。)

编辑:(关于新问题)

它很慢地掉下来(连同地面本身一起,因为我将它的质量设置为了0)

我会按照以下顺序尝试解决它。

Idea A

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

Idea B

  • 每个时间步先检查-> getCenterOfMassTransform(),它是否真的在下落?
  • 如果它确实在下落,请尝试dynamicsWorld->setGravity(btVector3(0,0,0));以确信。
  • 如果仍然不起作用,请尝试使用非常简单的世界(1个简单对象,没有复合体)并查看其结果。

Idea C(现在我开始绝望了)

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

你的位置输入给我带来了新问题,但我有东西可以看。有趣的是:如果我在那里设置一个硬编码位置,我会认为身体会停留在那里,对吧?然而,它并没有...它只是慢慢地掉下来(连同地面本身一起,但我已经将其质量设为0,不应该移动)。我已经没有更多的想法了。 - user4063815
@Sorona,我的第一个赏金,谢谢!我在答案的末尾添加了一些关于新问题的想法。 :) - javaLover
我正在设置物体的质量,而不是任何形状上。如果我没有设置重力,那当然它就不会掉下来。它也只会在有其他物体时才会掉落。如果只是地面,它就会留在原地(但完全偏移)...也许这与摄像头有关,我要检查一下。 - user4063815
@ Sorona 我从来没有成功地控制过世界引力,所以我总是将世界引力设为0,并手动为每个对象使用直接脉冲。 "只有在存在其他物体时才会下落"这意味着下落的力可能来自于碰撞脉冲(来自某对物体)。我遇到了一个问题,即这种未知速度来自于第一时间步的碰撞(因此很难找到该错误)。尝试在0时间步更改另一个物体的位置到非常远/添加一些碰撞回调进行检查。 - javaLover
@Sorona 另一个猜测:我希望您在将 (复合) 物体添加到世界后没有设置/修改其质量。 - javaLover

0

你所描述的不是正常的弹道行为。你对库的理解是正确的。

你最有可能遇到的问题是缓冲区溢出或悬空指针。你发布的代码没有明显的任何一个,所以它可能来自于你代码库中的其他地方。你可以使用适当放置的内存断点来追踪它。

你“可能”正在处理头文件/二进制版本不一致的问题,但这不太可能,因为你可能会看到其他主要问题。


0
刚刚遇到了与DebugDrawer悬浮在世界顶部的完全相同类型的行为。通过仅传递projectionview矩阵而不是模型矩阵来解决它,Bullet Physics已经乘以它:
glUseProgram(shaderID);

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接