diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 9869ca5..2fcdd46 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -388,8 +388,7 @@ void Client::initialize(Arguments &arg) { // Initialise GLFW if (!glfwInit()) { - fprintf(stderr, "Failed to initialize GLFW\n"); - exit(EXIT_FAILURE); + throw("Failed to initialize GLFW"); } setup_opengl(); @@ -401,6 +400,8 @@ void Client::initialize(Arguments &arg) { if (isMaster()) { Team *team = game.getTeam(0); game.local_player = game.spawn_player(team); + std::cout << "[Game] local player " << game.local_player->id + << std::endl; } size_t i; @@ -478,17 +479,17 @@ void Client::update() { glEnable( GL_LIGHTING); glEnable( GL_CULL_FACE); glDisable( GL_TEXTURE_2D); - for (size_t i = 0; i < game.teams.size(); i++) - draw_team(&game.teams[i]); +// for (size_t i = 0; i < game.teams.size(); i++) +// draw_team(&game.teams[i]); for (size_t i = 0; i < GAME_PLAYER_COUNT; i++) drawPlayer(&game.player[i]); - for (size_t i = 0; i < GAME_BOMB_COUNT; i++) - draw_bomb(&game.bomb[i]); - - for (size_t i = 0; i < GAME_POINT_COUNT; i++) - draw_point(&game.point[i]); +// for (size_t i = 0; i < GAME_BOMB_COUNT; i++) +// draw_bomb(&game.bomb[i]); +// +// for (size_t i = 0; i < GAME_POINT_COUNT; i++) +// draw_point(&game.point[i]); drawLevel(); diff --git a/src/common/Application.cpp b/src/common/Application.cpp index 3ff5e6d..56bad52 100644 --- a/src/common/Application.cpp +++ b/src/common/Application.cpp @@ -56,7 +56,7 @@ void Application::initialize(Arguments &arg) { if (host.empty()) { setMaster(true); } else { - setMaster(true); + setMaster(false); } // start @@ -77,7 +77,7 @@ void Application::update() { // network stuff network.service(master ? 1 : 0); - game.update(dt); + game.update(time, dt); if (master && gameUpdateSchudule.next(time)) { network.sendGameUpdates(); } diff --git a/src/common/Game.cpp b/src/common/Game.cpp index 1c2e3b2..4f69559 100644 --- a/src/common/Game.cpp +++ b/src/common/Game.cpp @@ -4,17 +4,21 @@ #include #include +#include + #include "btBulletDynamicsCommon.h" Game::Game() : - collisionConfiguration(new btDefaultCollisionConfiguration()), dispatcher( + local_player(0), 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) { - + slaveUpdate.setInterval(1. / 60.); + slaveUpdate.setExact(true); } Game::~Game() { @@ -33,7 +37,7 @@ void reset_team(Team *team) { void reset_player(player_t *player) { if (player->team) { - player->x = player->team->x + 100; + player->x = player->team->x; player->y = player->team->y; player->z = player->team->z; } else { @@ -60,9 +64,9 @@ void setup_team(Team *team, uint8_t id) { team->color[2] = .5f + .5f * (id & (1 << 2)); team->color[3] = 1.0f; - team->x = 2000.0 * (id & (1 << 0)); - team->y = 2000.0 * (id & (1 << 1)); - team->z = 2000.0 * (id & (1 << 2)); + team->x = 0.0; + team->y = 0; + team->z = 0; team->points = 0; team->wins = 0; @@ -94,9 +98,7 @@ void setup_bomb(bomb_t *bomb) { bomb->z = 0.0; } -void Game::setupLevel() { - dynamicsWorld->setGravity(btVector3(0,-10,0)); - +void Game::loadLevelShape() { levelMesh = tlLoadTrimesh("data/level.obj", TL_FVF_XYZ | TL_FVF_UV | TL_FVF_NORMAL); @@ -108,40 +110,64 @@ void Game::setupLevel() { im.m_numVertices = levelMesh->vertex_count; im.m_vertexBase = (unsigned char *) levelMesh->vertices; im.m_vertexStride = levelMesh->vertex_size; + im.m_vertexType = PHY_FLOAT; levelVertexArray.reset(new btTriangleIndexVertexArray); levelVertexArray->addIndexedMesh(im, PHY_SHORT); btBvhTriangleMeshShape *_levelShape = new btBvhTriangleMeshShape( - levelVertexArray.get(), true); + levelVertexArray.get(), true, true); + btVector3 center; + btScalar radius; + _levelShape->getBoundingSphere(center, radius); + std::cout << center.x() << " " << center.y() << " " << center.y() << ", " + << radius << std::endl; 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 +void Game::loadShipShape() { 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; - 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; + sim.m_vertexType = PHY_FLOAT; - 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(sim, PHY_SHORT); - shipVertexArray.reset(new btTriangleIndexVertexArray); - shipVertexArray->addIndexedMesh(im, PHY_SHORT); + btBvhTriangleMeshShape *_shipShape = new btBvhTriangleMeshShape( + shipVertexArray.get(), true, true); - btBvhTriangleMeshShape *_shipShape = new btBvhTriangleMeshShape( - shipVertexArray.get(), true); - shipShape.reset(_shipShape); + btVector3 center; + btScalar radius; + _shipShape->getBoundingSphere(center, radius); + std::cout << center.x() << " " << center.y() << " " << center.y() << ", " + << radius << std::endl; + shipShape.reset(_shipShape); + */ + shipShape.reset(new btBoxShape(btVector3(btScalar(1.5), btScalar(1.5), + btScalar(1.5)))); +} + +void Game::setupLevel() { + dynamicsWorld->setGravity(btVector3(0, 0, 0)); + + loadLevelShape(); + loadShipShape(); + + levelState.reset(new btDefaultMotionState()); + btRigidBody::btRigidBodyConstructionInfo rbInfo(0, levelState.get(), + levelShape.get()); + levelBody.reset(new btRigidBody(rbInfo)); + dynamicsWorld->addRigidBody(levelBody.get()); } void Game::setup() { @@ -190,7 +216,6 @@ player_t *Game::getFreePlayer() { if (player[i].status == 0) return &player[i]; } - return NULL; } player_t *Game::spawn_player(Team *team) { @@ -201,6 +226,7 @@ player_t *Game::spawn_player(Team *team) { reset_player(player); if (player->body.get() == 0) { + std::cout << "Game::spawn_player: create body" << std::endl; /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); @@ -213,6 +239,7 @@ player_t *Game::spawn_player(Team *team) { btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, player->state.get(), shipShape.get(), localInertia); player->body.reset(new btRigidBody(rbInfo)); + player->body->setCcdSweptSphereRadius(1.5); dynamicsWorld->addRigidBody(player->body.get()); } return player; @@ -225,12 +252,25 @@ player_t *Game::spawn_player_id(Team *team, uint16_t id) { if (max_player_id < id) max_player_id = id; player->status = 1; - player->x = team->x + 100; - player->y = team->y; - player->z = team->z; - player->vx = 0.; - player->vy = 0.; - player->vz = 0.; + reset_player(player); + + if (player->body.get() == 0) { + /// Create Dynamic Objects + std::cout << "[Game] create body" << std::endl; + 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)); + player->body->setCcdSweptSphereRadius(1.5); + dynamicsWorld->addRigidBody(player->body.get()); + } return player; } @@ -240,20 +280,24 @@ 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; - btTransform wt; - p->state->getWorldTransform(wt); - p->x = wt.getOrigin().x(); - p->y = wt.getOrigin().y(); - p->z = wt.getOrigin().z(); + if (master || true) { + btTransform wt; + p->state->getWorldTransform(wt); + p->x = wt.getOrigin().x(); + p->y = wt.getOrigin().y(); + p->z = wt.getOrigin().z(); + btVector3 v = p->body->getLinearVelocity(); + p->vx = v.x(); + p->vy = v.z(); + p->vz = v.z(); + } else { + std::cout << "update player " << p->id << ": " << p->x << " += " + << p->vx << " * " << dt << std::endl; + + p->x += p->vx * dt; + p->y += p->vy * dt; + p->z += p->vz * dt; + } double distance2 = pow(p->x - p->team->x, 2) + pow(p->y - p->team->y, 2) + pow(p->z - p->team->z, 2); @@ -262,29 +306,29 @@ void Game::update_players(double dt) { p->points = 0; } - if (p->x < (-1000 + 10)) { - p->x = (-1000 + 10); - p->vx *= -1; - } else if (p->x > (5000 - 10)) { - p->x = (5000 - 10); - p->vx *= -1; - } - - if (p->y < (-3000 + 10)) { - p->y = (-3000 + 10); - p->vy *= -1; - } else if (p->y > (3000 - 10)) { - p->y = (3000 - 10); - p->vy *= -1; - } - - if (p->z < (-3000 + 10)) { - p->z = (-3000 + 10); - p->vz *= -1; - } else if (p->z > (3000 - 10)) { - p->z = (3000 - 10); - p->vz *= -1; - } + // if (p->x < (-1000 + 10)) { + // p->x = (-1000 + 10); + // p->vx *= -1; + // } else if (p->x > (5000 - 10)) { + // p->x = (5000 - 10); + // p->vx *= -1; + // } + // + // if (p->y < (-3000 + 10)) { + // p->y = (-3000 + 10); + // p->vy *= -1; + // } else if (p->y > (3000 - 10)) { + // p->y = (3000 - 10); + // p->vy *= -1; + // } + // + // if (p->z < (-3000 + 10)) { + // p->z = (-3000 + 10); + // p->vz *= -1; + // } else if (p->z > (3000 - 10)) { + // p->z = (3000 - 10); + // p->vz *= -1; + // } } } @@ -386,17 +430,21 @@ 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) { - Game::update_players(delta); - Game::update_bombs(delta); - Game::update_points(delta); - updateTime -= delta; +void Game::update(double time, double dt) { + if (master || true) { + int steps = dynamicsWorld->stepSimulation(dt, 10); + if (steps > 0) { + double timeStep = dt; + Game::update_players(timeStep); + Game::update_bombs(timeStep); + Game::update_points(timeStep); + } + } else if (slaveUpdate.next(time)) { + Game::update_players(slaveUpdate.getInterval()); + Game::update_bombs(slaveUpdate.getInterval()); + Game::update_points(slaveUpdate.getInterval()); } + } size_t Game::active_team_players(Team *team) { diff --git a/src/common/Game.h b/src/common/Game.h index 7c4b139..5d2d831 100644 --- a/src/common/Game.h +++ b/src/common/Game.h @@ -4,6 +4,7 @@ #include "common.h" #include "sigslot.h" #include "trimeshloader.h" +#include "Schedule.h" #include #include @@ -88,7 +89,7 @@ public: point_t *spawn_point(); void update_bombs(double dt); void update_points(double dt); - void update(double dt); + void update(double time, double dt); void set_master(int master); player_t *getFreePlayer(); void explode_bomb(bomb_t *bomb); @@ -100,6 +101,8 @@ public: private: void setupLevel(); + void loadLevelShape(); + void loadShipShape(); const std::auto_ptr collisionConfiguration; const std::auto_ptr dispatcher; @@ -108,11 +111,13 @@ private: const std::auto_ptr dynamicsWorld; std::auto_ptr levelVertexArray; std::auto_ptr levelShape; + std::auto_ptr levelState; std::auto_ptr levelBody; std::auto_ptr shipVertexArray; std::auto_ptr shipShape; + Schedule slaveUpdate; }; #endif diff --git a/src/common/Network.cpp b/src/common/Network.cpp index 8f2ac5e..1690de8 100644 --- a/src/common/Network.cpp +++ b/src/common/Network.cpp @@ -82,12 +82,15 @@ void Network::sendGameUpdates() { player_update_message_t msg; msg.msg_id = MESSAGE_PLAYER_UPDATE; msg.player_id = game->player[i].id; - msg.x = game->player[i].x; - msg.y = game->player[i].y; - msg.z = game->player[i].z; - msg.vx = game->player[i].vx; - msg.vy = game->player[i].vy; - msg.vz = game->player[i].vz; + btVector3 v = game->player[i].body->getLinearVelocity(); + btVector3 p = game->player[i].body->getWorldTransform().getOrigin(); + + msg.x = p.x(); + msg.y = p.y(); + msg.z = p.z(); + msg.vx = v.x(); + msg.vy = v.y(); + msg.vz = v.z(); msg.points = game->player[i].points; ENetPacket * packet = enet_packet_create(&msg, sizeof(msg), 0); enet_host_broadcast(host, 0, packet); @@ -124,38 +127,52 @@ void Network::dispatch(enet_uint8 *data, size_t length) { case MESSAGE_ACCEPT: { accept_message_t *am = (accept_message_t *) data; game->local_player = game->getPlayer(am->player_id); + std::cout << "[Network] accpeted player " << am->player_id << std::endl; break; } case MESSAGE_PLAYER_UPDATE: { player_update_message_t *um = (player_update_message_t *) data; + std::cout << "[Network] update player " << um->player_id << std::endl; player_t *player = game->getPlayer(um->player_id); - if (player != game->local_player) { - player->x = um->x + um->vx * 0.0001; - player->y = um->y + um->vy * 0.0001; - player->z = um->z + um->vz * 0.0001; - player->vx = um->vx; - player->vy = um->vy; - player->vz = um->vz; +#if 1 + btVector3 v = player->body->getLinearVelocity(); + btVector3 p = player->body->getWorldTransform().getOrigin(); + btVector3 v1(um->vx, um->vy, um->vz); + btVector3 p1(um->x, um->y, um->z); + player->body->activate(true); + player->body->setLinearVelocity(v1); + player->body->getWorldTransform().setOrigin((2 * p + p1) / 3); + //player->body->applyCentralForce((v1 -v)/10.0); +#endif +#if 0 + std::cout << " v:" << um->vx << " " << um->vy << " " << um -> vz + << std::endl; + std::cout << " p:" << um->x << " " << um->y << " " << um -> z + << std::endl; + double threshold = 0.1; + double dx = um->x - player->x; + double dy = um->y - player->y; + double dz = um->z - player->z; + std::cout << " d:" << dx << " " << dy << " " << dz << std::endl; + if (fabs(dx) < threshold) { + player->x += 0.1 * dx; } else { - if (fabs(um->x - player->x) < 10.0) { - player->vx = um->vx + (um->x - player->x); - } else { - player->x = um->x; - player->vx = um->vx; - } - if (fabs(um->y - player->y) < 10.0) { - player->vy = um->vy + (um->y - player->y); - } else { - player->y = um->y; - player->vy = um->vy; - } - if (fabs(um->z - player->z) < 10.0) { - player->vz = um->vz + (um->z - player->z); - } else { - player->z = um->z; - player->vz = um->vz; - } + player->x = um->x; } + if (fabs(dy) < threshold) { + player->y += 0.1 * dy; + } else { + player->y = um->y; + } + if (fabs(dz) < threshold) { + player->z += 0.1 * dz; + } else { + player->z = um->z; + } + player->vx = um->vx; + player->vy = um->vy; + player->vz = um->vz; +#endif player->points = um->points; break; } @@ -174,6 +191,7 @@ void Network::dispatch(enet_uint8 *data, size_t length) { player->vx += um->x; player->vy += um->y; player->vz += um->z; + player->body->activate(true); player->body->applyCentralImpulse(btVector3(um->x, um->y, um->z)); break; }