[Add] Working on collision. Doesn't work, see how changing model scale screws collisions. If I set the model 62 scale to 2.0 then hitting it gives screwed up collisions. On scale 1.0 it works fine though.

This commit is contained in:
Rtch90 2017-11-19 11:41:35 +00:00
parent 15f17e08e5
commit 196e7345a1
19 changed files with 106 additions and 51 deletions

View File

@ -31,7 +31,7 @@ public:
const vector3d& GetProjectedPos() const;
bool IsOnscreen() const { return m_onscreen; }
void SetOnscreen(const bool onscreen) { m_onscreen = onscreen; }
virtual void TimeStepUpdate(const float timeStep) {}
enum { FLAG_CAN_MOVE_FRAME = 1 };
protected:

View File

@ -41,8 +41,9 @@ public:
static void Quit(void);
static float GetFrameTime(void) { return frameTime; }
static double GetGameTime(void) { return gameTime; }
static void SetTimeStep(float s) { timeStep = s; }
static float GetTimeStep(void) { return timeStep; }
static void SetTimeAccel(float s) { timeAccel = s; }
static float GetTimeAccel(void) { return timeAccel; }
static float GetTimeStep(void) { return timeAccel*frameTime; }
static int GetScrWidth(void) { return scrWidth; }
static int GetScrHeight(void) { return scrHeight; }
static int GetScrAspect(void) { return scrAspect; }
@ -91,7 +92,7 @@ private:
static StarSystem* selected_system;
static enum CamType cam_type;
static enum MapView map_view;
static float timeStep;
static float timeAccel;
static float frameTime;
static int scrWidth, scrHeight;
static float scrAspect;

View File

