1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-26 12:22:41 +01:00

Added initial collision model loading

Doesn't support all types of data yet, just spheres and boxes.
This commit is contained in:
Daniel Evans 2013-07-21 05:12:27 +01:00
parent bf045af1c1
commit 6969759c9b
10 changed files with 245 additions and 14 deletions

View File

@ -18,8 +18,9 @@ add_library(renderware
# Rendering
GTARenderer.cpp
DebugDraw.cpp
)
target_link_libraries(renderware sfml-window)
include_directories(include)
include_directories(include /usr/include/bullet)

119
framework2/DebugDraw.cpp Normal file
View File

@ -0,0 +1,119 @@
#include "renderwure/render/DebugDraw.hpp"
#define GLEW_STATIC
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
DebugDraw::DebugDraw()
{
glGenBuffers(1, &vbo);
glGenVertexArrays(1, &vao);
glGenTextures(1, &texture);
}
DebugDraw::~DebugDraw()
{
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vbo);
glDeleteTextures(1, &texture);
}
void DebugDraw::drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
float img[] = {color.getX(), color.getY(), color.getZ()};
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB, 1, 1,
0, GL_RGB, GL_FLOAT, img
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
float verts[] = {
from.getX(), from.getY(), from.getZ(),
to.getX(), to.getY(), to.getZ(),
};
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
GLint uniModel = glGetUniformLocation(shaderProgram, "model");
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STREAM_DRAW);
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
glm::mat4 model;
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));
glDrawArrays(GL_LINES, 0, 2);
}
void DebugDraw::drawTriangle(const btVector3 &a, const btVector3 &b, const btVector3 &c, const btVector3 &color, btScalar alpha)
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
float img[] = {color.getX(), color.getY(), color.getZ()};
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB, 1, 1,
0, GL_RGB, GL_FLOAT, img
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
GLint uniModel = glGetUniformLocation(shaderProgram, "model");
float verts[] = {
a.getX(), a.getY(), a.getZ(),
b.getX(), b.getY(), b.getZ(),
c.getX(), c.getY(), c.getZ(),
};
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STREAM_DRAW);
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
glm::mat4 model;
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void DebugDraw::drawContactPoint(const btVector3 &pointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color)
{
}
void DebugDraw::reportErrorWarning(const char *warningString)
{
std::cerr << warningString << std::endl;
}
void DebugDraw::draw3dText(const btVector3 &location, const char *textString)
{
std::cout << textString << std::endl;
}
void DebugDraw::setDebugMode(int debugMode)
{
this->debugMode = debugMode;
}
int DebugDraw::getDebugMode() const
{
return debugMode;
}

View File

