diff --git a/src/main.cpp b/src/main.cpp index 19e5b57..3a7432a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -205,9 +205,9 @@ void L3D::MainLoop(void) { { SpaceStation* body = new SpaceStation(); - body->SetLabel("Some Back Country Joint"); + body->SetLabel("Poemi-chan's Folly"); body->SetFrame(earth_frame); - body->SetPosition(vector3d(0, 0, 7999400)); + body->SetPosition(vector3d(0, 0, 7998000)); Space::AddBody(body); } diff --git a/src/matrix4x4.h b/src/matrix4x4.h index f9cec86..d981668 100644 --- a/src/matrix4x4.h +++ b/src/matrix4x4.h @@ -60,6 +60,14 @@ public: return m; } + static matrix4x4 MakeRotMatrix(vector3 rx, vector3 ry, vector3 rz) { + matrix4x4 m; + m[0] = rx.x; m[4] = rx.y; m[ 8] = rx.z; m[12] = 0; + m[1] = ry.x; m[5] = ry.y; m[ 9] = ry.z; m[13] = 0; + m[2] = rz.x; m[6] = rz.y; m[10] = rz.z; m[14] = 0; + m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1; + } + void RotateZ(T radians) { *this = (*this) * RotateZMatrix(radians); } void RotateY(T radians) { *this = (*this) * RotateYMatrix(radians); } void rotateX(T radians) { *this = (*this) * RotateXMatrix(radians); } diff --git a/src/model_body.cpp b/src/model_body.cpp index 47cbcde..8519109 100644 --- a/src/model_body.cpp +++ b/src/model_body.cpp @@ -43,10 +43,10 @@ void ModelBody::SetModel(int sbreModel) { geomColl.resize(mset->numMeshParts); geoms.resize(mset->numMeshParts); - for(unsigned int i = 0; i < mset->numMeshParts; i++) { + for(int i = 0; i < mset->numMeshParts; i++) { geoms[i] = dCreateTriMesh(0, mset->meshParts[i], NULL, NULL, NULL); geomColl[i].parent = this; - geomColl[i].flags = mset->meshFlags[i]; + geomColl[i].flags = mset->meshInfo[i].flags; dGeomSetData(geoms[i], static_cast(&geomColl[i])); } } diff --git a/src/model_body.h b/src/model_body.h index f245dec..2a05a15 100644 --- a/src/model_body.h +++ b/src/model_body.h @@ -36,8 +36,9 @@ public: Body* parent; int flags; }; -private: +protected: std::vector geomColl; +private: std::vector geoms; dReal triMeshTrans[32]; int triMeshLastMatrixIndex; diff --git a/src/model_coll_mesh_data.cpp b/src/model_coll_mesh_data.cpp index 9e91084..d368d17 100644 --- a/src/model_coll_mesh_data.cpp +++ b/src/model_coll_mesh_data.cpp @@ -40,9 +40,9 @@ void CollMeshSet::GetMeshParts(void) { if(curFlag != triIndices[i].flags) numMeshParts++; curFlag = triIndices[i].flags; } - printf("%d parts\n", numMeshParts); + //printf("%d parts\n", numMeshParts); meshParts = new dTriMeshDataID[numMeshParts]; - meshFlags = new int[numMeshParts]; + meshInfo = new meshinfo_t[numMeshParts]; int tidx = 0; int midx = 0; @@ -50,14 +50,16 @@ void CollMeshSet::GetMeshParts(void) { int len = 0; int flag = triIndices[tidx].flags; while((len < sbreCollMesh->ni/3) && (triIndices[tidx+len].flags == flag)) len++; - printf("%d: len %d\n", tidx, len); + //printf("%d: len %d\n", tidx, len); dTriMeshDataID triMeshDataID = dGeomTriMeshDataCreate(); dGeomTriMeshDataBuildSingle(triMeshDataID, (void*)sbreCollMesh->pVertex, 3*sizeof(float), sbreCollMesh->nv, (void*)&triIndices[tidx], 3*len, 4*sizeof(int)); - meshFlags[midx] = flag; - meshParts[midx++] = triMeshDataID; + meshInfo[midx].flags = flag; + meshInfo[midx].triStart = tidx; + meshInfo[midx].numTris = len; + meshParts[midx++] = triMeshDataID; tidx += len; } while(tidx < sbreCollMesh->ni/3); } diff --git a/src/model_coll_mesh_data.h b/src/model_coll_mesh_data.h index 889a909..8cbca35 100644 --- a/src/model_coll_mesh_data.h +++ b/src/model_coll_mesh_data.h @@ -6,12 +6,18 @@ struct coltri_t { int v1, v2, v3, flags; }; +struct meshinfo_t { + int flags; + int triStart; /* Into triIndices. */ + int numTris; +}; + class CollMeshSet { public: CollMesh* sbreCollMesh; coltri_t* triIndices; dTriMeshDataID* meshParts; - int* meshFlags; + meshinfo_t* meshInfo; int numMeshParts; CollMeshSet(int sbreModel); diff --git a/src/sbre/models.cpp b/src/sbre/models.cpp index 24a9d21..0bb71a3 100644 --- a/src/sbre/models.cpp +++ b/src/sbre/models.cpp @@ -781,7 +781,7 @@ static uint16 station1data[] = { PTYPE_END, }; -Model station1model = { 4.0f, 120.0f, 40, station1vtx1, 100, 0, station1vtx2, 1, +Model station1model = { 10.0f, 120.0f, 40, station1vtx1, 100, 0, station1vtx2, 1, { { 0, station1data, 0, 0, 0 } } }; static PlainVertex ship3vtx1[] = { diff --git a/src/ship.cpp b/src/ship.cpp index 6115de2..cc7a654 100644 --- a/src/ship.cpp +++ b/src/ship.cpp @@ -5,6 +5,7 @@ #include "world_view.h" #include "space.h" #include "model_coll_mesh_data.h" +#include "space_station.h" static ObjParams params = { { 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, @@ -141,13 +142,25 @@ const ShipType& Ship::GetShipType(void) { void Ship::SetDockedWith(SpaceStation* s) { if(m_dockedWith && !s) { - /* Launching. */ - printf("Buhbai!\n"); - m_dockedWith = 0; - Enable(); - vector3d pos = GetPosition(); - pos.x += 5000; + /* + * Position player in middle of docking bay, pointing out of it. + * TODO Need to do forced thrusting thingy. + * TODO ang vel not zeroed for some reason.. + */ + matrix4x4d stationRot; + m_dockedWith->GetRotMatrix(stationRot); + vector3d port_y = vector3d::Cross(-m_dockedWith->port.horiz, m_dockedWith->port.normal); + matrix4x4d rot = stationRot * matrix4x4d::MakeRotMatrix(m_dockedWith->port.horiz, port_y, m_dockedWith->port.normal); + rot.Print(); + vector3d pos = m_dockedWith->GetPosition() + stationRot*m_dockedWith->port.center; SetPosition(pos); + SetRotation(rot); + SetVelocity(vector3d(0, 0, 0)); + SetAngVelocity(vector3d(0, 0, 0)); + Enable(); + + m_dockedWith = 0; + } else { m_dockedWith = s; SetVelocity(vector3d(0, 0, 0)); diff --git a/src/space.cpp b/src/space.cpp index 7abdc25..172025b 100644 --- a/src/space.cpp +++ b/src/space.cpp @@ -180,7 +180,6 @@ static void nearCallback(void* data, dGeomID oO, dGeomID o1) { contact[i].surface.bounce_vel = 0.1; } if(int numc = dCollide(oO, o1, MAX_CONTACTS, &contact[0].geom, sizeof(dContact))) { - printf("%d contacts\n", numc); Object* po1 = static_cast(dGeomGetData(oO)); Object* po2 = static_cast(dGeomGetData(o1)); if(!_OnCollision(oO, o1, po1, po2, numc, contact)) return; diff --git a/src/space_station.cpp b/src/space_station.cpp index 1140c5f..5b5bb79 100644 --- a/src/space_station.cpp +++ b/src/space_station.cpp @@ -1,6 +1,7 @@ #include "space_station.h" #include "ship.h" #include "objimport.h" +#include "model_coll_mesh_data.h" #define STATION_SBRE_MODEL 65 @@ -20,10 +21,62 @@ static ObjParams params = { { "Hello you!", "CATZ" }, }; +void SpaceStation::GetDockingSurface(CollMeshSet* mset, int midx) { + meshinfo_t* minfo = &mset->meshInfo[midx]; + assert(minfo->flags == 0x1); + assert(minfo->numTris); + port.center = vector3d(0.0); + const int t = minfo->triStart; + float* const vts = mset->sbreCollMesh->pVertex; + for(int pos = 0; pos < minfo->numTris; pos++) { + vector3d v1(vts + 3*mset->triIndices[t+pos].v1); + vector3d v2(vts + 3*mset->triIndices[t+pos].v2); + vector3d v3(vts + 3*mset->triIndices[t+pos].v3); + /* + * Use first tri to get docking port normal (which points out of the + * docking port). + */ + if(pos == 0) { + port.normal = vector3d::Cross(v2-v1, v2-v3); + port.normal.Normalize(); + port.horiz = vector3d::Normalize(v1-v2); + } + port.center += v1+v2+v3; + } + port.center *= 1.0/(3.0*minfo->numTris); + /*printf("Docking port center %f,%f,%f, normal %f,%f,%f, horiz %f,%f,%f\n", + port.center.x, + port.center.y, + port.center.z, + port.normal.x, + port.normal.y, + port.normal.z, + port.horiz.x, + port.horiz.y, + port.horiz.z); */ +} + SpaceStation::SpaceStation(void) : ModelBody() { + allowDocking = true; SetModel(STATION_SBRE_MODEL); - matrix4x4d m = matrix4x4d::RotateYMatrix(M_PI); + matrix4x4d m = matrix4x4d::RotateYMatrix(M_PI-M_PI/6); SetRotation(m); + + CollMeshSet* mset = GetModelCollMeshSet(STATION_SBRE_MODEL); + for(unsigned int i = 0; i < geomColl.size(); i++) { + if(geomColl[i].flags == 0x1) { + /* Docking surface. */ + GetDockingSurface(mset, i); + //mset->meshInfo[i]; +#if 0 + struct meshinfo_t { + int flags; + int triStart; /* Into triIndices. */ + int numTris; + }; +#endif + } + } } SpaceStation::~SpaceStation(void) { @@ -35,7 +88,8 @@ bool SpaceStation::OnCollision(Body* b, Uint32 flags) { /* Hitting docking area of a station. */ if(b->GetType() == Object::SHIP) { Ship* s = static_cast(b); - if(!s->GetDockedWith()) { + if(!s->GetDockedWith() && allowDocking) { + allowDocking = false; s->Disable(); s->SetDockedWith(this); printf("Docking!\n"); diff --git a/src/space_station.h b/src/space_station.h index 848dc7c..d839ede 100644 --- a/src/space_station.h +++ b/src/space_station.h @@ -2,6 +2,8 @@ #include "libs.h" #include "model_body.h" +class CollMeshSet; + class SpaceStation : public ModelBody { public: SpaceStation(void); @@ -9,6 +11,14 @@ public: virtual bool OnCollision(Body* b, Uint32 flags); virtual Object::Type GetType(void) { return Object::SPACESTATION; } virtual void Render(const Frame* camFrame); -protected: + void GetDockingSurface(CollMeshSet* mset, int midx); + struct dockingport_t { + vector3d center; + vector3d normal; + vector3d horiz; + } port; + +private: + bool allowDocking; }; diff --git a/src/vector3.h b/src/vector3.h index 2a1d76f..c7146b9 100644 --- a/src/vector3.h +++ b/src/vector3.h @@ -6,20 +6,22 @@ class vector3 { public: T x,y,z; - vector3(void) { } - vector3(T val): x(val), y(val), z(val) { } - vector3(T _x, T _y, T _z): x(_x), y(_y), z(_z) { } - vector3(const T vals[3]): x(vals[0]), y(vals[1]), z(vals[2]) { } + vector3(void) { } + vector3(T val): x(val), y(val), z(val) { } + vector3(T _x, T _y, T _z): x(_x), y(_y), z(_z) { } + vector3(const double vals[3]): x(vals[0]), y(vals[1]), z(vals[2]) { } + vector3(const float vals[3]) : x(vals[0]), y(vals[1]), z(vals[2]) { } + + T& operator[] (const int i) { return ((T*)this)[i]; } + vector3 operator+ (const vector3 a) const { return vector3 (a.x+x, a.y+y, a.z+z); } + vector3& operator+= (const vector3 a) { x+=a.x; y+=a.y; z+=a.z; return *this; } + vector3& operator-= (const vector3 a) { x-=a.x; y-=a.y; z-=a.z; return *this; } + vector3& operator*= (const T a) { x*=a; y*=a; z*=a; return *this; } + vector3 operator- (const vector3 a) const { return vector3 (x-a.x, y-a.y, z-a.z); } + vector3 operator-(void) const { return vector3 (-x, -y, -z); } + bool operator==(const vector3 a) const { return ((a.x==x)&&(a.y==y)&&(a.z==z)); } + bool operator!=(const vector3 a) const { return ((a.x!=x)||(a.y!=y)||(a.z!=z)); } - T& operator[] (const int i) { return ((T*)this)[i]; } - vector3 operator+ (const vector3 a) const { return vector3 (a.x+x, a.y+y, a.z+z); } - vector3& operator+= (const vector3 a) { x+=a.x; y+=a.y; z+=a.z; return *this; } - vector3& operator-= (const vector3 a) { x-=a.x; y-=a.y; z-=a.z; return *this; } - vector3& operator*= (const T a) { x*=a; y*=a; z*=a; return *this; } - vector3 operator- (const vector3 a) const { return vector3 (x-a.x, y-a.y, z-a.z); } - vector3 operator-(void) const { return vector3 (-x, -y, -z); } - bool operator==(const vector3 a) const { return ((a.x==x)&&(a.y==y)&&(a.z==z)); } - bool operator!=(const vector3 a) const { return ((a.x!=x)||(a.y!=y)||(a.z!=z)); } friend vector3 operator*(const vector3 a, const vector3 b) { return vector3 (a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); } friend vector3 operator*(const vector3 a, const T scalar) {