@ -18,7 +18,7 @@
#include "space_station_view.h"
#include "info_view.h"
float L3D::timeStep = 1.0f;
float L3D::timeAccel = 1.0f;
int L3D::scrWidth;
int L3D::scrHeight;
float L3D::scrAspect;
@ -199,7 +199,7 @@ void L3D::MainLoop(void) {
snprintf(buf, sizeof(buf), "X%c-0%02d", "A"+i, i);
body->SetLabel(buf);
body->SetFrame(earth_frame);
body->SetPosition(vector3d(i*200, 0, -200));
body->SetPosition(vector3d(i*2000, 0, -400));
Space::AddBody(body);
}
@ -207,7 +207,7 @@ void L3D::MainLoop(void) {
SpaceStation* body = new SpaceStation();
body->SetLabel("Some Back Country Joint");
body->SetFrame(earth_frame);
body->SetPosition(vector3d(0, 0, 6000));
body->SetPosition(vector3d(0, 0, 600));
Space::AddBody(body);
}
@ -290,7 +290,7 @@ void L3D::MainLoop(void) {
//if(glGetError()) printf("GL: %s\n", gluErrorString(glGetError()));
L3D::frameTime = 0.001*(SDL_GetTicks() - time_before_frame);
float step = L3D::timeStep * L3D::frameTime;
float step = L3D::timeAccel * L3D::frameTime;
time_before_frame = SDL_GetTicks();
/* Game state update stuff. */

View File

@ -53,24 +53,25 @@ void Player::ApplyExternalViewRotation(void) {
}
#define MOUSE_CTRL_AREA 10.0f
#define MOUSE_RESTITUTION 0.9f
#define MOUSE_RESTITUTION 0.01f
void Player::AITurn(void) {
void Player::PollControls(void) {
int mouseMotion[2];
float time_step = L3D::GetTimeStep();
float ts2 = time_step*time_step;
float time_accel = L3D::GetTimeAccel();
float ta2 = time_accel*time_accel;
SetAngThrusterState(0, 0.0f);
SetAngThrusterState(1, 0.0f);
SetAngThrusterState(2, 0.0f);
if(time_step == 0) return;
if(GetDockedWith()) return;
if((time_accel == 0) || GetDockedWith()) {
return;
}
vector3f angThrust(0.0f);
if(L3D::MouseButtonState(3)) {
float restitution = powf(MOUSE_RESTITUTION, time_step);
float restitution = powf(MOUSE_RESTITUTION, L3D::GetTimeStep());
L3D::GetMouseMotion(mouseMotion);
m_mouseCMov[0] += mouseMotion[0];
m_mouseCMov[1] += mouseMotion[1];
@ -93,7 +94,7 @@ void Player::AITurn(void) {
else SetGunState(0,0);
/* No torques at huge time accels -- ODE hates it. */
if(time_step <= 10) {
if(time_accel <= 10) {
if(L3D::GetCamType() != L3D::CAM_EXTERNAL) {
if(L3D::KeyState(SDLK_LEFT)) angThrust.y += 1;
if(L3D::KeyState(SDLK_RIGHT)) angThrust.y += -1;
@ -107,7 +108,7 @@ void Player::AITurn(void) {
GetRotMatrix(rot);
angVel = rot.InverseOf() * angVel;
angVel *= 0.4;
angVel *= 0.6;
angThrust.x -= angVel.x;
angThrust.y -= angVel.y;
angThrust.z -= angVel.z;
@ -116,12 +117,12 @@ void Player::AITurn(void) {
* Divided by time step so controls don't go totally insane when
* used at 10x accel.
*/
angThrust *= 1.0f/ts2;
angThrust *= 1.0f/ta2;
SetAngThrusterState(0, angThrust.x);
SetAngThrusterState(1, angThrust.y);
SetAngThrusterState(2, angThrust.z);
}
if(time_step > 10) {
if(time_accel > 10) {
dBodySetAngularVel(m_body, 0, 0, 0);
}
if(L3D::GetCamType() == L3D::CAM_EXTERNAL) {
@ -133,7 +134,6 @@ void Player::AITurn(void) {
if(L3D::KeyState(SDLK_MINUS)) m_external_view_dist += 10;
m_external_view_dist = MAX(50, m_external_view_dist);
}
Ship::AITurn();
}
#define HUD_CROSSHAIR_SIZE 24.0f

View File

@ -5,7 +5,7 @@
class Player : public Ship {
public:
Player(ShipType::Type shipType);
virtual void AITurn();
void PollControls(void);
virtual void Render(const Frame* camFrame);
void DrawHUD(const Frame* cam_frame);
virtual void SetDockedWith(SpaceStation*);

View File

@ -13,6 +13,21 @@ RigidBody::RigidBody(void) : StaticRigidBody() {
dBodySetMass(m_body, &m_mass);
}
void RigidBody::SetMassDistributionFromCollMesh(const CollMesh* m) {
vector3d min = vector3d(FLT_MAX);
vector3d max = vector3d(-FLT_MAX);
for(int i = 0; i < 3*m->nv; i += 3) {
min.x = MIN(m->pVertex[i], min.x);
min.y = MIN(m->pVertex[i+1], min.y);
min.z = MIN(m->pVertex[i+2], min.z);
max.x = MAX(m->pVertex[i], max.x);
max.y = MAX(m->pVertex[i+1], max.y);
max.z = MAX(m->pVertex[i+2], max.z);
}
dMassSetBox(&m_mass, 1, max.x-min.x, max.y-min.y, max.z-min.z);
dBodySetMass(m_body, &m_mass);
}
vector3d RigidBody::GetAngularMomentum(void) {
matrix4x4d I;
I.LoadFromOdeMatrix(m_mass.I);

View File

@ -15,6 +15,7 @@ public:
void SetMesh(ObjMesh* m);
virtual bool OnCollision(Body* b) { return true; }
vector3d GetAngularMomentum(void);
void SetMassDistributionFromCollMesh(const CollMesh* m);
dBodyID m_body;
dMass m_mass;

View File

@ -88,7 +88,7 @@ static void ResolveVertices(Model* pMod, Vector* pRes, ObjParams* pObjParam) {
static float g_dn, g_df, g_sd;
static int g_wireframe = 0;
float SBRE_ZBIAS = 0;
float SBRE_ZBIAS = 0.00002f;
void sbreSetZBias(float zbias) {
SBRE_ZBIAS = zbias;

View File

@ -37,7 +37,9 @@ Ship::Ship(ShipType::Type shipType) : RigidBody() {
memset(m_thrusters, 0, sizeof(m_thrusters));
const ShipType& stype = GetShipType();
SetGeomFromSBREModel(stype.sbreModel, &params);
SetMassDistributionFromCollMesh(sbreCollMesh);
dGeomSetBody(m_geom, m_body);
UpdateMass();
}
void Ship::UpdateMass(void) {
@ -77,11 +79,10 @@ void Ship::CalcStats(shipstats_t* stats) {
stats->hyperspace_range = 200 * hyperclass * hyperclass / stats->total_mass;
}
void Ship::AITurn(void) {
void Ship::TimeStepUpdate(const float timeStep) {
/* ODE tri mesh likes to know our old position. */
TriMeshUpdateLastPos();
const ShipType& stype = GetShipType();
float timeStep = L3D::GetTimeStep();
for(int i = 0; i < ShipType::THRUSTER_MAX; i++) {
float force = timeStep * stype.linThrust[i] * m_thrusters[i];
switch(i) {
@ -172,7 +173,6 @@ void Ship::RenderLaserfire(void) {
glEnable(GL_LIGHTING);
}
#if 0
static void render_coll_mesh(const CollMesh* m) {
glDisable(GL_LIGHTING);
glColor3f(1, 0, 1);
@ -183,9 +183,18 @@ static void render_coll_mesh(const CollMesh* m) {
glVertex3fv(&m->pVertex[3*m->pIndex[i+2]]);
}
glEnd();
glColor3f(1,1,1);
glDepthRange(0, 1.0f-0.0002f);
for(int i = 0; i < m->ni; i += 3) {
glBegin(GL_LINE_LOOP);
glVertex3fv(&m->pVertex[3*m->pIndex[i]]);
glVertex3fv(&m->pVertex[3*m->pIndex[i+1]]);
glVertex3fv(&m->pVertex[3*m->pIndex[i+2]]);
glEnd();
}
glDepthRange(0.0, 1.0);
glEnable(GL_LIGHTING);
}
#endif
void Ship::Render(const Frame* camFrame) {
const ShipType& stype = GetShipType();
@ -208,6 +217,7 @@ void Ship::Render(const Frame* camFrame) {
glPushMatrix();
TransformToModelCoords(camFrame);
//render_coll_mesh(sbreCollMesh);
RenderLaserfire();
glPopMatrix();
}

View File

@ -17,7 +17,6 @@ struct shipstats_t {
class Ship : public RigidBody {
public:
Ship(ShipType::Type shipType);
virtual void AITurn(void);
virtual Object::Type GetType(void) { return Object::SHIP; }
virtual void SetDockedWith(SpaceStation*);
SpaceStation* GetDockedWith(void) { return m_dockedWith; }
@ -32,6 +31,7 @@ public:
void CalcStats(shipstats_t* stats);
void UpdateMass(void);
void SetWheelState(bool down);
virtual void TimeStepUpdate(const float timeStep);
class LaserObj : public Object {
public:

View File

@ -107,7 +107,7 @@ void ShipCpanel::OnChangeMapView(Gui::MultiStateImageButton* b) {
}
void ShipCpanel::OnClickTimeaccel(Gui::ISelectable* i, double step) {
L3D::SetTimeStep(step);
L3D::SetTimeAccel(step);
}
void ShipCpanel::OnClickComms(void) {

View File

@ -7,7 +7,7 @@ const ShipType ShipType::types[] = {
* Sirius corporation make a range of lovely ships!
*/
"Sirius Interdictor", 61,
{ 1e7, -1e7, 1e6, -1e6, -1e6, 1e6 },
{ 1e8, -1e8, 1e7, -1e6, -1e7, 1e7 },
1e7,
{
{ vector3f(0, -0.5, 0), vector3f(0, 0, -1) },

View File

@ -156,7 +156,7 @@ static void nearCallback(void* data, dGeomID oO, dGeomID o1) {
contact[i].surface.mode = dContactBounce;
contact[i].surface.mu = 0;
contact[i].surface.mu2 = 0;
contact[i].surface.bounce = 0;
contact[i].surface.bounce = 0.5;
contact[i].surface.bounce_vel = 0.1;
}
if(int numc = dCollide(oO, o1, MAX_CONTACTS, &contact[0].geom, sizeof(dContact))) {
@ -178,6 +178,16 @@ static void nearCallback(void* data, dGeomID oO, dGeomID o1) {
* finally create the temp contact joint between the two geom bodies.
*/
dJointID c = dJointCreateContact(Space::world, _contactgroup, contact + i);
printf("Depth: %f\n", contact[i].geom.depth);
#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);
}
}
@ -192,12 +202,15 @@ void Space::CollideFrame(Frame* f) {
void Space::TimeStep(float step) {
CollideFrame(rootFrame);
//CollideFrame(L3D::player->GetFrame());
dWorldQuickStep(world, step);
dJointGroupEmpty(_contactgroup);
/* TODO: Does not need to be done this often. */
UpdateFramesOfReference();
for(bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
(*i)->TimeStepUpdate(step);
}
}
struct body_zsort_t {

View File

@ -20,6 +20,7 @@ public:
static dWorldID world;
static std::list<Body*> bodies;
typedef std::list<Body*>::iterator bodiesIter_t;
private:
static void UpdateFramesOfReference(void);
static void CollideFrame(Frame* f);

View File

@ -22,15 +22,15 @@ static ObjParams params = {
SpaceStation::SpaceStation(void) : StaticRigidBody() {
SetGeomFromSBREModel(STATION_SBRE_MODEL, &params);
matrix4x4d m = matrix4x4d::RotateYMatrix(M_PI);
matrix4x4d m = matrix4x4d::RotateYMatrix(-M_PI/4);
dMatrix3 _m;
m.SaveToOdeMatrix(_m);
dGeomSetRotation(m_geom, _m);
m_mesh = 0;
dGeomSetBody(m_geom, 0);
}
SpaceStation::~SpaceStation(void) {
//dGeomDestroy(m_geom);
dGeomDestroy(m_geom);
}
bool SpaceStation::OnCollision(Body* b) {
@ -48,10 +48,6 @@ bool SpaceStation::OnCollision(Body* b) {
}
}
void SpaceStation::SetMesh(ObjMesh* m) {
m_mesh = m;
}
void SpaceStation::Render(const Frame* camFrame) {
RenderSbreModel(camFrame, STATION_SBRE_MODEL, &params);
}

View File

@ -9,8 +9,6 @@ public:
virtual bool OnCollision(Body* b);
virtual Object::Type GetType(void) { return Object::SPACESTATION; }
virtual void Render(const Frame* camFrame);
void SetMesh(ObjMesh* m);
protected:
ObjMesh* m_mesh;
};

View File

@ -9,6 +9,7 @@
StaticRigidBody::StaticRigidBody(void): Body() {
m_geom = 0;
sbreCollMesh = 0;
triMeshLastMatrixIndex = 0;
}
StaticRigidBody::~StaticRigidBody(void) {
@ -36,10 +37,26 @@ void StaticRigidBody::SetGeomFromSBREModel(int sbreModel, ObjParams* params) {
sbreCollMesh->pVertex[i] = -sbreCollMesh->pVertex[i];
sbreCollMesh->pVertex[i+2] = -sbreCollMesh->pVertex[i+2];
}
/* Make normals. */
meshNormals = new float[sbreCollMesh->ni];
for(int i = 0; i < sbreCollMesh->ni; i += 3) {
float* vtx1 = sbreCollMesh->pVertex + 3*sbreCollMesh->pIndex[i];
float* vtx2 = sbreCollMesh->pVertex + 3*sbreCollMesh->pIndex[i+1];
float* vtx3 = sbreCollMesh->pVertex + 3*sbreCollMesh->pIndex[i+2];
vector3f v1(vtx1[0], vtx1[1], vtx1[2]);
vector3f v2(vtx2[0], vtx2[1], vtx2[2]);
vector3f v3(vtx3[0], vtx3[1], vtx3[2]);
vector3f n = vector3f::Cross(v1-v2, v1-v3);
n.Normalize();
meshNormals[i] = n.x;
meshNormals[i+1] = n.y;
meshNormals[i+2] = n.z;
}
dTriMeshDataID triMeshDataID = dGeomTriMeshDataCreate();
dGeomTriMeshDataBuildSingle(triMeshDataID, (void*)sbreCollMesh->pVertex,
dGeomTriMeshDataBuildSingle1(triMeshDataID, (void*)sbreCollMesh->pVertex,
3*sizeof(float), sbreCollMesh->nv, (void*)sbreCollMesh->pIndex,
sbreCollMesh->ni, 3*sizeof(int));
sbreCollMesh->ni, 3*sizeof(int), NULL/*meshNormals*/);
/* TODO: Leaking StaticRigidBody m_geom. */
m_geom = dCreateTriMesh(0, triMeshDataID, NULL, NULL, NULL);
@ -101,13 +118,13 @@ void StaticRigidBody::TriMeshUpdateLastPos(void) {
/* ODE tri mesh likes to know our old position. */
const dReal* r = dGeomGetRotation(m_geom);
vector3d pos = GetPosition();
dMatrix4 t;
/* Row-major. */
t[0] = r[0]; t[1] = r[1]; t[ 2] = r[ 2]; t[ 3] = pos.x;
t[4] = r[4]; t[5] = r[5]; t[ 6] = r[ 6]; t[ 7] = pos.y;
t[8] = r[8]; t[9] = r[9]; t[10] = r[10]; t[11] = pos.z;
t[12] = t[13] = t[15] = 0;
dGeomTriMeshSetLastTransform(m_geom, t);
dReal* t = triMeshTrans + 16*triMeshLastMatrixIndex;
t[ 0] = r[0]; t[1] = r[1]; t[ 2] = r[ 2]; t[ 3] = 0;
t[ 4] = r[4]; t[5] = r[5]; t[ 6] = r[ 6]; t[ 7] = 0;
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));
}
void StaticRigidBody::RenderSbreModel(const Frame* camFrame, int model, ObjParams* params) {

View File

@ -30,5 +30,8 @@ public:
protected:
dGeomID m_geom;
CollMesh* sbreCollMesh;
float* meshNormals;
dReal triMeshTrans[32];
int triMeshLastMatrixIndex;
};

View File

@ -110,7 +110,7 @@ void WorldView::Update(void) {
m_hyperspaceButton->Hide();
}
/* Player control inputs. */
L3D::player->AITurn();
L3D::player->PollControls();
}
void WorldView::OnMouseDown(Gui::MouseButtonEvent* e) {