laser hit detection using new collision detection. ode replacement all done now maybe

git-svn-id: https://pioneer.svn.sourceforge.net/svnroot/pioneer/trunk@154 e632f14b-6550-0410-b89e-a82653faca30
master
tompox 2008-11-12 17:57:34 +00:00
parent 866854069c
commit e678f6912b
8 changed files with 68 additions and 133 deletions

View File

@ -26,17 +26,12 @@ public:
virtual void Disable();
virtual void Enable();
void GetAabb(Aabb &aabb);
Geom *GetGeom() { return m_geom; }
void TriMeshUpdateLastPos(const matrix4x4d &currentTransform);
void SetModel(int sbreModel);
void RenderSbreModel(const Frame *camFrame, int model, ObjParams *params);
class GeomBit: public Object {
public:
OBJDEF(GeomBit, Object, GEOM);
Body *parent;
int flags;
};
protected:
virtual void Save();
virtual void Load();

View File

@ -3,7 +3,7 @@
class Object {
public:
enum Type { OBJECT, BODY, MODELBODY, DYNAMICBODY, SHIP, PLAYER, SPACESTATION, LASER, GEOM, PLANET, STAR };
enum Type { OBJECT, BODY, MODELBODY, DYNAMICBODY, SHIP, PLAYER, SPACESTATION, PLANET, STAR };
virtual Type GetType() { return OBJECT; }
virtual bool IsType(Type c) { return GetType() == c; }
};

View File

