diff options
Diffstat (limited to 'src/entities')
-rw-r--r-- | src/entities/Entity.cpp | 99 | ||||
-rw-r--r-- | src/entities/Entity.h | 19 | ||||
-rw-r--r-- | src/entities/Physical.cpp | 118 | ||||
-rw-r--r-- | src/entities/Physical.h | 8 |
4 files changed, 202 insertions, 42 deletions
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index 8d51cae7..83c65eeb 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -1,10 +1,10 @@ #include "common.h" -#include "VuVector.h" #include "General.h" #include "RwHelper.h" #include "ModelIndices.h" #include "Timer.h" +#include "Streaming.h" #include "Entity.h" #include "Object.h" #include "World.h" @@ -27,6 +27,12 @@ #include "Dummy.h" #include "WindModifiers.h" #include "SaveBuf.h" +#include "SpecialFX.h" +#include "VisibilityPlugins.h" +#include "RpAnimBlend.h" +#include "CutsceneMgr.h" + +//--LCS: file done except TODO for distance alpha int gBuildings; @@ -79,6 +85,11 @@ CEntity::CEntity(void) bUnderwater = false; bHasPreRenderEffects = false; + bIsTreeModel = false; + m_flagG2 = false; + m_flagG4 = false; + m_flagG8 = false; + m_scanCode = 0; m_modelIndex = -1; m_rwObject = nil; @@ -97,6 +108,8 @@ void CEntity::SetModelIndex(uint32 id) { m_modelIndex = id; + bIsTreeModel = IsTreeModel(m_modelIndex); + bDrawLast |= bIsTreeModel; bHasPreRenderEffects = HasPreRenderEffects(); CreateRwObject(); } @@ -105,6 +118,8 @@ void CEntity::SetModelIndexNoCreate(uint32 id) { m_modelIndex = id; + bIsTreeModel = IsTreeModel(m_modelIndex); + bDrawLast |= bIsTreeModel; bHasPreRenderEffects = HasPreRenderEffects(); } @@ -127,6 +142,7 @@ CEntity::CreateRwObject(void) else if(RwObjectGetType(m_rwObject) == rpCLUMP) GetMatrix().AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump *)m_rwObject)), false); + // useless IsTextureLoaded(); mi->AddRef(); } } @@ -183,9 +199,11 @@ CEntity::DeleteRwObject(void) if(m_rwObject){ if(RwObjectGetType(m_rwObject) == rpATOMIC){ f = RpAtomicGetFrame((RpAtomic*)m_rwObject); + CStreaming::UnregisterInstance((RpAtomic*)m_rwObject, nil); RpAtomicDestroy((RpAtomic*)m_rwObject); RwFrameDestroy(f); }else if(RwObjectGetType(m_rwObject) == rpCLUMP){ + CStreaming::UnregisterInstance((RpClump*)m_rwObject); if(IsClumpSkinned((RpClump*)m_rwObject)) RpClumpForAllAtomics((RpClump*)m_rwObject, AtomicRemoveAnimFromSkinCB, nil); RpClumpDestroy((RpClump*)m_rwObject); @@ -251,9 +269,18 @@ CEntity::UpdateRwFrame(void) RwFrameUpdateObjects((RwFrame*)rwObjectGetParent(m_rwObject)); } +bool +PauseEntityAnims(void) +{ + return CSpecialFX::bSnapShotActive; +} + void CEntity::UpdateRpHAnim(void) { + if(PauseEntityAnims()) + return; + if(IsClumpSkinned(GetClump())){ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); RpHAnimHierarchyUpdateMatrices(hier); @@ -315,9 +342,10 @@ CEntity::PreRender(void) if(!bHasPreRenderEffects) return; + // separate function in LCS but we don't know the name switch(m_type){ case ENTITY_TYPE_BUILDING: - if(IsTreeModel(GetModelIndex())){ + if(bIsTreeModel){ float dist = (TheCamera.GetPosition() - GetPosition()).Magnitude2D(); CObject::fDistToNearestTree = Min(CObject::fDistToNearestTree, dist); ModifyMatrixForTreeInWind(); @@ -416,12 +444,50 @@ void CEntity::Render(void) { if(m_rwObject){ - bImBeingRendered = true; - if(RwObjectGetType(m_rwObject) == rpATOMIC) - RpAtomicRender((RpAtomic*)m_rwObject); - else - RpClumpRender((RpClump*)m_rwObject); - bImBeingRendered = false; + if(CVisibilityPlugins::GetObjectDistanceAlpha(m_rwObject) != 0){ + // NB: LCS does not use bImBeingRendered here, + // but that may be due to the streamed world. better keep it for safety + bImBeingRendered = true; + if(RwObjectGetType(m_rwObject) == rpATOMIC) + RpAtomicRender((RpAtomic*)m_rwObject); + else + RpClumpRender((RpClump*)m_rwObject); + bImBeingRendered = false; + } + } +} + +void +CEntity::UpdateDistanceFade(void) +{ +// TODO(LCS): +// increasing and decreasing alpha depending on bDistanceFade doesn't make any sense +// so disable this whole thing until it does. +return; + int alpha = CVisibilityPlugins::GetObjectDistanceAlpha(m_rwObject); + if(CCutsceneMgr::IsRunning() || TheCamera.WorldViewerBeingUsed) + alpha = 255; + else if(bDistanceFade) + alpha = Max(alpha-16, 0); + else if(alpha < 255) + alpha = Min(alpha+32, 255); + CVisibilityPlugins::SetObjectDistanceAlpha(m_rwObject, alpha); +} + +void +CEntity::UpdateAnim(void) +{ + if(PauseEntityAnims()) + return; + + if(m_rwObject && RwObjectGetType(m_rwObject) == rpCLUMP && RpAnimBlendClumpGetFirstAssociation(GetClump())) { + if (IsObject()) + RpAnimBlendClumpUpdateAnimations(GetClump(), CTimer::GetTimeStepNonClippedInSeconds()); + else { + if (!bOffscreen) + bOffscreen = !GetIsOnScreen(); + RpAnimBlendClumpUpdateAnimations(GetClump(), CTimer::GetTimeStepInSeconds(), !bOffscreen); + } } } @@ -434,6 +500,12 @@ CEntity::GetIsTouching(CVUVECTOR const ¢er, float radius) } bool +CEntity::GetIsTouching(CEntity *other) +{ + return sq(GetBoundRadius()+other->GetBoundRadius()) > (GetBoundCentre()-other->GetBoundCentre()).MagnitudeSqr(); +} + +bool CEntity::IsVisible(void) { return m_rwObject && bIsVisible && GetIsOnScreen(); @@ -634,10 +706,15 @@ CEntity::SetupBigBuilding(void) m_level = CTheZones::GetLevelFromPosition(&GetPosition()); if(mi->m_lodDistances[0] <= 2000.0f) bStreamBIGBuilding = true; - if(mi->m_lodDistances[0] > 2500.0f || mi->m_ignoreDrawDist) + if(m_modelIndex == islandLODindust || + m_modelIndex == islandLODcomInd || + m_modelIndex == islandLODcomSub || + m_modelIndex == islandLODsubInd || + m_modelIndex == islandLODsubCom || + mi->m_lodDistances[0] > 5000.0f || mi->m_ignoreDrawDist) m_level = LEVEL_GENERIC; - else if(m_level == LEVEL_GENERIC) - printf("%s isn't in a level\n", mi->GetModelName()); +// else if(m_level == LEVEL_GENERIC) +// printf("%s isn't in a level\n", mi->GetModelName()); } float WindTabel[] = { diff --git a/src/entities/Entity.h b/src/entities/Entity.h index 957ee3bf..4db58eef 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -24,11 +24,11 @@ enum eEntityStatus STATUS_PHYSICS, STATUS_ABANDONED, STATUS_WRECKED, - STATUS_TRAIN_MOVING, + STATUS_TRAIN_MOVING, // these probably copied for FERRY STATUS_TRAIN_NOT_MOVING, STATUS_HELI, STATUS_PLANE, - STATUS_PLAYER_REMOTE, + STATUS_PLAYER_REMOTE, // 12 in LCS STATUS_PLAYER_DISABLED, STATUS_GHOST }; @@ -43,6 +43,7 @@ private: uint32 m_status : 5; public: // flagsA + // LCS flagsB 02 uint32 bUsesCollision : 1; // does entity use collision uint32 bCollisionProcessed : 1; // has object been processed by a ProcessEntityCollision function uint32 bIsStatic : 1; // is entity static @@ -50,6 +51,7 @@ public: uint32 bPedPhysics : 1; uint32 bIsStuck : 1; // is entity stuck uint32 bIsInSafePosition : 1; // is entity in a collision free safe position + // LCS flagsC uint32 bUseCollisionRecords : 1; // flagsB @@ -60,6 +62,7 @@ public: uint32 bRenderScorched : 1; uint32 bHasBlip : 1; uint32 bIsBIGBuilding : 1; // Set if this entity is a big building + // LCS flagsD uint32 bStreamBIGBuilding : 1; // set when draw dist <= 2000 // flagsC @@ -70,6 +73,7 @@ public: uint32 bMeleeProof : 1; uint32 bOnlyDamagedByPlayer : 1; uint32 bStreamingDontDelete : 1; // Dont let the streaming remove this + // LCS flagsE uint32 bRemoveFromWorld : 1; // remove this entity next time it should be processed // flagsD @@ -80,6 +84,7 @@ public: uint32 bDrawLast : 1; // draw object last uint32 bNoBrightHeadLights : 1; uint32 bDoNotRender : 1; //-- only applies to CObjects apparently + // LCS flagsF uint32 bDistanceFade : 1; // Fade entity because it is far away // flagsE @@ -91,6 +96,12 @@ public: uint32 bUnderwater : 1; // this object is underwater change drawing order uint32 bHasPreRenderEffects : 1; // Object has a prerender effects attached to it + // LCS flagsG + uint32 bIsTreeModel : 1; + uint32 m_flagG2 : 1; + uint32 m_flagG4 : 1; + uint32 m_flagG8 : 1; + uint16 m_scanCode; uint16 m_randomSeed; int16 m_modelIndex; @@ -118,6 +129,7 @@ public: virtual void Add(void); virtual void Remove(void); + virtual bool UpdatesInCutscene(void) { return false; } virtual void SetModelIndex(uint32 id); virtual void SetModelIndexNoCreate(uint32 id); virtual void CreateRwObject(void); @@ -129,6 +141,7 @@ public: virtual void Teleport(CVector v) {} virtual void PreRender(void); virtual void Render(void); + virtual void UpdateAnim(void); virtual bool SetupLighting(void); virtual void RemoveLighting(bool); virtual void FlagToDestroyWhenNextProcessed(void) {} @@ -148,11 +161,13 @@ public: return (RpClump*)m_rwObject; } + void UpdateDistanceFade(void); void GetBoundCentre(CVUVECTOR &out); CVector GetBoundCentre(void); float GetBoundRadius(void); float GetDistanceFromCentreOfMassToBaseOfModel(void); bool GetIsTouching(CVUVECTOR const ¢er, float r); + bool GetIsTouching(CEntity *other); bool GetIsOnScreen(void); bool GetIsOnScreenComplex(void); bool IsVisible(void); diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index 890e7876..69110a83 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -21,9 +21,7 @@ #include "Pickups.h" #include "Physical.h" -#ifdef WALLCLIMB_CHEAT bool gGravityCheat; -#endif CPhysical::CPhysical(void) @@ -357,7 +355,7 @@ CPhysical::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints) return numSpheres; } -// --MIAMI: Proof-read once +//--LCS: done void CPhysical::ProcessControl(void) { @@ -425,7 +423,7 @@ CPhysical::GetSpeed(const CVector &r) return m_vecMoveSpeed + m_vecMoveFriction + CrossProduct(m_vecTurnFriction + m_vecTurnSpeed, r); } -// --MIAMI: Proof-read once +//--LCS: done void CPhysical::ApplyMoveSpeed(void) { @@ -435,13 +433,13 @@ CPhysical::ApplyMoveSpeed(void) GetMatrix().Translate(m_vecMoveSpeed * CTimer::GetTimeStep()); } -// --MIAMI: Proof-read once +//--LCS: done void CPhysical::ApplyTurnSpeed(void) { if(bIsFrozen){ m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f); - }else{ + }else if(!m_vecTurnSpeed.IsZero()){ // Move the coordinate axes by their speed // Note that this denormalizes the matrix CVector turnvec = m_vecTurnSpeed*CTimer::GetTimeStep(); @@ -451,29 +449,36 @@ CPhysical::ApplyTurnSpeed(void) } } -// --MIAMI: Proof-read once +//--LCS: done void CPhysical::ApplyMoveForce(float jx, float jy, float jz) { m_vecMoveSpeed += CVector(jx, jy, jz)*(1.0f/m_fMass); + m_vecTurnSpeed.x = Clamp(m_vecTurnSpeed.x, -4.0f, 4.0f); + m_vecTurnSpeed.y = Clamp(m_vecTurnSpeed.y, -4.0f, 4.0f); + m_vecTurnSpeed.z = Clamp(m_vecTurnSpeed.z, -4.0f, 4.0f); } -// --MIAMI: Proof-read once +//--LCS: done void CPhysical::ApplyTurnForce(float jx, float jy, float jz, float px, float py, float pz) { CVector com = Multiply3x3(GetMatrix(), m_vecCentreOfMass); CVector turnimpulse = CrossProduct(CVector(px, py, pz)-com, CVector(jx, jy, jz)); m_vecTurnSpeed += turnimpulse*(1.0f/m_fTurnMass); + m_vecTurnSpeed.x = Clamp(m_vecTurnSpeed.x, -4.0f, 4.0f); + m_vecTurnSpeed.y = Clamp(m_vecTurnSpeed.y, -4.0f, 4.0f); + m_vecTurnSpeed.z = Clamp(m_vecTurnSpeed.z, -4.0f, 4.0f); } +//--LCS: done void CPhysical::ApplyFrictionMoveForce(float jx, float jy, float jz) { m_vecMoveFriction += CVector(jx, jy, jz)*(1.0f/m_fMass); } -// --MIAMI: Proof-read once +//--LCS: done void CPhysical::ApplyFrictionTurnForce(float jx, float jy, float jz, float px, float py, float pz) { @@ -482,7 +487,7 @@ CPhysical::ApplyFrictionTurnForce(float jx, float jy, float jz, float px, float m_vecTurnFriction += turnimpulse*(1.0f/m_fTurnMass); } -// --MIAMI: Proof-read once +//--LCS: done bool CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector &point, float springRatio, float bias) { @@ -496,16 +501,16 @@ CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector & return true; } -// --MIAMI: Proof-read once +//--LCS: done bool -CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir) +CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir, float &impulse) { float compression = 1.0f - springRatio; if(compression > 0.0f){ if(DotProduct(springDir, forceDir) > 0.0f) forceDir *= -1.0f; float step = Min(CTimer::GetTimeStep(), 3.0f); - float impulse = GRAVITY*m_fMass*step * springConst * compression * bias*2.0f; + impulse = GRAVITY*m_fMass*step * springConst * compression * bias*2.0f; if(bIsHeavy) impulse *= 0.75f; ApplyMoveForce(forceDir*impulse); @@ -514,36 +519,53 @@ CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVecto return true; } -// --MIAMI: Proof-read once +float DAMPING_LIMIT_OF_SPRING_FORCE = 0.999f; +float DAMPING_LIMIT_IN_FRAME= 0.25f; + +//--LCS: done // What exactly is speed? bool -CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed) +CPhysical::ApplySpringDampening(float damping, float dampingLimit, CVector &springDir, CVector &point, CVector &speed) { float speedA = DotProduct(speed, springDir); float speedB = DotProduct(GetSpeed(point), springDir); float step = Min(CTimer::GetTimeStep(), 3.0f); - float impulse = -damping * (speedA + speedB)/2.0f * m_fMass * step * 0.53f; + damping *= step; if(bIsHeavy) - impulse *= 2.0f; + damping *= 2.0f; + damping = Clamp(damping, -DAMPING_LIMIT_IN_FRAME, DAMPING_LIMIT_IN_FRAME); // what is this? - float a = m_fTurnMass / ((point.MagnitudeSqr() + 1.0f) * 2.0f * m_fMass); - a = Min(a, 1.0f); - float b = Abs(impulse / (speedB * m_fMass)); - if(a < b) - impulse *= a/b; + float fSpeed = -speedA * damping; + if(fSpeed > 0.0f && fSpeed+speedB > 0.0f){ + if(speedB < 0.0f) + fSpeed = -speedB; + else + fSpeed = 0.0f; + }else if(fSpeed < 0.0f && fSpeed+speedB < 0.0f){ + if(speedB > 0.0f) + fSpeed = -speedB; + else + fSpeed = 0.0f; + } + + CVector com = Multiply3x3(m_matrix, m_vecCentreOfMass); + float impulse = fSpeed*GetMass(point-com, springDir); + float limit = Abs(dampingLimit)*DAMPING_LIMIT_OF_SPRING_FORCE; + if(impulse > limit) + impulse = limit; ApplyMoveForce(springDir*impulse); ApplyTurnForce(springDir*impulse, point); return true; } +//--LCS: done void CPhysical::ApplyGravity(void) { if (!bAffectedByGravity) return; -#ifdef WALLCLIMB_CHEAT if (gGravityCheat && this == FindPlayerVehicle()) { static CVector gravityUp(0.0f, 0.0f, 1.0f), surfaceUp(0.0f, 0.0f, 1.0f); CVector belowCar = GetPosition() - 2.0f*GetUp(); @@ -562,10 +584,10 @@ CPhysical::ApplyGravity(void) m_vecMoveSpeed -= GRAVITY * CTimer::GetTimeStep() * gravityUp; return; } -#endif m_vecMoveSpeed.z -= GRAVITY * CTimer::GetTimeStep(); } +//--LCS: done void CPhysical::ApplyFriction(void) { @@ -575,7 +597,7 @@ CPhysical::ApplyFriction(void) m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f); } -// --MIAMI: Proof-read once +//--LCS: done void CPhysical::ApplyAirResistance(void) { @@ -583,8 +605,8 @@ CPhysical::ApplyAirResistance(void) float f = Pow(m_fAirResistance, CTimer::GetTimeStep()); m_vecMoveSpeed *= f; m_vecTurnSpeed *= f; - }else if(GetStatus() != STATUS_GHOST){ - float f = Pow(1.0f/Abs(1.0f + m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr()), CTimer::GetTimeStep()); + }else{ + float f = Pow(1.0f - m_fAirResistance*m_vecMoveSpeed.Magnitude(), CTimer::GetTimeStep()); m_vecMoveSpeed *= f; m_vecTurnSpeed *= 0.99f; } @@ -693,6 +715,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl int16 model = B->GetModelIndex(); if(model == MI_FIRE_HYDRANT && !Bobj->bHasBeenDamaged){ CParticleObject::AddObject(POBJECT_FIRE_HYDRANT, B->GetPosition() - CVector(0.0f, 0.0f, 0.5f), true); + CParticleObject::AddObject(POBJECT_FIRE_HYDRANT_STEAM, B->GetPosition() - CVector(0.0f, 0.0f, 0.5f), true); Bobj->bHasBeenDamaged = true; }else if(model == MI_PARKINGMETER || model == MI_PARKINGMETER2){ CPickups::CreateSomeMoney(GetPosition(), CGeneral::GetRandomNumber()%100); @@ -2308,3 +2331,44 @@ CPhysical::ProcessCollision(void) m_fElasticity = savedElasticity; RemoveAndAdd(); } + + + +// TEMP old VC code until bikes are done +bool +CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir) +{ + float compression = 1.0f - springRatio; + if(compression > 0.0f){ + if(DotProduct(springDir, forceDir) > 0.0f) + forceDir *= -1.0f; + float step = Min(CTimer::GetTimeStep(), 3.0f); + float impulse = GRAVITY*m_fMass*step * springConst * compression * bias*2.0f; + if(bIsHeavy) + impulse *= 0.75f; + ApplyMoveForce(forceDir*impulse); + ApplyTurnForce(forceDir*impulse, point); + } + return true; +} +bool +CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed) +{ + float speedA = DotProduct(speed, springDir); + float speedB = DotProduct(GetSpeed(point), springDir); + float step = Min(CTimer::GetTimeStep(), 3.0f); + float impulse = -damping * (speedA + speedB)/2.0f * m_fMass * step * 0.53f; + if(bIsHeavy) + impulse *= 2.0f; + + // what is this? + float a = m_fTurnMass / ((point.MagnitudeSqr() + 1.0f) * 2.0f * m_fMass); + a = Min(a, 1.0f); + float b = Abs(impulse / (speedB * m_fMass)); + if(a < b) + impulse *= a/b; + + ApplyMoveForce(springDir*impulse); + ApplyTurnForce(springDir*impulse, point); + return true; +} diff --git a/src/entities/Physical.h b/src/entities/Physical.h index 926b9762..290c267c 100644 --- a/src/entities/Physical.h +++ b/src/entities/Physical.h @@ -158,8 +158,8 @@ public: void ApplyFrictionTurnForce(const CVector &j, const CVector &p) { ApplyFrictionTurnForce(j.x, j.y, j.z, p.x, p.y, p.z); } // springRatio: 1.0 fully extended, 0.0 fully compressed bool ApplySpringCollision(float springConst, CVector &springDir, CVector &point, float springRatio, float bias); - bool ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir); - bool ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed); + bool ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir, float &impulse); + bool ApplySpringDampening(float damping, float dampingLimit, CVector &springDir, CVector &point, CVector &speed); void ApplyGravity(void); void ApplyFriction(void); void ApplyAirResistance(void); @@ -174,4 +174,8 @@ public: bool ProcessCollisionSectorList(CPtrList *lists); bool CheckCollision(void); bool CheckCollision_SimpleCar(void); + + // TEMP + bool ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir); + bool ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed); }; |