initial mesh and physics support

This commit is contained in:
gmueller
2011-01-19 23:20:08 +01:00
parent 6fcb3dbff4
commit 12153ffbea
16 changed files with 4231 additions and 20 deletions

View File

@ -71,15 +71,30 @@ void draw_team(Team *team) {
gluSphere(quadratic, 50.f, 32, 32);
glPopMatrix();
}
void draw_player(player_t *player) {
GLuint wallTex = 0;
void Client::drawPlayer(player_t *player) {
if (player->status == 0)
return;
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, player->team->color);
glMatrixMode( GL_MODELVIEW);
glPushMatrix();
glTranslated(player->x, player->y, player->z);
gluSphere(quadratic, 10.f, 32, 32);
glEnableClientState( GL_VERTEX_ARRAY);
glEnableClientState( GL_TEXTURE_COORD_ARRAY);
glEnableClientState( GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, game.shipMesh->vertex_size,
game.shipMesh->vertices);
glTexCoordPointer(2, GL_FLOAT, game.shipMesh->vertex_size,
game.shipMesh->vertices + 3);
glNormalPointer(GL_FLOAT, game.shipMesh->vertex_size,
game.shipMesh->vertices + 5);
for (size_t i = 0; i < game.shipMesh->object_count; i++) {
glDrawElements(GL_TRIANGLES, game.shipMesh->objects[i].face_count * 3,
GL_UNSIGNED_SHORT,
&game.shipMesh->faces[game.shipMesh->objects[i].face_index]);
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
}
@ -152,9 +167,7 @@ void setup_explosion() {
textures[4]);
}
GLuint wallTex = 0;
void draw_box() {
void Client::drawLevel() {
if (wallTex == 0) {
glGenTextures(1, &wallTex);
@ -180,13 +193,14 @@ void draw_box() {
//glDisable( GL_DEPTH_TEST);
// glEnable( GL_LIGHTING);
// glDisable( GL_BLEND);
glColor4f(1, 1, 1, 1);
glMatrixMode( GL_MODELVIEW);
glPushMatrix();
#if 0
glTranslated(2000.0, 0.0, 0.0);
//glScaled(5000.0f, 5000.0f, 5000.0f);
float s = 3000.0f, t = 10.0f;
// Just in case we set all vertices to white.
glColor4f(1, 1, 1, 1);
// Render the front quad
glBegin( GL_QUADS);
@ -278,6 +292,24 @@ void draw_box() {
glTexCoord2f(t, 0);
glVertex3f(s, -s, -s);
glEnd();
#else
glEnableClientState( GL_VERTEX_ARRAY);
glEnableClientState( GL_TEXTURE_COORD_ARRAY);
glEnableClientState( GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, game.levelMesh->vertex_size,
game.levelMesh->vertices);
glTexCoordPointer(2, GL_FLOAT, game.levelMesh->vertex_size,
game.levelMesh->vertices + 3);
glNormalPointer(GL_FLOAT, game.levelMesh->vertex_size,
game.levelMesh->vertices + 5);
for (size_t i = 0; i < game.levelMesh->object_count; i++) {
glDrawElements(GL_TRIANGLES, game.levelMesh->objects[i].face_count * 3,
GL_UNSIGNED_SHORT,
&game.levelMesh->faces[game.levelMesh->objects[i].face_index]);
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#endif
// Restore enable bits and matrix
glPopAttrib();
@ -450,7 +482,7 @@ void Client::update() {
draw_team(&game.teams[i]);
for (size_t i = 0; i < GAME_PLAYER_COUNT; i++)
draw_player(&game.player[i]);
drawPlayer(&game.player[i]);
for (size_t i = 0; i < GAME_BOMB_COUNT; i++)
draw_bomb(&game.bomb[i]);
@ -458,7 +490,7 @@ void Client::update() {
for (size_t i = 0; i < GAME_POINT_COUNT; i++)
draw_point(&game.point[i]);
draw_box();
drawLevel();
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);

View File

@ -33,6 +33,9 @@ private:
void loadConsoleFont();
void onExplosion(double x, double y, double z);
void drawLevel();
void drawPlayer(player_t *player);
};
#endif /* CLIENT_H_ */

View File

@ -9,11 +9,11 @@ add_library( common
)
add_dependencies( common
enet pugixml bullet
enet pugixml bullet trimeshloader
)
target_link_libraries(common
enet pugixml bullet
enet pugixml bullet trimeshloader
)
if (WIN32)

View File

@ -4,6 +4,24 @@
#include <math.h>
#include <stdlib.h>
#include "btBulletDynamicsCommon.h"
Game::Game() :
collisionConfiguration(new btDefaultCollisionConfiguration()), dispatcher(
new btCollisionDispatcher(collisionConfiguration.get())),
overlappingPairCache(new btDbvtBroadphase), solver(
new btSequentialImpulseConstraintSolver), dynamicsWorld(
new btDiscreteDynamicsWorld(dispatcher.get(),
overlappingPairCache.get(), solver.get(),
collisionConfiguration.get())), levelMesh(0) {
}
Game::~Game() {
tlDeleteTrimesh(levelMesh);
tlDeleteTrimesh(shipMesh);
}
double rand2() {
float u = (float) rand() / (float) RAND_MAX;
return 2.0 * (u - 0.5);
@ -76,9 +94,61 @@ void setup_bomb(bomb_t *bomb) {
bomb->z = 0.0;
}
void Game::setupLevel() {
dynamicsWorld->setGravity(btVector3(0,-10,0));
levelMesh = tlLoadTrimesh("data/level.obj", TL_FVF_XYZ | TL_FVF_UV
| TL_FVF_NORMAL);
btIndexedMesh im;
im.m_numTriangles = levelMesh->face_count;
im.m_triangleIndexBase = (unsigned char *) levelMesh->faces;
im.m_triangleIndexStride = sizeof(unsigned short) * 3;
im.m_numVertices = levelMesh->vertex_count;
im.m_vertexBase = (unsigned char *) levelMesh->vertices;
im.m_vertexStride = levelMesh->vertex_size;
levelVertexArray.reset(new btTriangleIndexVertexArray);
levelVertexArray->addIndexedMesh(im, PHY_SHORT);
btBvhTriangleMeshShape *_levelShape = new btBvhTriangleMeshShape(
levelVertexArray.get(), true);
levelShape.reset(_levelShape);
btVector3 localInertia(0, 0, 0);
btRigidBody::btRigidBodyConstructionInfo rbInfo(0, 0, _levelShape,
localInertia);
levelBody.reset(new btRigidBody(rbInfo));
dynamicsWorld->addRigidBody(levelBody.get());
// load ship
shipMesh = tlLoadTrimesh("data/ship.obj", TL_FVF_XYZ | TL_FVF_UV
| TL_FVF_NORMAL);
btIndexedMesh sim;
sim.m_numTriangles = shipMesh->face_count;
sim.m_triangleIndexBase = (unsigned char *) shipMesh->faces;
sim.m_triangleIndexStride = sizeof(unsigned short) * 3;
sim.m_numVertices = shipMesh->vertex_count;
sim.m_vertexBase = (unsigned char *) shipMesh->vertices;
sim.m_vertexStride = shipMesh->vertex_size;
shipVertexArray.reset(new btTriangleIndexVertexArray);
shipVertexArray->addIndexedMesh(im, PHY_SHORT);
btBvhTriangleMeshShape *_shipShape = new btBvhTriangleMeshShape(
shipVertexArray.get(), true);
shipShape.reset(_shipShape);
}
void Game::setup() {
size_t i;
setupLevel();
teams.resize(2);
for (i = 0; i < teams.size(); i++)
setup_team(&teams[i], i);
@ -129,6 +199,22 @@ player_t *Game::spawn_player(Team *team) {
player->status = 1;
player->id = max_player_id++;
reset_player(player);
if (player->body.get() == 0) {
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(player->x, player->y, player->z));
btScalar mass(1.f);
btVector3 localInertia(0, 0, 0);
shipShape->calculateLocalInertia(mass, localInertia);
player->state.reset(new btDefaultMotionState());
player->state->setWorldTransform(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,
player->state.get(), shipShape.get(), localInertia);
player->body.reset(new btRigidBody(rbInfo));
dynamicsWorld->addRigidBody(player->body.get());
}
return player;
}
@ -154,15 +240,20 @@ void Game::update_players(double dt) {
player_t *p = &player[i];
if (p->status == 0)
return;
if (p->vx > 1000.0)
p->vx = 1000.0;
if (p->vy > 1000.0)
p->vy = 1000.0;
if (p->vz > 1000.0)
p->vz = 1000.0;
p->x += p->vx * dt;
p->y += p->vy * dt;
p->z += p->vz * dt;
// if (p->vx > 1000.0)
// p->vx = 1000.0;
// if (p->vy > 1000.0)
// p->vy = 1000.0;
// if (p->vz > 1000.0)
// p->vz = 1000.0;
// p->x += p->vx * dt;
// p->y += p->vy * dt;
// p->z += p->vz * dt;
btTransform wt;
p->state->getWorldTransform(wt);
p->x = wt.getOrigin().x();
p->y = wt.getOrigin().y();
p->z = wt.getOrigin().z();
double distance2 = pow(p->x - p->team->x, 2)
+ pow(p->y - p->team->y, 2) + pow(p->z - p->team->z, 2);
@ -296,6 +387,8 @@ void Game::update_points(double dt) {
}
void Game::update(double dt) {
dynamicsWorld->stepSimulation(dt,10);
const double delta = 1. / 120.;
updateTime += dt;
while (updateTime > delta) {

View File

@ -3,8 +3,21 @@
#include "common.h"
#include "sigslot.h"
#include "trimeshloader.h"
#include <vector>
#include <memory>
// bullet forward declatations
class btDefaultCollisionConfiguration;
class btCollisionDispatcher;
class btBroadphaseInterface;
class btSequentialImpulseConstraintSolver;
class btDiscreteDynamicsWorld;
class btCollisionShape;
class btTriangleIndexVertexArray;
class btRigidBody;
class btMotionState;
typedef struct Team Team;
typedef struct player_t player_t;
@ -22,6 +35,8 @@ struct player_t {
double vx, vy, vz;
Team *team;
uint16_t points;
std::auto_ptr<btMotionState> state;
std::auto_ptr<btRigidBody> body;
};
struct bomb_t {
@ -47,6 +62,9 @@ public:
class Game {
public:
Game();
~Game();
std::vector<Team> teams;
player_t player[GAME_PLAYER_COUNT];
bomb_t bomb[GAME_BOMB_COUNT];
@ -76,6 +94,25 @@ public:
void explode_bomb(bomb_t *bomb);
void update_point(point_t *point);
size_t active_team_players(Team *team);
tlTrimesh *levelMesh;
tlTrimesh *shipMesh;
private:
void setupLevel();
const std::auto_ptr<btDefaultCollisionConfiguration> collisionConfiguration;
const std::auto_ptr<btCollisionDispatcher> dispatcher;
const std::auto_ptr<btBroadphaseInterface> overlappingPairCache;
const std::auto_ptr<btSequentialImpulseConstraintSolver> solver;
const std::auto_ptr<btDiscreteDynamicsWorld> dynamicsWorld;
std::auto_ptr<btTriangleIndexVertexArray> levelVertexArray;
std::auto_ptr<btCollisionShape> levelShape;
std::auto_ptr<btRigidBody> levelBody;
std::auto_ptr<btTriangleIndexVertexArray> shipVertexArray;
std::auto_ptr<btCollisionShape> shipShape;
};
#endif