I have some structure:
there is class Model3D which has only it's vertices and indices.
Than, i have class WorldObject3D, which has the reference to Model3D instance, it's coordinates, rotation, their matrices, render function, set and get methods etc
The class World has vector of WorldObject3D like vector<WorldObject3D*> m_sceneObjects.
Class World has bullet initialization function and step function, which updates coordinates and rotation of each member of vector<WorldObject3D*> m_sceneObjects.
Class Engine has Update function, where i call world's step function.
Class Engine has render function, where i pass each m_sceneObjects member and render it.
So, some code:
WorldObject3D.h
Code: Select all
#ifndef _WORLD_OBJECT_3D_H
#define _WORLD_OBJECT_3D_H
#include "Model3D.h"
#include "ResourceShader.h"
#include "Structs.h"
#include "btBulletDynamicsCommon.h"
class WorldObject3D
{
private:
Model3D* m_model;
float posX, posY, posZ;
float rotX, rotY, rotZ;
D3DXMATRIX m_translateMatrix;
D3DXMATRIX m_rotationMatrix[3];
D3DXMATRIX m_worldMatrix;
Material m_currMaterial;
ResourceShader* m_shader;
btRigidBody* m_body;
btCompoundShape* m_compoundShape;
vector<btConvexHullShape*> m_convexArray;
float m_mass;
float m_friction;
float m_restitution;
int m_type;
public:
WorldObject3D();
~WorldObject3D();
void Render(D3DXMATRIX camera, D3DXMATRIX projection);
void SetShader(ResourceShader* shader);
void SetModel3D(Model3D* modelRef);
void SetPosition(float X, float Y, float Z);
void SetRotation(float X, float Y, float Z);
void GetPosition(float& X, float& Y, float& Z);
void GetRotation(float& X, float& Y, float& Z);
string GetName();
void SetType(int type);
int GetType();
void SetMass(float mass);
float GetMass();
void SetFriction(float friction);
float GetFriction();
void SetRestitution(float restitution);
float GetRestitution();
void InitializePhysics();
btRigidBody* GetRigidBody();
};
#endif
Code: Select all
#include "WorldObject3D.h"
#include "Engine.h"
#define SPHERE_TYPE 0
#define MESH_TYPE 1
#define PLANE_TYPE 2
WorldObject3D::WorldObject3D()
{
m_model = NULL;
m_body = NULL;
m_compoundShape = NULL;
m_mass = 0;
m_friction = 1.0f;
m_restitution = 0.0f;
m_shader = NULL;
posX = 0;
posY = 0;
posZ = 0;
rotX = 0;
rotY = 0;
rotZ = 0;
}
WorldObject3D::~WorldObject3D()
{
}
void WorldObject3D::Render(D3DXMATRIX camera, D3DXMATRIX projection)
{
D3DXMatrixIdentity(&m_translateMatrix);
D3DXMatrixTranslation(&m_translateMatrix, posX, posY, posZ);
D3DXMatrixRotationX(&m_rotationMatrix[0], rotX);
D3DXMatrixRotationY(&m_rotationMatrix[1], rotY);
D3DXMatrixRotationZ(&m_rotationMatrix[2], rotZ);
m_worldMatrix = m_translateMatrix * m_rotationMatrix[0] * m_rotationMatrix[1] * m_rotationMatrix[2];
if (m_model->m_objModel->Subsets > 0)
{
for (int i = 0; i < m_model->m_objModel->Subsets; i++)
{
if (m_model->m_materials[m_model->m_objModel->SubsetMaterialID[i]].HasDiffTexture)
{
m_currMaterial.HasDiffuseTexture = true;
m_currMaterial.DiffuseColor = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
ID3D11ShaderResourceView *view = Engine::GetEngine()->GetWorld()->GetRSM()->GetTextureVector()[m_model->m_materials[m_model->m_objModel->SubsetMaterialID[i]].DiffuseTextureID - 1]->GetTexture()->GetTexture();
m_shader->GetShader()->SetShaderParameters(m_model->m_deviceContext, view, 1);
}
m_shader->GetShader()->SetShaderParameters(m_model->m_deviceContext, m_worldMatrix, camera, projection, m_currMaterial, Engine::GetEngine()->GetWorld()->GetLightVec()[0]->GetLightDesc());
int indexStart = m_model->m_objModel->SubsetIndexStart[i];
int indexDrawAmount = m_model->m_objModel->SubsetIndexStart[i + 1] - indexStart;
m_model->m_vertexBuffer->SetShader(m_shader);
m_model->m_vertexBuffer->Render(m_model->m_deviceContext, indexDrawAmount, indexStart);
}
}
}
void WorldObject3D::SetShader(ResourceShader* shader)
{
m_shader = shader;
}
void WorldObject3D::SetModel3D(Model3D* modelRef)
{
m_model = modelRef;
}
void WorldObject3D::SetPosition(float X, float Y, float Z)
{
posX = X;
posY = Y;
posZ = Z;
}
void WorldObject3D::SetRotation(float X, float Y, float Z)
{
rotX = X;
rotY = Y;
rotZ = Z;
}
void WorldObject3D::GetPosition(float& X, float& Y, float& Z)
{
X = posX;
Y = posY;
Z = posZ;
}
void WorldObject3D::GetRotation(float& X, float& Y, float& Z)
{
X = rotX;
Y = rotY;
Z = rotZ;
}
void WorldObject3D::SetType(int type)
{
m_type = type;
}
int WorldObject3D::GetType()
{
return m_type;
}
void WorldObject3D::SetMass(float mass)
{
m_mass = mass;
}
float WorldObject3D::GetMass()
{
return m_mass;
}
void WorldObject3D::SetFriction(float friction)
{
m_friction = friction;
}
float WorldObject3D::GetFriction()
{
return m_friction;
}
void WorldObject3D::SetRestitution(float restitution)
{
m_restitution = restitution;
}
float WorldObject3D::GetRestitution()
{
return m_restitution;
}
void WorldObject3D::InitializePhysics()
{
if (m_type == SPHERE_TYPE)
{
float radius;
float x, y, z;
x = m_model->m_vertices[0].position.x;
y = m_model->m_vertices[0].position.y;
z = m_model->m_vertices[0].position.z;
radius = max(x, y);
if (radius == x)
radius = max(x, z);
else
radius = max(y, z);
btSphereShape* sphere = new btSphereShape(btScalar(radius));
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(0, 0, 0));
m_compoundShape = new btCompoundShape();
m_compoundShape->addChildShape(tr, sphere);
}
else if (m_type == MESH_TYPE)
{
int sizeOfConvexHull = 5;
for (size_t i = sizeOfConvexHull; i <= m_model->m_vertices.size(); i += sizeOfConvexHull)
{
if (i > m_model->m_vertices.size())
i = m_model->m_vertices.size();
m_convexArray.push_back(new btConvexHullShape());
for (size_t j = i - 1; j >= i - sizeOfConvexHull; j--)
{
m_convexArray.back()->addPoint(btVector3(m_model->m_vertices[j].position.x, m_model->m_vertices[j].position.y, m_model->m_vertices[j].position.z));
}
}
btTransform trans;
trans.setIdentity();
trans.setOrigin(btVector3(0, 0, 0));
m_compoundShape = new btCompoundShape();
for (size_t i = 0; i < m_convexArray.size(); i++)
m_compoundShape->addChildShape(trans, m_convexArray[i]);
}
else if (m_type == PLANE_TYPE)
{
btStaticPlaneShape* plane = new btStaticPlaneShape(btVector3(m_model->m_vertices[0].normal.x, m_model->m_vertices[0].normal.y, m_model->m_vertices[0].normal.z), 0);
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(0, 0, 0));
m_compoundShape = new btCompoundShape();
m_compoundShape->addChildShape(tr, plane);
}
btVector3 inertia = btVector3(0, 0, 0);
if (m_mass != 0)
m_compoundShape->calculateLocalInertia(m_mass, inertia);
btTransform positionMatrix;
positionMatrix.setIdentity();
positionMatrix.setOrigin(btVector3(posX, posY, posZ));
btQuaternion quat;
quat.setEulerZYX(rotX, rotY, rotZ);
positionMatrix.setRotation(quat);
btMotionState* motionState = new btDefaultMotionState(positionMatrix);
m_body = new btRigidBody(m_mass, motionState, m_compoundShape, inertia);
m_body->setFriction(m_friction);
m_body->setRestitution(m_restitution);
}
btRigidBody* WorldObject3D::GetRigidBody()
{
return m_body;
}
string WorldObject3D::GetName()
{
return m_model->GetName();
}
Code: Select all
#ifndef _WORLD_H
#define _WORLD_H
#include "Camera.h"
#include "Light.h"
#include "ResourceManager.h"
#include "WorldObject3D.h"
#include "btBulletDynamicsCommon.h"
class World
{
private:
Camera* m_camera;
vector<Light*> m_lights;
ResourceManager* m_rsManager;
btDiscreteDynamicsWorld* m_dynamicsWorld;
btDefaultCollisionConfiguration* m_collisionConfiguration;
btCollisionDispatcher* m_dispatcher;
btBroadphaseInterface* m_overlappingPairCache;
btSequentialImpulseConstraintSolver* m_solver;
vector<WorldObject3D*> m_sceneObjects;
public:
World();
~World();
void StepSimulation(float time);
void InitDynamicsWorld();
void AddLightSource(UINT type, D3DXVECTOR4 color, bool enabled, float intense, float range, float angle, D3DXVECTOR3 pos, D3DXVECTOR3 dir);
bool AddObjectToScene(string name, int type, float mass = 0.0f, float friction = 1.0f, float restitution = 0.0f, float posX = 0.0f, float posY = 0.0f, float posZ = 0.0f, float rotX = 0.0f, float rotY = 0.0f, float rotZ = 0.0f);
bool DeleteObjectFromScene(int ID);
bool DeleteObjectFromScene(string name);
vector<WorldObject3D*>& GetSceneObjectsVector();
size_t GetSceneObjectsCount();
btDiscreteDynamicsWorld* GetDynamicsWorld();
ResourceManager* GetRSM();
Camera* GetCamera();
vector<Light*>& GetLightVec();
};
#endif
Code: Select all
#include "World.h"
World::World()
{
m_camera = new Camera();
m_rsManager = ResourceManager::GetInstance();
m_dynamicsWorld = NULL;
m_collisionConfiguration = NULL;
m_dispatcher = NULL;
m_overlappingPairCache = NULL;
m_solver = NULL;
}
World::~World()
{
if (m_camera)
{
delete m_camera;
m_camera = 0;
}
if (m_rsManager)
{
delete m_rsManager;
m_rsManager = 0;
}
for (int i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
delete body->getMotionState();
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
if (m_collisionConfiguration)
{
delete m_collisionConfiguration;
m_collisionConfiguration = 0;
}
if (m_dispatcher)
{
delete m_dispatcher;
m_dispatcher = 0;
}
if (m_overlappingPairCache)
{
delete m_overlappingPairCache;
m_overlappingPairCache = 0;
}
if (m_solver)
{
delete m_solver;
m_solver = 0;
}
if (m_dynamicsWorld)
{
delete m_dynamicsWorld;
m_dynamicsWorld = 0;
}
}
Camera* World::GetCamera()
{
return m_camera;
}
ResourceManager* World::GetRSM()
{
return m_rsManager;
}
vector<Light*>& World::GetLightVec()
{
return m_lights;
}
void World::AddLightSource(UINT type, D3DXVECTOR4 color, bool enabled, float intense, float range, float angle, D3DXVECTOR3 pos, D3DXVECTOR3 dir)
{
LightDesc desc;
ZeroMemory(&desc, sizeof(LightDesc));
desc.Color = color;
desc.Enabled = enabled;
desc.Intensity = intense;
desc.Range = range;
desc.SpotlightAngle = angle;
desc.Type = type;
desc.DirectionVS = dir;
desc.PositionVS = pos;
Light* light = new Light();
light->SetLightDesc(desc);
m_lights.push_back(light);
}
btDiscreteDynamicsWorld* World::GetDynamicsWorld()
{
return m_dynamicsWorld;
}
void World::InitDynamicsWorld()
{
m_collisionConfiguration = new btDefaultCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_overlappingPairCache = new btDbvtBroadphase();
m_solver = new btSequentialImpulseConstraintSolver;
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_overlappingPairCache, m_solver, m_collisionConfiguration);
m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
}
void World::StepSimulation(float time)
{
m_dynamicsWorld->stepSimulation(time, 10);
for (int i = 0; i < m_dynamicsWorld->getNumCollisionObjects(); i++)
{
if (m_dynamicsWorld->getNumCollisionObjects() != m_sceneObjects.size())
{
cout << "[World] - getNumCollisionObjects() != m_sceneObjects.size()" << endl;
return;
}
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
btTransform trans;
if (body && body->getMotionState())
body->getMotionState()->getWorldTransform(trans);
else
trans = obj->getWorldTransform();
m_sceneObjects[i]->SetPosition(trans.getOrigin().getX(), trans.getOrigin().getY(), trans.getOrigin().getZ());
btQuaternion quat = trans.getRotation();
float X, Y, Z;
quat.getEulerZYX(Z, Y, X);
m_sceneObjects[i]->SetRotation(X, Y, Z);
}
}
bool World::AddObjectToScene(string name, int type, float mass, float friction, float restitution, float posX, float posY, float posZ, float rotX, float rotY, float rotZ)
{
if (GetRSM()->GetObjectsCount() == 0)
{
cout << "[World] - Error: there are no objects loaded by RSM" << endl;
return false;
}
for (size_t i = 0; i < GetRSM()->GetObjectsCount(); i++)
{
if (strcmp(GetRSM()->GetObjectsVector()[i]->GetName().c_str(), name.c_str()) == 0)
{
WorldObject3D* obj = new WorldObject3D();
obj->SetModel3D(GetRSM()->GetObjectsVector()[i]);
obj->SetShader(GetRSM()->GetShadersVector()[0]);
obj->SetPosition(posX, posY, posZ);
obj->SetRotation(rotX, rotY, rotZ);
obj->SetMass(mass);
obj->SetFriction(friction);
obj->SetRestitution(restitution);
obj->SetType(type);
obj->InitializePhysics();
m_sceneObjects.push_back(obj);
m_dynamicsWorld->addRigidBody(obj->GetRigidBody());
cout << "[World] - Created object '" << name << "' ID: " << m_dynamicsWorld->getNumCollisionObjects() << endl;
return true;
}
}
cout << "[World] - Error: RSM has no object with name '" << name << "'" << endl;
return false;
}
bool World::DeleteObjectFromScene(int ID)
{
if (ID > m_sceneObjects.size())
{
cout << "[World] - Error: there is no object with ID " << ID << endl;
return false;
}
else if (m_sceneObjects[ID] != 0)
{
m_dynamicsWorld->removeRigidBody(m_sceneObjects[ID]->GetRigidBody());
m_sceneObjects.erase(m_sceneObjects.begin() + ID);
}
else
{
cout << "[World] - Error: there is no object with ID " << ID << endl;
return false;
}
return true;
}
bool World::DeleteObjectFromScene(string name)
{
int count = 0;
for (size_t i = 0; i < m_sceneObjects.size(); i++)
{
if (m_sceneObjects[i]->GetName() == name)
{
m_dynamicsWorld->removeRigidBody(m_sceneObjects[i]->GetRigidBody());
m_sceneObjects.erase(m_sceneObjects.begin() + i);
count++;
}
}
if (count == 0)
{
cout << "[World] - Error: there are no objects with name '" << name << "'" << endl;
return false;
}
return true;
}
size_t World::GetSceneObjectsCount()
{
return m_sceneObjects.size();
}
vector<WorldObject3D*>& World::GetSceneObjectsVector()
{
return m_sceneObjects;
}
Code: Select all
void Engine::Render()
{
m_graphics->BeginScene(0.0f, 0.3f, 0.0f, 1.0f);
for (size_t i = 0; i < m_world->GetSceneObjectsCount(); i++)
m_world->GetSceneObjectsVector()[i]->Render(m_world->GetCamera()->GetViewMatrix(), m_world->GetCamera()->GetProjectionMatrix());
m_graphics->EndScene();
}