@ -165,16 +165,10 @@ void GTAData::loadCOL(const size_t zone, const std::string& name)
{
LoaderCOL col;
auto lowername = name;
for(size_t t = 0; t < lowername.size(); ++t)
{
lowername[t] = tolower(lowername[t]);
if(lowername[t] == '\\') {
lowername[t] = '/';
}
}
std::string realPath = fixPath(name);
realPath = findPathRealCase(datpath, realPath);
if(col.load(datpath + "/" + name)) {
if(col.load(realPath)) {
for( size_t i = 0; i < col.instances.size(); ++i ) {
collisions[std::string(col.instances[i].header.name)] = std::move(std::unique_ptr<CollisionInstance>( new CollisionInstance(col.instances[i]) ));
}

View File

@ -10,6 +10,12 @@ GTAEngine::GTAEngine(const std::string& path)
bool GTAEngine::load()
{
collisionConfig = new btDefaultCollisionConfiguration;
collisionDispatcher = new btCollisionDispatcher(collisionConfig);
broadphase = new btDbvtBroadphase();
solver = new btSequentialImpulseConstraintSolver;
dynamicsWorld = new btDiscreteDynamicsWorld(collisionDispatcher, broadphase, solver, collisionConfig);
gameData.load();
// Loade all of the IDEs.
@ -113,6 +119,47 @@ bool GTAEngine::placeItems(const std::string& name)
gameData.loadTXD(oi->second->textureName + ".txd");
}
btRigidBody* body = nullptr;
auto phyit = gameData.collisions.find(oi->second->modelName);
if( phyit != gameData.collisions.end() ) {
btCompoundShape* cmpShape = new btCompoundShape;
btDefaultMotionState* msta = new btDefaultMotionState;
msta->setWorldTransform(btTransform(
btQuaternion(
inst.rotX, inst.rotY, inst.rotZ, inst.rotW
),
btVector3(
inst.posX, inst.posY, inst.posZ
)
));
btRigidBody::btRigidBodyConstructionInfo info(0.f, msta, cmpShape);
CollisionInstance& physInst = *phyit->second.get();
// Boxes
for( size_t i = 0; i < physInst.boxes.size(); ++i ) {
CollTBox& box = physInst.boxes[i];
auto size = (box.max - box.min) / 2.f;
auto mid = (box.min + box.max) / 2.f;
btCollisionShape* bshape = new btBoxShape( btVector3(size.x, size.y, size.z) );
btTransform t(btQuaternion(0.f, 0.f, 0.f, 1.f), btVector3(mid.x, mid.y, mid.z));
cmpShape->addChildShape(t, bshape);
}
// Spheres
for( size_t i = 0; i < physInst.spheres.size(); ++i ) {
CollTSphere& sphere = physInst.spheres[i];
btCollisionShape* sshape = new btSphereShape(sphere.radius);
btTransform t(btQuaternion(0.f, 0.f, 0.f, 1.f), btVector3(sphere.center.x, sphere.center.y, sphere.center.z));
cmpShape->addChildShape(t, sshape);
}
// Todo: other shapes.
body = new btRigidBody(info);
//body->setWorldTransform();
dynamicsWorld->addRigidBody(body);
}
objectInstances.push_back({ inst, oi->second });
}
else {

View File

@ -7,6 +7,7 @@
#include <renderwure/loaders/LoaderDFF.hpp>
#include <renderwure/loaders/LoaderIDE.hpp>
#include <renderwure/loaders/WeatherLoader.hpp>
#include <renderwure/loaders/LoaderCOL.hpp>
#include <string>
#include <map>
@ -148,6 +149,11 @@ public:
*/
std::map<std::string, std::unique_ptr<Model>> models;
/**
* Loaded collision proxies
*/
std::map<std::string, std::unique_ptr<CollisionInstance>> collisions;
/**
* Water Rectangles
*/

View File

@ -8,6 +8,9 @@
#include <glm/glm.hpp>
#include <btBulletDynamicsCommon.h>
#include <btBulletCollisionCommon.h>
#include <vector>
#include <queue>
#include <random>
@ -149,6 +152,16 @@ public:
* Randomness Engine
*/
std::default_random_engine randomEngine;
/**
* Bullet
*/
btDefaultCollisionConfiguration* collisionConfig;
btCollisionDispatcher* collisionDispatcher;
btBroadphaseInterface* broadphase;
btSequentialImpulseConstraintSolver* solver;
btDiscreteDynamicsWorld* dynamicsWorld;
};
#endif

View File

@ -1,4 +1,3 @@
#pragma once
#ifndef _LOADERIPL_HPP_
#define _LOADERIPL_HPP_

View File

@ -0,0 +1,31 @@
#pragma once
#include <LinearMath/btIDebugDraw.h>
#define GLEW_STATIC
#include <GL/glew.h>
class DebugDraw : public btIDebugDraw
{
public:
DebugDraw();
~DebugDraw();
void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color);
void drawTriangle(const btVector3 &a, const btVector3 &b, const btVector3 &c, const btVector3 &color, btScalar alpha);
void drawContactPoint(const btVector3 &pointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color);
void reportErrorWarning(const char *warningString);
void draw3dText(const btVector3 &location, const char *textString);
void setDebugMode(int debugMode);
int getDebugMode() const;
void setShaderProgram(GLuint shaderProgram) {
this->shaderProgram = shaderProgram;
}
protected:
int debugMode;
GLuint shaderProgram;
GLuint vbo, vao, texture;
};

View File

@ -1,7 +1,7 @@
add_executable(viewer main.cpp)
include_directories(../framework2/include)
include_directories(../framework2/include /usr/include/bullet)
target_link_libraries( viewer renderware sfml-graphics sfml-window sfml-system GL GLEW )
target_link_libraries( viewer renderware sfml-graphics sfml-window sfml-system GL GLEW BulletDynamics BulletCollision LinearMath )
install(TARGETS viewer RUNTIME DESTINATION bin)

View File

@ -3,6 +3,7 @@
#include <renderwure/engine/GTAEngine.hpp>
#include <renderwure/loaders/LoaderDFF.hpp>
#include <renderwure/render/DebugDraw.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
@ -28,6 +29,7 @@ glm::vec2 plyLook;
float moveSpeed = 20.0f;
bool inFocus = false;
bool mouseGrabbed = true;
bool showPhysics = false;
sf::Font font;
@ -45,6 +47,9 @@ void handleEvent(sf::Event &event)
case sf::Keyboard::M:
mouseGrabbed = ! mouseGrabbed;
break;
case sf::Keyboard::P:
showPhysics = ! showPhysics;
break;
default: break;
}
break;
@ -92,6 +97,11 @@ void init(std::string gtapath)
spawnPos += glm::vec3(5, 0, 0);
if((k++ % 4) == 0) { spawnPos += glm::vec3(-20, -15, 0); }
}
DebugDraw* debg = new DebugDraw;
debg->setShaderProgram(gta->renderer.worldProgram);
debg->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
gta->dynamicsWorld->setDebugDrawer(debg);
}
void update(float dt)
@ -152,7 +162,18 @@ void render()
glEnable(GL_DEPTH_TEST);
//glEnable(GL_CULL_FACE);
gta->renderer.renderWorld(gta);
if( showPhysics) {
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
glUseProgram(gta->renderer.worldProgram);
glm::mat4 proj = gta->renderer.camera.frustum.projection();
glm::mat4 view = gta->renderer.camera.frustum.view;
glUniformMatrix4fv(gta->renderer.uniView, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(gta->renderer.uniProj, 1, GL_FALSE, glm::value_ptr(proj));
gta->dynamicsWorld->debugDrawWorld();
}
else {
gta->renderer.renderWorld(gta);
}
window.resetGLStates();