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-a82653faca30master
parent
866854069c
commit
e678f6912b
|
@ -26,17 +26,12 @@ public:
|
|||
virtual void Disable();
|
||||
virtual void Enable();
|
||||
void GetAabb(Aabb &aabb);
|
||||
Geom *GetGeom() { return m_geom; }
|
||||
|
||||
void TriMeshUpdateLastPos(const matrix4x4d ¤tTransform);
|
||||
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();
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
|
27
src/Ship.cpp
27
src/Ship.cpp
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
109
src/Space.cpp
109
src/Space.cpp
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue