Missile * Ship::SpawnMissile(ShipType::Id missile_type, int power) { if (GetFlightState() != FLYING) return 0; Missile *missile = new Missile(missile_type, this, power); missile->SetOrient(GetOrient()); missile->SetFrame(GetFrame()); const vector3d pos = GetOrient() * vector3d(0, GetAabb().min.y - 10, GetAabb().min.z); const vector3d vel = -40.0 * GetOrient().VectorZ(); missile->SetPosition(GetPosition()+pos); missile->SetVelocity(GetVelocity()+vel); Pi::game->GetSpace()->AddBody(missile); return missile; }
//----------------------------------------------------------------------------- // Name: Bound::GetMaxRadius // Desc: Computes the maximum radius of the bound. //----------------------------------------------------------------------------- FLOAT Bound::GetMaxRadius() const { switch( m_Type ) { case Bound::Sphere_Bound: { float Radius = GetSphere().Radius; return Radius; } case Bound::Frustum_Bound: { FLOAT MaxZ = abs( GetFrustum().Far - GetFrustum().Near ); FLOAT MaxX = abs( GetFrustum().LeftSlope * GetFrustum().Far - GetFrustum().RightSlope * GetFrustum().Far ); FLOAT MaxY = abs( GetFrustum().TopSlope * GetFrustum().Far - GetFrustum().BottomSlope * GetFrustum().Far ); return max( MaxZ, max( MaxX, MaxY ) ); } case Bound::OBB_Bound: { XMVECTOR v = XMVector3Length( XMLoadFloat3( &( GetObb().Extents ) ) ); return XMVectorGetX( v ); } case Bound::AABB_Bound: { XMVECTOR v = XMVector3Length( XMLoadFloat3( &( GetAabb().Extents ) ) ); return XMVectorGetX( v ); } case Bound::No_Bound: break; } return 0.0f; }
void Ship::TestLanded() { m_testLanded = false; if (m_launchLockTimeout > 0.0f) return; if (m_wheelState < 1.0f) return; if (GetFrame()->GetBody()->IsType(Object::PLANET)) { double speed = GetVelocity().Length(); vector3d up = GetPosition().Normalized(); const double planetRadius = static_cast<Planet*>(GetFrame()->GetBody())->GetTerrainHeight(up); if (speed < MAX_LANDING_SPEED) { // check player is sortof sensibly oriented for landing if (GetOrient().VectorY().Dot(up) > 0.99) { // position at zero altitude SetPosition(up * (planetRadius - GetAabb().min.y)); // position facing in roughly the same direction vector3d right = up.Cross(GetOrient().VectorZ()).Normalized(); SetOrient(matrix3x3d::FromVectors(right, up)); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); ClearThrusterState(); SetFlightState(LANDED); Sound::BodyMakeNoise(this, "Rough_Landing", 1.0f); LuaEvent::Queue("onShipLanded", this, GetFrame()->GetBody()); onLanded.emit(); } } } }
bool Ship::Jettison(Equip::Type t) { if (m_flightState != FLYING) return false; if (t == Equip::NONE) return false; Equip::Slot slot = EquipType::types[int(t)].slot; if (m_equipment.Count(slot, t) > 0) { m_equipment.Remove(t, 1); UpdateMass(); Aabb aabb; GetAabb(aabb); matrix4x4d rot; GetRotMatrix(rot); vector3d pos = rot * vector3d(0, aabb.min.y-5, 0); CargoBody *cargo = new CargoBody(t); cargo->SetFrame(GetFrame()); cargo->SetPosition(GetPosition()+pos); cargo->SetVelocity(GetVelocity()+rot*vector3d(0,-10,0)); Space::AddBody(cargo); Pi::luaOnJettison->Queue(this, cargo); return true; } else { return false; } }
void Ship::Blastoff() { if (m_flightState != LANDED) return; ClearThrusterState(); m_flightState = FLYING; m_testLanded = false; m_dockedWith = 0; m_launchLockTimeout = 2.0; // two second of applying thrusters vector3d up = GetPosition().Normalized(); Enable(); assert(GetFrame()->m_astroBody->IsType(Object::PLANET)); const double planetRadius = 2.0 + static_cast<Planet*>(GetFrame()->m_astroBody)->GetTerrainHeight(up); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); SetForce(vector3d(0, 0, 0)); SetTorque(vector3d(0, 0, 0)); Aabb aabb; GetAabb(aabb); // XXX hm. we need to be able to get sbre aabb SetPosition(up*planetRadius - aabb.min.y*up); SetThrusterState(1, 1.0); // thrust upwards Pi::luaOnShipTakeOff->Queue(this, GetFrame()->m_astroBody); }
//----------------------------------------------------------------------------- // Name: Bound::operator* // Desc: transforms the bound by the current matrix //----------------------------------------------------------------------------- Bound Bound::operator*( CXMMATRIX World ) const { //$OPTIMIZE: store matrix decomposed XMVECTOR Translation = World.r[3]; FLOAT Scale = XMVectorGetX( XMVector3Length( World.r[2] ) ); XMVECTOR Rotation = XMQuaternionNormalize( XMQuaternionRotationMatrix( World ) ); // switch based off this bounds type and call the correct // bound transform function switch( m_Type ) { case Bound::Sphere_Bound: { Sphere WorldSphere = GetSphere(); TransformSphere( &WorldSphere, &WorldSphere, Scale, Rotation, Translation ); return Bound( WorldSphere ); } case Bound::Frustum_Bound: { Frustum WorldFrustum = GetFrustum(); TransformFrustum( &WorldFrustum, &WorldFrustum, Scale, Rotation, Translation ); return Bound( WorldFrustum ); } case Bound::OBB_Bound: { OrientedBox WorldObb = GetObb(); TransformOrientedBox( &WorldObb, &WorldObb, Scale, Rotation, Translation ); return Bound( WorldObb ); } case Bound::AABB_Bound: { AxisAlignedBox WorldAabb = GetAabb(); TransformAxisAlignedBox( &WorldAabb, &WorldAabb, Scale, Rotation, Translation ); return Bound( WorldAabb ); } case Bound::No_Bound: return Bound(); } return Bound(); }
bool Ship::SpawnCargo(CargoBody * c_body) const { if (m_flightState != FLYING) return false; vector3d pos = GetOrient() * vector3d(0, GetAabb().min.y - 5, 0); c_body->SetFrame(GetFrame()); c_body->SetPosition(GetPosition() + pos); c_body->SetVelocity(GetVelocity() + GetOrient()*vector3d(0, -10, 0)); Pi::game->GetSpace()->AddBody(c_body); return true; }
bool CcdGraphicController::SetGraphicTransform() { if (!m_handle) return false; btVector3 aabbMin; btVector3 aabbMax; GetAabb(aabbMin, aabbMax); // update Aabb in broadphase m_phyEnv->GetCullingTree()->setAabb(m_handle, aabbMin, aabbMax, NULL); return true; }
void Ship::TestLanded() { m_testLanded = false; if (m_launchLockTimeout > 0.0f) return; if (m_wheelState < 1.0f) return; if (GetFrame()->GetBodyFor()->IsType(Object::PLANET)) { double speed = GetVelocity().Length(); vector3d up = GetPosition().Normalized(); const double planetRadius = static_cast<Planet*>(GetFrame()->GetBodyFor())->GetTerrainHeight(up); if (speed < MAX_LANDING_SPEED) { // orient the damn thing right // Q: i'm totally lost. why is the inverse of the body rot matrix being used? // A: NFI. it just works this way matrix4x4d rot; GetRotMatrix(rot); matrix4x4d invRot = rot.InverseOf(); // check player is sortof sensibly oriented for landing const double dot = vector3d(invRot[1], invRot[5], invRot[9]).Normalized().Dot(up); if (dot > 0.99) { Aabb aabb; GetAabb(aabb); // position at zero altitude SetPosition(up * (planetRadius - aabb.min.y)); vector3d forward = rot * vector3d(0,0,1); vector3d other = up.Cross(forward).Normalized(); forward = other.Cross(up); rot = matrix4x4d::MakeRotMatrix(other, up, forward); rot = rot.InverseOf(); SetRotMatrix(rot); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); SetForce(vector3d(0, 0, 0)); SetTorque(vector3d(0, 0, 0)); // we don't use DynamicBody::Disable because that also disables the geom, and that must still get collisions DisableBodyOnly(); ClearThrusterState(); m_flightState = LANDED; Sound::PlaySfx("Rough_Landing", 1.0f, 1.0f, 0); Pi::luaOnShipLanded->Queue(this, GetFrame()->GetBodyFor()); } } } }
void Ship::Blastoff() { if (m_flightState != LANDED) return; vector3d up = GetPosition().Normalized(); assert(GetFrame()->GetBody()->IsType(Object::PLANET)); const double planetRadius = 2.0 + static_cast<Planet*>(GetFrame()->GetBody())->GetTerrainHeight(up); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); SetFlightState(FLYING); SetPosition(up*planetRadius - GetAabb().min.y*up); SetThrusterState(1, 1.0); // thrust upwards LuaEvent::Queue("onShipTakeOff", this, GetFrame()->GetBody()); }
void Ship::SetLandedOn(Planet *p, float latitude, float longitude) { m_wheelTransition = 0; m_wheelState = 1.0f; Frame* f = p->GetFrame()->GetRotFrame(); SetFrame(f); vector3d up = vector3d(cos(latitude)*sin(longitude), sin(latitude), cos(latitude)*cos(longitude)); const double planetRadius = p->GetTerrainHeight(up); SetPosition(up * (planetRadius - GetAabb().min.y)); vector3d right = up.Cross(vector3d(0,0,1)).Normalized(); SetOrient(matrix3x3d::FromVectors(right, up)); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); ClearThrusterState(); SetFlightState(LANDED); LuaEvent::Queue("onShipLanded", this, p); onLanded.emit(); }
//----------------------------------------------------------------------------- // Name: Bound::Collide // Desc: collides this bound with a frustum //----------------------------------------------------------------------------- BOOL Bound::Collide( const Frustum& Frustum ) const { switch( m_Type ) { case Bound::Sphere_Bound: return ( BOOL )IntersectSphereFrustum( &GetSphere(), &Frustum ); case Bound::Frustum_Bound: return ( BOOL )IntersectFrustumFrustum( &GetFrustum(), &Frustum ); case Bound::OBB_Bound: return ( BOOL )IntersectOrientedBoxFrustum( &GetObb(), &Frustum ); case Bound::AABB_Bound: return ( BOOL )IntersectAxisAlignedBoxFrustum( &GetAabb(), &Frustum ); case Bound::No_Bound: return TRUE; } return FALSE; }
//----------------------------------------------------------------------------- // Name: Bound::GetCenter // Desc: Gets the center of the bound. //----------------------------------------------------------------------------- XMFLOAT3 Bound::GetCenter() const { switch( m_Type ) { case Bound::Sphere_Bound: return *( ( XMFLOAT3* )&GetSphere().Center ); case Bound::Frustum_Bound: return *( ( XMFLOAT3* )&GetFrustum().Origin ); case Bound::OBB_Bound: return *( ( XMFLOAT3* )&GetObb().Center ); case Bound::AABB_Bound: return *( ( XMFLOAT3* )&GetAabb().Center ); case Bound::No_Bound: break; } return XMFLOAT3( 0.0f, 0.0f, 0.0f ); }
//----------------------------------------------------------------------------- // Name: Bound::Collide // Desc: collides this bound with a sphere //----------------------------------------------------------------------------- BOOL Bound::Collide( const Sphere& Sphere ) const { switch( m_Type ) { case Bound::Sphere_Bound: return IntersectSphereSphere( &GetSphere(), &Sphere ); case Bound::Frustum_Bound: return ( BOOL )IntersectSphereFrustum( &Sphere, &GetFrustum() ); case Bound::OBB_Bound: return IntersectSphereOrientedBox( &Sphere, &GetObb() ); case Bound::AABB_Bound: return IntersectSphereAxisAlignedBox( &Sphere, &GetAabb() ); case Bound::No_Bound: return TRUE; } return FALSE; }
//----------------------------------------------------------------------------- // Name: Bound::Collide // Desc: collides this bound with an obb //----------------------------------------------------------------------------- BOOL Bound::Collide( const OrientedBox& Obb ) const { // switch on bound type and call the correct intersection function switch( m_Type ) { case Bound::Sphere_Bound: return IntersectSphereOrientedBox( &GetSphere(), &Obb ); case Bound::Frustum_Bound: return ( BOOL )IntersectOrientedBoxFrustum( &Obb, &GetFrustum() ); case Bound::OBB_Bound: return IntersectOrientedBoxOrientedBox( &GetObb(), &Obb ); case Bound::AABB_Bound: return IntersectAxisAlignedBoxOrientedBox( &GetAabb(), &Obb ); case Bound::No_Bound: return TRUE; } return FALSE; }
void Ship::Init() { m_invulnerable = false; m_sensors.reset(new Sensors(this)); m_navLights.reset(new NavLights(GetModel())); m_navLights->SetEnabled(true); SetMassDistributionFromModel(); UpdateEquipStats(); m_stats.hull_mass_left = float(m_type->hullMass); m_stats.shield_mass_left = 0; PropertyMap &p = Properties(); p.Set("hullMassLeft", m_stats.hull_mass_left); p.Set("hullPercent", 100.0f * (m_stats.hull_mass_left / float(m_type->hullMass))); p.Set("shieldMassLeft", m_stats.shield_mass_left); p.Set("fuelMassLeft", m_stats.fuel_tank_mass_left); p.Set("shipName", m_shipName); m_hyperspace.now = false; // TODO: move this on next savegame change, maybe m_hyperspaceCloud = 0; m_landingGearAnimation = GetModel()->FindAnimation("gear_down"); InitGun("tag_gunmount_0", 0); InitGun("tag_gunmount_1", 1); // If we've got the tag_landing set then use it for an offset otherwise grab the AABB const SceneGraph::MatrixTransform *mt = GetModel()->FindTagByName("tag_landing"); if( mt ) { m_landingMinOffset = mt->GetTransform().GetTranslate().y; } else { m_landingMinOffset = GetAabb().min.y; } InitMaterials(); }
void PolyhedralConvexShape::CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia) { //not yet, return box inertia float margin = GetMargin(); SimdTransform ident; ident.setIdentity(); SimdVector3 aabbMin,aabbMax; GetAabb(ident,aabbMin,aabbMax); SimdVector3 halfExtents = (aabbMax-aabbMin)*0.5f; SimdScalar lx=2.f*(halfExtents.x()+margin); SimdScalar ly=2.f*(halfExtents.y()+margin); SimdScalar lz=2.f*(halfExtents.z()+margin); const SimdScalar x2 = lx*lx; const SimdScalar y2 = ly*ly; const SimdScalar z2 = lz*lz; const SimdScalar scaledmass = mass * 0.08333333f; inertia = scaledmass * (SimdVector3(y2+z2,x2+z2,x2+y2)); }