Esempio n. 1
0
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;
}
Esempio n. 2
0
//-----------------------------------------------------------------------------
// 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;
}
Esempio n. 3
0
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();
			}
		}
	}
}
Esempio n. 4
0
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;
	}
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
//-----------------------------------------------------------------------------
// 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();
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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());
			}
		}
	}
}
Esempio n. 10
0
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());
}
Esempio n. 11
0
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();
}
Esempio n. 12
0
//-----------------------------------------------------------------------------
// 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;
}
Esempio n. 13
0
//-----------------------------------------------------------------------------
// 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 );
}
Esempio n. 14
0
//-----------------------------------------------------------------------------
// 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;
}
Esempio n. 15
0
//-----------------------------------------------------------------------------
// 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;
}
Esempio n. 16
0
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();
}
Esempio n. 17
0
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));

}