@ -6,6 +6,7 @@
#include "ModelCollMeshData.h"
#include "SpaceStation.h"
#include "Serializer.h"
#include "collider/collider.h"
static ObjParams params = {
{ 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
@ -63,7 +64,6 @@ void Ship::Load()
m_flightState = (FlightState) rd_int();
for (int i=0; i<ShipType::GUNMOUNT_MAX; i++) {
m_gunState[i] = rd_int();
m_tempLaserGeom[i] = 0;
}
m_shipType = (ShipType::Type)rd_int();
m_dockedWithPort = rd_int();
@ -102,10 +102,8 @@ Ship::Ship(ShipType::Type shipType): DynamicBody()
m_combatTarget = 0;
m_shipType = shipType;
m_angThrusters[0] = m_angThrusters[1] = m_angThrusters[2] = 0;
m_laserCollisionObj.owner = this;
m_equipment = EquipSet(shipType);
for (int i=0; i<ShipType::GUNMOUNT_MAX; i++) {
m_tempLaserGeom[i] = 0;
m_gunState[i] = 0;
}
memset(m_thrusters, 0, sizeof(m_thrusters));
@ -304,21 +302,26 @@ void Ship::TimeStepUpdate(const float timeStep)
stype.angThrust*m_angThrusters[2]));
// lasers
for (int i=0; i<ShipType::GUNMOUNT_MAX; i++) {
// free old temp laser geoms
/*if (m_tempLaserGeom[i]) dGeomDestroy(m_tempLaserGeom[i]);
m_tempLaserGeom[i] = 0;
if (!m_gunState[i]) continue;
dGeomID ray = dCreateRay(GetFrame()->GetSpaceID(), 10000);
const vector3d pos = GetPosition();
const vector3f _dir = stype.gunMount[i].dir;
vector3d dir = vector3d(_dir.x, _dir.y, _dir.z);
const vector3f _pos = stype.gunMount[i].pos;
vector3d pos = vector3d(_pos.x, _pos.y, _pos.z);
matrix4x4d m;
GetRotMatrix(m);
dir = m.ApplyRotationOnly(dir);
dGeomRaySet(ray, pos.x, pos.y, pos.z, dir.x, dir.y, dir.z);
dGeomSetData(ray, static_cast<Object*>(&m_laserCollisionObj));
m_tempLaserGeom[i] = ray;
*/
pos = m.ApplyRotationOnly(pos);
pos += GetPosition();
CollisionContact c;
GetFrame()->GetCollisionSpace()->TraceRay(pos, dir, 10000.0, &c, GetGeom());
if (c.userData1) {
Body *hit = static_cast<Body*>(c.userData1);
printf("Hit %s\n", hit->GetLabel().c_str());
} else {
printf("Hit nothing\n");
}
}
if (m_wheelTransition != 0.0f) {

View File

@ -47,12 +47,6 @@ public:
FlightState GetFlightState() const { return m_flightState; }
float GetWheelState() const { return m_wheelState; }
class LaserObj: public Object {
public:
OBJDEF(LaserObj, Object, LASER);
Ship *owner;
};
EquipSet m_equipment;
virtual void PostLoadFixup();
@ -79,9 +73,6 @@ private:
float m_thrusters[ShipType::THRUSTER_MAX];
float m_angThrusters[3];
float m_dockingTimer;
dGeomID m_tempLaserGeom[ShipType::GUNMOUNT_MAX];
LaserObj m_laserCollisionObj;
Body* m_navTarget;
Body* m_combatTarget;
shipstats_t m_stats;

View File

@ -275,67 +275,13 @@ void Space::UpdateFramesOfReference()
}
}
/*
* return false if ode is not to apply collision
*/
#if 0
static bool _OnCollision(dGeomID g1, dGeomID g2, Object *o1, Object *o2, int numContacts, dContact contacts[])
static bool OnCollision(Object *o1, Object *o2, CollisionContact *c)
{
if ((o1->IsType(Object::LASER)) || (o2->IsType(Object::LASER))) {
if (o1->IsType(Object::LASER)) {
std::swap<Object*>(o1, o2);
std::swap<dGeomID>(g1, g2);
}
Ship::LaserObj *lobj = static_cast<Ship::LaserObj*>(o2);
if (o1 == lobj->owner) return false;
if (o1->IsType(Object::SHIP)) {
DynamicBody *rb = (DynamicBody*)o1;
dVector3 start,dir;
dGeomRayGet(g2, start, dir);
rb->AddForceAtPos(vector3d(dir[0], dir[1], dir[2])*100,
vector3d(contacts[0].geom.pos[0], contacts[0].geom.pos[1], contacts[0].geom.pos[2]));
}
return false;
} else {
Body *pb1, *pb2;
int flags = 0;
// geom bodies point to their parents
if (o1->IsType(Object::GEOM)) {
pb1 = static_cast<ModelBody::GeomBit*>(o1)->parent;
flags |= static_cast<ModelBody::GeomBit*>(o1)->flags;
} else pb1 = static_cast<Body*>(o1);
if (o2->IsType(Object::GEOM)) {
pb2 = static_cast<ModelBody::GeomBit*>(o2)->parent;
flags |= static_cast<ModelBody::GeomBit*>(o2)->flags;
} else pb2 = static_cast<Body*>(o2);
if ((pb1 && !pb1->OnCollision(pb2, flags)) || (pb2 && !pb2->OnCollision(pb1, flags))) return false;
}
Body *pb1 = static_cast<Body*>(o1);
Body *pb2 = static_cast<Body*>(o2);
if ((pb1 && !pb1->OnCollision(pb2, c->geomFlag)) || (pb2 && !pb2->OnCollision(pb1, c->geomFlag))) return false;
return true;
}
#endif
static bool _OnCollision2(Object *o1, Object *o2, CollisionContact *c)
{
Body *pb1, *pb2;
int flags = c->geomFlag;
// printf("Collision flags %x (triIdx %d)\n", flags, c->triIdx);
// geom bodies point to their parents
if (o1->IsType(Object::GEOM)) {
pb1 = static_cast<ModelBody::GeomBit*>(o1)->parent;
flags |= static_cast<ModelBody::GeomBit*>(o1)->flags;
} else pb1 = static_cast<Body*>(o1);
if (o2->IsType(Object::GEOM)) {
pb2 = static_cast<ModelBody::GeomBit*>(o2)->parent;
flags |= static_cast<ModelBody::GeomBit*>(o2)->flags;
} else pb2 = static_cast<Body*>(o2);
if ((pb1 && !pb1->OnCollision(pb2, flags)) || (pb2 && !pb2->OnCollision(pb1, flags))) return false;
return true;
}
static void hitCallback(CollisionContact *c)
{
@ -344,7 +290,7 @@ static void hitCallback(CollisionContact *c)
Object *po1 = static_cast<Object*>(c->userData1);
Object *po2 = static_cast<Object*>(c->userData2);
if (!_OnCollision2(po1, po2, c)) return;
if (!OnCollision(po1, po2, c)) return;
const bool po1_isDynBody = po1->IsType(Object::DYNAMICBODY);
const bool po2_isDynBody = po2->IsType(Object::DYNAMICBODY);
@ -410,55 +356,10 @@ static void hitCallback(CollisionContact *c)
mover->SetAngVelocity(mover->GetAngVelocity() - vector3d::Cross(hitPos1, (j*c->normal))*(1.0/mover->GetAngularInertia()));
}
}
#if 0
static void nearCallback(void *data, dGeomID o0, dGeomID o1)
{
// Create an array of dContact objects to hold the contact joints
static const int MAX_CONTACTS = 100;
dContact contact[MAX_CONTACTS];
for (int i = 0; i < MAX_CONTACTS; i++)
{
contact[i].surface.mode = dContactBounce;
contact[i].surface.mu = 0.8;
contact[i].surface.mu2 = 0;
contact[i].surface.bounce = 0.1;
contact[i].surface.bounce_vel = 0.1;
}
if (int numc = dCollide(o0, o1, MAX_CONTACTS, &contact[0].geom, sizeof(dContact)))
{
// don't ye get confused between Pi Body class and libODE bodies
Object *po1 = static_cast<Object*>(dGeomGetData(o0));
Object *po2 = static_cast<Object*>(dGeomGetData(o1));
if (!_OnCollision(o0, o1, po1, po2, numc, contact)) return;
// Get the dynamics body for each geom
dBodyID b1 = dGeomGetBody(o0);
dBodyID b2 = dGeomGetBody(o1);
// To add each contact point found to our joint group we call dJointCreateContact which is just one of the many
// different joint types available.
for (int i = 0; i < numc; i++)
{
printf("\nODE collision:\n");
dump_contact(contact+i);
// dJointCreateContact needs to know which world and joint group to work with as well as the dContact
// object itself. It returns a new dJointID which we then use with dJointAttach to finally create the
// temporary contact joint between the two geom bodies.
//dJointID c = dJointCreateContact(Space::world, _contactgroup, contact + i);
/* struct dContactGeom {
dVector3 pos; // contact position
dVector3 normal; // normal vector
dReal depth; // penetration depth
dGeomID g1,g2; // the colliding geoms
};*/
//dJointAttach(c, b1, b2);
}
}
}
#endif
void Space::CollideFrame(Frame *f)
{
f->GetCollisionSpace()->Collide(&hitCallback);
//dSpaceCollide(f->GetSpaceID(), NULL, &nearCallback);
for (std::list<Frame*>::iterator i = f->m_children.begin(); i != f->m_children.end(); ++i) {
CollideFrame(*i);
}

View File

@ -63,6 +63,51 @@ void CollisionSpace::TraceRay(const vector3d &start, const vector3d &dir, isect_
CollideRaySphere(start, dir, isect);
}
void CollisionSpace::TraceRay(const vector3d &start, const vector3d &dir, float len, CollisionContact *c, Geom *ignore)
{
double dist = len;
for (std::list<Geom*>::iterator i = m_geoms.begin(); i != m_geoms.end(); ++i) {
if ((*i) == ignore) continue;
if ((*i)->IsEnabled()) {
const matrix4x4d &invTrans = (*i)->GetInvTransform();
vector3d ms = invTrans * start;
vector3d md = invTrans.ApplyRotationOnly(dir);
vector3f modelStart = vector3f(ms.x, ms.y, ms.z);
vector3f modelDir = vector3f(md.x, md.y, md.z);
isect_t isect;
isect.dist = dist;
isect.triIdx = -1;
(*i)->GetGeomTree()->TraceRay(modelStart, modelDir, &isect);
if (isect.triIdx != -1) {
c->pos = start + dir*isect.dist;
c->normal = vector3d(0.0);
c->depth = len - isect.dist;
c->triIdx = isect.triIdx;
c->userData1 = (*i)->GetUserData();
c->userData2 = 0;
c->geomFlag = (*i)->GetGeomTree()->GetTriFlag(isect.triIdx);
dist = isect.dist;
}
}
}
{
isect_t isect;
isect.dist = dist;
isect.triIdx = -1;
CollideRaySphere(start, dir, &isect);
if (isect.triIdx != -1) {
c->pos = start + dir*isect.dist;
c->normal = vector3d(0.0);
c->depth = len - isect.dist;
c->triIdx = -1;
c->userData1 = sphere.userData;
c->userData2 = 0;
c->geomFlag = 0;
}
}
}
void CollisionSpace::CollideGeoms(Geom *a)
{
// our big aabb

View File

@ -22,6 +22,7 @@ public:
void AddGeom(Geom*);
void RemoveGeom(Geom*);
void TraceRay(const vector3d &start, const vector3d &dir, isect_t *isect);
void TraceRay(const vector3d &start, const vector3d &dir, float len, CollisionContact *c, Geom *ignore = 0);
void Collide(void (*callback)(CollisionContact*));
void SetSphere(const vector3d &pos, double radius, void *user_data) {
sphere.pos = pos; sphere.radius = radius; sphere.userData = user_data;

View File

@ -7,7 +7,6 @@
#include <SDL.h>
#include <SDL_opengl.h>
#include <SDL_image.h>
#include <ode/ode.h>
#include <float.h>
#include <limits>
#include <time.h>