[Change] Get the collision geom flags through to the collision
detection..
This commit is contained in:
parent
08265741a7
commit
40f38a0f58
@ -8,7 +8,7 @@ Lephisto3D_SOURCES = main.cpp gui_button.cpp gui.cpp gui_fixed.cpp gui_screen.cp
|
||||
gui_image_radio_button.cpp gui_multi_state_image_button.cpp ship_cpanel.cpp gui_widget.cpp sector_view.cpp \
|
||||
mtrand.cpp world_view.cpp system_view.cpp star_system.cpp sector.cpp system_info_view.cpp generic_system_view.cpp \
|
||||
gui_container.cpp date.cpp space_station.cpp space_station_view.cpp static_rigid_body.cpp ship_type.cpp \
|
||||
info_view.cpp
|
||||
info_view.cpp model_coll_mesh_data.cpp
|
||||
Lephisto3D_LDADD = sbre/libsbre.a
|
||||
|
||||
include_HEADERS = body.h frame.h generic_system_view.h glfreetype.h gui_button.h gui_container.h gui_events.h gui_fixed.h \
|
||||
@ -16,5 +16,5 @@ include_HEADERS = body.h frame.h generic_system_view.h glfreetype.h gui_button.h
|
||||
gui_radio_group.h gui_screen.h gui_toggle_button.h gui_widget.h libs.h matrix4x4.h mtrand.h objimport.h l3d.h \
|
||||
planet.h player.h rigid_body.h sector.h sector_view.h ship_cpanel.h ship.h space.h star.h star_system.h system_info_view.h \
|
||||
system_view.h vector3.h view.h world_view.h date.h space_station.h space_station_view.h static_rigid_body.h gui_iselectable.h \
|
||||
ship_type.h object.h info_view.h
|
||||
ship_type.h object.h info_view.h model_coll_mesh_data.h
|
||||
|
||||
|
102
src/model_coll_mesh_data.cpp
Normal file
102
src/model_coll_mesh_data.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include "libs.h"
|
||||
#include "model_coll_mesh_data.h"
|
||||
#include "sbre/sbre.h"
|
||||
|
||||
/*
|
||||
* In order to do space station doors and other flagged bits of collision
|
||||
* meshes, we have to make a different dTriMeshData for each.
|
||||
* Vertex indices for each flagged bit of the mesh need to be contiguous,
|
||||
* so we waste some time and memory making this so.
|
||||
*/
|
||||
struct coltri_compare : public std::binary_function<coltri_t, coltri_t, bool> {
|
||||
bool operator()(coltri_t a, coltri_t b) { return a.flags < b.flags; }
|
||||
};
|
||||
|
||||
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.f, 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]. */
|
||||
{ "", "" },
|
||||
};
|
||||
|
||||
/* Indexed by sbre model ID. */
|
||||
static std::map<int, CollMeshSet*> modelCollStuff;
|
||||
|
||||
void CollMeshSet::GetMeshParts(void) {
|
||||
numMeshParts = 1;
|
||||
int curFlag = triIndices[0].flags;
|
||||
for(int i = 0; i < sbreCollMesh->ni/3; i++) {
|
||||
if(curFlag != triIndices[i].flags) numMeshParts++;
|
||||
curFlag = triIndices[i].flags;
|
||||
}
|
||||
printf("%d parts\n", numMeshParts);
|
||||
meshParts = new dTriMeshDataID[numMeshParts];
|
||||
meshFlags = new int[numMeshParts];
|
||||
|
||||
int tidx = 0;
|
||||
int midx = 0;
|
||||
do {
|
||||
int len = 0;
|
||||
int flag = triIndices[tidx].flags;
|
||||
while((len < sbreCollMesh->ni/3) && (triIndices[tidx+len].flags == flag)) len++;
|
||||
printf("%d: len %d\n", tidx, len);
|
||||
|
||||
dTriMeshDataID triMeshDataID = dGeomTriMeshDataCreate();
|
||||
dGeomTriMeshDataBuildSingle(triMeshDataID, (void*)sbreCollMesh->pVertex,
|
||||
3*sizeof(float), sbreCollMesh->nv, (void*)&triIndices[tidx],
|
||||
3*len, 4*sizeof(int));
|
||||
meshFlags[midx] = flag;
|
||||
meshParts[midx++] = triMeshDataID;
|
||||
tidx += len;
|
||||
} while(tidx < sbreCollMesh->ni/3);
|
||||
}
|
||||
|
||||
CollMeshSet::CollMeshSet(int sbreModel) {
|
||||
sbreCollMesh = (CollMesh*)calloc(1, sizeof(CollMesh));
|
||||
sbreGenCollMesh(sbreCollMesh, sbreModel, ¶ms);
|
||||
/* 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];
|
||||
}
|
||||
|
||||
triIndices = new coltri_t[sbreCollMesh->ni/3];
|
||||
int tidx = 0;
|
||||
/* Copy the tri indices into our lovely coltri_t array. */
|
||||
for(int i = 0; i < sbreCollMesh->ni; i += 3) {
|
||||
triIndices[tidx].v1 = sbreCollMesh->pIndex[i];
|
||||
triIndices[tidx].v2 = sbreCollMesh->pIndex[i+1];
|
||||
triIndices[tidx].v3 = sbreCollMesh->pIndex[i+2];
|
||||
triIndices[tidx].flags = sbreCollMesh->pFlag[i/3];
|
||||
tidx++;
|
||||
}
|
||||
/* Sort collmesh tris by flag, ascending. */
|
||||
sort(triIndices, triIndices+(sbreCollMesh->ni/3), coltri_compare());
|
||||
|
||||
GetMeshParts();
|
||||
}
|
||||
|
||||
CollMeshSet* GetModelCollMeshSet(int sbreModel) {
|
||||
std::map<int, CollMeshSet*>::iterator it = modelCollStuff.find(sbreModel);
|
||||
if(it != modelCollStuff.end()) return (*it).second;
|
||||
|
||||
CollMeshSet* cstuff = new CollMeshSet(sbreModel);
|
||||
modelCollStuff[sbreModel] = cstuff;
|
||||
return cstuff;
|
||||
}
|
||||
|
||||
CollMesh* GetModelSBRECollMesh(int sbreModel) {
|
||||
return modelCollStuff[sbreModel]->sbreCollMesh;
|
||||
}
|
||||
|
24
src/model_coll_mesh_data.h
Normal file
24
src/model_coll_mesh_data.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "libs.h"
|
||||
#include "sbre/sbre.h"
|
||||
|
||||
struct coltri_t {
|
||||
int v1, v2, v3, flags;
|
||||
};
|
||||
|
||||
class CollMeshSet {
|
||||
public:
|
||||
CollMesh* sbreCollMesh;
|
||||
coltri_t* triIndices;
|
||||
dTriMeshDataID* meshParts;
|
||||
int* meshFlags;
|
||||
int numMeshParts;
|
||||
|
||||
CollMeshSet(int sbreModel);
|
||||
private:
|
||||
void GetMeshParts(void);
|
||||
};
|
||||
|
||||
CollMeshSet* GetModelCollMeshSet(int sbreModel);
|
||||
CollMesh* GetModelSBRECollMesh(int sbreModel);
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
class Object {
|
||||
public:
|
||||
enum Type { NONE, BODY, SHIP, SPACESTATION, LASER };
|
||||
enum Type { NONE, BODY, SHIP, SPACESTATION, LASER, GEOM };
|
||||
virtual Type GetType(void) = 0;
|
||||
};
|
||||
|
||||
|
@ -672,10 +672,10 @@ static PlainVertex station1vtx1[] = {
|
||||
{ VTYPE_PLAIN, { 0.0f, 0.0f, 25.0f } }, /* 34, ring start, end. */
|
||||
{ VTYPE_PLAIN, { 0.0f, 0.0f, -25.0f } },
|
||||
|
||||
{ VTYPE_PLAIN, { -10.0f, 5.0f, 10.0f } },
|
||||
{ VTYPE_PLAIN, { 10.0f, 5.0f, 10.0f } }, /* 36, inlet middle (for docking). */
|
||||
{ VTYPE_PLAIN, { 10.0f, -5.0f, 10.0f } },
|
||||
{ VTYPE_PLAIN, { -10.0f, -5.0f, 10.0f } },
|
||||
{ VTYPE_PLAIN, { -9.0f, 4.5f, 10.0f } },
|
||||
{ VTYPE_PLAIN, { 9.0f, 4.5f, 10.0f } }, /* 36, inlet middle (for docking). */
|
||||
{ VTYPE_PLAIN, { 9.0f, -4.5f, 10.0f } },
|
||||
{ VTYPE_PLAIN, { -9.0f, -4.5f, 10.0f } },
|
||||
|
||||
#if 0
|
||||
{ VTYPE_PLAIN, { 0.0f, 120.0f, 15.0f } }, /* 34, ring top. */
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "l3d.h"
|
||||
#include "world_view.h"
|
||||
#include "space.h"
|
||||
#include "model_coll_mesh_data.h"
|
||||
|
||||
static ObjParams params = {
|
||||
{ 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
@ -38,8 +39,8 @@ 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);
|
||||
SetMassDistributionFromCollMesh(GetModelSBRECollMesh(stype.sbreModel));
|
||||
GeomsSetBody(m_body);
|
||||
UpdateMass();
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,9 @@ static bool _OnCollision(dGeomID g1, dGeomID g2, Object* o1, Object* o2,
|
||||
}
|
||||
Ship::LaserObj* lobj = static_cast<Ship::LaserObj*>(o2);
|
||||
if(o1 == lobj->owner) return false;
|
||||
printf("%s was shot by %s\n", ((Body*)o1)->GetLabel().c_str(), lobj->owner->GetLabel().c_str());
|
||||
printf("%s (geom flag %x) was shot by %s\n", ((StaticRigidBody::Geom*)o1)->parent->GetLabel().c_str(),
|
||||
((StaticRigidBody::Geom*)o1)->flags, lobj->owner->GetLabel().c_str());
|
||||
|
||||
if(o1->GetType() == Object::SHIP) {
|
||||
RigidBody* rb = (RigidBody*)o1;
|
||||
dVector3 start, dir;
|
||||
@ -147,8 +149,19 @@ static bool _OnCollision(dGeomID g1, dGeomID g2, Object* o1, Object* o2,
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
Body* pb1 = static_cast<Body*>(o1);
|
||||
Body* pb2 = static_cast<Body*>(o2);
|
||||
Body* pb1, *pb2;
|
||||
int flags = 0;
|
||||
/* Geom bodies point to their parents. */
|
||||
if(o1->GetType() == Object::GEOM) {
|
||||
pb1 = static_cast<StaticRigidBody::Geom*>(o1)->parent;
|
||||
flags |= static_cast<StaticRigidBody::Geom*>(o1)->flags;
|
||||
} else pb1 = static_cast<Body*>(o1);
|
||||
if(o2->GetType() == Object::GEOM) {
|
||||
pb2 = static_cast<StaticRigidBody::Geom*>(o2)->parent;
|
||||
flags |= static_cast<StaticRigidBody::Geom*>(o2)->flags;
|
||||
} else pb2 = static_cast<Body*>(o2);
|
||||
|
||||
printf("Collision flags %x\n", flags);
|
||||
if((pb1 && !pb1->OnCollision(pb2)) || (pb2 && !pb2->OnCollision(pb1))) return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -25,8 +25,8 @@ SpaceStation::SpaceStation(void) : StaticRigidBody() {
|
||||
matrix4x4d m = matrix4x4d::RotateYMatrix(-M_PI/4);
|
||||
dMatrix3 _m;
|
||||
m.SaveToOdeMatrix(_m);
|
||||
dGeomSetRotation(m_geom, _m);
|
||||
dGeomSetBody(m_geom, 0);
|
||||
//dGeomSetRotation(m_geom, _m);
|
||||
//dGeomSetBody(m_geom, 0);
|
||||
}
|
||||
|
||||
SpaceStation::~SpaceStation(void) {
|
||||
|
@ -5,51 +5,44 @@
|
||||
#include "frame.h"
|
||||
#include "l3d.h"
|
||||
#include "world_view.h"
|
||||
#include "model_coll_mesh_data.h"
|
||||
|
||||
StaticRigidBody::StaticRigidBody(void): Body() {
|
||||
m_geom = 0;
|
||||
sbreCollMesh = 0;
|
||||
triMeshLastMatrixIndex = 0;
|
||||
}
|
||||
|
||||
StaticRigidBody::~StaticRigidBody(void) {
|
||||
if(sbreCollMesh) {
|
||||
free(sbreCollMesh->pVertex);
|
||||
free(sbreCollMesh->pIndex);
|
||||
free(sbreCollMesh->pFlag);
|
||||
free(sbreCollMesh);
|
||||
}
|
||||
SetFrame(0); /* Will remove geom from frame if necessary. */
|
||||
dGeomDestroy(m_geom);
|
||||
for(unsigned int i = 0; i < geoms.size(); i++) {
|
||||
dGeomDestroy(geoms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void StaticRigidBody::SetGeomSphere(double radius) {
|
||||
assert(!m_geom);
|
||||
m_geom = dCreateSphere(0, radius);
|
||||
void StaticRigidBody::GeomsSetBody(dBodyID body) {
|
||||
for(unsigned int i = 0; i < geoms.size(); i++) {
|
||||
dGeomSetBody(geoms[i], body);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
assert(geoms.size() == 0);
|
||||
CollMeshSet* mset = GetModelCollMeshSet(sbreModel);
|
||||
|
||||
/* TODO: Leaking StaticRigidBody m_geom. */
|
||||
m_geom = dCreateTriMesh(0, triMeshDataID, NULL, NULL, NULL);
|
||||
dGeomSetData(m_geom, static_cast<Body*>(this));
|
||||
geomColl.resize(mset->numMeshParts);
|
||||
geoms.resize(mset->numMeshParts);
|
||||
|
||||
for(unsigned int i = 0; i < mset->numMeshParts; i++) {
|
||||
geoms[i] = dCreateTriMesh(0, mset->meshParts[i], NULL, NULL, NULL);
|
||||
geomColl[i].parent = this;
|
||||
geomColl[i].flags = mset->meshFlags[i];
|
||||
dGeomSetData(geoms[i], static_cast<Object*>(&geomColl[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void StaticRigidBody::SetPosition(vector3d p) {
|
||||
dGeomSetPosition(m_geom, p.x, p.y, p.z);
|
||||
for(unsigned int i = 0; i < geoms.size(); i++) {
|
||||
dGeomSetPosition(geoms[i], p.x, p.y, p.z);
|
||||
}
|
||||
}
|
||||
|
||||
void StaticRigidBody::SetVelocity(vector3d v) {
|
||||
@ -57,12 +50,12 @@ void StaticRigidBody::SetVelocity(vector3d v) {
|
||||
}
|
||||
|
||||
vector3d StaticRigidBody::GetPosition(void) {
|
||||
const dReal* pos = dGeomGetPosition(m_geom);
|
||||
const dReal* pos = dGeomGetPosition(geoms[0]);
|
||||
return vector3d(pos[0], pos[1], pos[2]);
|
||||
}
|
||||
|
||||
void StaticRigidBody::GetRotMatrix(matrix4x4d& m) {
|
||||
m.LoadFromOdeMatrix(dGeomGetRotation(m_geom));
|
||||
m.LoadFromOdeMatrix(dGeomGetRotation(geoms[0]));
|
||||
}
|
||||
|
||||
void StaticRigidBody::ViewingRotation(void) {
|
||||
@ -73,7 +66,7 @@ void StaticRigidBody::ViewingRotation(void) {
|
||||
}
|
||||
|
||||
void StaticRigidBody::TransformCameraTo(void) {
|
||||
const dReal* p = dGeomGetPosition(m_geom);
|
||||
const dReal* p = dGeomGetPosition(geoms[0]);
|
||||
matrix4x4d m;
|
||||
GetRotMatrix(m);
|
||||
m = m.InverseOf();
|
||||
@ -84,7 +77,7 @@ void StaticRigidBody::TransformCameraTo(void) {
|
||||
void StaticRigidBody::TransformToModelCoords(const Frame* camFrame) {
|
||||
vector3d fpos = GetPositionRelTo(camFrame);
|
||||
|
||||
const dReal* r = dGeomGetRotation(m_geom);
|
||||
const dReal* r = dGeomGetRotation(geoms[0]);
|
||||
matrix4x4d m;
|
||||
m[ 0] = r[ 0]; m[ 1] = r[ 4]; m[ 2] = r[ 8]; m[ 3] = 0;
|
||||
m[ 4] = r[ 1]; m[ 5] = r[ 5]; m[ 6] = r[ 9]; m[ 7] = 0;
|
||||
@ -94,14 +87,22 @@ void StaticRigidBody::TransformToModelCoords(const Frame* camFrame) {
|
||||
}
|
||||
|
||||
void StaticRigidBody::SetFrame(Frame* f) {
|
||||
if(GetFrame()) GetFrame()->RemoveGeom(m_geom);
|
||||
if(GetFrame()) {
|
||||
for(unsigned int i = 0; i < geoms.size(); i++) {
|
||||
GetFrame()->RemoveGeom(geoms[i]);
|
||||
}
|
||||
}
|
||||
Body::SetFrame(f);
|
||||
if(f) f->AddGeom(m_geom);
|
||||
if(f) {
|
||||
for(unsigned int i = 0; i < geoms.size(); i++) {
|
||||
f->AddGeom(geoms[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StaticRigidBody::TriMeshUpdateLastPos(void) {
|
||||
/* ODE tri mesh likes to know our old position. */
|
||||
const dReal* r = dGeomGetRotation(m_geom);
|
||||
const dReal* r = dGeomGetRotation(geoms[0]);
|
||||
vector3d pos = GetPosition();
|
||||
dReal* t = triMeshTrans + 16*triMeshLastMatrixIndex;
|
||||
t[ 0] = r[0]; t[1] = r[1]; t[ 2] = r[ 2]; t[ 3] = 0;
|
||||
@ -109,7 +110,9 @@ void StaticRigidBody::TriMeshUpdateLastPos(void) {
|
||||
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));
|
||||
for(unsigned int i = 0; i < geoms.size(); i++) {
|
||||
dGeomTriMeshSetLastTransform(geoms[i], *(dMatrix4*)(triMeshTrans + 16*triMeshLastMatrixIndex));
|
||||
}
|
||||
}
|
||||
|
||||
void StaticRigidBody::RenderSbreModel(const Frame* camFrame, int model, ObjParams* params) {
|
||||
@ -145,7 +148,7 @@ void StaticRigidBody::RenderSbreModel(const Frame* camFrame, int model, ObjParam
|
||||
pos = L3D::world_view->viewingRotation*pos;
|
||||
Vector p; p.x = pos.x; p.y = pos.y; p.z = -pos.z;
|
||||
matrix4x4d rot;
|
||||
rot.LoadFromOdeMatrix(dGeomGetRotation(m_geom));
|
||||
rot.LoadFromOdeMatrix(dGeomGetRotation(geoms[0]));
|
||||
rot = L3D::world_view->viewingRotation * rot;
|
||||
Matrix m;
|
||||
m.x1 = rot[0]; m.x2 = rot[4]; m.x3 = -rot[8];
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "body.h"
|
||||
#include "vector3.h"
|
||||
#include "matrix4x4.h"
|
||||
@ -21,16 +22,22 @@ public:
|
||||
void ViewingRotation(void);
|
||||
void GetRotMatrix(matrix4x4d& m);
|
||||
virtual void SetFrame(Frame* f);
|
||||
void GeomsSetBody(dBodyID body);
|
||||
|
||||
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;
|
||||
float* meshNormals;
|
||||
|
||||
class Geom : public Object {
|
||||
public:
|
||||
virtual Type GetType(void) { return Object::GEOM; }
|
||||
Body* parent;
|
||||
int flags;
|
||||
};
|
||||
private:
|
||||
std::vector<Geom> geomColl;
|
||||
std::vector<dGeomID> geoms;
|
||||
dReal triMeshTrans[32];
|
||||
int triMeshLastMatrixIndex;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user