I'm working on a game called Omeganaut, and I decided to use Bullet for collisions because it will involve physics in the future.
The engine is ZGameEditor with a wrapper for Bullet Physics Library.
Until now, everything was fine. The player could fly and collide with buildings and enemies made out of collision boxes and spheres. But recently, I started adding pillars that are not vertical and discovered this problem:
When the pillar is vertical or horizontal (fig. A), like a lot of the objects in my game, everything's fine.
But if it's rotated (fig. B), the ball collides with the box that encompasses the rotated pillar...
Code: Select all
shape = zbtCreateCylinderShape(0.5, 10);
On the contrary, if the shape of the pillar is "complex", the collision works better, but it's not perfect: the ball gets the collision correctly with the pillar, but then it stays collided as long as the ball stays in the red rectangle.
Code: Select all
shape = zbtCreateCompoundShape();
zbtAddChildShape(shape, zbtCreateCylinderShape(0.5, 10), 0,0,0, 0,0,0);
I could replace all shapes by compound shapes in my game, but it would be overkill for what it is supposed to do.
I made a working example if you want to try, but here's the general idea:
I heavily simplified the code for readability. As you will see, it's quite simple. I use setPosRot to set the physics of the rotating pillar, and the coordinates of the ball. Then I use isColliding to check if both collides.
Code: Select all
<OnLoaded>
// init physical world
xptr World = zbtCreateWorld();
zbtSetCurrentWorld(World);
// Create models
createModel(PillarModel);
createModel(BallModel);
</OnLoaded>
<OnUpdate>
zbtStepSimulation(App.DeltaTime, 0, 0);
</OnUpdate>
<Model Name="PillarModel">
<Definitions>
<Variable Name="PillarBody" Type="xptr"/>
</Definitions>
<OnSpawn>
xptr shape = zbtCreateCylinderShape(0.5, 10);
PillarBody = zbtCreateRigidBody(1, shape, CurrentModel.Position, CurrentModel.Rotation);
</OnSpawn>
<OnUpdate>
// Rotate the pillar
CurrentModel.Rotation.Z += 0.001;
zbtSetPosRot(PillarBody, CurrentModel.Position, CurrentModel.Rotation);
</OnUpdate>
<OnRender>
<RenderMesh Mesh="PillarMesh"/>
</OnRender>
</Model>
<Model Name="BallModel">
<Definitions>
<Variable Name="BallBody" Type="xptr"/>
</Definitions>
<OnSpawn>
xptr shape = zbtCreateSphereShape(1.0);
BallBody = zbtCreateRigidBody(1, shape, CurrentModel.Position, CurrentModel.Rotation);
</OnSpawn>
<OnUpdate>
// Set Ball position to mouse coordinate
CurrentModel.Position = vector3(App.MousePosition.X, App.MousePosition.Y, 0);
zbtSetPosRot(BallBody, CurrentModel.Position, CurrentModel.Rotation);
// Test collision between ball and rotating pillar
if (zbtIsColliding(BallBody)) {
BallColor.Color = vector3(1, 0, 0); // red
} else {
BallColor.Color = vector3(1, 1, 1); // white
}
</OnUpdate>
<OnRender>
<RenderSetColor Name="BallColor" />
<RenderMesh Mesh="BallMesh"/>
</OnRender>
</Model>
Thanks for your help.