From 2a5a81dcf346479d37d7bee6d665cbdf05406170 Mon Sep 17 00:00:00 2001 From: Rtch90 <ritchie.cunningham@protonmail.com> Date: Sat, 18 Nov 2017 18:18:31 +0000 Subject: [PATCH] [Add] Collisions using collision meshes. --- src/player.cpp | 1 + src/rigid_body.cpp | 2 -- src/ship.cpp | 57 ++++++++++++++++++++++++--------------- src/ship.h | 3 +-- src/space.cpp | 7 +++-- src/space_station.cpp | 41 +++++++++++++++------------- src/static_rigid_body.cpp | 49 ++++++++++++++++++++++++++++++--- src/static_rigid_body.h | 5 ++++ 8 files changed, 114 insertions(+), 51 deletions(-) diff --git a/src/player.cpp b/src/player.cpp index 9f2b61c..82967e7 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -157,6 +157,7 @@ void Player::DrawHUD(const Frame* cam_frame) { { for(std::list<Body*>::iterator i = Space::bodies.begin(); i != Space::bodies.end(); ++i) { + if((L3D::GetCamType() != L3D::CAM_EXTERNAL) && (*i == this)) continue; Body* b = *i; vector3d _pos = b->GetPositionRelTo(cam_frame); vector3d cam_coord = rot*_pos; diff --git a/src/rigid_body.cpp b/src/rigid_body.cpp index 00bde01..9a6cc37 100644 --- a/src/rigid_body.cpp +++ b/src/rigid_body.cpp @@ -11,8 +11,6 @@ RigidBody::RigidBody(void) : StaticRigidBody() { dMassAdjust(&m_mass, 1.0f); dBodySetMass(m_body, &m_mass); - dGeomSetBody(m_geom, m_body); - SetPosition(vector3d(0,0,0)); } vector3d RigidBody::GetAngularMomentum(void) { diff --git a/src/ship.cpp b/src/ship.cpp index e9a03e1..e8ba68e 100644 --- a/src/ship.cpp +++ b/src/ship.cpp @@ -3,15 +3,29 @@ #include "frame.h" #include "l3d.h" #include "world_view.h" -#include "sbre/sbre.h" #include "space.h" +static ObjParams params = { + { 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, + + /* pColor[3] */ + { + { { 1.0f, 0.0f, 1.0f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 }, + { { 0.8f, 0.6f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 }, + { { 0.5f, 0.5f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 } + }, + + /* pText[3][256] */ + { "IR-L33T", "ME TOO" }, +}; + Ship::Ship(ShipType::Type shipType) : RigidBody() { m_wheelTransition = 0; m_wheelState = 0; m_dockedWith = 0; m_target = 0; - m_mesh = 0; m_shipType = shipType; m_angThrusters[0] = m_angThrusters[1] = m_angThrusters[2] = 0; m_laserCollisionObj.owner = this; @@ -20,7 +34,9 @@ Ship::Ship(ShipType::Type shipType) : RigidBody() { m_tempLaserGeom[i] = 0; m_gunState[i] = 0; } - dGeomSetData(m_geom, static_cast<Body*>(this)); + const ShipType& stype = GetShipType(); + SetGeomFromSBREModel(stype.sbreModel, ¶ms); + dGeomSetBody(m_geom, m_body); } void Ship::UpdateMass(void) { @@ -61,6 +77,8 @@ void Ship::CalcStats(shipstats_t* stats) { } void Ship::AITurn(void) { + /* 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++) { @@ -125,10 +143,6 @@ void Ship::SetDockedWith(SpaceStation* s) { } } -void Ship::SetMesh(ObjMesh* m) { - m_mesh = m; -} - void Ship::SetGunState(int idx, int state) { m_gunState[idx] = state; } @@ -157,20 +171,20 @@ void Ship::RenderLaserfire(void) { glEnable(GL_LIGHTING); } -static ObjParams params = { - { 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, - - /* pColor[3] */ - { - { { 1.0f, 0.0f, 1.0f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 }, - { { 0.8f, 0.6f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 }, - { { 0.5f, 0.5f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 } - }, - /* pText[3][256] */ - { "IZ-L33T", "ME TOO" }, -}; +#if 0 +static void render_coll_mesh(const CollMesh* m) { + glDisable(GL_LIGHTING); + glColor3f(1, 0, 1); + glBegin(GL_TRIANGLES); + for(int i = 0; i < m->ni; i += 3) { + glVertex3fv(&m->pVertex[3*m->pIndex[i]]); + glVertex3fv(&m->pVertex[3*m->pIndex[i+1]]); + glVertex3fv(&m->pVertex[3*m->pIndex[i+2]]); + } + glEnd(); + glEnable(GL_LIGHTING); +} +#endif void Ship::Render(const Frame* camFrame) { const ShipType& stype = GetShipType(); @@ -190,6 +204,7 @@ void Ship::Render(const Frame* camFrame) { strncpy(params.pText[0], GetLabel().c_str(), sizeof(params.pText)); RenderSbreModel(camFrame, stype.sbreModel, ¶ms); + glPushMatrix(); TransformToModelCoords(camFrame); RenderLaserfire(); diff --git a/src/ship.h b/src/ship.h index a5e54d1..6a9d400 100644 --- a/src/ship.h +++ b/src/ship.h @@ -2,6 +2,7 @@ #include "libs.h" #include "rigid_body.h" #include "ship_type.h" +#include "sbre/sbre.h" class SpaceStation; @@ -23,7 +24,6 @@ public: void SetTarget(Body* const target) { m_target = target; } Body* GetTarget(void) const { return m_target; } virtual void Render(const Frame* camFrame); - void SetMesh(ObjMesh* m); void SetThrusterState(enum ShipType::Thruster t, float level); void SetAngThrusterState(int axis, float level) { m_angThrusters[axis] = CLAMP(level, -1, 1); } void ClearThrusterState(void); @@ -45,7 +45,6 @@ protected: SpaceStation* m_dockedWith; enum ShipType::Type m_shipType; - ObjMesh* m_mesh; Uint32 m_gunState[ShipType::GUNMOUNT_MAX]; private: float m_wheelState; diff --git a/src/space.cpp b/src/space.cpp index 7ca99e5..bd9cfa0 100644 --- a/src/space.cpp +++ b/src/space.cpp @@ -153,12 +153,11 @@ static void nearCallback(void* data, dGeomID oO, dGeomID o1) { dContact contact[MAX_CONTACTS]; for(int i = 0; i < MAX_CONTACTS; i++) { - contact[i].surface.mode = dContactBounce | dContactSoftCFM; - contact[i].surface.mu = dInfinity; + contact[i].surface.mode = dContactBounce; + contact[i].surface.mu = 0; contact[i].surface.mu2 = 0; - contact[i].surface.bounce = 0.8; + contact[i].surface.bounce = 0; contact[i].surface.bounce_vel = 0.1; - contact[i].surface.soft_cfm = 0.01; } if(int numc = dCollide(oO, o1, MAX_CONTACTS, &contact[0].geom, sizeof(dContact))) { Object* po1 = static_cast<Object*>(dGeomGetData(oO)); diff --git a/src/space_station.cpp b/src/space_station.cpp index 17d0168..08c3ce0 100644 --- a/src/space_station.cpp +++ b/src/space_station.cpp @@ -2,9 +2,26 @@ #include "ship.h" #include "objimport.h" +#define STATION_SBRE_MODEL 65 + +static ObjParams params = { + { 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, + + /* pColor[3] */ + { + { { 1.0f, 0.0f, 1.0f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 }, + { { 0.8f, 0.6f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 }, + { { 0.5f, 0.5f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 } + }, + + /* pText[3][256] */ + { "Hello you!", "CATZ" }, +}; + SpaceStation::SpaceStation(void) : StaticRigidBody() { - dGeomSphereSetRadius(m_geom, 100.0); - dGeomSetData(m_geom, static_cast<Body*>(this)); + SetGeomFromSBREModel(STATION_SBRE_MODEL, ¶ms); matrix4x4d m = matrix4x4d::RotateYMatrix(M_PI); dMatrix3 _m; m.SaveToOdeMatrix(_m); @@ -17,6 +34,8 @@ SpaceStation::~SpaceStation(void) { } bool SpaceStation::OnCollision(Body* b) { + return true; + if(b->GetType() == Object::SHIP) { Ship* s = static_cast<Ship*>(b); if(!s->GetDockedWith()) { @@ -33,23 +52,7 @@ void SpaceStation::SetMesh(ObjMesh* m) { m_mesh = m; } -static ObjParams params = { - { 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, - - /* pColor[3] */ - { - { { 1.0f, 0.0f, 1.0f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 }, - { { 0.8f, 0.6f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 }, - { { 0.5f, 0.5f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 } - }, - - /* pText[3][256] */ - { "Hello old bean", "CATZ!" }, -}; - void SpaceStation::Render(const Frame* camFrame) { - RenderSbreModel(camFrame, 65, ¶ms); + RenderSbreModel(camFrame, STATION_SBRE_MODEL, ¶ms); } diff --git a/src/static_rigid_body.cpp b/src/static_rigid_body.cpp index d100394..3b264ba 100644 --- a/src/static_rigid_body.cpp +++ b/src/static_rigid_body.cpp @@ -7,15 +7,45 @@ #include "world_view.h" StaticRigidBody::StaticRigidBody(void): Body() { - m_geom = dCreateSphere(0, 50.0f); - dGeomSetBody(m_geom, 0); - SetPosition(vector3d(0,0,0)); + m_geom = 0; + sbreCollMesh = 0; } StaticRigidBody::~StaticRigidBody(void) { + if(sbreCollMesh) { + free(sbreCollMesh->pVertex); + free(sbreCollMesh->pIndex); + free(sbreCollMesh->pFlag); + free(sbreCollMesh); + } dGeomDestroy(m_geom); } +void StaticRigidBody::SetGeomSphere(double radius) { + assert(!m_geom); + m_geom = dCreateSphere(0, radius); +} + +void StaticRigidBody::SetGeomFromSBREModel(int sbreModel, ObjParams* params) { + assert(!m_geom); + assert(sbreCollMesh == 0); + sbreCollMesh = (CollMesh*)calloc(1, sizeof(CollMesh)); + sbreGenCollMesh(sbreCollMesh, sbreModel, params); + /* TODO: Flip Z & X because SBRE is in magicspace. */ + for(int i = 0; i < 3*sbreCollMesh->nv; i += 3) { + sbreCollMesh->pVertex[i] = -sbreCollMesh->pVertex[i]; + sbreCollMesh->pVertex[i+2] = -sbreCollMesh->pVertex[i+2]; + } + dTriMeshDataID triMeshDataID = dGeomTriMeshDataCreate(); + dGeomTriMeshDataBuildSingle(triMeshDataID, (void*)sbreCollMesh->pVertex, + 3*sizeof(float), sbreCollMesh->nv, (void*)sbreCollMesh->pIndex, + sbreCollMesh->ni, 3*sizeof(int)); + + /* TODO: Leaking StaticRigidBody m_geom. */ + m_geom = dCreateTriMesh(0, triMeshDataID, NULL, NULL, NULL); + dGeomSetData(m_geom, static_cast<Body*>(this)); +} + void StaticRigidBody::SetPosition(vector3d p) { dGeomSetPosition(m_geom, p.x, p.y, p.z); } @@ -67,6 +97,19 @@ void StaticRigidBody::SetFrame(Frame* f) { if(f) f->AddGeom(m_geom); } +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); +} + void StaticRigidBody::RenderSbreModel(const Frame* camFrame, int model, ObjParams* params) { glPushMatrix(); diff --git a/src/static_rigid_body.h b/src/static_rigid_body.h index 292ce18..2fc2854 100644 --- a/src/static_rigid_body.h +++ b/src/static_rigid_body.h @@ -22,8 +22,13 @@ public: void GetRotMatrix(matrix4x4d& m); virtual void SetFrame(Frame* f); + void TriMeshUpdateLastPos(void); + void SetGeomFromSBREModel(int sbreModel, ObjParams* params); + void SetGeomSphere(double radius); + void RenderSbreModel(const Frame* camFrame, int model, ObjParams* params); protected: dGeomID m_geom; + CollMesh* sbreCollMesh; };