diff options
Diffstat (limited to 'src/render/Shadows.cpp')
-rw-r--r-- | src/render/Shadows.cpp | 2520 |
1 files changed, 0 insertions, 2520 deletions
diff --git a/src/render/Shadows.cpp b/src/render/Shadows.cpp deleted file mode 100644 index dd87bff6..00000000 --- a/src/render/Shadows.cpp +++ /dev/null @@ -1,2520 +0,0 @@ -#include "common.h" - -#include "main.h" -#include "TxdStore.h" -#include "Timer.h" -#include "Camera.h" -#include "Timecycle.h" -#include "CutsceneMgr.h" -#include "Automobile.h" -#include "Bike.h" -#include "Ped.h" -#include "PlayerPed.h" -#include "World.h" -#include "Weather.h" -#include "ModelIndices.h" -#include "RenderBuffer.h" -#ifdef FIX_BUGS -#include "Replay.h" -#endif -#include "PointLights.h" -#include "SpecialFX.h" -#include "Script.h" -#include "TimeStep.h" -#include "Shadows.h" -#include "CutsceneObject.h" -#include "CutsceneShadow.h" -#include "Clock.h" -#include "VarConsole.h" - -#ifdef DEBUGMENU -//SETTWEAKPATH("Shadows"); -//TWEAKBOOL(gbPrintShite); -#endif - -RwImVertexIndex ShadowIndexList[24]; - -RwTexture *gpShadowCarTex; -RwTexture *gpShadowPedTex; -RwTexture *gpShadowHeliTex; -RwTexture *gpShadowBikeTex; -RwTexture *gpShadowBaronTex; -RwTexture *gpShadowExplosionTex; -RwTexture *gpShadowHeadLightsTex; -RwTexture *gpOutline1Tex; -RwTexture *gpOutline2Tex; -RwTexture *gpOutline3Tex; -RwTexture *gpBloodPoolTex; -RwTexture *gpReflectionTex; -RwTexture *gpWalkDontTex; -RwTexture *gpCrackedGlassTex; -RwTexture *gpPostShadowTex; -RwTexture *gpGoalTex; - -int16 CShadows::ShadowsStoredToBeRendered; -CStoredShadow CShadows::asShadowsStored [MAX_STOREDSHADOWS]; -CPolyBunch CShadows::aPolyBunches [MAX_POLYBUNCHES]; -CStaticShadow CShadows::aStaticShadows [MAX_STATICSHADOWS]; -CPolyBunch *CShadows::pEmptyBunchList; -CPermanentShadow CShadows::aPermanentShadows[MAX_PERMAMENTSHADOWS]; - -#ifndef MASTER -bool gbCountPolysInShadow; -#endif - -void -CShadows::Init(void) -{ - CTxdStore::PushCurrentTxd(); - - int32 slut = CTxdStore::FindTxdSlot("particle"); - CTxdStore::SetCurrentTxd(slut); - - gpShadowCarTex = RwTextureRead("shad_car", nil); - gpShadowPedTex = RwTextureRead("shad_ped", nil); - gpShadowHeliTex = RwTextureRead("shad_heli", nil); - gpShadowBikeTex = RwTextureRead("shad_bike", nil); - gpShadowBaronTex = RwTextureRead("shad_rcbaron", nil); - gpShadowExplosionTex = RwTextureRead("shad_exp", nil); - gpShadowHeadLightsTex = RwTextureRead("headlight", nil); - gpOutline1Tex = RwTextureRead("outline_64", nil); - gpOutline2Tex = RwTextureRead("outline2_64", nil); - gpOutline3Tex = RwTextureRead("outline3_64", nil); - gpBloodPoolTex = RwTextureRead("bloodpool_64", nil); - gpReflectionTex = RwTextureRead("reflection01", nil); - gpWalkDontTex = RwTextureRead("walk_dont", nil); - gpCrackedGlassTex = RwTextureRead("wincrack_32", nil); - gpPostShadowTex = RwTextureRead("lamp_shad_64", nil); - - CTxdStore::PopCurrentTxd(); - - ASSERT(gpShadowCarTex != nil); - ASSERT(gpShadowPedTex != nil); - ASSERT(gpShadowHeliTex != nil); - ASSERT(gpShadowBikeTex != nil); - ASSERT(gpShadowBaronTex != nil); - ASSERT(gpShadowExplosionTex != nil); - ASSERT(gpShadowHeadLightsTex != nil); - ASSERT(gpOutline1Tex != nil); - ASSERT(gpOutline2Tex != nil); - ASSERT(gpOutline3Tex != nil); - ASSERT(gpBloodPoolTex != nil); - ASSERT(gpReflectionTex != nil); - ASSERT(gpWalkDontTex != nil); - ASSERT(gpCrackedGlassTex != nil); - ASSERT(gpPostShadowTex != nil); - - - ShadowIndexList[0] = 0; - ShadowIndexList[1] = 2; - ShadowIndexList[2] = 1; - - ShadowIndexList[3] = 0; - ShadowIndexList[4] = 3; - ShadowIndexList[5] = 2; - - ShadowIndexList[6] = 0; - ShadowIndexList[7] = 4; - ShadowIndexList[8] = 3; - - ShadowIndexList[9] = 0; - ShadowIndexList[10] = 5; - ShadowIndexList[11] = 4; - - ShadowIndexList[12] = 0; - ShadowIndexList[13] = 6; - ShadowIndexList[14] = 5; - - ShadowIndexList[15] = 0; - ShadowIndexList[16] = 7; - ShadowIndexList[17] = 6; - - ShadowIndexList[18] = 0; - ShadowIndexList[19] = 8; - ShadowIndexList[20] = 7; - - ShadowIndexList[21] = 0; - ShadowIndexList[22] = 9; - ShadowIndexList[23] = 8; - - - for ( int32 i = 0; i < MAX_STATICSHADOWS; i++ ) - { - aStaticShadows[i].m_nId = 0; - aStaticShadows[i].m_pPolyBunch = nil; - } - - pEmptyBunchList = &aPolyBunches[0]; - - for ( int32 i = 0; i < MAX_POLYBUNCHES; i++ ) - { - if ( i == MAX_POLYBUNCHES - 1 ) - aPolyBunches[i].m_pNext = nil; - else - aPolyBunches[i].m_pNext = &aPolyBunches[i + 1]; - } - - for ( int32 i = 0; i < MAX_PERMAMENTSHADOWS; i++ ) - { - aPermanentShadows[i].m_nType = SHADOWTYPE_NONE; - } - -#ifndef MASTER - VarConsole.Add("Count polys in shadow", &gbCountPolysInShadow, true); -#endif -} - -void -CShadows::Shutdown(void) -{ - ASSERT(gpShadowCarTex != nil); - ASSERT(gpShadowPedTex != nil); - ASSERT(gpShadowHeliTex != nil); - ASSERT(gpShadowBikeTex != nil); - ASSERT(gpShadowBaronTex != nil); - ASSERT(gpShadowExplosionTex != nil); - ASSERT(gpShadowHeadLightsTex != nil); - ASSERT(gpOutline1Tex != nil); - ASSERT(gpOutline2Tex != nil); - ASSERT(gpOutline3Tex != nil); - ASSERT(gpBloodPoolTex != nil); - ASSERT(gpReflectionTex != nil); - ASSERT(gpWalkDontTex != nil); - ASSERT(gpCrackedGlassTex != nil); - ASSERT(gpPostShadowTex != nil); - - RwTextureDestroy(gpShadowCarTex); - RwTextureDestroy(gpShadowPedTex); - RwTextureDestroy(gpShadowHeliTex); - RwTextureDestroy(gpShadowBikeTex); - RwTextureDestroy(gpShadowBaronTex); - RwTextureDestroy(gpShadowExplosionTex); - RwTextureDestroy(gpShadowHeadLightsTex); - RwTextureDestroy(gpOutline1Tex); - RwTextureDestroy(gpOutline2Tex); - RwTextureDestroy(gpOutline3Tex); - RwTextureDestroy(gpBloodPoolTex); - RwTextureDestroy(gpReflectionTex); - RwTextureDestroy(gpWalkDontTex); - RwTextureDestroy(gpCrackedGlassTex); - RwTextureDestroy(gpPostShadowTex); -} - -void -CShadows::AddPermanentShadow(uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, - float fFrontX, float fFrontY, float fSideX, float fSideY, - int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, - float fZDistance, uint32 nTime, float fScale) -{ - ASSERT(pTexture != nil); - ASSERT(pPosn != nil); - - - // find free slot - int32 nSlot = 0; - while ( nSlot < MAX_PERMAMENTSHADOWS && aPermanentShadows[nSlot].m_nType != SHADOWTYPE_NONE ) - nSlot++; - - if ( nSlot < MAX_PERMAMENTSHADOWS ) - { - aPermanentShadows[nSlot].m_nType = ShadowType; - aPermanentShadows[nSlot].m_pTexture = pTexture; - aPermanentShadows[nSlot].m_vecPos = *pPosn; - aPermanentShadows[nSlot].m_vecFront.x = fFrontX; - aPermanentShadows[nSlot].m_vecFront.y = fFrontY; - aPermanentShadows[nSlot].m_vecSide.x = fSideX; - aPermanentShadows[nSlot].m_vecSide.y = fSideY; - aPermanentShadows[nSlot].m_nIntensity = nIntensity; - aPermanentShadows[nSlot].m_nRed = nRed; - aPermanentShadows[nSlot].m_nGreen = nGreen; - aPermanentShadows[nSlot].m_nBlue = nBlue; - aPermanentShadows[nSlot].m_fZDistance = fZDistance; - aPermanentShadows[nSlot].m_nLifeTime = nTime; - aPermanentShadows[nSlot].m_nTimeCreated = CTimer::GetTimeInMilliseconds(); - } -} - -bool -CShadows::StoreStaticShadow(uint32 nID, uint8 ShadowType, RwTexture *pTexture, Const CVector *pPosn, - float fFrontX, float fFrontY, float fSideX, float fSideY, - int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, - float fZDistance, float fScale, float fDrawDistance, bool bTempShadow, float fUpDistance) -{ - ASSERT(pPosn != nil); - - float fDistToCamSqr = (*pPosn - TheCamera.GetPosition()).MagnitudeSqr2D(); - - if ( SQR(fDrawDistance) > fDistToCamSqr || fDrawDistance == 0.0f ) - { - if ( fDrawDistance != 0.0f ) - { - float fDistToCam = Sqrt(fDistToCamSqr); - - if ( fDistToCam >= (fDrawDistance*(1.0f-(1.0f/4.0f))) ) - { - //fDistToCam == 0 -> 4 - //fDistToCam == fDrawDistance -> 0 - float fMult = 1.0f - (4.0f / fDrawDistance) * (fDistToCam - (fDrawDistance*(1.0f-(1.0f/4.0f)))); - - nIntensity = (int32)(nIntensity * fMult); - nRed = (int32)(nRed * fMult); - nGreen = (int32)(nGreen * fMult); - nBlue = (int32)(nBlue * fMult); - } - } - - int32 nSlot; - - nSlot = 0; - while ( nSlot < MAX_STATICSHADOWS && !(nID == aStaticShadows[nSlot].m_nId && aStaticShadows[nSlot].m_pPolyBunch != nil) ) - nSlot++; - - if ( nSlot < MAX_STATICSHADOWS ) - { - if ( Abs(pPosn->x - aStaticShadows[nSlot].m_vecPosn.x) < fUpDistance - && Abs(pPosn->y - aStaticShadows[nSlot].m_vecPosn.y) < fUpDistance ) - { - aStaticShadows[nSlot].m_bJustCreated = true; - aStaticShadows[nSlot].m_nType = ShadowType; - aStaticShadows[nSlot].m_pTexture = pTexture; - aStaticShadows[nSlot].m_nIntensity = nIntensity; - aStaticShadows[nSlot].m_nRed = nRed; - aStaticShadows[nSlot].m_nGreen = nGreen; - aStaticShadows[nSlot].m_nBlue = nBlue; - aStaticShadows[nSlot].m_fZDistance = fZDistance; - aStaticShadows[nSlot].m_fScale = fScale; - aStaticShadows[nSlot].m_bTemp = bTempShadow; - aStaticShadows[nSlot].m_nTimeCreated = CTimer::GetTimeInMilliseconds(); - - return true; - } - else if ( Abs(pPosn->x - aStaticShadows[nSlot].m_vecPosn.x) < 0.05f - && Abs(pPosn->y - aStaticShadows[nSlot].m_vecPosn.y) < 0.05f - && Abs(pPosn->z - aStaticShadows[nSlot].m_vecPosn.z) < 2.0f - - && fFrontX == aStaticShadows[nSlot].m_vecFront.x - && fFrontY == aStaticShadows[nSlot].m_vecFront.y - && fSideX == aStaticShadows[nSlot].m_vecSide.x - && fSideY == aStaticShadows[nSlot].m_vecSide.y ) - { - aStaticShadows[nSlot].m_bJustCreated = true; - aStaticShadows[nSlot].m_nType = ShadowType; - aStaticShadows[nSlot].m_pTexture = pTexture; - aStaticShadows[nSlot].m_nIntensity = nIntensity; - aStaticShadows[nSlot].m_nRed = nRed; - aStaticShadows[nSlot].m_nGreen = nGreen; - aStaticShadows[nSlot].m_nBlue = nBlue; - aStaticShadows[nSlot].m_fZDistance = fZDistance; - aStaticShadows[nSlot].m_fScale = fScale; - aStaticShadows[nSlot].m_bTemp = bTempShadow; - aStaticShadows[nSlot].m_nTimeCreated = CTimer::GetTimeInMilliseconds(); - - return true; - } - else - { - aStaticShadows[nSlot].Free(); - - aStaticShadows[nSlot].m_nId = nID; - aStaticShadows[nSlot].m_nType = ShadowType; - aStaticShadows[nSlot].m_pTexture = pTexture; - aStaticShadows[nSlot].m_nIntensity = nIntensity; - aStaticShadows[nSlot].m_nRed = nRed; - aStaticShadows[nSlot].m_nGreen = nGreen; - aStaticShadows[nSlot].m_nBlue = nBlue; - aStaticShadows[nSlot].m_fZDistance = fZDistance; - aStaticShadows[nSlot].m_fScale = fScale; - aStaticShadows[nSlot].m_vecPosn = *pPosn; - aStaticShadows[nSlot].m_vecFront.x = fFrontX; - aStaticShadows[nSlot].m_vecFront.y = fFrontY; - aStaticShadows[nSlot].m_vecSide.x = fSideX; - aStaticShadows[nSlot].m_vecSide.y = fSideY; - aStaticShadows[nSlot].m_bJustCreated = true; - aStaticShadows[nSlot].m_bTemp = bTempShadow; - aStaticShadows[nSlot].m_nTimeCreated = CTimer::GetTimeInMilliseconds(); - - GeneratePolysForStaticShadow(nSlot); - - return aStaticShadows[nSlot].m_pPolyBunch != nil; - } - } - else - { - nSlot = 0; - while ( nSlot < MAX_STATICSHADOWS && aStaticShadows[nSlot].m_pPolyBunch != nil ) - nSlot++; - - if ( nSlot != MAX_STATICSHADOWS ) - { - aStaticShadows[nSlot].m_nId = nID; - aStaticShadows[nSlot].m_nType = ShadowType; - aStaticShadows[nSlot].m_pTexture = pTexture; - aStaticShadows[nSlot].m_nIntensity = nIntensity; - aStaticShadows[nSlot].m_nRed = nRed; - aStaticShadows[nSlot].m_nGreen = nGreen; - aStaticShadows[nSlot].m_nBlue = nBlue; - aStaticShadows[nSlot].m_fZDistance = fZDistance; - aStaticShadows[nSlot].m_fScale = fScale; - aStaticShadows[nSlot].m_vecPosn = *pPosn; - aStaticShadows[nSlot].m_vecFront.x = fFrontX; - aStaticShadows[nSlot].m_vecFront.y = fFrontY; - aStaticShadows[nSlot].m_vecSide.x = fSideX; - aStaticShadows[nSlot].m_vecSide.y = fSideY; - aStaticShadows[nSlot].m_bJustCreated = true; - aStaticShadows[nSlot].m_bTemp = bTempShadow; - aStaticShadows[nSlot].m_nTimeCreated = CTimer::GetTimeInMilliseconds(); - - GeneratePolysForStaticShadow(nSlot); - - return aStaticShadows[nSlot].m_pPolyBunch != nil; - } - } - } - - return true; -} - -void -CShadows::StoreShadowToBeRendered(uint8 ShadowTexture, CVector *pPosn, - float fFrontX, float fFrontY, float fSideX, float fSideY, - int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue) -{ - ASSERT(pPosn != nil); - - switch ( ShadowTexture ) - { - case SHADOWTEX_NONE: - { - break; - } - - case SHADOWTEX_CAR: - { - StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowCarTex, pPosn, - fFrontX, fFrontY, fSideX, fSideY, - nIntensity, nRed, nGreen, nBlue, - 15.0f, false, 1.0f, nil, false); - - break; - } - - case SHADOWTEX_PED: - { - StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowPedTex, pPosn, - fFrontX, fFrontY, fSideX, fSideY, - nIntensity, nRed, nGreen, nBlue, - 15.0f, false, 1.0f, nil, false); - - break; - } - - case SHADOWTEX_EXPLOSION: - { - StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, pPosn, - fFrontX, fFrontY, fSideX, fSideY, - nIntensity, nRed, nGreen, nBlue, - 15.0f, false, 1.0f, nil, false); - - break; - } - - case SHADOWTEX_HELI: - { - StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowHeliTex, pPosn, - fFrontX, fFrontY, fSideX, fSideY, - nIntensity, nRed, nGreen, nBlue, - 15.0f, false, 1.0f, nil, false); - - break; - } - - case SHADOWTEX_HEADLIGHTS: - { - StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowHeadLightsTex, pPosn, - fFrontX, fFrontY, fSideX, fSideY, - nIntensity, nRed, nGreen, nBlue, - 15.0f, false, 1.0f, nil, false); - - break; - } - - case SHADOWTEX_BLOOD: - { - StoreShadowToBeRendered(SHADOWTYPE_DARK, gpBloodPoolTex, pPosn, - fFrontX, fFrontY, fSideX, fSideY, - nIntensity, nRed, 150, 0, - 15.0f, false, 1.0f, nil, false); - - break; - } - } - - //ASSERT(false); -} - -void -CShadows::StoreShadowToBeRendered(uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, - float fFrontX, float fFrontY, float fSideX, float fSideY, - int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, - float fZDistance, bool bDrawOnWater, float fScale, CCutsceneShadow *pShadow, bool bDrawOnBuildings) -{ - ASSERT(pTexture != nil); - ASSERT(pPosn != nil); - - if ( ShadowsStoredToBeRendered < MAX_STOREDSHADOWS ) - { - asShadowsStored[ShadowsStoredToBeRendered].m_ShadowType = ShadowType; - asShadowsStored[ShadowsStoredToBeRendered].m_pTexture = pTexture; - asShadowsStored[ShadowsStoredToBeRendered].m_vecPos = *pPosn; - asShadowsStored[ShadowsStoredToBeRendered].m_vecFront.x = fFrontX; - asShadowsStored[ShadowsStoredToBeRendered].m_vecFront.y = fFrontY; - asShadowsStored[ShadowsStoredToBeRendered].m_vecSide.x = fSideX; - asShadowsStored[ShadowsStoredToBeRendered].m_vecSide.y = fSideY; - asShadowsStored[ShadowsStoredToBeRendered].m_nIntensity = nIntensity; - asShadowsStored[ShadowsStoredToBeRendered].m_nRed = nRed; - asShadowsStored[ShadowsStoredToBeRendered].m_nGreen = nGreen; - asShadowsStored[ShadowsStoredToBeRendered].m_nBlue = nBlue; - asShadowsStored[ShadowsStoredToBeRendered].m_fZDistance = fZDistance; - asShadowsStored[ShadowsStoredToBeRendered].m_nFlags.bDrawOnWater = bDrawOnWater; - asShadowsStored[ShadowsStoredToBeRendered].m_nFlags.bDrawOnBuildings = bDrawOnBuildings; - asShadowsStored[ShadowsStoredToBeRendered].m_fScale = fScale; - asShadowsStored[ShadowsStoredToBeRendered].m_pCutsceneShadow = pShadow; - - ShadowsStoredToBeRendered++; - } -} - - -void -CShadows::StoreShadowForVehicle(CVehicle *pCar, VEH_SHD_TYPE type) -{ - ASSERT(pCar != nil); - - if ( CTimeCycle::GetShadowStrength() != 0 ) - { - CVector CarPos = pCar->GetPosition(); - float fDistToCamSqr = (CarPos - TheCamera.GetPosition()).MagnitudeSqr2D(); - - if ( CCutsceneMgr::IsRunning() ) - fDistToCamSqr /= SQR(TheCamera.LODDistMultiplier) * 4.0f; - - float fDrawDistance; - switch ( type ) - { - case VEH_SHD_TYPE_SEAPLANE: - case VEH_SHD_TYPE_RCPLANE: - fDrawDistance = 144.0f; - break; - - case VEH_SHD_TYPE_HELI: - fDrawDistance = 144.0f; - break; - - default: - fDrawDistance = 18.0f; - break; - } - - if ( fDistToCamSqr < SQR(fDrawDistance) ) - { - float fDistToCam = Sqrt(fDistToCamSqr); - - //fDistToCam == 0 -> 4 - //fDistToCam == fDrawDistance -> 0 - float fMult = 1.0f - (fDistToCam - (fDrawDistance*(1.0f-(1.0f/4.0f)))) / (fDrawDistance*(1.0f/4.0f)); - - int32 nColorStrength; - - if ( fDistToCam >= (fDrawDistance*(1.0f-(1.0f/4.0f))) ) - nColorStrength = (int32)(fMult * CTimeCycle::GetShadowStrength()); - else - nColorStrength = CTimeCycle::GetShadowStrength(); - - - float fVehicleHeight = pCar->GetColModel()->boundingBox.GetSize().y; - float fVehicleWidth = pCar->GetColModel()->boundingBox.GetSize().x; - - float size = 1.0f; - - if ( pCar->GetModelIndex() == MI_HUNTER ) - { - fVehicleWidth *= 3.0f; - fVehicleHeight *= 1.4f; - size *= 0.5f; - } - else if ( pCar->GetModelIndex() == MI_ANGEL ) - { - fVehicleHeight = fVehicleHeight * 1.5f; - size = 0.03f; - } - else if ( pCar->GetModelIndex() == MI_SEASPAR ) - { - fVehicleWidth *= 3.0f; - fVehicleHeight *= 1.4f; - size *= 0.5f; - } - else if ( pCar->GetModelIndex() == MI_PIZZABOY || pCar->GetModelIndex() == MI_PCJ600 || pCar->GetModelIndex() == MI_FAGGIO ) - { - fVehicleHeight *= 1.2f; - size = 0.05f; - } - else if ( pCar->GetModelIndex() == MI_FREEWAY ) - { - fVehicleHeight *= 1.5f; - size = 0.03f; - } - else if ( pCar->GetModelIndex() == MI_RCRAIDER ) - { - fVehicleHeight *= 1.5f; - fVehicleWidth *= 2.0f; - size = 0.2f; - } - else if ( pCar->GetModelIndex() == MI_SANCHEZ ) - { - fVehicleHeight *= 1.5f; - size = 0.03f; - } - else if ( pCar->GetModelIndex() == MI_SPARROW || pCar->GetModelIndex() == MI_MAVERICK || pCar->GetModelIndex() == MI_VCNMAV || pCar->GetModelIndex() == MI_POLMAV ) - { - fVehicleWidth *= 3.0f; - fVehicleHeight *= 1.4f; - size *= 0.5f; - } - else if ( pCar->GetModelIndex() == MI_RCGOBLIN ) - { - fVehicleHeight *= 1.5f; - fVehicleWidth *= 2.0f; - size = 0.2f; - } - else if ( pCar->GetModelIndex() == MI_DODO ) - { - fVehicleHeight *= 0.9f; - fVehicleWidth *= 0.4f; - } - - CarPos.x -= pCar->GetForward().x * (((fVehicleHeight/2) - pCar->GetColModel()->boundingBox.max.y)*size); - CarPos.y -= pCar->GetForward().y * (((fVehicleHeight/2) - pCar->GetColModel()->boundingBox.max.y)*size); - - RwTexture *tex = gpShadowCarTex; - switch ( type ) - { - case VEH_SHD_TYPE_BIKE: - { - float wheelZ = Abs(((CBike*)pCar)->m_fLeanLRAngle); - float mul = 5.092958f * wheelZ + 1.0f; - if (pCar->GetStatus() == STATUS_PHYSICS) - { - float z = pCar->GetRight().z; - if (z > 0.6f) - mul += 4.0f * z; - } - fVehicleWidth *= mul; - tex = gpShadowBikeTex; - break; - } - - case VEH_SHD_TYPE_HELI: - tex = gpShadowHeliTex; - break; - - case VEH_SHD_TYPE_SEAPLANE: - nColorStrength = CTimeCycle::GetShadowStrength(); - tex = gpShadowBaronTex; - break; - - case VEH_SHD_TYPE_RCPLANE: - tex = gpShadowBaronTex; - fVehicleHeight *= 1.5f; - fVehicleWidth *= 2.2f; - break; - - case VEH_SHD_TYPE_CAR: - tex = gpShadowCarTex; - break; - } - - float frontx = pCar->GetForward().x; - float fronty = pCar->GetForward().y; - float sidex = pCar->GetRight().x; - float sidey = pCar->GetRight().y; - - switch ( type ) - { - case VEH_SHD_TYPE_BIKE: - if ( Abs(pCar->GetRight().z) > 0.6f ) - { - sidex = pCar->GetUp().x; - sidey = pCar->GetUp().y; - } - break; - - case VEH_SHD_TYPE_HELI: - if ( Abs(pCar->GetRight().z) > 0.57f ) - { - sidex = pCar->GetUp().x; - sidey = pCar->GetUp().y; - } - if ( Abs(pCar->GetForward().z) > 0.57f ) - { - frontx = pCar->GetUp().x; - fronty = pCar->GetUp().y; - } - break; - } - - bool bDrawOnBuildings = false; - if ( pCar->GetModelIndex() == MI_RCBANDIT - || pCar->GetModelIndex() == MI_RCBARON - || pCar->GetModelIndex() == MI_RCRAIDER - || pCar->GetModelIndex() == MI_RCGOBLIN - || pCar == FindPlayerVehicle() ) - { - bDrawOnBuildings = true; - } - - if ( pCar->m_vecMoveSpeed.Magnitude() * CTimeStep::ms_fTimeStep > 0.1f || bDrawOnBuildings ) - { - if ( pCar->GetUp().z > 0.0f ) - { - StoreShadowToBeRendered(SHADOWTYPE_DARK, tex, &CarPos, - frontx * (fVehicleHeight / 2), - fronty * (fVehicleHeight / 2), - sidex * (fVehicleWidth / 2), - sidey * (fVehicleWidth / 2), - nColorStrength, nColorStrength, nColorStrength, nColorStrength, - 4.5f, false, 1.0f, nil, bDrawOnBuildings); - } - else - { - StoreShadowToBeRendered(SHADOWTYPE_DARK, tex, &CarPos, - frontx * (fVehicleHeight / 2), - fronty * (fVehicleHeight / 2), - -sidex * (fVehicleWidth / 2), - -sidey * (fVehicleWidth / 2), - nColorStrength, nColorStrength, nColorStrength, nColorStrength, - 4.5f, false, 1.0f, nil, bDrawOnBuildings); - } - } - else - { - if ( pCar->GetUp().z > 0.0f ) - { - StoreStaticShadow((uintptr)pCar + 1, SHADOWTYPE_DARK, tex, &CarPos, - frontx * (fVehicleHeight / 2), - fronty * (fVehicleHeight / 2), - sidex * (fVehicleWidth / 2), - sidey * (fVehicleWidth / 2), - nColorStrength, nColorStrength, nColorStrength, nColorStrength, - 4.5f, 1.0f, 0.0f, false, 0.1f); - } - else - { - StoreStaticShadow((uintptr)pCar + 1, SHADOWTYPE_DARK, tex, &CarPos, - frontx * (fVehicleHeight / 2), - fronty * (fVehicleHeight / 2), - -sidex * (fVehicleWidth / 2), - -sidey * (fVehicleWidth / 2), - nColorStrength, nColorStrength, nColorStrength, nColorStrength, - 4.5f, 1.0f, 0.0f, false, 0.1f); - } - } - } - } -} - -void -CShadows::StoreCarLightShadow(CVehicle *pCar, int32 nID, RwTexture *pTexture, CVector *pPosn, - float fFrontX, float fFrontY, float fSideX, float fSideY, uint8 nRed, uint8 nGreen, uint8 nBlue, - float fMaxViewAngle) -{ - ASSERT(pCar != nil); - ASSERT(pPosn != nil); - - float fDistToCamSqr = (*pPosn - TheCamera.GetPosition()).MagnitudeSqr2D(); - - bool bSpecialCam = TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN - || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED - || CCutsceneMgr::IsRunning(); - - float fDrawDistance = 27.0f; - - if ( fDistToCamSqr < SQR(fDrawDistance) || bSpecialCam ) - { - if ( bSpecialCam || DotProduct2D(CVector2D(TheCamera.CamFrontXNorm, TheCamera.CamFrontYNorm), - *pPosn - TheCamera.GetPosition() ) > -fMaxViewAngle ) - { - float fDistToCam = Sqrt(fDistToCamSqr); - - if ( fDistToCam >= (fDrawDistance*(1.0f-(1.0f/4.0f))) && !bSpecialCam ) // BUG? must be 3.0? - { - //fDistToCam == 0 -> 3 - //fDistToCam == fDrawDistance -> 0 - float fMult = 1.0f - (3.0f / fDrawDistance) * (fDistToCam - (fDrawDistance*(1.0f-(1.0f/3.0f))) ); - - nRed = (int32)(nRed * fMult); - nGreen = (int32)(nGreen * fMult); - nBlue = (int32)(nBlue * fMult); - } - - if ( pCar->m_vecMoveSpeed.Magnitude() * CTimeStep::ms_fTimeStep > 0.4f || pCar == FindPlayerVehicle() ) - { - StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, pTexture, pPosn, - fFrontX, fFrontY, - fSideX, fSideY, - 128, nRed, nGreen, nBlue, - 6.0f, false, 1.0f, - nil, pCar == FindPlayerVehicle()); - } - else - { - StoreStaticShadow((uintptr)pCar + nID, SHADOWTYPE_ADDITIVE, pTexture, pPosn, - fFrontX, fFrontY, - fSideX, fSideY, - 128, nRed, nGreen, nBlue, - 6.0f, 1.0f, 27.0f, - false, 0.4f); - } - } - } -} - - -#ifdef USE_CUTSCENE_SHADOW_FOR_PED -void -StoreShadowForCutscenePedObject(CPed *pObject, float fDisplacementX, float fDisplacementY, - float fFrontX, float fFrontY, float fSideX, float fSideY) -{ - ASSERT(pObject != nil); - - CCutsceneShadow *shadow = pObject->m_pRTShadow; - - if ( shadow == nil ) - return; - - if ( !shadow->IsInitialized() ) - return; - - CVector pos = pObject->GetPosition(); - - float fDistToCamSqr = (pos - TheCamera.GetPosition()).MagnitudeSqr2D(); - - float fDrawDistance = 100.0f; - - if ( fDistToCamSqr < SQR(fDrawDistance*0.5f) ) - { - if ( (CEntity*)pObject == FindPlayerPed() || TheCamera.IsSphereVisible(pos, 2.0f) ) - { - float fDistToCam = Sqrt(fDistToCamSqr); - - float fMult = 1.0f - (4.0f / fDrawDistance) * (fDistToCam - (fDrawDistance*(1.0f/4.0f))); - int32 nColorStrength; - - if ( fDistToCam >= (fDrawDistance*(1.0f/4.0f)) ) - nColorStrength = (int32)(CTimeCycle::GetShadowStrength() * fMult); - else - nColorStrength = CTimeCycle::GetShadowStrength(); - - int32 color = int32(nColorStrength * 0.8f); - - pos.x += fDisplacementX; - pos.y += fDisplacementY; - - RwTexture *texture = shadow->GetShadowRwTexture(); - ASSERT(texture); - RwRGBA bordercolor = {0, 0, 0, 0}; - shadow->DrawBorderAroundTexture(bordercolor); - - pos.x -= fDisplacementX; - pos.y -= fDisplacementY; - - float angleY = 360.0f - RADTODEG((CClock::ms_nGameClockMinutes - +60*CClock::ms_nGameClockHours+CClock::ms_nGameClockSeconds/60)*(HALFPI/360.0f)); - - RwFrame *frame = shadow->SetLightProperties(angleY, -85.0f, true); - ASSERT(frame); - CVector at(RwFrameGetMatrix(frame)->at); - at.Normalise(); - - CShadows::CalcPedShadowValues(at, &fFrontX, &fFrontY, &fSideX, &fSideY, &fDisplacementX, &fDisplacementY); - - pos.x -= 2.5f * fDisplacementX; - pos.y -= 2.5f * fDisplacementY; - - CShadows::StoreShadowToBeRendered(SHADOWTYPE_INVCOLOR, texture, &pos, - fFrontX * 1.5f, fFrontY * 1.5f, - fSideX * 1.5f, fSideY * 1.5f, - color, color, color, color, - 4.0f, false, 1.0f, shadow, false); - } - } -} -#endif - - -void -CShadows::StoreShadowForPed(CPed *pPed, float fDisplacementX, float fDisplacementY, - float fFrontX, float fFrontY, float fSideX, float fSideY) -{ - ASSERT(pPed != nil); - - if ( pPed->bIsVisible ) - { - if ( !(pPed->bInVehicle && pPed->m_nPedState != PED_DRAG_FROM_CAR && pPed->m_nPedState != PED_EXIT_CAR) ) - { - if ( CTimeCycle::GetShadowStrength() != 0 ) - { -#ifdef USE_CUTSCENE_SHADOW_FOR_PED - CCutsceneShadow *pShadow = pPed->m_pRTShadow; - - if (pShadow) - { - if (pShadow->IsInitialized()) - pShadow->UpdateForCutscene(); - ::StoreShadowForCutscenePedObject(pPed, fDisplacementX, fDisplacementY, fFrontX, fFrontY, fSideX, fSideY); - } - - return; -#endif - - StoreShadowForPedObject(pPed, - fDisplacementX, fDisplacementY, - fFrontX, fFrontY, - fSideX, fSideY); - } - } - } -} - -void -CShadows::StoreShadowForPedObject(CEntity *pPedObject, float fDisplacementX, float fDisplacementY, - float fFrontX, float fFrontY, float fSideX, float fSideY) -{ - ASSERT(pPedObject != nil); - - CVector PedPos = pPedObject->GetPosition(); - - float fDistToCamSqr = (PedPos - TheCamera.GetPosition()).MagnitudeSqr2D(); - - float fDrawDistance = 26.0f; - - if ( fDistToCamSqr < SQR(fDrawDistance*0.5f) ) - { - if ( pPedObject == FindPlayerPed() || TheCamera.IsSphereVisible(PedPos, 2.0f) != false ) - { - float fDistToCam = Sqrt(fDistToCamSqr); - - //fDistToCam == 0 -> 2 - //fDistToCam == fDrawDistance -> -2 - float fMult = 1.0f - (4.0f / fDrawDistance) * (fDistToCam - (fDrawDistance*(1.0f/4.0f))); // BUG ? negative - int32 nColorStrength; - - if ( fDistToCam >= (fDrawDistance*(1.0f/4.0f)) ) // BUG ? negative - nColorStrength = (int32)(CTimeCycle::GetShadowStrength() * fMult); - else - nColorStrength = CTimeCycle::GetShadowStrength(); - - PedPos.x += fDisplacementX; - PedPos.y += fDisplacementY; - - StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowPedTex, &PedPos, - fFrontX, fFrontY, - fSideX, fSideY, - nColorStrength, nColorStrength, nColorStrength, nColorStrength, - 4.0f, false, 1.0f, nil, pPedObject == FindPlayerPed()); - } - } -} - - -void -CShadows::StoreShadowForCutscenePedObject(CCutsceneObject *pObject, float fDisplacementX, float fDisplacementY, - float fFrontX, float fFrontY, float fSideX, float fSideY) -{ -#ifdef DISABLE_CUTSCENE_SHADOWS - return; -#endif - ASSERT(pObject != nil); - - CCutsceneShadow *shadow = pObject->m_pShadow; - - if ( shadow == nil ) - return; - - if ( !shadow->IsInitialized() ) - return; - - CVector pos = pObject->GetPosition(); - - float fDistToCamSqr = (pos - TheCamera.GetPosition()).MagnitudeSqr2D(); - - float fDrawDistance = 100.0f; - - if ( fDistToCamSqr < SQR(fDrawDistance*0.5f) ) - { - if ( (CEntity*)pObject == FindPlayerPed() || TheCamera.IsSphereVisible(pos, 2.0f) ) - { - float fDistToCam = Sqrt(fDistToCamSqr); - - float fMult = 1.0f - (4.0f / fDrawDistance) * (fDistToCam - (fDrawDistance*(1.0f/4.0f))); - int32 nColorStrength; - - if ( fDistToCam >= (fDrawDistance*(1.0f/4.0f)) ) - nColorStrength = (int32)(CTimeCycle::GetShadowStrength() * fMult); - else - nColorStrength = CTimeCycle::GetShadowStrength(); - - int32 color = int32(nColorStrength * 0.8f); - - pos.x += fDisplacementX; - pos.y += fDisplacementY; - - RwTexture *texture = shadow->GetShadowRwTexture(); - ASSERT(texture); - RwRGBA bordercolor = {0, 0, 0, 0}; - shadow->DrawBorderAroundTexture(bordercolor); - - pos.x -= fDisplacementX; - pos.y -= fDisplacementY; - - float angleY = 360.0f - RADTODEG((CClock::ms_nGameClockMinutes+60* - CClock::ms_nGameClockHours+CClock::ms_nGameClockSeconds/60)*(HALFPI/360.0f)); - - RwFrame *frame = shadow->SetLightProperties(angleY, -85.0f, true); - ASSERT(frame); - CVector at(RwFrameGetMatrix(frame)->at); - at.Normalise(); - - CalcPedShadowValues(at, &fFrontX, &fFrontY, &fSideX, &fSideY, &fDisplacementX, &fDisplacementY); - - pos.x -= 2.5f * fDisplacementX; - pos.y -= 2.5f * fDisplacementY; - - StoreShadowToBeRendered(SHADOWTYPE_INVCOLOR, texture, &pos, - fFrontX * 1.5f, fFrontY * 1.5f, - fSideX * 1.5f, fSideY * 1.5f, - color, color, color, color, - 4.0f, false, 1.0f, shadow, false); - } - } -} - -void -CShadows::StoreShadowForTree(CEntity *pTree) -{ - ASSERT(pTree != nil); -} - - -void -CShadows::StoreShadowForPole(CEntity *pPole, float fOffsetX, float fOffsetY, float fOffsetZ, - float fPoleHeight, float fPoleWidth, uint32 nID) -{ - ASSERT(pPole != nil); - - if ( CTimeCycle::GetShadowStrength() != 0 ) - { - if ( pPole->GetUp().z < 0.5f ) - return; - - CVector PolePos = pPole->GetPosition(); - - PolePos.x += fOffsetX * pPole->GetRight().x + fOffsetY * pPole->GetForward().x; - PolePos.y += fOffsetX * pPole->GetRight().y + fOffsetY * pPole->GetForward().y; - PolePos.z += fOffsetZ; - - PolePos.x += -CTimeCycle::GetSunDirection().x * (fPoleHeight / 2); - PolePos.y += -CTimeCycle::GetSunDirection().y * (fPoleHeight / 2); - - StoreStaticShadow((uintptr)pPole + nID + _TODOCONST(51), SHADOWTYPE_DARK, gpPostShadowTex, &PolePos, - -CTimeCycle::GetSunDirection().x * (fPoleHeight / 2), - -CTimeCycle::GetSunDirection().y * (fPoleHeight / 2), - CTimeCycle::GetShadowSideX() * fPoleWidth, - CTimeCycle::GetShadowSideY() * fPoleWidth, - 2 * (int32)((pPole->GetUp().z - 0.5f) * CTimeCycle::GetShadowStrength() * 2.0f) / 3, - 0, 0, 0, - 15.0f, 1.0f, 40.0f, false, 0.0f); - } -} - -void -CShadows::SetRenderModeForShadowType(uint8 ShadowType) -{ - switch ( ShadowType ) - { - case SHADOWTYPE_DARK: - { - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA); - break; - } - - case SHADOWTYPE_ADDITIVE: - { - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDONE); - break; - } - - case SHADOWTYPE_INVCOLOR: - { - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDZERO); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCCOLOR); - break; - } - } -} - - -void -CShadows::RenderStoredShadows(void) -{ - PUSH_RENDERGROUP("CShadows::RenderStoredShadows"); - - RenderBuffer::ClearRenderBuffer(); - - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE); - RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE); - RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void *)rwTEXTUREADDRESSCLAMP); - - - for ( int32 i = 0; i < ShadowsStoredToBeRendered; i++ ) - asShadowsStored[i].m_nFlags.bRendered = false; - - - for ( int32 i = 0; i < ShadowsStoredToBeRendered; i++ ) - { - if ( !asShadowsStored[i].m_nFlags.bRendered ) - { - SetRenderModeForShadowType(asShadowsStored[i].m_ShadowType); - - ASSERT(asShadowsStored[i].m_pTexture != nil); - - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(asShadowsStored[i].m_pTexture)); - - for ( int32 j = i; j < ShadowsStoredToBeRendered; j++ ) - { - if ( asShadowsStored[i].m_ShadowType == asShadowsStored[j].m_ShadowType - && asShadowsStored[i].m_pTexture == asShadowsStored[j].m_pTexture ) - { - float fWidth = Abs(asShadowsStored[j].m_vecFront.x) + Abs(asShadowsStored[j].m_vecSide.x); - float fHeight = Abs(asShadowsStored[j].m_vecFront.y) + Abs(asShadowsStored[j].m_vecSide.y); - - CVector shadowPos = asShadowsStored[j].m_vecPos; - - float fStartX = shadowPos.x - fWidth; - float fEndX = shadowPos.x + fWidth; - float fStartY = shadowPos.y - fHeight; - float fEndY = shadowPos.y + fHeight; - - int32 nStartX = Max(CWorld::GetSectorIndexX(fStartX), 0); - int32 nStartY = Max(CWorld::GetSectorIndexY(fStartY), 0); - int32 nEndX = Min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X-1); - int32 nEndY = Min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y-1); - - CWorld::AdvanceCurrentScanCode(); - - for ( int32 y = nStartY; y <= nEndY; y++ ) - { - for ( int32 x = nStartX; x <= nEndX; x++ ) - { - CSector *pCurSector = CWorld::GetSector(x, y); - - ASSERT(pCurSector != nil); - - if ( asShadowsStored[j].m_pCutsceneShadow ) - { - CastCutsceneShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS], - fStartX, fStartY, - fEndX, fEndY, - &shadowPos, - asShadowsStored[j].m_vecFront.x, - asShadowsStored[j].m_vecFront.y, - asShadowsStored[j].m_vecSide.x, - asShadowsStored[j].m_vecSide.y, - asShadowsStored[j].m_nIntensity, - asShadowsStored[j].m_nRed, - asShadowsStored[j].m_nGreen, - asShadowsStored[j].m_nBlue, - asShadowsStored[j].m_fZDistance, - asShadowsStored[j].m_fScale, - nil, - asShadowsStored[j].m_pCutsceneShadow); - - CastCutsceneShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], - fStartX, fStartY, - fEndX, fEndY, - &shadowPos, - asShadowsStored[j].m_vecFront.x, - asShadowsStored[j].m_vecFront.y, - asShadowsStored[j].m_vecSide.x, - asShadowsStored[j].m_vecSide.y, - asShadowsStored[j].m_nIntensity, - asShadowsStored[j].m_nRed, - asShadowsStored[j].m_nGreen, - asShadowsStored[j].m_nBlue, - asShadowsStored[j].m_fZDistance, - asShadowsStored[j].m_fScale, - nil, - asShadowsStored[j].m_pCutsceneShadow); - } - else if ( asShadowsStored[j].m_nFlags.bDrawOnBuildings ) - { - CastPlayerShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS], - fStartX, fStartY, - fEndX, fEndY, - &shadowPos, - asShadowsStored[j].m_vecFront.x, - asShadowsStored[j].m_vecFront.y, - asShadowsStored[j].m_vecSide.x, - asShadowsStored[j].m_vecSide.y, - asShadowsStored[j].m_nIntensity, - asShadowsStored[j].m_nRed, - asShadowsStored[j].m_nGreen, - asShadowsStored[j].m_nBlue, - asShadowsStored[j].m_fZDistance, - asShadowsStored[j].m_fScale, - nil); - - CastPlayerShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], - fStartX, fStartY, - fEndX, fEndY, - &shadowPos, - asShadowsStored[j].m_vecFront.x, - asShadowsStored[j].m_vecFront.y, - asShadowsStored[j].m_vecSide.x, - asShadowsStored[j].m_vecSide.y, - asShadowsStored[j].m_nIntensity, - asShadowsStored[j].m_nRed, - asShadowsStored[j].m_nGreen, - asShadowsStored[j].m_nBlue, - asShadowsStored[j].m_fZDistance, - asShadowsStored[j].m_fScale, - nil); - } - else - { - CastShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS], - fStartX, fStartY, - fEndX, fEndY, - &shadowPos, - asShadowsStored[j].m_vecFront.x, - asShadowsStored[j].m_vecFront.y, - asShadowsStored[j].m_vecSide.x, - asShadowsStored[j].m_vecSide.y, - asShadowsStored[j].m_nIntensity, - asShadowsStored[j].m_nRed, - asShadowsStored[j].m_nGreen, - asShadowsStored[j].m_nBlue, - asShadowsStored[j].m_fZDistance, - asShadowsStored[j].m_fScale, - nil); - - CastShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], - fStartX, fStartY, - fEndX, fEndY, - &shadowPos, - asShadowsStored[j].m_vecFront.x, - asShadowsStored[j].m_vecFront.y, - asShadowsStored[j].m_vecSide.x, - asShadowsStored[j].m_vecSide.y, - asShadowsStored[j].m_nIntensity, - asShadowsStored[j].m_nRed, - asShadowsStored[j].m_nGreen, - asShadowsStored[j].m_nBlue, - asShadowsStored[j].m_fZDistance, - asShadowsStored[j].m_fScale, - nil); - } - } - } - - asShadowsStored[j].m_nFlags.bRendered = true; - } - } - - RenderBuffer::RenderStuffInBuffer(); - } - } - - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE); - RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE); - RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void *)rwTEXTUREADDRESSWRAP); - - ShadowsStoredToBeRendered = 0; - - POP_RENDERGROUP(); -} - - -void -CShadows::RenderStaticShadows(void) -{ - PUSH_RENDERGROUP("CShadows::RenderStaticShadows"); - - RenderBuffer::ClearRenderBuffer(); - - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE); - RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)FALSE); - - SetAlphaTest(0); - - for ( int32 i = 0; i < MAX_STATICSHADOWS; i++ ) - aStaticShadows[i].m_bRendered = false; - - for ( int32 i = 0; i < MAX_STATICSHADOWS; i++ ) - { - if ( aStaticShadows[i].m_pPolyBunch && !aStaticShadows[i].m_bRendered ) - { - SetRenderModeForShadowType(aStaticShadows[i].m_nType); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(aStaticShadows[i].m_pTexture)); - - // optimization trick, render all shadows with same renderstate and texture - for ( int32 j = i; j < MAX_STATICSHADOWS; j++ ) - { - if ( aStaticShadows[j].m_pPolyBunch != nil - && aStaticShadows[i].m_nType == aStaticShadows[j].m_nType - && aStaticShadows[i].m_pTexture == aStaticShadows[j].m_pTexture ) - { - for ( CPolyBunch *bunch = aStaticShadows[j].m_pPolyBunch; bunch != nil; bunch = bunch->m_pNext ) - { - RwImVertexIndex *pIndexes; - RwIm3DVertex *pVerts; - - RenderBuffer::StartStoring(3 * (bunch->m_nNumVerts - 2), bunch->m_nNumVerts, &pIndexes, &pVerts); - - ASSERT(pIndexes != nil); - ASSERT(pVerts != nil); - - for ( int32 k = 0; k < bunch->m_nNumVerts; k++ ) - { - RwIm3DVertexSetRGBA(&pVerts[k], - aStaticShadows[j].m_nRed, - aStaticShadows[j].m_nGreen, - aStaticShadows[j].m_nBlue, - (int32)(aStaticShadows[j].m_nIntensity * (1.0f - CWeather::Foggyness * 0.5f))); - - RwIm3DVertexSetU (&pVerts[k], bunch->m_aU[k] / 200.0f); - RwIm3DVertexSetV (&pVerts[k], bunch->m_aV[k] / 200.0f); - RwIm3DVertexSetPos(&pVerts[k], bunch->m_aVerts[k].x, bunch->m_aVerts[k].y, bunch->m_aVerts[k].z + 0.03f); - } - - for ( int32 k = 0; k < 3 * (bunch->m_nNumVerts - 2); k++ ) - pIndexes[k] = ShadowIndexList[k]; - - RenderBuffer::StopStoring(); - } - - aStaticShadows[j].m_bRendered = true; - } - } - - RenderBuffer::RenderStuffInBuffer(); - } - } - RestoreAlphaTest(); - - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE); - - POP_RENDERGROUP(); -} - - -void -CShadows::GeneratePolysForStaticShadow(int16 nStaticShadowID) -{ - float fWidth = Abs(aStaticShadows[nStaticShadowID].m_vecFront.x) + Abs(aStaticShadows[nStaticShadowID].m_vecSide.x); - float fHeight = Abs(aStaticShadows[nStaticShadowID].m_vecFront.y) + Abs(aStaticShadows[nStaticShadowID].m_vecSide.y); - - CVector shadowPos = aStaticShadows[nStaticShadowID].m_vecPosn; - - float fStartX = shadowPos.x - fWidth; - float fEndX = shadowPos.x + fWidth; - float fStartY = shadowPos.y - fHeight; - float fEndY = shadowPos.y + fHeight; - - int32 nStartX = Max(CWorld::GetSectorIndexX(fStartX), 0); - int32 nStartY = Max(CWorld::GetSectorIndexY(fStartY), 0); - int32 nEndX = Min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X-1); - int32 nEndY = Min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y-1); - - CWorld::AdvanceCurrentScanCode(); - - for ( int32 y = nStartY; y <= nEndY; y++ ) - { - for ( int32 x = nStartX; x <= nEndX; x++ ) - { - CSector *pCurSector = CWorld::GetSector(x, y); - - ASSERT(pCurSector != nil); - - CastShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS], - fStartX, fStartY, - fEndX, fEndY, - &shadowPos, - aStaticShadows[nStaticShadowID].m_vecFront.x, - aStaticShadows[nStaticShadowID].m_vecFront.y, - aStaticShadows[nStaticShadowID].m_vecSide.x, - aStaticShadows[nStaticShadowID].m_vecSide.y, - 0, 0, 0, 0, - aStaticShadows[nStaticShadowID].m_fZDistance, - aStaticShadows[nStaticShadowID].m_fScale, - &aStaticShadows[nStaticShadowID].m_pPolyBunch); - - CastShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], - fStartX, fStartY, - fEndX, fEndY, - &shadowPos, - aStaticShadows[nStaticShadowID].m_vecFront.x, - aStaticShadows[nStaticShadowID].m_vecFront.y, - aStaticShadows[nStaticShadowID].m_vecSide.x, - aStaticShadows[nStaticShadowID].m_vecSide.y, - 0, 0, 0, 0, - aStaticShadows[nStaticShadowID].m_fZDistance, - aStaticShadows[nStaticShadowID].m_fScale, - &aStaticShadows[nStaticShadowID].m_pPolyBunch); - } - } -} - - -void -CShadows::CastShadowSectorList(CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY, CVector *pPosn, - float fFrontX, float fFrontY, float fSideX, float fSideY, - int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, - float fZDistance, float fScale, CPolyBunch **ppPolyBunch) -{ - ASSERT(pPosn != nil); - - CPtrNode *pNode = PtrList.first; - - CRect Bound; - - while ( pNode != nil ) - { - CEntity *pEntity = (CEntity *)pNode->item; - uint16 nScanCode = pEntity->m_scanCode; - pNode = pNode->next; - - ASSERT( pEntity != nil ); - - if ( nScanCode != CWorld::GetCurrentScanCode() ) - { - pEntity->m_scanCode = CWorld::GetCurrentScanCode(); - - if ( pEntity->bUsesCollision && !pEntity->bDontCastShadowsOn) - { - if ( IsAreaVisible(pEntity->m_area) ) - { - Bound = pEntity->GetBoundRect(); - - if ( fStartX < Bound.right - && fEndX > Bound.left - && fStartY < Bound.bottom - && fEndY > Bound.top ) - { - if ( pPosn->z - fZDistance < pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.max.z - && pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.min.z < pPosn->z ) - { - CastShadowEntityXY(pEntity, - fStartX, fStartY, - fEndX, fEndY, - pPosn, - fFrontX, fFrontY, - fSideX, fSideY, - nIntensity, nRed, nGreen, nBlue, - fZDistance, fScale, ppPolyBunch); - } - } - } - } - } - } -} - - -void -CShadows::CastPlayerShadowSectorList(CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY, CVector *pPosn, - float fFrontX, float fFrontY, float fSideX, float fSideY, - int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, - float fZDistance, float fScale, CPolyBunch **ppPolyBunch) -{ - ASSERT(pPosn != nil); - - CPtrNode *pNode = PtrList.first; - - CRect Bound; - - while ( pNode != nil ) - { - CEntity *pEntity = (CEntity *)pNode->item; - uint16 nScanCode = pEntity->m_scanCode; - pNode = pNode->next; - - ASSERT( pEntity != nil ); - - if ( nScanCode != CWorld::GetCurrentScanCode() ) - { - pEntity->m_scanCode = CWorld::GetCurrentScanCode(); - - if ( pEntity->bUsesCollision ) - { - if ( IsAreaVisible(pEntity->m_area) ) - { - Bound = pEntity->GetBoundRect(); - - if ( fStartX < Bound.right - && fEndX > Bound.left - && fStartY < Bound.bottom - && fEndY > Bound.top ) - { - if ( pPosn->z - fZDistance < pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.max.z - && pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.min.z < pPosn->z ) - { - CastShadowEntityXY(pEntity, - fStartX, fStartY, - fEndX, fEndY, - pPosn, - fFrontX, fFrontY, - fSideX, fSideY, - nIntensity, nRed, nGreen, nBlue, - fZDistance, fScale, ppPolyBunch); - } - } - } - } - } - } -} - - -void -CShadows::CastCutsceneShadowSectorList(CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY, CVector *pPosn, - float fFrontX, float fFrontY, float fSideX, float fSideY, - int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, - float fZDistance, float fScale, CPolyBunch **ppPolyBunch, CCutsceneShadow *pShadow) -{ - ASSERT(pPosn != nil); - ASSERT(pShadow != nil); - - CPtrNode *pNode = PtrList.first; - - CRect Bound; - - while ( pNode != nil ) - { - CEntity *pEntity = (CEntity *)pNode->item; - uint16 nScanCode = pEntity->m_scanCode; - pNode = pNode->next; - - ASSERT( pEntity != nil ); - - if ( nScanCode != CWorld::GetCurrentScanCode() ) - { - pEntity->m_scanCode = CWorld::GetCurrentScanCode(); - - if ( pEntity->bUsesCollision ) - { - if ( IsAreaVisible(pEntity->m_area) ) - { - Bound = pEntity->GetBoundRect(); - - if ( fStartX < Bound.right - && fEndX > Bound.left - && fStartY < Bound.bottom - && fEndY > Bound.top ) - { - if ( pPosn->z - fZDistance < pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.max.z - && pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.min.z < pPosn->z ) - { - CastShadowEntityXYZ(pEntity, pPosn, - fFrontX, fFrontY, - fSideX, fSideY, - nIntensity, nRed, nGreen, nBlue, - fZDistance, fScale, ppPolyBunch, pShadow); - } - } - } - } - } - } -} - -void -CShadows::CastShadowEntityXY(CEntity *pEntity, float fStartX, float fStartY, float fEndX, float fEndY, CVector *pPosn, - float fFrontX, float fFrontY, float fSideX, float fSideY, - int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, - float fZDistance, float fScale, CPolyBunch **ppPolyBunch) -{ - ASSERT(pEntity != nil); - ASSERT(pPosn != nil); - - static CVector List [20]; - static CVector Texture[20]; - static CVector Points [4]; - - CColModel *pCol = pEntity->GetColModel(); - ASSERT(pCol != nil); - -#ifndef MASTER - if ( gbPrintShite ) - printf("MI:%d Triangles:%d Coors:%f %f BBoxXY:%f %f\n", - pEntity->GetModelIndex(), - pCol->numTriangles, - pEntity->GetPosition().x, - pEntity->GetPosition().y, - pCol->boundingBox.GetSize().x, - pCol->boundingBox.GetSize().y); -#endif - - CCollision::CalculateTrianglePlanes(pCol); - - float fFrontRight = DotProduct2D(CVector2D(fFrontX, fFrontY), pEntity->GetRight()); - float fFrontForward = DotProduct2D(CVector2D(fFrontX, fFrontY), pEntity->GetForward()); - float fSideRight = DotProduct2D(CVector2D(fSideX, fSideY), pEntity->GetRight()); - float fSideForward = DotProduct2D(CVector2D(fSideX, fSideY), pEntity->GetForward()); - float fLengthRight = DotProduct2D(*pPosn - pEntity->GetPosition(), pEntity->GetRight()); - float fLengthForward = DotProduct2D(*pPosn - pEntity->GetPosition(), pEntity->GetForward()); - - Points[0].x = (fLengthRight + fFrontRight ) - fSideRight; - Points[0].y = (fLengthForward + fFrontForward) - fSideForward; - - Points[1].x = fSideRight + (fLengthRight + fFrontRight); - Points[1].y = fSideForward + (fLengthForward + fFrontForward); - - Points[2].x = fSideRight + (fLengthRight - fFrontRight); - Points[2].y = fSideForward + (fLengthForward - fFrontForward); - - Points[3].x = (fLengthRight - fFrontRight) - fSideRight; - Points[3].y = (fLengthForward - fFrontForward) - fSideForward; - - float MinX = Min(Min(Points[0].x, Points[1].x), Min(Points[2].x, Points[3].x)); - float MaxX = Max(Max(Points[0].x, Points[1].x), Max(Points[2].x, Points[3].x)); - - float MinY = Min(Min(Points[0].y, Points[1].y), Min(Points[2].y, Points[3].y)); - float MaxY = Max(Max(Points[0].y, Points[1].y), Max(Points[2].y, Points[3].y)); - - float MaxZ = pPosn->z - pEntity->GetPosition().z; - float MinZ = MaxZ - fZDistance; - - for ( int32 i = 0; i < pCol->numTriangles; i++ ) - { - CColTrianglePlane *pColTriPlanes = pCol->trianglePlanes; - ASSERT(pColTriPlanes != nil); - - CVector normal; - pColTriPlanes[i].GetNormal(normal); - if ( Abs(normal.z) > 0.1f ) - { - CColTriangle *pColTri = pCol->triangles; - ASSERT(pColTri != nil); - - CVector PointA, PointB, PointC; - - pCol->GetTrianglePoint(PointA, pColTri[i].a); - pCol->GetTrianglePoint(PointB, pColTri[i].b); - pCol->GetTrianglePoint(PointC, pColTri[i].c); - - if ( (PointA.x > MinX || PointB.x > MinX || PointC.x > MinX) - && (PointA.x < MaxX || PointB.x < MaxX || PointC.x < MaxX) - && (PointA.y > MinY || PointB.y > MinY || PointC.y > MinY) - && (PointA.y < MaxY || PointB.y < MaxY || PointC.y < MaxY) - && (PointA.z < MaxZ || PointB.z < MaxZ || PointC.z < MaxZ) - && (PointA.z > MinZ || PointB.z > MinZ || PointC.z > MinZ) ) - - { - List[0].x = Points[0].x; - List[0].y = Points[0].y; - - List[1].x = Points[1].x; - List[1].y = Points[1].y; - - List[2].x = Points[2].x; - List[2].y = Points[2].y; - - List[3].x = Points[3].x; - List[3].y = Points[3].y; - - Texture[0].x = 0.0f; - Texture[0].y = 0.0f; - - Texture[1].x = 1.0f; - Texture[1].y = 0.0f; - - Texture[2].x = 1.0f; - Texture[2].y = 1.0f; - - Texture[3].x = 0.0f; - Texture[3].y = 1.0f; - - - CVector2D start; - CVector2D dist; - - int32 numVerts1 = 0; - int16 vertType1 = 0; - { - for ( int32 j = 0; j < 4; j++ ) - { - start = PointA; - dist = PointB - PointA; - - int32 in = j; - - float cp = CrossProduct2D(CVector2D(List[in]) - start, dist); - - if ( cp > 0.0f ) - { - switch ( vertType1 ) - { - case 0: - { - int32 out = numVerts1++ + 10; - - Texture[out].x = Texture[in].x; - Texture[out].y = Texture[in].y; - List[out].x = List[in].x; - List[out].y = List[in].y; - - break; - } - - case 1: - { - int32 out = numVerts1++ + 10; - - Texture[out].x = Texture[in].x; - Texture[out].y = Texture[in].y; - List[out].x = List[in].x; - List[out].y = List[in].y; - - break; - } - - case 2: - { - float prevcp = CrossProduct2D(CVector2D(List[in-1]) - start, dist); - - float Scale = Abs(prevcp) / (Abs(prevcp) + Abs(cp)); - float Compl = 1.0f - Scale; - - int32 out1 = numVerts1++ + 10; - int32 out2 = numVerts1++ + 10; - - Texture[out1].x = Compl*Texture[in-1].x + Scale*Texture[in].x; - Texture[out1].y = Compl*Texture[in-1].y + Scale*Texture[in].y; - List[out1].x = Compl*List[in-1].x + Scale*List[in].x; - List[out1].y = Compl*List[in-1].y + Scale*List[in].y; - - Texture[out2].x = Texture[in].x; - Texture[out2].y = Texture[in].y; - List[out2].x = List[in].x; - List[out2].y = List[in].y; - - break; - } - } - - vertType1 = 1; - } - else - { - switch ( vertType1 ) - { - case 1: - { - float prevcp = CrossProduct2D(CVector2D(List[in-1]) - start, dist); - - float Scale = Abs(prevcp) / (Abs(prevcp) + Abs(cp)); - float Compl = 1.0f - Scale; - - int32 out = numVerts1++ + 10; - - Texture[out].x = Compl*Texture[in-1].x + Scale*Texture[in].x; - Texture[out].y = Compl*Texture[in-1].y + Scale*Texture[in].y; - List[out].x = Compl*List[in-1].x + Scale*List[in].x; - List[out].y = Compl*List[in-1].y + Scale*List[in].y; - - break; - } - } - - vertType1 = 2; - } - } - - float cp1 = CrossProduct2D(CVector2D(List[0]) - start, dist); - if ( cp1 > 0.0f && vertType1 == 2 || cp1 <= 0.0f && vertType1 == 1 ) - { - float cp2 = CrossProduct2D(CVector2D(List[3]) - start, dist); - - float Scale = Abs(cp2) / (Abs(cp2) + Abs(cp1)); - float Compl = 1.0f - Scale; - - int32 out = numVerts1++ + 10; - - Texture[out].x = Compl*Texture[3].x + Scale*Texture[0].x; - Texture[out].y = Compl*Texture[3].y + Scale*Texture[0].y; - List[out].x = Compl*List[3].x + Scale*List[0].x; - List[out].y = Compl*List[3].y + Scale*List[0].y; - } - } - - int32 numVerts2 = 0; - int16 vertType2 = 0; - { - for ( int32 j = 0; j < numVerts1; j++ ) - { - start = PointB; - dist = PointC - PointB; - - int32 in = j + 10; - float cp = CrossProduct2D(CVector2D(List[in]) - start, dist); - - if ( cp > 0.0f ) - { - switch ( vertType2 ) - { - case 0: - { - int32 out = numVerts2++; - - Texture[out].x = Texture[in].x; - Texture[out].y = Texture[in].y; - List[out].x = List[in].x; - List[out].y = List[in].y; - - break; - } - - case 1: - { - int32 out = numVerts2++; - - Texture[out].x = Texture[in].x; - Texture[out].y = Texture[in].y; - List[out].x = List[in].x; - List[out].y = List[in].y; - - break; - } - - case 2: - { - float prevcp = CrossProduct2D(CVector2D(List[in-1]) - start, dist); - - float Scale = Abs(prevcp) / (Abs(prevcp) + Abs(cp)); - float Compl = 1.0f - Scale; - - int32 out1 = numVerts2++; - int32 out2 = numVerts2++; - - Texture[out1].x = Compl*Texture[in-1].x + Scale*Texture[in].x; - Texture[out1].y = Compl*Texture[in-1].y + Scale*Texture[in].y; - List[out1].x = Compl*List[in-1].x + Scale*List[in].x; - List[out1].y = Compl*List[in-1].y + Scale*List[in].y; - - Texture[out2].x = Texture[in].x; - Texture[out2].y = Texture[in].y; - List[out2].x = List[in].x; - List[out2].y = List[in].y; - - break; - } - } - - vertType2 = 1; - } - else - { - switch ( vertType2 ) - { - case 1: - { - float prevcp = CrossProduct2D(CVector2D(List[in-1]) - start, dist); - - float Scale = Abs(prevcp) / (Abs(prevcp) + Abs(cp)); - float Compl = 1.0f - Scale; - - int32 out = numVerts2++; - - Texture[out].x = Compl*Texture[in-1].x + Scale*Texture[in].x; - Texture[out].y = Compl*Texture[in-1].y + Scale*Texture[in].y; - List[out].x = Compl*List[in-1].x + Scale*List[in].x; - List[out].y = Compl*List[in-1].y + Scale*List[in].y; - - break; - } - } - - vertType2 = 2; - } - } - - float cp1 = CrossProduct2D(CVector2D(List[10]) - start, dist); - if ( cp1 > 0.0f && vertType2 == 2 || cp1 <= 0.0f && vertType2 == 1 ) - { - int32 in = numVerts1 + 10; - - float cp2 = CrossProduct2D(CVector2D(List[in-1]) - start, dist); - - float Scale = Abs(cp2) / (Abs(cp2) + Abs(cp1)); - float Compl = 1.0f - Scale; - - int32 out = numVerts2++; - - Texture[out].x = Compl*Texture[in-1].x + Scale*Texture[10].x; - Texture[out].y = Compl*Texture[in-1].y + Scale*Texture[10].y; - List[out].x = Compl*List[in-1].x + Scale*List[10].x; - List[out].y = Compl*List[in-1].y + Scale*List[10].y; - } - } - - int32 numVerts3 = 0; - int16 vertType3 = 0; - { - for ( int32 j = 0; j < numVerts2; j++ ) - { - start = PointC; - dist = PointA - PointC; - - int32 in = j; - float cp = CrossProduct2D(CVector2D(List[in]) - start, dist); - - if ( cp > 0.0f ) - { - switch ( vertType3 ) - { - case 0: - { - int32 out = numVerts3++ + 10; - - Texture[out].x = Texture[in].x; - Texture[out].y = Texture[in].y; - List[out].x = List[in].x; - List[out].y = List[in].y; - - break; - } - - case 1: - { - int32 out = numVerts3++ + 10; - - Texture[out].x = Texture[in].x; - Texture[out].y = Texture[in].y; - List[out].x = List[in].x; - List[out].y = List[in].y; - - break; - } - - case 2: - { - float prevcp = CrossProduct2D(CVector2D(List[in-1]) - start, dist); - - float Scale = Abs(prevcp) / (Abs(prevcp) + Abs(cp)); - float Compl = 1.0f - Scale; - - int32 out1 = numVerts3++ + 10; - int32 out2 = numVerts3++ + 10; - - Texture[out1].x = Compl*Texture[in-1].x + Scale*Texture[in].x; - Texture[out1].y = Compl*Texture[in-1].y + Scale*Texture[in].y; - List[out1].x = Compl*List[in-1].x + Scale*List[in].x; - List[out1].y = Compl*List[in-1].y + Scale*List[in].y; - - Texture[out2].x = Texture[in].x; - Texture[out2].y = Texture[in].y; - List[out2].x = List[in].x; - List[out2].y = List[in].y; - - break; - } - } - - vertType3 = 1; - } - else - { - switch ( vertType3 ) - { - case 1: - { - float prevcp = CrossProduct2D(CVector2D(List[in-1]) - start, dist); - - float Scale = Abs(prevcp) / (Abs(prevcp) + Abs(cp)); - float Compl = 1.0f - Scale; - - int32 out = numVerts3++ + 10; - - Texture[out].x = Compl*Texture[in-1].x + Scale*Texture[in].x; - Texture[out].y = Compl*Texture[in-1].y + Scale*Texture[in].y; - List[out].x = Compl*List[in-1].x + Scale*List[in].x; - List[out].y = Compl*List[in-1].y + Scale*List[in].y; - - break; - } - } - - vertType3 = 2; - } - } - - float cp1 = CrossProduct2D(CVector2D(List[0]) - start, dist); - if ( cp1 > 0.0f && vertType3 == 2 || cp1 <= 0.0f && vertType3 == 1 ) - { - int32 in = numVerts2; - - float cp2 = CrossProduct2D(CVector2D(List[in-1]) - start, dist); - - float Scale = Abs(cp2) / (Abs(cp2) + Abs(cp1)); - float Compl = 1.0f - Scale; - - int32 out = numVerts3++ + 10; - - Texture[out].x = Compl*Texture[in-1].x + Scale*Texture[0].x; - Texture[out].y = Compl*Texture[in-1].y + Scale*Texture[0].y; - List[out].x = Compl*List[in-1].x + Scale*List[0].x; - List[out].y = Compl*List[in-1].y + Scale*List[0].y; - } - } - - if ( numVerts3 >= 3 ) - { - CVector norm; - - pColTriPlanes[i].GetNormal(norm); - - float dot = DotProduct(norm, PointA); - - for ( int32 j = 0; j < numVerts3; j++ ) - { - int32 idx = j + 10; - - List[idx].z = -(DotProduct2D(norm, List[idx]) - dot) / norm.z; - } - - for ( int32 j = 0; j < numVerts3; j++ ) - { - int32 idx = j + 10; - - CVector p = List[idx]; - - List[idx].x = p.y * pEntity->GetForward().x + p.x * pEntity->GetRight().x + pEntity->GetPosition().x; - List[idx].y = p.y * pEntity->GetForward().y + p.x * pEntity->GetRight().y + pEntity->GetPosition().y; - List[idx].z = p.z + pEntity->GetPosition().z; - } - - - if ( ppPolyBunch != nil ) - { - if ( pEmptyBunchList != nil ) - { - CPolyBunch *pBunch = pEmptyBunchList; - ASSERT(pBunch != nil); - pEmptyBunchList = pEmptyBunchList->m_pNext; - pBunch->m_pNext = *ppPolyBunch; - *ppPolyBunch = pBunch; - - pBunch->m_nNumVerts = numVerts3; - - for ( int32 j = 0; j < numVerts3; j++ ) - { - int32 in = j + 10; - - pBunch->m_aVerts[j] = List[in]; - - pBunch->m_aU[j] = (int32)(Texture[in].x * 200.0f); - pBunch->m_aV[j] = (int32)(Texture[in].y * 200.0f); - } - } - } - else - { - RwImVertexIndex *pIndexes; - RwIm3DVertex *pVerts; - - RenderBuffer::StartStoring(3 * (numVerts3 - 2), numVerts3, &pIndexes, &pVerts); - - ASSERT(pIndexes != nil); - ASSERT(pVerts != nil); - - - for ( int32 j = 0; j < numVerts3; j++ ) - { - int32 in = j + 10; - - RwIm3DVertexSetRGBA(&pVerts[j], nRed, nGreen, nBlue, nIntensity); - RwIm3DVertexSetU (&pVerts[j], Texture[in].x*fScale); - RwIm3DVertexSetV (&pVerts[j], Texture[in].y*fScale); - RwIm3DVertexSetPos (&pVerts[j], List[in].x, List[in].y, List[in].z + 0.03f); - } - - for ( int32 j = 0; j < 3*(numVerts3 - 2); j++ ) - pIndexes[j] = ShadowIndexList[j]; - - RenderBuffer::StopStoring(); - } - } - } - } - } -} - - -typedef struct _ProjectionParam -{ - RwV3d at; /* Camera at vector */ - RwMatrix invMatrix; /* Transforms to shadow camera space */ - RwUInt8 shadowValue; /* Shadow opacity value */ - RwBool fade; /* Shadow fades with distance */ - RwUInt32 numIm3DBatch; /* Number of buffer flushes */ - RwMatrix entityMatrix; -} -ProjectionParam; - -RwV3d *ShadowRenderTriangleCB(RwV3d *points, RwV3d *normal, ProjectionParam *param) -{ - RwV3d vIn[3]; - RwV3d vShad[3]; - - RwV3dTransformPoints(&vIn[0], points, 3, ¶m->entityMatrix); - - /* - * Reject backfacing triangles - * This reject the triangles parallel to the light as well - */ - if (RwV3dDotProduct(normal, ¶m->at) > 0.0f) - { - return points; - } - - RwV3dTransformPoints(&vShad[0], &vIn[0], 3, ¶m->invMatrix); - - /* - * Reject triangles behind the camera (z test). Note that any world - * triangles lying in front of the camera but before the object may - * have a shadow applied. To minimize such artefacts, this test could - * be modified to use a specific value rather than 0.0f, perhaps - * to reject triangles behind the center plane of the object. - * - * Reject triangles that lie entirely outside the shadow texture range - * (x,y test). - */ - if (((vShad[0].z < 0.0f) && (vShad[1].z < 0.0f) - && (vShad[2].z < 0.0f)) || ((vShad[0].x < 0.0f) - && (vShad[1].x < 0.0f) - && (vShad[2].x < 0.0f)) - || ((vShad[0].x > 1.0f) && (vShad[1].x > 1.0f) - && (vShad[2].x > 1.0f)) || ((vShad[0].y < 0.0f) - && (vShad[1].y < 0.0f) - && (vShad[2].y < 0.0f)) - || ((vShad[0].y > 1.0f) && (vShad[1].y > 1.0f) - && (vShad[2].y > 1.0f))) - { - return points; - } - - RwIm3DVertex *imv = nil; - RwImVertexIndex *imi = nil; - - RenderBuffer::StartStoring(3, 3, &imi, &imv); - - /* - * Set the immediate mode vertices for this triangle - */ - - RwIm3DVertexSetPos(imv, vIn[0].x, vIn[0].y, vIn[0].z); - RwIm3DVertexSetPos(imv + 1, vIn[1].x, vIn[1].y, vIn[1].z); - RwIm3DVertexSetPos(imv + 2, vIn[2].x, vIn[2].y, vIn[2].z); - - RwIm3DVertexSetU(imv, vShad[0].x); - RwIm3DVertexSetU(imv + 1, vShad[1].x); - RwIm3DVertexSetU(imv + 2, vShad[2].x); - - RwIm3DVertexSetV(imv, vShad[0].y); - RwIm3DVertexSetV(imv + 1, vShad[1].y); - RwIm3DVertexSetV(imv + 2, vShad[2].y); - - /* - * Do we fade out the shadow with distance? - */ - if (param->fade) - { - RwReal fadeVal; - RwUInt8 val; - - fadeVal = 1.0f - vShad[0].z * vShad[0].z; - val = - (fadeVal < - 0.0f) ? 0 : (RwUInt8) (fadeVal * param->shadowValue); - RwIm3DVertexSetRGBA(imv, val, val, val, val); - - fadeVal = 1.0f - vShad[1].z * vShad[1].z; - val = - (fadeVal < - 0.0f) ? 0 : (RwUInt8) (fadeVal * param->shadowValue); - RwIm3DVertexSetRGBA(imv + 1, val, val, val, val); - - fadeVal = 1.0f - vShad[2].z * vShad[2].z; - val = - (fadeVal < - 0.0f) ? 0 : (RwUInt8) (fadeVal * param->shadowValue); - RwIm3DVertexSetRGBA(imv + 2, val, val, val, val); - } - else - { - RwUInt8 val = param->shadowValue; - - RwIm3DVertexSetRGBA(imv, val, val, val, val); - RwIm3DVertexSetRGBA(imv + 1, val, val, val, val); - RwIm3DVertexSetRGBA(imv + 2, val, val, val, val); - } - - /* - * Update buffer position - */ - imi[0] = 0; - imi[1] = 1; - imi[2] = 2; - - RenderBuffer::StopStoring(); - - return points; -} - -void -CShadows::CastShadowEntityXYZ(CEntity *pEntity, CVector *pPosn, - float fFrontX, float fFrontY, float fSideX, float fSideY, - int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, - float fZDistance, float fScale, CPolyBunch **ppPolyBunch, CCutsceneShadow *pShadow) -{ - ASSERT(pEntity != nil); - ASSERT(pPosn != nil); - - if ( pShadow ) - { - ProjectionParam proj; - RwV3d scl; - RwV3d tr; - - CShadowCamera *shadow = pShadow->GetShadowCamera(); - CColModel *collision = pEntity->GetColModel(); - - CCollision::CalculateTrianglePlanes(collision); - - RwMatrix mat; - mat = *RwFrameGetMatrix(RwCameraGetFrame(shadow->GetRwCamera())); - - RwV3d Xaxis = { 1.0f, 0.0f, 0.0f }; - - RwMatrixRotate(&mat, &Xaxis, -45.0f, rwCOMBINEPRECONCAT); - - proj.at = mat.at; - pEntity->GetMatrix().CopyToRwMatrix(&proj.entityMatrix); - - RwMatrixInvert(&proj.invMatrix, &mat); - RwReal radius = RwCameraGetViewWindow(shadow->GetRwCamera())->x; - - scl.x = scl.y = -0.5f / (radius*0.9f); - scl.z = 1.0f / (radius*0.8f); - RwMatrixScale(&proj.invMatrix, &scl, rwCOMBINEPOSTCONCAT); - - tr.x = 0.5f; - tr.y = tr.z = 0.0f; - RwMatrixTranslate(&proj.invMatrix, &tr, rwCOMBINEPOSTCONCAT); - - proj.shadowValue = nIntensity; - proj.fade = 0; - - RwMatrix matrix; - pEntity->GetMatrix().CopyToRwMatrix(&matrix); - RwMatrix invMatrix; - RwMatrixInvert(&invMatrix, &matrix); - - - CVector center(pShadow->GetBaseSphere().center); - center += CVector(-fFrontX * 1.1f, -fFrontY * 1.1f, -0.5f); - - CSphere sphere; - sphere.Set(2.0f, center); - - RwV3d point; - RwV3dTransformPoints(&point, ¢er, 1, &invMatrix); - - CColSphere colSphere; - colSphere.Set(2.0f, CVector(point), 0, 0); - - int i = 0; - while ( i < collision->numTriangles ) - { - CVector p[3]; - - collision->GetTrianglePoint(p[0], collision->triangles[i].a); - collision->GetTrianglePoint(p[1], collision->triangles[i].b); - collision->GetTrianglePoint(p[2], collision->triangles[i].c); - - if ( CCollision::TestSphereTriangle(colSphere, collision->vertices, collision->triangles[i], collision->trianglePlanes[i]) ) - { - CVector n(collision->trianglePlanes[i].GetNormalX(), collision->trianglePlanes[i].GetNormalY(), collision->trianglePlanes[i].GetNormalZ()); - CVector offset = n * 0.028f; - - p[0] += offset; - p[1] += offset; - p[2] += offset; - - if ( !ShadowRenderTriangleCB(p, &n, &proj) ) - break; - } - i++; - } - } -} - -void -CShadows::UpdateStaticShadows(void) -{ - for ( int32 i = 0; i < MAX_STATICSHADOWS; i++ ) - { - if ( aStaticShadows[i].m_pPolyBunch != nil && !aStaticShadows[i].m_bJustCreated - && (!aStaticShadows[i].m_bTemp || CTimer::GetTimeInMilliseconds() > aStaticShadows[i].m_nTimeCreated + 5000) ) - { - aStaticShadows[i].Free(); - } - - aStaticShadows[i].m_bJustCreated = false; - } -} - -void -CShadows::UpdatePermanentShadows(void) -{ - for ( int32 i = 0; i < MAX_PERMAMENTSHADOWS; i++ ) - { - if ( aPermanentShadows[i].m_nType != SHADOWTYPE_NONE ) - { - uint32 timePassed = CTimer::GetTimeInMilliseconds() - aPermanentShadows[i].m_nTimeCreated; - - if ( timePassed >= aPermanentShadows[i].m_nLifeTime ) - aPermanentShadows[i].m_nType = SHADOWTYPE_NONE; - else - { - bool bOk; - if ( timePassed >= (aPermanentShadows[i].m_nLifeTime * 3 / 4) ) - { - // timePassed == 0 -> 4 - // timePassed == aPermanentShadows[i].m_nLifeTime -> 0 - float fMult = 1.0f - float(timePassed - (aPermanentShadows[i].m_nLifeTime * 3 / 4)) / (aPermanentShadows[i].m_nLifeTime / 4); - - bOk = StoreStaticShadow((uintptr)&aPermanentShadows[i], - aPermanentShadows[i].m_nType, - aPermanentShadows[i].m_pTexture, - &aPermanentShadows[i].m_vecPos, - aPermanentShadows[i].m_vecFront.x, - aPermanentShadows[i].m_vecFront.y, - aPermanentShadows[i].m_vecSide.x, - aPermanentShadows[i].m_vecSide.y, - (int32)(aPermanentShadows[i].m_nIntensity * fMult), - (int32)(aPermanentShadows[i].m_nRed * fMult), - (int32)(aPermanentShadows[i].m_nGreen * fMult), - (int32)(aPermanentShadows[i].m_nBlue * fMult), - aPermanentShadows[i].m_fZDistance, - 1.0f, 40.0f, false, 0.0f); - } - else - { - bOk = StoreStaticShadow((uintptr)&aPermanentShadows[i], - aPermanentShadows[i].m_nType, - aPermanentShadows[i].m_pTexture, - &aPermanentShadows[i].m_vecPos, - aPermanentShadows[i].m_vecFront.x, - aPermanentShadows[i].m_vecFront.y, - aPermanentShadows[i].m_vecSide.x, - aPermanentShadows[i].m_vecSide.y, - aPermanentShadows[i].m_nIntensity, - aPermanentShadows[i].m_nRed, - aPermanentShadows[i].m_nGreen, - aPermanentShadows[i].m_nBlue, - aPermanentShadows[i].m_fZDistance, - 1.0f, 40.0f, false, 0.0f); - } - - if ( !bOk ) - aPermanentShadows[i].m_nType = SHADOWTYPE_NONE; - } - } - } -} - -void -CStaticShadow::Free(void) -{ - if ( m_pPolyBunch != nil ) - { - CPolyBunch *pFree = CShadows::pEmptyBunchList; - CShadows::pEmptyBunchList = m_pPolyBunch; - - CPolyBunch *pUsed = m_pPolyBunch; - while (pUsed->m_pNext != nil) - pUsed = pUsed->m_pNext; - - pUsed->m_pNext = pFree; - } - - m_pPolyBunch = nil; - - m_nId = 0; -} - -void -CShadows::CalcPedShadowValues(CVector vecLightDir, - float *pfFrontX, float *pfFrontY, - float *pfSideX, float *pfSideY, - float *pfDisplacementX, float *pfDisplacementY) -{ - ASSERT(pfFrontX != nil); - ASSERT(pfFrontY != nil); - ASSERT(pfSideX != nil); - ASSERT(pfSideY != nil); - ASSERT(pfDisplacementX != nil); - ASSERT(pfDisplacementY != nil); - - *pfFrontX = -vecLightDir.x; - *pfFrontY = -vecLightDir.y; - - float fDist = Sqrt(*pfFrontY * *pfFrontY + *pfFrontX * *pfFrontX); - float fMult = (fDist + 1.0f) / fDist; - - *pfFrontX *= fMult; - *pfFrontY *= fMult; - - *pfSideX = -vecLightDir.y / fDist; - *pfSideY = vecLightDir.x / fDist; - - *pfDisplacementX = -vecLightDir.x; - *pfDisplacementY = -vecLightDir.y; - - *pfFrontX /= 2; - *pfFrontY /= 2; - - *pfSideX /= 2; - *pfSideY /= 2; - - *pfDisplacementX /= 2; - *pfDisplacementY /= 2; - -} - - -void -CShadows::RenderExtraPlayerShadows(void) -{ -#ifdef FIX_BUGS - if (CReplay::IsPlayingBack()) - return; -#endif - if ( CTimeCycle::GetLightShadowStrength() != 0 ) - { - CVehicle *pCar = FindPlayerVehicle(); - if ( pCar == nil ) - ; // R* cut it out for playerped - else - { - if ( pCar->GetModelIndex() != MI_RCBANDIT - && pCar->GetVehicleAppearance() != VEHICLE_APPEARANCE_BIKE - && !pCar->IsBike() && !pCar->IsPlane() && !pCar->IsBoat() ) - { - for ( int32 i = 0; i < CPointLights::NumLights; i++ ) - { - if ( CPointLights::aLights[i].type == CPointLights::LIGHT_POINT - && CPointLights::aLights[i].castExtraShadows - &&(0.0f != CPointLights::aLights[i].red - || 0.0f != CPointLights::aLights[i].green - || 0.0f != CPointLights::aLights[i].blue) ) - { - CVector vecLight = CPointLights::aLights[i].coors - FindPlayerCoors(); - float fLightDist = vecLight.Magnitude(); - float fRadius = CPointLights::aLights[i].radius; - - if ( fLightDist < fRadius ) - { - // fLightDist == 0 -> 2.0f - // fLightDist == fRadius -> 0.0f - float fMult = (1.0f - (2.0f * fLightDist - fRadius) / fRadius); - - int32 nColorStrength; - if ( fLightDist < fRadius*0.5f ) - nColorStrength = (5*CTimeCycle::GetLightShadowStrength()/8); - else - nColorStrength = int32((5*CTimeCycle::GetLightShadowStrength()/8) * fMult); - - float fInv = 1.0f / fLightDist; - vecLight.x *= fInv; - vecLight.y *= fInv; - vecLight.z *= fInv; - - CVector shadowPos = pCar->GetPosition(); - - shadowPos.x -= vecLight.x * 1.2f; - shadowPos.y -= vecLight.y * 1.2f; - - float fVehicleWidth = pCar->GetColModel()->boundingBox.GetSize().x; - float fVehicleHeight = pCar->GetColModel()->boundingBox.GetSize().y; - - shadowPos.x -= ((fVehicleHeight/2) - pCar->GetColModel()->boundingBox.max.y) - * pCar->GetForward().x; - - shadowPos.y -= ((fVehicleHeight/2) - pCar->GetColModel()->boundingBox.max.y) - * pCar->GetForward().y; - - if ( pCar->GetUp().z > 0.0f ) - { - StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowCarTex, &shadowPos, - pCar->GetForward().x * (fVehicleHeight/2), - pCar->GetForward().y * (fVehicleHeight/2), - pCar->GetRight().x * (fVehicleWidth/3), - pCar->GetRight().y * (fVehicleWidth/3), - nColorStrength, 0, 0, 0, - 4.5f, false, 1.0f, nil, false); - } - else - { - StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowCarTex, &shadowPos, - pCar->GetForward().x * (fVehicleHeight/2), - pCar->GetForward().y * (fVehicleHeight/2), - -pCar->GetRight().x * (fVehicleWidth/2), - -pCar->GetRight().y * (fVehicleWidth/2), - nColorStrength, 0, 0, 0, - 4.5f, false, 1.0f, nil, false); - } - } - } - } - } - } - } -} - -void -CShadows::TidyUpShadows(void) -{ - for ( int32 i = 0; i < MAX_PERMAMENTSHADOWS; i++ ) - aPermanentShadows[i].m_nType = SHADOWTYPE_NONE; -} - -void -CShadows::RenderIndicatorShadow(uint32 nID, uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, - float fFrontX, float fFrontY, float fSideX, float fSideY, - int16 nIntensity) -{ - ASSERT(pPosn != nil); - - C3dMarkers::PlaceMarkerSet(nID, MARKERTYPE_CYLINDER, *pPosn, Max(fFrontX, -fSideY), - SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, - SPHERE_MARKER_A, SPHERE_MARKER_PULSE_PERIOD, 0.2f, 0); -} |