Hello,
I'm trying to figure out why the mesh (cube) isn't showing up for the ground. The only thing showing right now is the wireframe grid. I'm using Bullet Physics and Raylib.
#include <iostream>
#include <vector>
#include "raylib.h"
#include <btBulletDynamicsCommon.h>
btDefaultCollisionConfiguration* collisionConfig;
btCollisionDispatcher* dispatcher;
btBroadphaseInterface* broadphase;
btSequentialImpulseConstraintSolver* solver;
btDiscreteDynamicsWorld* world;
btAlignedObjectArray<btCollisionShape*> collide_shapes;
Model model;
Color color;
Vector3 position;
btQuaternion quat;
Vector3 axis;
float angle;
void InitPhysics();
void ExitPhysics();
void StepPhysics();
void DrawPhysics();
void PhysicsGround();
btBoxShape* createBoxShape(const btVector3& halfExtents)
{
btBoxShape* box = new btBoxShape(halfExtents);
return box;
}
btSphereShape* createSphereShape(btScalar radius)
{
btSphereShape* sphere = new btSphereShape(radius);
return sphere;
}
btRigidBody* createRigidBody(btDiscreteDynamicsWorld* world, float mass, const btTransform& transform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1))
{
btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
shape->calculateLocalInertia(mass, localInertia);
#define USE_MOTIONSTATE 1
#ifdef USE_MOTIONSTATE
btDefaultMotionState* motionState = new btDefaultMotionState(transform);
btRigidBody::btRigidBodyConstructionInfo info(mass, motionState, shape, localInertia);
btRigidBody* body = new btRigidBody(info);
#else
btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia);
#endif
body->setUserIndex(-1);
world->addRigidBody(body);
return body;
}
const int MAX_WIDTH = 1024;
const int MAX_HEIGHT = 720;
const int MAX_FPS = 60;
int main(int argc, char* argv[])
{
InitWindow(MAX_WIDTH, MAX_HEIGHT, "Raylib & Bullet Physics");
Camera3D cam = { 0 };
cam.position = { 10.0f, 5.0f, 10.0f };
cam.target = { 0.0f,0.0f,0.0f };
cam.up = { 0.0f,1.0f,0.0f };
cam.fovy = 60.0f;
cam.projection = CAMERA_PERSPECTIVE;
SetTargetFPS(MAX_FPS);
InitPhysics();
PhysicsGround();
//a solid flat cube should be the ground, but nothing is shown
model = LoadModelFromMesh(GenMeshCube(10, 10, 10));
while (!WindowShouldClose())
{
UpdateCamera(&cam, CAMERA_ORBITAL);
StepPhysics();
BeginDrawing();
ClearBackground(BLACK);
BeginMode3D(cam);
DrawPhysics();
DrawGrid(10, 1.0);
EndMode3D();
DrawFPS(1, 1);
EndDrawing();
}
ExitPhysics();
CloseWindow();
return 0;
}
void InitPhysics()
{
collisionConfig = new btDefaultCollisionConfiguration();
dispatcher = new btCollisionDispatcher(collisionConfig);
broadphase = new btDbvtBroadphase();
solver = new btSequentialImpulseConstraintSolver();
world = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfig);
world->setGravity(btVector3(0, -10, 0));
}
void StepPhysics()
{
world->stepSimulation(1.0 / float(MAX_FPS), 10);
}
void DrawPhysics()
{
const float radian_scale = 57.296;
int numObjects = world->getNumCollisionObjects();
for (int j = numObjects - 1; j >= 0; j--)
{
btCollisionObject* obj = world->getCollisionObjectArray()[j];
btRigidBody* body = btRigidBody::upcast(obj);
btTransform transform;
if (body && body->getMotionState())
{
body->getMotionState()->getWorldTransform(transform);
Mesh* mesh = reinterpret_cast<Mesh*>(body->getUserPointer());
if (mesh != NULL)
{
position = {float(transform.getOrigin().getX()), float(transform.getOrigin().getY()), float(transform.getOrigin().getZ())};
quat = transform.getRotation();
axis = {float(quat.getAxis().getX()), float(quat.getAxis().getY()), float(quat.getAxis().getZ())};
angle = float(quat.getAngle()) * radian_scale;
DrawModelEx(model, position, axis, angle, { 1,1,1 }, color);
}
}
else
{
transform = obj->getWorldTransform();
};
}
}
void PhysicsGround()
{
Vector3 size = { 0,0,0 };
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(size.x/2.0), btScalar(size.y/2.0), btScalar(size.z /2.0)));
model = LoadModelFromMesh(GenMeshCube(size.x, size.y, size.y));
collide_shapes.push_back(groundShape);
btTransform transform;
transform.setIdentity();
transform.setOrigin(btVector3(0, -56, 0));
btScalar mass(0.);
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
btDefaultMotionState* motionState = new btDefaultMotionState(transform);
btRigidBody::btRigidBodyConstructionInfo info(mass, motionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(info);
body->setUserIndex(5);
body->setFriction(1);
world->addRigidBody(body);
}
void ExitPhysics()
{
for (int i = world->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = world->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
world->removeCollisionObject(obj);
delete obj;
}
for (int i = 0; i < collide_shapes.size(); i++)
{
btCollisionShape* shape = collide_shapes[i];
collide_shapes[i] = 0;
delete shape;
}
delete world;
delete solver;
delete broadphase;
delete dispatcher;
delete collisionConfig;
collide_shapes.clear();
}