[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) {
if((L3D::GetCamType() != L3D::CAM_EXTERNAL) && (*i == this)) continue;
Body* b = *i;
vector3d _pos = b->GetPositionRelTo(cam_frame);
vector3d cam_coord = rot*_pos;

View File

@ -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) {

View File

@ -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, &params);
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, &params);
glPushMatrix();
TransformToModelCoords(camFrame);
RenderLaserfire();

View File

@ -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;

View File

@ -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));

View File

@ -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, &params);
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, &params);
RenderSbreModel(camFrame, STATION_SBRE_MODEL, &params);
}

View File

@ -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();

View File

@ -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;
};