From 196e7345a1e89f23bbf6ebec0bd1d0c4fde05dce Mon Sep 17 00:00:00 2001 From: Rtch90 Date: Sun, 19 Nov 2017 11:41:35 +0000 Subject: [PATCH] [Add] Working on collision. Doesn't work, see how changing model scale screws collisions. If I set the model 62 scale to 2.0 then hitting it gives screwed up collisions. On scale 1.0 it works fine though. --- src/body.h | 2 +- src/l3d.h | 7 ++++--- src/main.cpp | 8 ++++---- src/player.cpp | 26 +++++++++++++------------- src/player.h | 2 +- src/rigid_body.cpp | 15 +++++++++++++++ src/rigid_body.h | 1 + src/sbre/brender.cpp | 2 +- src/ship.cpp | 18 ++++++++++++++---- src/ship.h | 2 +- src/ship_cpanel.cpp | 2 +- src/ship_type.cpp | 2 +- src/space.cpp | 17 +++++++++++++++-- src/space.h | 1 + src/space_station.cpp | 10 +++------- src/space_station.h | 2 -- src/static_rigid_body.cpp | 35 ++++++++++++++++++++++++++--------- src/static_rigid_body.h | 3 +++ src/world_view.cpp | 2 +- 19 files changed, 106 insertions(+), 51 deletions(-) diff --git a/src/body.h b/src/body.h index c8ac8e6..126b5ca 100644 --- a/src/body.h +++ b/src/body.h @@ -31,7 +31,7 @@ public: const vector3d& GetProjectedPos() const; bool IsOnscreen() const { return m_onscreen; } void SetOnscreen(const bool onscreen) { m_onscreen = onscreen; } - + virtual void TimeStepUpdate(const float timeStep) {} enum { FLAG_CAN_MOVE_FRAME = 1 }; protected: diff --git a/src/l3d.h b/src/l3d.h index bd81df3..0ef1e5a 100644 --- a/src/l3d.h +++ b/src/l3d.h @@ -41,8 +41,9 @@ public: static void Quit(void); static float GetFrameTime(void) { return frameTime; } static double GetGameTime(void) { return gameTime; } - static void SetTimeStep(float s) { timeStep = s; } - static float GetTimeStep(void) { return timeStep; } + static void SetTimeAccel(float s) { timeAccel = s; } + static float GetTimeAccel(void) { return timeAccel; } + static float GetTimeStep(void) { return timeAccel*frameTime; } static int GetScrWidth(void) { return scrWidth; } static int GetScrHeight(void) { return scrHeight; } static int GetScrAspect(void) { return scrAspect; } @@ -91,7 +92,7 @@ private: static StarSystem* selected_system; static enum CamType cam_type; static enum MapView map_view; - static float timeStep; + static float timeAccel; static float frameTime; static int scrWidth, scrHeight; static float scrAspect; diff --git a/src/main.cpp b/src/main.cpp index 44af530..ca85ebd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,7 +18,7 @@ #include "space_station_view.h" #include "info_view.h" -float L3D::timeStep = 1.0f; +float L3D::timeAccel = 1.0f; int L3D::scrWidth; int L3D::scrHeight; float L3D::scrAspect; @@ -199,7 +199,7 @@ void L3D::MainLoop(void) { snprintf(buf, sizeof(buf), "X%c-0%02d", "A"+i, i); body->SetLabel(buf); body->SetFrame(earth_frame); - body->SetPosition(vector3d(i*200, 0, -200)); + body->SetPosition(vector3d(i*2000, 0, -400)); Space::AddBody(body); } @@ -207,7 +207,7 @@ void L3D::MainLoop(void) { SpaceStation* body = new SpaceStation(); body->SetLabel("Some Back Country Joint"); body->SetFrame(earth_frame); - body->SetPosition(vector3d(0, 0, 6000)); + body->SetPosition(vector3d(0, 0, 600)); Space::AddBody(body); } @@ -290,7 +290,7 @@ void L3D::MainLoop(void) { //if(glGetError()) printf("GL: %s\n", gluErrorString(glGetError())); L3D::frameTime = 0.001*(SDL_GetTicks() - time_before_frame); - float step = L3D::timeStep * L3D::frameTime; + float step = L3D::timeAccel * L3D::frameTime; time_before_frame = SDL_GetTicks(); /* Game state update stuff. */ diff --git a/src/player.cpp b/src/player.cpp index 82967e7..7577e6a 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -53,24 +53,25 @@ void Player::ApplyExternalViewRotation(void) { } #define MOUSE_CTRL_AREA 10.0f -#define MOUSE_RESTITUTION 0.9f +#define MOUSE_RESTITUTION 0.01f -void Player::AITurn(void) { +void Player::PollControls(void) { int mouseMotion[2]; - float time_step = L3D::GetTimeStep(); - float ts2 = time_step*time_step; - + float time_accel = L3D::GetTimeAccel(); + float ta2 = time_accel*time_accel; + SetAngThrusterState(0, 0.0f); SetAngThrusterState(1, 0.0f); SetAngThrusterState(2, 0.0f); - if(time_step == 0) return; - if(GetDockedWith()) return; + if((time_accel == 0) || GetDockedWith()) { + return; + } vector3f angThrust(0.0f); if(L3D::MouseButtonState(3)) { - float restitution = powf(MOUSE_RESTITUTION, time_step); + float restitution = powf(MOUSE_RESTITUTION, L3D::GetTimeStep()); L3D::GetMouseMotion(mouseMotion); m_mouseCMov[0] += mouseMotion[0]; m_mouseCMov[1] += mouseMotion[1]; @@ -93,7 +94,7 @@ void Player::AITurn(void) { else SetGunState(0,0); /* No torques at huge time accels -- ODE hates it. */ - if(time_step <= 10) { + if(time_accel <= 10) { if(L3D::GetCamType() != L3D::CAM_EXTERNAL) { if(L3D::KeyState(SDLK_LEFT)) angThrust.y += 1; if(L3D::KeyState(SDLK_RIGHT)) angThrust.y += -1; @@ -107,7 +108,7 @@ void Player::AITurn(void) { GetRotMatrix(rot); angVel = rot.InverseOf() * angVel; - angVel *= 0.4; + angVel *= 0.6; angThrust.x -= angVel.x; angThrust.y -= angVel.y; angThrust.z -= angVel.z; @@ -116,12 +117,12 @@ void Player::AITurn(void) { * Divided by time step so controls don't go totally insane when * used at 10x accel. */ - angThrust *= 1.0f/ts2; + angThrust *= 1.0f/ta2; SetAngThrusterState(0, angThrust.x); SetAngThrusterState(1, angThrust.y); SetAngThrusterState(2, angThrust.z); } - if(time_step > 10) { + if(time_accel > 10) { dBodySetAngularVel(m_body, 0, 0, 0); } if(L3D::GetCamType() == L3D::CAM_EXTERNAL) { @@ -133,7 +134,6 @@ void Player::AITurn(void) { if(L3D::KeyState(SDLK_MINUS)) m_external_view_dist += 10; m_external_view_dist = MAX(50, m_external_view_dist); } - Ship::AITurn(); } #define HUD_CROSSHAIR_SIZE 24.0f diff --git a/src/player.h b/src/player.h index 37c010d..a45e161 100644 --- a/src/player.h +++ b/src/player.h @@ -5,7 +5,7 @@ class Player : public Ship { public: Player(ShipType::Type shipType); - virtual void AITurn(); + void PollControls(void); virtual void Render(const Frame* camFrame); void DrawHUD(const Frame* cam_frame); virtual void SetDockedWith(SpaceStation*); diff --git a/src/rigid_body.cpp b/src/rigid_body.cpp index 9a6cc37..71f7adf 100644 --- a/src/rigid_body.cpp +++ b/src/rigid_body.cpp @@ -13,6 +13,21 @@ RigidBody::RigidBody(void) : StaticRigidBody() { dBodySetMass(m_body, &m_mass); } +void RigidBody::SetMassDistributionFromCollMesh(const CollMesh* m) { + vector3d min = vector3d(FLT_MAX); + vector3d max = vector3d(-FLT_MAX); + for(int i = 0; i < 3*m->nv; i += 3) { + min.x = MIN(m->pVertex[i], min.x); + min.y = MIN(m->pVertex[i+1], min.y); + min.z = MIN(m->pVertex[i+2], min.z); + max.x = MAX(m->pVertex[i], max.x); + max.y = MAX(m->pVertex[i+1], max.y); + max.z = MAX(m->pVertex[i+2], max.z); + } + dMassSetBox(&m_mass, 1, max.x-min.x, max.y-min.y, max.z-min.z); + dBodySetMass(m_body, &m_mass); +} + vector3d RigidBody::GetAngularMomentum(void) { matrix4x4d I; I.LoadFromOdeMatrix(m_mass.I); diff --git a/src/rigid_body.h b/src/rigid_body.h index 6aae5ac..4a3c8a4 100644 --- a/src/rigid_body.h +++ b/src/rigid_body.h @@ -15,6 +15,7 @@ public: void SetMesh(ObjMesh* m); virtual bool OnCollision(Body* b) { return true; } vector3d GetAngularMomentum(void); + void SetMassDistributionFromCollMesh(const CollMesh* m); dBodyID m_body; dMass m_mass; diff --git a/src/sbre/brender.cpp b/src/sbre/brender.cpp index 7203614..71c34a1 100644 --- a/src/sbre/brender.cpp +++ b/src/sbre/brender.cpp @@ -88,7 +88,7 @@ static void ResolveVertices(Model* pMod, Vector* pRes, ObjParams* pObjParam) { static float g_dn, g_df, g_sd; static int g_wireframe = 0; -float SBRE_ZBIAS = 0; +float SBRE_ZBIAS = 0.00002f; void sbreSetZBias(float zbias) { SBRE_ZBIAS = zbias; diff --git a/src/ship.cpp b/src/ship.cpp index f2bc78a..cb56faa 100644 --- a/src/ship.cpp +++ b/src/ship.cpp @@ -37,7 +37,9 @@ Ship::Ship(ShipType::Type shipType) : RigidBody() { memset(m_thrusters, 0, sizeof(m_thrusters)); const ShipType& stype = GetShipType(); SetGeomFromSBREModel(stype.sbreModel, ¶ms); + SetMassDistributionFromCollMesh(sbreCollMesh); dGeomSetBody(m_geom, m_body); + UpdateMass(); } void Ship::UpdateMass(void) { @@ -77,11 +79,10 @@ void Ship::CalcStats(shipstats_t* stats) { stats->hyperspace_range = 200 * hyperclass * hyperclass / stats->total_mass; } -void Ship::AITurn(void) { +void Ship::TimeStepUpdate(const float timeStep) { /* ODE tri mesh likes to know our old position. */ TriMeshUpdateLastPos(); const ShipType& stype = GetShipType(); - float timeStep = L3D::GetTimeStep(); for(int i = 0; i < ShipType::THRUSTER_MAX; i++) { float force = timeStep * stype.linThrust[i] * m_thrusters[i]; switch(i) { @@ -172,7 +173,6 @@ void Ship::RenderLaserfire(void) { glEnable(GL_LIGHTING); } -#if 0 static void render_coll_mesh(const CollMesh* m) { glDisable(GL_LIGHTING); glColor3f(1, 0, 1); @@ -183,9 +183,18 @@ static void render_coll_mesh(const CollMesh* m) { glVertex3fv(&m->pVertex[3*m->pIndex[i+2]]); } glEnd(); + glColor3f(1,1,1); + glDepthRange(0, 1.0f-0.0002f); + for(int i = 0; i < m->ni; i += 3) { + glBegin(GL_LINE_LOOP); + glVertex3fv(&m->pVertex[3*m->pIndex[i]]); + glVertex3fv(&m->pVertex[3*m->pIndex[i+1]]); + glVertex3fv(&m->pVertex[3*m->pIndex[i+2]]); + glEnd(); + } + glDepthRange(0.0, 1.0); glEnable(GL_LIGHTING); } -#endif void Ship::Render(const Frame* camFrame) { const ShipType& stype = GetShipType(); @@ -208,6 +217,7 @@ void Ship::Render(const Frame* camFrame) { glPushMatrix(); TransformToModelCoords(camFrame); + //render_coll_mesh(sbreCollMesh); RenderLaserfire(); glPopMatrix(); } diff --git a/src/ship.h b/src/ship.h index 6a9d400..f9c92e7 100644 --- a/src/ship.h +++ b/src/ship.h @@ -17,7 +17,6 @@ struct shipstats_t { class Ship : public RigidBody { public: Ship(ShipType::Type shipType); - virtual void AITurn(void); virtual Object::Type GetType(void) { return Object::SHIP; } virtual void SetDockedWith(SpaceStation*); SpaceStation* GetDockedWith(void) { return m_dockedWith; } @@ -32,6 +31,7 @@ public: void CalcStats(shipstats_t* stats); void UpdateMass(void); void SetWheelState(bool down); + virtual void TimeStepUpdate(const float timeStep); class LaserObj : public Object { public: diff --git a/src/ship_cpanel.cpp b/src/ship_cpanel.cpp index 154add6..ee06ec5 100644 --- a/src/ship_cpanel.cpp +++ b/src/ship_cpanel.cpp @@ -107,7 +107,7 @@ void ShipCpanel::OnChangeMapView(Gui::MultiStateImageButton* b) { } void ShipCpanel::OnClickTimeaccel(Gui::ISelectable* i, double step) { - L3D::SetTimeStep(step); + L3D::SetTimeAccel(step); } void ShipCpanel::OnClickComms(void) { diff --git a/src/ship_type.cpp b/src/ship_type.cpp index fc30184..f2870b3 100644 --- a/src/ship_type.cpp +++ b/src/ship_type.cpp @@ -7,7 +7,7 @@ const ShipType ShipType::types[] = { * Sirius corporation make a range of lovely ships! */ "Sirius Interdictor", 61, - { 1e7, -1e7, 1e6, -1e6, -1e6, 1e6 }, + { 1e8, -1e8, 1e7, -1e6, -1e7, 1e7 }, 1e7, { { vector3f(0, -0.5, 0), vector3f(0, 0, -1) }, diff --git a/src/space.cpp b/src/space.cpp index bd9cfa0..6d3d290 100644 --- a/src/space.cpp +++ b/src/space.cpp @@ -156,7 +156,7 @@ static void nearCallback(void* data, dGeomID oO, dGeomID o1) { contact[i].surface.mode = dContactBounce; contact[i].surface.mu = 0; contact[i].surface.mu2 = 0; - contact[i].surface.bounce = 0; + contact[i].surface.bounce = 0.5; contact[i].surface.bounce_vel = 0.1; } if(int numc = dCollide(oO, o1, MAX_CONTACTS, &contact[0].geom, sizeof(dContact))) { @@ -178,6 +178,16 @@ static void nearCallback(void* data, dGeomID oO, dGeomID o1) { * finally create the temp contact joint between the two geom bodies. */ dJointID c = dJointCreateContact(Space::world, _contactgroup, contact + i); + printf("Depth: %f\n", contact[i].geom.depth); +#if 0 + struct dContactGeom { + dVector3 pos; /* Constact position. */ + dVector3 normal; /* Normal vector. */ + dReal depth; /* Penetration depth. */ + dGeomId g1, g2; /* The colliding geoms. */ + }; +#endif + dJointAttach(c, b1, b2); } } @@ -192,12 +202,15 @@ void Space::CollideFrame(Frame* f) { void Space::TimeStep(float step) { CollideFrame(rootFrame); - //CollideFrame(L3D::player->GetFrame()); dWorldQuickStep(world, step); dJointGroupEmpty(_contactgroup); /* TODO: Does not need to be done this often. */ UpdateFramesOfReference(); + + for(bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) { + (*i)->TimeStepUpdate(step); + } } struct body_zsort_t { diff --git a/src/space.h b/src/space.h index cd3a4c7..8195557 100644 --- a/src/space.h +++ b/src/space.h @@ -20,6 +20,7 @@ public: static dWorldID world; static std::list bodies; + typedef std::list::iterator bodiesIter_t; private: static void UpdateFramesOfReference(void); static void CollideFrame(Frame* f); diff --git a/src/space_station.cpp b/src/space_station.cpp index 08c3ce0..a6a1683 100644 --- a/src/space_station.cpp +++ b/src/space_station.cpp @@ -22,15 +22,15 @@ static ObjParams params = { SpaceStation::SpaceStation(void) : StaticRigidBody() { SetGeomFromSBREModel(STATION_SBRE_MODEL, ¶ms); - matrix4x4d m = matrix4x4d::RotateYMatrix(M_PI); + matrix4x4d m = matrix4x4d::RotateYMatrix(-M_PI/4); dMatrix3 _m; m.SaveToOdeMatrix(_m); dGeomSetRotation(m_geom, _m); - m_mesh = 0; + dGeomSetBody(m_geom, 0); } SpaceStation::~SpaceStation(void) { - //dGeomDestroy(m_geom); + dGeomDestroy(m_geom); } bool SpaceStation::OnCollision(Body* b) { @@ -48,10 +48,6 @@ bool SpaceStation::OnCollision(Body* b) { } } -void SpaceStation::SetMesh(ObjMesh* m) { - m_mesh = m; -} - void SpaceStation::Render(const Frame* camFrame) { RenderSbreModel(camFrame, STATION_SBRE_MODEL, ¶ms); } diff --git a/src/space_station.h b/src/space_station.h index fb66114..6949654 100644 --- a/src/space_station.h +++ b/src/space_station.h @@ -9,8 +9,6 @@ public: virtual bool OnCollision(Body* b); virtual Object::Type GetType(void) { return Object::SPACESTATION; } virtual void Render(const Frame* camFrame); - void SetMesh(ObjMesh* m); protected: - ObjMesh* m_mesh; }; diff --git a/src/static_rigid_body.cpp b/src/static_rigid_body.cpp index 3b264ba..33dcd78 100644 --- a/src/static_rigid_body.cpp +++ b/src/static_rigid_body.cpp @@ -9,6 +9,7 @@ StaticRigidBody::StaticRigidBody(void): Body() { m_geom = 0; sbreCollMesh = 0; + triMeshLastMatrixIndex = 0; } StaticRigidBody::~StaticRigidBody(void) { @@ -36,10 +37,26 @@ void StaticRigidBody::SetGeomFromSBREModel(int sbreModel, ObjParams* params) { sbreCollMesh->pVertex[i] = -sbreCollMesh->pVertex[i]; sbreCollMesh->pVertex[i+2] = -sbreCollMesh->pVertex[i+2]; } + /* Make normals. */ + meshNormals = new float[sbreCollMesh->ni]; + for(int i = 0; i < sbreCollMesh->ni; i += 3) { + float* vtx1 = sbreCollMesh->pVertex + 3*sbreCollMesh->pIndex[i]; + float* vtx2 = sbreCollMesh->pVertex + 3*sbreCollMesh->pIndex[i+1]; + float* vtx3 = sbreCollMesh->pVertex + 3*sbreCollMesh->pIndex[i+2]; + vector3f v1(vtx1[0], vtx1[1], vtx1[2]); + vector3f v2(vtx2[0], vtx2[1], vtx2[2]); + vector3f v3(vtx3[0], vtx3[1], vtx3[2]); + vector3f n = vector3f::Cross(v1-v2, v1-v3); + n.Normalize(); + meshNormals[i] = n.x; + meshNormals[i+1] = n.y; + meshNormals[i+2] = n.z; + + } dTriMeshDataID triMeshDataID = dGeomTriMeshDataCreate(); - dGeomTriMeshDataBuildSingle(triMeshDataID, (void*)sbreCollMesh->pVertex, + dGeomTriMeshDataBuildSingle1(triMeshDataID, (void*)sbreCollMesh->pVertex, 3*sizeof(float), sbreCollMesh->nv, (void*)sbreCollMesh->pIndex, - sbreCollMesh->ni, 3*sizeof(int)); + sbreCollMesh->ni, 3*sizeof(int), NULL/*meshNormals*/); /* TODO: Leaking StaticRigidBody m_geom. */ m_geom = dCreateTriMesh(0, triMeshDataID, NULL, NULL, NULL); @@ -101,13 +118,13 @@ void StaticRigidBody::TriMeshUpdateLastPos(void) { /* ODE tri mesh likes to know our old position. */ const dReal* r = dGeomGetRotation(m_geom); vector3d pos = GetPosition(); - dMatrix4 t; - /* Row-major. */ - t[0] = r[0]; t[1] = r[1]; t[ 2] = r[ 2]; t[ 3] = pos.x; - t[4] = r[4]; t[5] = r[5]; t[ 6] = r[ 6]; t[ 7] = pos.y; - t[8] = r[8]; t[9] = r[9]; t[10] = r[10]; t[11] = pos.z; - t[12] = t[13] = t[15] = 0; - dGeomTriMeshSetLastTransform(m_geom, t); + dReal* t = triMeshTrans + 16*triMeshLastMatrixIndex; + t[ 0] = r[0]; t[1] = r[1]; t[ 2] = r[ 2]; t[ 3] = 0; + t[ 4] = r[4]; t[5] = r[5]; t[ 6] = r[ 6]; t[ 7] = 0; + t[ 8] = r[8]; t[9] = r[9]; t[10] = r[10]; t[11] = 0; + t[12] = pos.x; t[13] = pos.y; t[14] = pos.z; t[15] = 1; + triMeshLastMatrixIndex = !triMeshLastMatrixIndex; + dGeomTriMeshSetLastTransform(m_geom, *(dMatrix4*)(triMeshTrans + 16*triMeshLastMatrixIndex)); } void StaticRigidBody::RenderSbreModel(const Frame* camFrame, int model, ObjParams* params) { diff --git a/src/static_rigid_body.h b/src/static_rigid_body.h index 2fc2854..3e16343 100644 --- a/src/static_rigid_body.h +++ b/src/static_rigid_body.h @@ -30,5 +30,8 @@ public: protected: dGeomID m_geom; CollMesh* sbreCollMesh; + float* meshNormals; + dReal triMeshTrans[32]; + int triMeshLastMatrixIndex; }; diff --git a/src/world_view.cpp b/src/world_view.cpp index 896ffd7..c749955 100644 --- a/src/world_view.cpp +++ b/src/world_view.cpp @@ -110,7 +110,7 @@ void WorldView::Update(void) { m_hyperspaceButton->Hide(); } /* Player control inputs. */ - L3D::player->AITurn(); + L3D::player->PollControls(); } void WorldView::OnMouseDown(Gui::MouseButtonEvent* e) {