[Change] Laser hit uses new collision detection.
This commit is contained in:
parent
279b39dcd7
commit
abfd826e73
@ -58,6 +58,52 @@ void CollisionSpace::TraceRay(const vector3d& start, const vector3d& dir, isect_
|
|||||||
CollideRaySphere(start, 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) {
|
void CollisionSpace::CollideGeoms(Geom* a) {
|
||||||
/* Our big Aabb. */
|
/* Our big Aabb. */
|
||||||
vector3d pos = a->GetPosition();
|
vector3d pos = a->GetPosition();
|
||||||
|
@ -20,6 +20,7 @@ public:
|
|||||||
void AddGeom(Geom*);
|
void AddGeom(Geom*);
|
||||||
void RemoveGeom(Geom*);
|
void RemoveGeom(Geom*);
|
||||||
void TraceRay(const vector3d& start, const vector3d& dir, isect_t* isect);
|
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 Collide(void (*callback)(CollisionContact*));
|
||||||
void SetSphere(const vector3d& pos, double radius, void* user_data) {
|
void SetSphere(const vector3d& pos, double radius, void* user_data) {
|
||||||
sphere.pos = pos; sphere.radius = radius; sphere.userData = user_data;
|
sphere.pos = pos; sphere.radius = radius; sphere.userData = user_data;
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <SDL_opengl.h>
|
#include <SDL_opengl.h>
|
||||||
#include <SDL_image.h>
|
#include <SDL_image.h>
|
||||||
#include <ode/ode.h>
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
@ -25,18 +25,13 @@ public:
|
|||||||
virtual void Disable(void);
|
virtual void Disable(void);
|
||||||
virtual void Enable(void);
|
virtual void Enable(void);
|
||||||
void GetAabb(Aabb& aabb);
|
void GetAabb(Aabb& aabb);
|
||||||
|
Geom* GetGeom(void) { return m_geom; }
|
||||||
|
|
||||||
void TriMeshUpdateLastPos(const matrix4x4d& currentTransform);
|
void TriMeshUpdateLastPos(const matrix4x4d& currentTransform);
|
||||||
void SetModel(int sbreModel);
|
void SetModel(int sbreModel);
|
||||||
|
|
||||||
void RenderSbreModel(const Frame* camFrame, int model, ObjParams* params);
|
void RenderSbreModel(const Frame* camFrame, int model, ObjParams* params);
|
||||||
|
|
||||||
class GeomBit : public Object {
|
|
||||||
public:
|
|
||||||
OBJDEF(GeomBit, Object, GEOM);
|
|
||||||
Body* parent;
|
|
||||||
int flags;
|
|
||||||
};
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Save(void);
|
virtual void Save(void);
|
||||||
virtual void Load(void);
|
virtual void Load(void);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
class Object {
|
class Object {
|
||||||
public:
|
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(void) { return OBJECT; }
|
virtual Type GetType(void) { return OBJECT; }
|
||||||
virtual bool IsType(Type c) { return GetType() == c; }
|
virtual bool IsType(Type c) { return GetType() == c; }
|
||||||
};
|
};
|
||||||
|
26
src/ship.cpp
26
src/ship.cpp
@ -6,6 +6,7 @@
|
|||||||
#include "model_coll_mesh_data.h"
|
#include "model_coll_mesh_data.h"
|
||||||
#include "space_station.h"
|
#include "space_station.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
|
#include "collider/collider.h"
|
||||||
|
|
||||||
static ObjParams params = {
|
static ObjParams params = {
|
||||||
{ 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
{ 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
@ -63,7 +64,6 @@ void Ship::Load(void) {
|
|||||||
m_flightState = (FlightState) rd_int();
|
m_flightState = (FlightState) rd_int();
|
||||||
for(int i = 0; i < ShipType::GUNMOUNT_MAX; i++) {
|
for(int i = 0; i < ShipType::GUNMOUNT_MAX; i++) {
|
||||||
m_gunState[i] = rd_int();
|
m_gunState[i] = rd_int();
|
||||||
m_tempLaserGeom[i] = 0;
|
|
||||||
}
|
}
|
||||||
m_shipType = (ShipType::Type)rd_int();
|
m_shipType = (ShipType::Type)rd_int();
|
||||||
m_dockedWithPort = rd_int();
|
m_dockedWithPort = rd_int();
|
||||||
@ -99,10 +99,8 @@ Ship::Ship(ShipType::Type shipType) : DynamicBody() {
|
|||||||
m_combatTarget = 0;
|
m_combatTarget = 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_equipment = EquipSet(shipType);
|
m_equipment = EquipSet(shipType);
|
||||||
for(int i = 0; i < ShipType::GUNMOUNT_MAX; i++) {
|
for(int i = 0; i < ShipType::GUNMOUNT_MAX; i++) {
|
||||||
m_tempLaserGeom[i] = 0;
|
|
||||||
m_gunState[i] = 0;
|
m_gunState[i] = 0;
|
||||||
}
|
}
|
||||||
memset(m_thrusters, 0, sizeof(m_thrusters));
|
memset(m_thrusters, 0, sizeof(m_thrusters));
|
||||||
@ -298,20 +296,26 @@ void Ship::TimeStepUpdate(const float timeStep) {
|
|||||||
|
|
||||||
/* LASERZ!! */
|
/* LASERZ!! */
|
||||||
for(int i = 0; i < ShipType::GUNMOUNT_MAX; i++) {
|
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;
|
if(!m_gunState[i]) continue;
|
||||||
dGeomID ray = dCreateRay(GetFrame()->GetSpaceID(), 10000);
|
|
||||||
const vector3d pos = GetPosition();
|
|
||||||
const vector3f _dir = stype.gunMount[i].dir;
|
const vector3f _dir = stype.gunMount[i].dir;
|
||||||
vector3d dir = vector3d(_dir.x, _dir.y, _dir.z);
|
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;
|
matrix4x4d m;
|
||||||
GetRotMatrix(m);
|
GetRotMatrix(m);
|
||||||
dir = m.ApplyRotationOnly(dir);
|
dir = m.ApplyRotationOnly(dir);
|
||||||
dGeomRaySet(ray, pos.x, pos.y, pos.z, dir.x, dir.y, dir.z);
|
pos = m.ApplyRotationOnly(pos);
|
||||||
dGeomSetData(ray, static_cast<Object*>(&m_laserCollisionObj));
|
pos += GetPosition();
|
||||||
m_tempLaserGeom[i] = ray; */
|
|
||||||
|
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) {
|
if(m_wheelTransition != 0.0f) {
|
||||||
|
@ -45,12 +45,6 @@ public:
|
|||||||
FlightState GetFlightState(void) const { return m_flightState; }
|
FlightState GetFlightState(void) const { return m_flightState; }
|
||||||
float GetWheelState(void) const { return m_wheelState; }
|
float GetWheelState(void) const { return m_wheelState; }
|
||||||
|
|
||||||
class LaserObj : public Object {
|
|
||||||
public:
|
|
||||||
OBJDEF(LaserObj, Object, LASER);
|
|
||||||
Ship* owner;
|
|
||||||
};
|
|
||||||
|
|
||||||
EquipSet m_equipment;
|
EquipSet m_equipment;
|
||||||
|
|
||||||
virtual void PostLoadFixup(void);
|
virtual void PostLoadFixup(void);
|
||||||
@ -77,9 +71,7 @@ private:
|
|||||||
float m_thrusters[ShipType::THRUSTER_MAX];
|
float m_thrusters[ShipType::THRUSTER_MAX];
|
||||||
float m_angThrusters[3];
|
float m_angThrusters[3];
|
||||||
float m_dockingTimer;
|
float m_dockingTimer;
|
||||||
dGeomID m_tempLaserGeom[ShipType::GUNMOUNT_MAX];
|
|
||||||
|
|
||||||
LaserObj m_laserCollisionObj;
|
|
||||||
Body* m_navTarget;
|
Body* m_navTarget;
|
||||||
Body* m_combatTarget;
|
Body* m_combatTarget;
|
||||||
shipstats_t m_stats;
|
shipstats_t m_stats;
|
||||||
|
108
src/space.cpp
108
src/space.cpp
@ -271,58 +271,10 @@ void Space::UpdateFramesOfReference(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
static bool OnCollision(Object* o1, Object* o2, CollisionContact* c) {
|
||||||
static bool _OnCollision(dGeomID g1, dGeomID g2, Object* o1, Object* o2,
|
Body* pb1 = static_cast<Body*>(o1);
|
||||||
int numContacts, dContact contacts[]) {
|
Body* pb2 = static_cast<Body*>(o2);
|
||||||
if((o1->IsType(Object::LASER)) || (o2->IsType(Object::LASER))) {
|
if((pb1 && !pb1->OnCollision(pb2, c->geomFlag)) || (pb2 && !pb2->OnCollision(pb1, c->geomFlag))) return false;
|
||||||
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;
|
|
||||||
}
|
|
||||||
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +284,7 @@ static void hitCallback(CollisionContact* c) {
|
|||||||
Object* po1 = static_cast<Object*>(c->userData1);
|
Object* po1 = static_cast<Object*>(c->userData1);
|
||||||
Object* po2 = static_cast<Object*>(c->userData2);
|
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 po1_isDynBody = po1->IsType(Object::DYNAMICBODY);
|
||||||
const bool po2_isDynBody = po2->IsType(Object::DYNAMICBODY);
|
const bool po2_isDynBody = po2->IsType(Object::DYNAMICBODY);
|
||||||
@ -401,58 +353,8 @@ static void hitCallback(CollisionContact* c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void nearCallback(void* data, dGeomID oO, 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(oO, o1, MAX_CONTACTS, &contact[0].geom, sizeof(dContact))) {
|
|
||||||
Object* po1 = static_cast<Object*>(dGeomGetData(oO));
|
|
||||||
Object* po2 = static_cast<Object*>(dGeomGetData(o1));
|
|
||||||
if(!_OnCollision(oO, o1, po1, po2, numc, contact)) return;
|
|
||||||
/* Get the dynamics body for each geom. */
|
|
||||||
dBodyID b1 = dGeomGetBody(oO);
|
|
||||||
dBodyID b2 = dGeomGetBody(o1);
|
|
||||||
/*
|
|
||||||
* To add contact point found to our joint group we call dJointCreateContact
|
|
||||||
* which is just one of the many different 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 temp contact joint between the two geom bodies.
|
|
||||||
*/
|
|
||||||
//dJointID c = dJointCreateContact(Space::world, _contactgroup, contact + i);
|
|
||||||
#if 0
|
|
||||||
struct dContactGeom {
|
|
||||||
dVector3 pos; /* Constact position. */
|
|
||||||
dVector3 normal; /* Normal vector. */
|
|
||||||
dReal depth; /* Penetration depth. */
|
|
||||||
dGeomId g1, g2; /* The colliding geoms. */
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//dJointAttach(c, b1, b2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Space::CollideFrame(Frame* f) {
|
void Space::CollideFrame(Frame* f) {
|
||||||
f->GetCollisionSpace()->Collide(&hitCallback);
|
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) {
|
for(std::list<Frame*>::iterator i = f->m_children.begin(); i != f->m_children.end(); ++i) {
|
||||||
CollideFrame(*i);
|
CollideFrame(*i);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user