[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);
|
||||
}
|
||||
|
||||
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. */
|
||||
vector3d pos = a->GetPosition();
|
||||
|
@ -20,6 +20,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;
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <SDL.h>
|
||||
#include <SDL_opengl.h>
|
||||
#include <SDL_image.h>
|
||||
#include <ode/ode.h>
|
||||
#include <float.h>
|
||||
#include <limits>
|
||||
#include <time.h>
|
||||
|
@ -25,18 +25,13 @@ public:
|
||||
virtual void Disable(void);
|
||||
virtual void Enable(void);
|
||||
void GetAabb(Aabb& aabb);
|
||||
Geom* GetGeom(void) { 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(void);
|
||||
virtual void Load(void);
|
||||
|
@ -2,7 +2,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(void) { return OBJECT; }
|
||||
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 "space_station.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(void) {
|
||||
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();
|
||||
@ -99,10 +99,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));
|
||||
@ -298,20 +296,26 @@ void Ship::TimeStepUpdate(const float timeStep) {
|
||||
|
||||
/* LASERZ!! */
|
||||
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) {
|
||||
|
@ -45,12 +45,6 @@ public:
|
||||
FlightState GetFlightState(void) const { return m_flightState; }
|
||||
float GetWheelState(void) const { return m_wheelState; }
|
||||
|
||||
class LaserObj : public Object {
|
||||
public:
|
||||
OBJDEF(LaserObj, Object, LASER);
|
||||
Ship* owner;
|
||||
};
|
||||
|
||||
EquipSet m_equipment;
|
||||
|
||||
virtual void PostLoadFixup(void);
|
||||
@ -77,9 +71,7 @@ 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;
|
||||
|
108
src/space.cpp
108
src/space.cpp
@ -271,58 +271,10 @@ void Space::UpdateFramesOfReference(void) {
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool _OnCollision(dGeomID g1, dGeomID g2, Object* o1, Object* o2,
|
||||
int numContacts, dContact contacts[]) {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
static bool OnCollision(Object* o1, Object* o2, CollisionContact* c) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -332,7 +284,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);
|
||||
@ -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) {
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user