CPlanet* CSPCharacter::FindNearestPlanet() const { CPlanet* pNearestPlanet = NULL; CScalableFloat flNearestDistance; for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++) { CPlanet* pPlanet = dynamic_cast<CPlanet*>(CBaseEntity::GetEntity(i)); if (!pPlanet) continue; CScalableFloat flDistance = (pPlanet->GetGlobalOrigin() - GetGlobalOrigin()).Length(); flDistance -= pPlanet->GetRadius(); if (pNearestPlanet == NULL) { pNearestPlanet = pPlanet; flNearestDistance = flDistance; continue; } if (flDistance > flNearestDistance) continue; pNearestPlanet = pPlanet; flNearestDistance = flDistance; } return pNearestPlanet; }
void CSPCharacter::Think() { BaseClass::Think(); CPlanet* pPlanet = GetNearestPlanet(); if (pPlanet && !HasMoveParent()) { m_flLastEnteredAtmosphere = GameServer()->GetGameTime(); m_flRollFromSpace = GetGlobalAngles().r; } SetMoveParent(pPlanet); if (pPlanet) { // Estimate this planet's mass given things we know about earth. Assume equal densities. double flEarthVolume = 1097509500000000000000.0; // cubic meters double flEarthMass = 5974200000000000000000000.0; // kilograms // 4/3 * pi * r^3 = volume of a sphere CScalableFloat flPlanetVolume = pPlanet->GetRadius()*pPlanet->GetRadius()*pPlanet->GetRadius()*(M_PI*4/3); double flPlanetMass = RemapVal(flPlanetVolume, CScalableFloat(), CScalableFloat(flEarthVolume, SCALE_METER), 0, flEarthMass); double flG = 0.0000000000667384; // Gravitational constant CScalableVector vecDistance = (pPlanet->GetGlobalOrigin() - GetGlobalOrigin()); CScalableFloat flDistance = vecDistance.Length(); CScalableFloat flGravity = CScalableFloat(flPlanetMass*flG, SCALE_METER)/(flDistance*flDistance); CScalableVector vecGravity = vecDistance * flGravity / flDistance; SetGlobalGravity(vecGravity); } }
void CStructure::PostSetLocalTransform(const TMatrix& m) { BaseClass::PostSetLocalTransform(m); CPlanet* pPlanet = GameData().GetPlanet(); if (!pPlanet) return; if (!pPlanet->GetChunkManager()->HasGroupCenter()) return; TMatrix mLocalTransform = m; CBaseEntity* pMoveParent = GetMoveParent(); if (pMoveParent) { while (pMoveParent != pPlanet) { mLocalTransform = pMoveParent->GetLocalTransform() * mLocalTransform; pMoveParent = pMoveParent->GetMoveParent(); } } else mLocalTransform = pPlanet->GetGlobalToLocalTransform() * m; GameData().SetGroupTransform(pPlanet->GetChunkManager()->GetPlanetToGroupCenterTransform() * mLocalTransform.GetMeters()); }
void CStructure::SetPhysicsTransform(const Matrix4x4& m) { CPlanet* pPlanet = GameData().GetPlanet(); if (!pPlanet) { SetLocalTransform(TMatrix(m)); return; } if (!pPlanet->GetChunkManager()->HasGroupCenter()) { SetLocalTransform(TMatrix(m)); return; } GameData().SetGroupTransform(m); TMatrix mLocalTransform(pPlanet->GetChunkManager()->GetGroupCenterToPlanetTransform() * m); CBaseEntity* pMoveParent = GetMoveParent(); TAssert(pMoveParent); if (pMoveParent) { while (pMoveParent != pPlanet) { mLocalTransform = pMoveParent->GetLocalTransform().InvertedRT() * mLocalTransform; pMoveParent = pMoveParent->GetMoveParent(); } } SetLocalTransform(mLocalTransform); }
void CTestParticleSet::setupTestParticles( ) { RemoveAll( ); // Check for invalid ranges. if( m_xRange.m_y < m_xRange.m_x || m_yRange.m_y < m_yRange.m_x || m_zRange.m_y < m_zRange.m_x || IS_LESS_THAN_OR_EQUAL( m_xRange.m_z, 0 ) || IS_LESS_THAN_OR_EQUAL( m_yRange.m_z, 0 ) || IS_LESS_THAN_OR_EQUAL( m_zRange.m_z, 0 ) ) return; for( double i=m_xRange.m_x; i<=m_xRange.m_y; i+=m_xRange.m_z ) { for( double j=m_yRange.m_x; j<=m_yRange.m_y; j+=m_yRange.m_z ) { for( double k=m_zRange.m_x; k<=m_zRange.m_y; k+=m_zRange.m_z ) { // A planet. CPlanet newPlanet; newPlanet.setPositionOptimized( CVector3D( i, j, k ) ); newPlanet.setRadius( 0.1 ); newPlanet.setDrawAsPoint( true ); Add( newPlanet ); } } } }
TVector CSPCharacter::GetUpVector() const { CPlanet* pNearestPlanet = GetNearestPlanet(); if (pNearestPlanet) return (GetGlobalOrigin() - pNearestPlanet->GetGlobalOrigin()).Normalized(); return Vector(0, 1, 0); }
const Matrix4x4 CStructure::GetPhysicsTransform() const { CPlanet* pPlanet = GameData().GetPlanet(); if (!pPlanet) return GetLocalTransform(); if (!pPlanet->GetChunkManager()->HasGroupCenter()) return GetLocalTransform(); return GameData().GetGroupTransform(); }
void CSPCharacter::StandOnNearestPlanet() { CPlanet* pPlanet = GetNearestPlanet(FINDPLANET_ANY); if (!pPlanet) return; CScalableVector vecPlanetOrigin = pPlanet->GetGlobalOrigin(); CScalableVector vecCharacterOrigin = GetGlobalOrigin(); CScalableVector vecCharacterDirection = (vecCharacterOrigin - vecPlanetOrigin).Normalized(); SetMoveParent(pPlanet); TVector vecPoint, vecNormal; pPlanet->CollideLocal(vecCharacterDirection * (pPlanet->GetRadius()*2.0f), TVector(), vecPoint, vecNormal); SetLocalOrigin(vecPoint); }
CPlanet* CSPCharacter::GetNearestPlanet(findplanet_t eFindPlanet) const { if (eFindPlanet != FINDPLANET_INATMOSPHERE) { if (m_hNearestPlanet != NULL) return m_hNearestPlanet; CPlanet* pNearestPlanet = FindNearestPlanet(); if (eFindPlanet == FINDPLANET_ANY) return pNearestPlanet; CScalableFloat flDistance = (pNearestPlanet->GetGlobalOrigin() - GetGlobalOrigin()).Length() - pNearestPlanet->GetRadius(); if (eFindPlanet == FINDPLANET_CLOSEORBIT && flDistance > pNearestPlanet->GetCloseOrbit()) return NULL; else return pNearestPlanet; } return m_hNearestPlanet; }
void RiseTransitSet(long when, float lat, float lon, float ra, float dec, long* rise, long* transit, long* set) { long daybase = when - (when % 86400); CPlanet* earth = FindPlanet("Earth"); float full_set_angle = -0.83 * deg2rad; float latrad = lat * deg2rad; float decrad = dec * deg2rad; const OrbitData* obs_orbit = earth->GetOrbit(); float mean_anomaly = obs_orbit->MeanAnomaly(when); float transit_hour_utc = fmod((ra - lon - mean_anomaly),360.0)/15 + 17.1375; long transit_time = (long)(transit_hour_utc * 3600.0); float horizon_hour = acosf((sinf(full_set_angle) - sinf(latrad)*sinf(decrad))/(cosf(latrad)*cosf(decrad))) * rad2hour; long horizon_time = (long)(horizon_hour * 3600); transit_time += daybase; *rise = transit_time - horizon_time; *transit = transit_time; *set = transit_time + horizon_time; }
CPlanet* CSPCharacter::GetNearestPlanet(findplanet_t eFindPlanet) { if (GameServer()->GetGameTime() > m_flNextPlanetCheck) { CPlanet* pNearestPlanet = FindNearestPlanet(); CScalableFloat flDistance = (pNearestPlanet->GetGlobalOrigin() - GetGlobalOrigin()).Length() - pNearestPlanet->GetRadius(); if (flDistance < pNearestPlanet->GetAtmosphereThickness()) m_hNearestPlanet = pNearestPlanet; else m_hNearestPlanet = NULL; m_flNextPlanetCheck = GameServer()->GetGameTime() + 0.3f; } if (eFindPlanet != FINDPLANET_INATMOSPHERE) { if (m_hNearestPlanet != NULL) return m_hNearestPlanet; CPlanet* pNearestPlanet = FindNearestPlanet(); if (eFindPlanet == FINDPLANET_ANY) return pNearestPlanet; CScalableFloat flDistance = (pNearestPlanet->GetGlobalOrigin() - GetGlobalOrigin()).Length() - pNearestPlanet->GetRadius(); if (eFindPlanet == FINDPLANET_CLOSEORBIT && flDistance > pNearestPlanet->GetCloseOrbit()) return NULL; else return pNearestPlanet; } return m_hNearestPlanet; }
void SunRiseSet(long when, float lat, float lon, long* out_rise, long* out_set, long* out_trans) { float ra, dec; long dummy, rise, set, transit; CPlanet* earth = FindPlanet("Earth"); SolarRADec(*earth->GetOrbit(), when, &ra, &dec); RiseTransitSet(when, lat, lon, ra, dec, &rise, &dummy, &set); SolarRADec(*earth->GetOrbit(), rise, &ra, &dec); RiseTransitSet(rise, lat, lon, ra, dec, &rise, &dummy, &dummy); SolarRADec(*earth->GetOrbit(), transit, &ra, &dec); RiseTransitSet(rise, lat, lon, ra, dec, &dummy, &transit, &dummy); SolarRADec(*earth->GetOrbit(), set, &ra, &dec); RiseTransitSet(set, lat, lon, ra, dec, &dummy, &dummy, &set); *out_rise = rise; *out_trans = transit; *out_set = set; }
void CStar::PostRender() const { BaseClass::PostRender(); if (GameServer()->GetRenderer()->IsRenderingTransparent()) return; CSPCharacter* pCharacter = SPGame()->GetLocalPlayerCharacter(); CPlanet* pNearestPlanet = pCharacter->GetNearestPlanet(); float flRadius = (float)(GetRadius()*2.0f).GetUnits(SPGame()->GetSPRenderer()->GetRenderingScale()); CScalableFloat flDistance; float flAtmosphere = 0; if (pNearestPlanet) { flDistance = (pNearestPlanet->GetGlobalOrigin() - pCharacter->GetGlobalOrigin()).Length() - pNearestPlanet->GetRadius(); flAtmosphere = (float)RemapValClamped(flDistance, CScalableFloat(1.0f, SCALE_KILOMETER), pNearestPlanet->GetAtmosphereThickness(), 1.0, 0.0); } CGameRenderingContext c(GameServer()->GetRenderer(), true); c.SetDepthMask(false); c.ResetTransformations(); c.Transform(BaseGetRenderTransform()); // Set material and uniform now so RenderBillboard doesn't overwrite the alpha value. c.UseMaterial("textures/star-yellow-atmosphere.mat"); c.SetUniform("flAlpha", flAtmosphere); c.RenderBillboard("textures/star-yellow-atmosphere.mat", flRadius); c.UseMaterial("textures/star-yellow-space.mat"); c.SetUniform("flAlpha", 1-flAtmosphere); c.RenderBillboard("textures/star-yellow-space.mat", flRadius); }