[Add] Collisions using collision meshes.

This commit is contained in:
Rtch90 2017-11-18 18:18:31 +00:00
parent dadae15b47
commit 2a5a81dcf3
8 changed files with 114 additions and 51 deletions

View File

@ -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) { 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; Body* b = *i;
vector3d _pos = b->GetPositionRelTo(cam_frame); vector3d _pos = b->GetPositionRelTo(cam_frame);
vector3d cam_coord = rot*_pos; vector3d cam_coord = rot*_pos;

View File

@ -11,8 +11,6 @@ RigidBody::RigidBody(void) : StaticRigidBody() {
dMassAdjust(&m_mass, 1.0f); dMassAdjust(&m_mass, 1.0f);
dBodySetMass(m_body, &m_mass); dBodySetMass(m_body, &m_mass);
dGeomSetBody(m_geom, m_body);
SetPosition(vector3d(0,0,0));
} }
vector3d RigidBody::GetAngularMomentum(void) { vector3d RigidBody::GetAngularMomentum(void) {

View File

@ -3,15 +3,29 @@
#include "frame.h" #include "frame.h"
#include "l3d.h" #include "l3d.h"
#include "world_view.h" #include "world_view.h"
#include "sbre/sbre.h"
#include "space.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() { Ship::Ship(ShipType::Type shipType) : RigidBody() {
m_wheelTransition = 0; m_wheelTransition = 0;
m_wheelState = 0; m_wheelState = 0;
m_dockedWith = 0; m_dockedWith = 0;
m_target = 0; m_target = 0;
m_mesh = 0;
m_shipType = shipType; m_shipType = shipType;
m_angThrusters[0] = m_angThrusters[1] = m_angThrusters[2] = 0; m_angThrusters[0] = m_angThrusters[1] = m_angThrusters[2] = 0;
m_laserCollisionObj.owner = this; m_laserCollisionObj.owner = this;
@ -20,7 +34,9 @@ Ship::Ship(ShipType::Type shipType) : RigidBody() {
m_tempLaserGeom[i] = 0; m_tempLaserGeom[i] = 0;
m_gunState[i] = 0; m_gunState[i] = 0;
} }
dGeomSetData(m_geom, static_cast<Body*>(this)); const ShipType& stype = GetShipType();
SetGeomFromSBREModel(stype.sbreModel, &params);
dGeomSetBody(m_geom, m_body);
} }
void Ship::UpdateMass(void) { void Ship::UpdateMass(void) {
@ -61,6 +77,8 @@ void Ship::CalcStats(shipstats_t* stats) {
} }
void Ship::AITurn(void) { void Ship::AITurn(void) {
/* ODE tri mesh likes to know our old position. */
TriMeshUpdateLastPos();
const ShipType& stype = GetShipType(); const ShipType& stype = GetShipType();
float timeStep = L3D::GetTimeStep(); float timeStep = L3D::GetTimeStep();
for(int i = 0; i < ShipType::THRUSTER_MAX; i++) { 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) { void Ship::SetGunState(int idx, int state) {
m_gunState[idx] = state; m_gunState[idx] = state;
} }
@ -157,20 +171,20 @@ void Ship::RenderLaserfire(void) {
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
} }
static ObjParams params = { #if 0
{ 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, static void render_coll_mesh(const CollMesh* m) {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, glDisable(GL_LIGHTING);
{ 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, glColor3f(1, 0, 1);
glBegin(GL_TRIANGLES);
/* pColor[3] */ for(int i = 0; i < m->ni; i += 3) {
{ glVertex3fv(&m->pVertex[3*m->pIndex[i]]);
{ { 1.0f, 0.0f, 1.0f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 }, glVertex3fv(&m->pVertex[3*m->pIndex[i+1]]);
{ { 0.8f, 0.6f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 }, glVertex3fv(&m->pVertex[3*m->pIndex[i+2]]);
{ { 0.5f, 0.5f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 } }
}, glEnd();
/* pText[3][256] */ glEnable(GL_LIGHTING);
{ "IZ-L33T", "ME TOO" }, }
}; #endif
void Ship::Render(const Frame* camFrame) { void Ship::Render(const Frame* camFrame) {
const ShipType& stype = GetShipType(); const ShipType& stype = GetShipType();
@ -190,6 +204,7 @@ void Ship::Render(const Frame* camFrame) {
strncpy(params.pText[0], GetLabel().c_str(), sizeof(params.pText)); strncpy(params.pText[0], GetLabel().c_str(), sizeof(params.pText));
RenderSbreModel(camFrame, stype.sbreModel, &params); RenderSbreModel(camFrame, stype.sbreModel, &params);
glPushMatrix(); glPushMatrix();
TransformToModelCoords(camFrame); TransformToModelCoords(camFrame);
RenderLaserfire(); RenderLaserfire();

View File

@ -2,6 +2,7 @@
#include "libs.h" #include "libs.h"
#include "rigid_body.h" #include "rigid_body.h"
#include "ship_type.h" #include "ship_type.h"
#include "sbre/sbre.h"
class SpaceStation; class SpaceStation;
@ -23,7 +24,6 @@ public:
void SetTarget(Body* const target) { m_target = target; } void SetTarget(Body* const target) { m_target = target; }
Body* GetTarget(void) const { return m_target; } Body* GetTarget(void) const { return m_target; }
virtual void Render(const Frame* camFrame); virtual void Render(const Frame* camFrame);
void SetMesh(ObjMesh* m);
void SetThrusterState(enum ShipType::Thruster t, float level); void SetThrusterState(enum ShipType::Thruster t, float level);
void SetAngThrusterState(int axis, float level) { m_angThrusters[axis] = CLAMP(level, -1, 1); } void SetAngThrusterState(int axis, float level) { m_angThrusters[axis] = CLAMP(level, -1, 1); }
void ClearThrusterState(void); void ClearThrusterState(void);
@ -45,7 +45,6 @@ protected:
SpaceStation* m_dockedWith; SpaceStation* m_dockedWith;
enum ShipType::Type m_shipType; enum ShipType::Type m_shipType;
ObjMesh* m_mesh;
Uint32 m_gunState[ShipType::GUNMOUNT_MAX]; Uint32 m_gunState[ShipType::GUNMOUNT_MAX];
private: private:
float m_wheelState; float m_wheelState;

View File

@ -153,12 +153,11 @@ static void nearCallback(void* data, dGeomID oO, dGeomID o1) {
dContact contact[MAX_CONTACTS]; dContact contact[MAX_CONTACTS];
for(int i = 0; i < MAX_CONTACTS; i++) { for(int i = 0; i < MAX_CONTACTS; i++) {
contact[i].surface.mode = dContactBounce | dContactSoftCFM; contact[i].surface.mode = dContactBounce;
contact[i].surface.mu = dInfinity; contact[i].surface.mu = 0;
contact[i].surface.mu2 = 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.bounce_vel = 0.1;
contact[i].surface.soft_cfm = 0.01;
} }
if(int numc = dCollide(oO, o1, MAX_CONTACTS, &contact[0].geom, sizeof(dContact))) { if(int numc = dCollide(oO, o1, MAX_CONTACTS, &contact[0].geom, sizeof(dContact))) {
Object* po1 = static_cast<Object*>(dGeomGetData(oO)); Object* po1 = static_cast<Object*>(dGeomGetData(oO));

View File

@ -2,9 +2,26 @@
#include "ship.h" #include "ship.h"
#include "objimport.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() { SpaceStation::SpaceStation(void) : StaticRigidBody() {
dGeomSphereSetRadius(m_geom, 100.0); SetGeomFromSBREModel(STATION_SBRE_MODEL, &params);
dGeomSetData(m_geom, static_cast<Body*>(this));
matrix4x4d m = matrix4x4d::RotateYMatrix(M_PI); matrix4x4d m = matrix4x4d::RotateYMatrix(M_PI);
dMatrix3 _m; dMatrix3 _m;
m.SaveToOdeMatrix(_m); m.SaveToOdeMatrix(_m);
@ -17,6 +34,8 @@ SpaceStation::~SpaceStation(void) {
} }
bool SpaceStation::OnCollision(Body* b) { bool SpaceStation::OnCollision(Body* b) {
return true;
if(b->GetType() == Object::SHIP) { if(b->GetType() == Object::SHIP) {
Ship* s = static_cast<Ship*>(b); Ship* s = static_cast<Ship*>(b);
if(!s->GetDockedWith()) { if(!s->GetDockedWith()) {
@ -33,23 +52,7 @@ void SpaceStation::SetMesh(ObjMesh* m) {
m_mesh = 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) { void SpaceStation::Render(const Frame* camFrame) {
RenderSbreModel(camFrame, 65, &params); RenderSbreModel(camFrame, STATION_SBRE_MODEL, &params);
} }

View File

@ -7,15 +7,45 @@
#include "world_view.h" #include "world_view.h"
StaticRigidBody::StaticRigidBody(void): Body() { StaticRigidBody::StaticRigidBody(void): Body() {
m_geom = dCreateSphere(0, 50.0f); m_geom = 0;
dGeomSetBody(m_geom, 0); sbreCollMesh = 0;
SetPosition(vector3d(0,0,0));
} }
StaticRigidBody::~StaticRigidBody(void) { StaticRigidBody::~StaticRigidBody(void) {
if(sbreCollMesh) {
free(sbreCollMesh->pVertex);
free(sbreCollMesh->pIndex);
free(sbreCollMesh->pFlag);
free(sbreCollMesh);
}
dGeomDestroy(m_geom); 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) { void StaticRigidBody::SetPosition(vector3d p) {
dGeomSetPosition(m_geom, p.x, p.y, p.z); dGeomSetPosition(m_geom, p.x, p.y, p.z);
} }
@ -67,6 +97,19 @@ void StaticRigidBody::SetFrame(Frame* f) {
if(f) f->AddGeom(m_geom); 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) { void StaticRigidBody::RenderSbreModel(const Frame* camFrame, int model, ObjParams* params) {
glPushMatrix(); glPushMatrix();

View File

@ -22,8 +22,13 @@ public:
void GetRotMatrix(matrix4x4d& m); void GetRotMatrix(matrix4x4d& m);
virtual void SetFrame(Frame* f); 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); void RenderSbreModel(const Frame* camFrame, int model, ObjParams* params);
protected: protected:
dGeomID m_geom; dGeomID m_geom;
CollMesh* sbreCollMesh;
}; };