Advertisement

Why isn't the Mesh Showing

Started by June 24, 2023 05:07 AM
2 comments, last by LeftyGuitar 1 year, 5 months ago

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();
}

This is not the simplest test program you can debug: at the very least, rip out the physics and leave only one function that draws one Model (or a few related variants) without complications like updates, creations and deletions and all those horrible global variables.

Omae Wa Mou Shindeiru

Advertisement

I've figured out a better way to go about this. This example is working.

#include <iostream>
#include <vector>

#include "raylib.h"
#include "btBulletDynamicsCommon.h"

btDefaultCollisionConfiguration* collisionConfig;
btCollisionDispatcher* dispatcher;
btBroadphaseInterface* broadphase;
btSequentialImpulseConstraintSolver* solver;
btDynamicsWorld* world;

btAlignedObjectArray<btCollisionShape*> collide_shapes;

enum SHAPETYPES
{
	CUBE,
	SPHERE,
	RAGDOLL,
	SOFTBODY,
	CAPSULE
};

enum PHYSICSTYPES
{
	STATIC,
	DYNAMIC
};

class PObject
{
private:
	btRigidBody* body;
	btCollisionShape* shape;
	Model model;

public:
	Color color;

	PObject(Vector3 Position = { 0,0,0 }, Vector3 Rotation = { 0,0,0 }, Vector3 Size = { 0,0,0 },
		SHAPETYPES st = CUBE, PHYSICSTYPES types = STATIC, float mass = 0, Color color = WHITE)
	{
		this->color = color;

		if (st == CUBE)
		{
			shape = 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.z));
		}
		else if (st == SPHERE)
		{
			shape = new btSphereShape(btScalar(Size.x));
			model = LoadModelFromMesh(GenMeshSphere(Size.x, 8, 16));
		}

		collide_shapes.push_back(shape);

		btTransform Transform;
		Transform.setIdentity();
		Transform.setOrigin(btVector3(Position.x, Position.y, Position.z));
		Transform.setRotation(btQuaternion(btScalar(Rotation.z), btScalar(Rotation.y), btScalar(Rotation.x)));

		btScalar object_mass(mass);

		btVector3 localInertia(0, 0, 0);
		if (types == DYNAMIC || mass != 0.0)
		{
			shape->calculateLocalInertia(mass, localInertia);
		}

		btDefaultMotionState* motionState = new btDefaultMotionState(Transform);

		btRigidBody::btRigidBodyConstructionInfo info(object_mass, motionState, shape, localInertia);
		body = new btRigidBody(info);

		world->addRigidBody(body);
	}

	void draw()
	{
		const float radian_scale = 57.296;
		btTransform trans;

		if (body && body->getMotionState())
		{
			body->getMotionState()->getWorldTransform(trans);
		}
		else
		{
			return;
		}

		Vector3 pos = {float(trans.getOrigin().getX()), float(trans.getOrigin().getY()), float(trans.getOrigin().getZ())};

		btQuaternion quat = trans.getRotation();

		Vector3 axis = {float(quat.getAxis().getX()), float(quat.getAxis().getY()), float(quat.getAxis().getZ())};
		float angle = float(quat.getAngle()) * radian_scale;

		DrawModelEx(model, pos, axis, angle, { 1,1,1 }, color);
	}

	void unload()
	{
		UnloadModel(model);
	}
};

const int MAX_WIDTH = 1024;
const int MAX_HEIGHT = 720;
const int MAX_FPS = 60;

void InitPhysics();
void ExitPhysics();
void StepPhysics();

int main(int argc, char* argv[])
{
	SetConfigFlags(FLAG_MSAA_4X_HINT);
	InitWindow(MAX_WIDTH, MAX_HEIGHT, "Raylib Physics Playground");

	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();

	PObject Ground;
	Ground = {PObject({0,0,0},{0,0,0},{10,0,8.8},CUBE,STATIC,0.0,GRAY)};

	while (!WindowShouldClose())
	{
		UpdateCamera(&cam, CAMERA_ORBITAL);

		StepPhysics();

		BeginDrawing();

		ClearBackground(BLACK);

		BeginMode3D(cam);

		Ground.draw();

		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 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;
	}

	//collide_shapes.clear();

	delete world;
	delete solver;
	delete broadphase;
	delete dispatcher;
	delete collisionConfig;
}

This topic is closed to new replies.

Advertisement