diff options
Diffstat (limited to 'src/render/WaterLevel.cpp')
-rw-r--r-- | src/render/WaterLevel.cpp | 3377 |
1 files changed, 0 insertions, 3377 deletions
diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp deleted file mode 100644 index dee60d66..00000000 --- a/src/render/WaterLevel.cpp +++ /dev/null @@ -1,3377 +0,0 @@ -#include "common.h" -#include "main.h" -#include "FileMgr.h" -#include "FileLoader.h" -#include "TxdStore.h" -#include "Timer.h" -#include "Weather.h" -#include "Camera.h" -#include "Vehicle.h" -#include "PlayerPed.h" -#include "Boat.h" -#include "World.h" -#include "General.h" -#include "Timecycle.h" -#include "ZoneCull.h" -#include "Clock.h" -#include "Particle.h" -#include "ParticleMgr.h" -#include "RwHelper.h" -#include "Streaming.h" -#include "ColStore.h" -#include "CdStream.h" -#include "Pad.h" -#include "RenderBuffer.h" -#include <rwcore.h> -#include <rpworld.h> -#include <rpmatfx.h> -#include "Occlusion.h" -#include "Replay.h" -#include "WaterLevel.h" -#include "SurfaceTable.h" -#include "WaterCreatures.h" - -#define RwIm3DVertexSet_RGBA(vert, rgba) RwIm3DVertexSetRGBA(vert, rgba.red, rgba.green, rgba.blue, rgba.alpha) // (RwRGBAAssign(&(_dst)->color, &_src)) - -float TEXTURE_ADDU; -float TEXTURE_ADDV; - -float _TEXTURE_MASK_ADDU; -float _TEXTURE_MASK_ADDV; - -float _TEXTURE_WAKE_ADDU; -float _TEXTURE_WAKE_ADDV; - -int32 CWaterLevel::ms_nNoOfWaterLevels; -float CWaterLevel::ms_aWaterZs[48]; -CRect CWaterLevel::ms_aWaterRects[48]; -int8 CWaterLevel::aWaterBlockList[MAX_LARGE_SECTORS][MAX_LARGE_SECTORS]; -int8 CWaterLevel::aWaterFineBlockList[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS]; -bool CWaterLevel::WavesCalculatedThisFrame; - - -bool CWaterLevel::RequireWavySector; -bool CWaterLevel::MaskCalculatedThisFrame; -CVector CWaterLevel::PreCalculatedMaskPosn; -bool CWaterLevel::m_bRenderSeaBed; -int32 CWaterLevel::m_nRenderWaterLayers; - -RpAtomic *CWaterLevel::ms_pWavyAtomic; -RpAtomic *CWaterLevel::ms_pMaskAtomic; -//"Custom" Don't Render Water Toggle -bool gbDontRenderWater; - - -RwTexture *gpWaterTex; -RwTexture *gpWaterEnvTex; -RwTexture *gpWaterEnvBaseTex; -RwTexture *gpWaterWakeTex; - -RwRaster *gpWaterRaster; -RwRaster *gpWaterEnvRaster; -RwRaster *gpWaterEnvBaseRaster; -RwRaster *gpWaterWakeRaster; - -bool _bSeaLife; -float _fWaterZOffset = WATER_Z_OFFSET; - -#ifdef PC_WATER -float fEnvScale = 0.25f; -#else -float fEnvScale = 0.5f; -#endif -float fWave2InvLength = 0.03f; -float fWave2NormScale = 0.5f; -float fWave2Ampl = 0.1f; -uint8 nWaterAlpha = 192; -uint8 nWakeAlpha = 192; -float fUnder1 = 4.0; -float fUnder2 = 2.5; -float fUnder3 = 1.5; -int nMaskAlpha = 230; -float fAdd1 = 180.0f; -float fAdd2 = 80.0; -float fRedMult = 0.6f; -float fGreenMult = 1.0f; -float fBlueMult = 1.4f; -float fAlphaMult = 500.0f; -float fAlphaBase = 30.0f; -float fRandomMoveDiv = 8.0f; -float fRandomDamp = 0.99f; -float fNormMult = 2.0f; -float fNormMultB = 1.0f; -float fBumpScale = 1.5; -float fBumpTexRepeat = 2.0; -float fNormalDirectionScalar1 = 2.0f; -float fNormalDirectionScalar2 = 1.0f; -bool bTestDoNormals = true; -float fSeaBedZ = 25.0f; -float aAlphaFade[5] = { 0.4f, 1.0f, 0.2f, 1.0f, 0.4f}; //CWaterLevel::RenderWakeSegment -float fFlatWaterBlendRange = 0.05f; -float fStartBlendDistanceAdd = 64.0f; -float fMinWaterAlphaMult = -30.0f; - - -void -CWaterLevel::Initialise(Const char *pWaterDat) -{ - ms_nNoOfWaterLevels = 0; - -#ifdef MASTER - int32 hFile = -1; - - do - { - hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb"); - } - while ( hFile < 0 ); -#else - int32 hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb"); -#endif - - if (hFile > 0) - { - CFileMgr::Read(hFile, (char *)&ms_nNoOfWaterLevels, sizeof(ms_nNoOfWaterLevels)); - CFileMgr::Read(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs)); - CFileMgr::Read(hFile, (char *)ms_aWaterRects, sizeof(ms_aWaterRects)); - CFileMgr::Read(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList)); - CFileMgr::Read(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList)); - CFileMgr::CloseFile(hFile); - } -#ifndef MASTER - else - { - printf("Init waterlevels\n"); - - // collision is streamed in VC - CColStore::LoadAllCollision(); - - CFileMgr::SetDir(""); - hFile = CFileMgr::OpenFile(pWaterDat, "r"); - - char *line; - - while ((line = CFileLoader::LoadLine(hFile))) - { - if (*line && *line != ';' && !strstr(line, "* ;end of file")) - { - float z, l, b, r, t; - sscanf(line, "%f %f %f %f %f", &z, &l, &b, &r, &t); - AddWaterLevel(l, b, r, t, z); - } - } - - CFileMgr::CloseFile(hFile); - - for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) - { - for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) - { - aWaterFineBlockList[x][y] = NO_WATER; - } - } - - // rasterize water rects read from file - for (int32 i = 0; i < ms_nNoOfWaterLevels; i++) - { - int32 l = WATER_HUGE_X(ms_aWaterRects[i].left + WATER_X_OFFSET); - int32 r = WATER_HUGE_X(ms_aWaterRects[i].right + WATER_X_OFFSET) + 1.0f; - int32 t = WATER_HUGE_Y(ms_aWaterRects[i].top); - int32 b = WATER_HUGE_Y(ms_aWaterRects[i].bottom) + 1.0f; - - l = Clamp(l, 0, MAX_SMALL_SECTORS - 1); - r = Clamp(r, 0, MAX_SMALL_SECTORS - 1); - t = Clamp(t, 0, MAX_SMALL_SECTORS - 1); - b = Clamp(b, 0, MAX_SMALL_SECTORS - 1); - - for (int32 x = l; x <= r; x++) - { - for (int32 y = t; y <= b; y++) - { - aWaterFineBlockList[x][y] = i; - } - } - } - - // remove tiles that are obscured by land - for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) - { - float worldX = WATER_START_X + x * SMALL_SECTOR_SIZE - WATER_X_OFFSET; - - for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) - { - if (CWaterLevel::aWaterFineBlockList[x][y] >= 0) - { - float worldY = WATER_START_Y + y * SMALL_SECTOR_SIZE; - - int32 i; - for (i = 0; i <= 8; i++) - { - for (int32 j = 0; j <= 8; j++) - { - CVector worldPos = CVector(worldX + i * (SMALL_SECTOR_SIZE / 8), worldY + j * (SMALL_SECTOR_SIZE / 8), ms_aWaterZs[aWaterFineBlockList[x][y]]); - - if ((worldPos.x > WORLD_MIN_X && worldPos.x < WORLD_MAX_X) && (worldPos.y > WORLD_MIN_Y && worldPos.y < WORLD_MAX_Y) && - (!WaterLevelAccordingToRectangles(worldPos.x, worldPos.y) || TestVisibilityForFineWaterBlocks(worldPos))) - continue; - - // at least one point in the tile wasn't blocked, so don't remove water - i = 1000; - break; - } - } - - if (i < 1000) - aWaterFineBlockList[x][y] = NO_WATER; - } - } - } - - RemoveIsolatedWater(); - - // calculate coarse tiles from fine tiles - for (int32 x = 0; x < MAX_LARGE_SECTORS; x++) - { - for (int32 y = 0; y < MAX_LARGE_SECTORS; y++) - { - if (aWaterFineBlockList[x * 2][y * 2] >= 0) - { - aWaterBlockList[x][y] = aWaterFineBlockList[x * 2][y * 2]; - } - else if (aWaterFineBlockList[x * 2 + 1][y * 2] >= 0) - { - aWaterBlockList[x][y] = aWaterFineBlockList[x * 2 + 1][y * 2]; - } - else if (aWaterFineBlockList[x * 2][y * 2 + 1] >= 0) - { - aWaterBlockList[x][y] = aWaterFineBlockList[x * 2][y * 2 + 1]; - } - else if (aWaterFineBlockList[x * 2 + 1][y * 2 + 1] >= 0) - { - aWaterBlockList[x][y] = aWaterFineBlockList[x * 2 + 1][y * 2 + 1]; - } - else - { - aWaterBlockList[x][y] = NO_WATER; - } - } - } - - hFile = CFileMgr::OpenFileForWriting("data\\waterpro.dat"); - - if (hFile > 0) - { - CFileMgr::Write(hFile, (char *)&ms_nNoOfWaterLevels, sizeof(ms_nNoOfWaterLevels)); - CFileMgr::Write(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs)); - CFileMgr::Write(hFile, (char *)ms_aWaterRects, sizeof(ms_aWaterRects)); - CFileMgr::Write(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList)); - CFileMgr::Write(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList)); - - CFileMgr::CloseFile(hFile); - } - - // collision is streamed in VC - CColStore::RemoveAllCollision(); - } -#endif - - CTxdStore::PushCurrentTxd(); - - int32 slot = CTxdStore::FindTxdSlot("particle"); - CTxdStore::SetCurrentTxd(slot); - - if ( gpWaterTex == nil ) - gpWaterTex = RwTextureRead("waterclear256", nil); - gpWaterRaster = RwTextureGetRaster(gpWaterTex); - - if ( gpWaterEnvTex == nil ) - gpWaterEnvTex = RwTextureRead("waterreflection2", nil); - gpWaterEnvRaster = RwTextureGetRaster(gpWaterEnvTex); - -#ifdef PC_WATER - if ( gpWaterEnvBaseTex == nil ) - gpWaterEnvBaseTex = RwTextureRead("sandywater", nil); - gpWaterEnvBaseRaster = RwTextureGetRaster(gpWaterEnvBaseTex); -#endif - - if ( gpWaterWakeTex == nil ) - gpWaterWakeTex = RwTextureRead("waterwake", nil); - gpWaterWakeRaster = RwTextureGetRaster(gpWaterWakeTex); - - CTxdStore::PopCurrentTxd(); - - CreateWavyAtomic(); - - printf("Done Initing waterlevels\n"); -} - -void -CWaterLevel::Shutdown() -{ - DestroyWavyAtomic(); - -#define _DELETE_TEXTURE(t) if ( t ) \ - { \ - RwTextureDestroy(t); \ - t = nil; \ - } - - _DELETE_TEXTURE(gpWaterTex); - _DELETE_TEXTURE(gpWaterEnvTex); - _DELETE_TEXTURE(gpWaterWakeTex); - _DELETE_TEXTURE(gpWaterEnvBaseTex); - -#undef _DELETE_TEXTURE -} - -void -CWaterLevel::CreateWavyAtomic() -{ - RpGeometry *wavyGeometry; - RpGeometry *maskGeometry; - RpMaterial *wavyMaterial; - RpMaterial *maskMaterial; - - RpTriangle *wavytlist; - RpTriangle *masktlist; - - RpMorphTarget *wavyMorphTarget; - RpMorphTarget *maskMorphTarget; - - RwSphere boundingSphere; - - RwV3d *wavyVert; - RwV3d *wavyNormal; - - RwV3d *maskVert; - RwV3d *maskNormal; - - RwFrame *wavyFrame; - RwFrame *maskFrame; - - { - wavyGeometry = RpGeometryCreate(17*17, 512, rpGEOMETRYTRISTRIP - |rpGEOMETRYTEXTURED - |rpGEOMETRYPRELIT - |rpGEOMETRYNORMALS - |rpGEOMETRYMODULATEMATERIALCOLOR); -#ifdef PC_WATER - RpGeometryAddMorphTarget(wavyGeometry); -#endif - } - - { - maskGeometry = RpGeometryCreate(33*33, 2048, rpGEOMETRYTRISTRIP - |rpGEOMETRYTEXTURED - |rpGEOMETRYPRELIT - |rpGEOMETRYNORMALS - |rpGEOMETRYMODULATEMATERIALCOLOR); -#ifdef PC_WATER - RpGeometryAddMorphTarget(maskGeometry); -#endif - } - - { - wavyMaterial = RpMaterialCreate(); - RpMaterialSetTexture(wavyMaterial, gpWaterTex); - RwRGBA watercolor = { 255, 255, 255, 192 }; - RpMaterialSetColor(wavyMaterial, &watercolor); - } - - { - maskMaterial = RpMaterialCreate(); -#ifdef PC_WATER - RpMaterialSetTexture(maskMaterial, gpWaterEnvBaseTex); -#else - RpMaterialSetTexture(maskMaterial, gpWaterTex); -#endif - RwRGBA watercolor = { 255, 255, 255, 192 }; - RpMaterialSetColor(maskMaterial, &watercolor); - } - - { - wavytlist = RpGeometryGetTriangles(wavyGeometry); - - for ( int32 i = 0; i < 16; i++ ) - { - for ( int32 j = 0; j < 16; j++ ) - { - const RwUInt16 base = (RwUInt16)((16 + 1)*i+j); - - RpGeometryTriangleSetVertexIndices(wavyGeometry, - wavytlist, (RwInt16)base, (RwInt16)(base+1), (RwInt16)(base+16+2)); - - RpGeometryTriangleSetVertexIndices(wavyGeometry, - (wavytlist+1), (RwInt16)base, (RwInt16)(base+16+2), (RwInt16)(base+16+1)); - - RpGeometryTriangleSetMaterial(wavyGeometry, wavytlist, wavyMaterial); - - RpGeometryTriangleSetMaterial(wavyGeometry, (wavytlist+1), wavyMaterial); - - wavytlist+=2; - } - } - } - - { - masktlist = RpGeometryGetTriangles(maskGeometry); - - for ( int32 i = 0; i < 32; i++ ) - { - for ( int32 j = 0; j < 32; j++ ) - { - const RwUInt16 base = (RwUInt16)((32 + 1)*i+j); - - RpGeometryTriangleSetVertexIndices(maskGeometry, - masktlist, (RwInt16)base, (RwInt16)(base+1), (RwInt16)(base+32+2)); - - RpGeometryTriangleSetVertexIndices(maskGeometry, - (masktlist+1), (RwInt16)base, (RwInt16)(base+32+2), (RwInt16)(base+32+1)); - - RpGeometryTriangleSetMaterial(maskGeometry, masktlist, maskMaterial); - - RpGeometryTriangleSetMaterial(maskGeometry, (masktlist+1), maskMaterial); - - masktlist+=2; - } - } - } - - { - wavyMorphTarget = RpGeometryGetMorphTarget(wavyGeometry, 0); - wavyVert = RpMorphTargetGetVertices(wavyMorphTarget); - wavyNormal = RpMorphTargetGetVertexNormals(wavyMorphTarget); - - for ( int32 i = 0; i < 17; i++ ) - { - for ( int32 j = 0; j < 17; j++ ) - { - (*wavyVert).x = (float)i * 2.0f; - (*wavyVert).y = (float)j * 2.0f; - (*wavyVert).z = 0.0f; - - (*wavyNormal).x = 0.0f; - (*wavyNormal).y = 0.0f; - (*wavyNormal).z = 1.0f; - - wavyVert++; - wavyNormal++; - } - } - - RpMorphTargetCalcBoundingSphere(wavyMorphTarget, &boundingSphere); - RpMorphTargetSetBoundingSphere(wavyMorphTarget, &boundingSphere); - RpGeometryUnlock(wavyGeometry); - } - - { - maskMorphTarget = RpGeometryGetMorphTarget(maskGeometry, 0); - maskVert = RpMorphTargetGetVertices(maskMorphTarget); - maskNormal = RpMorphTargetGetVertexNormals(maskMorphTarget); - - for ( int32 i = 0; i < 33; i++ ) - { - for ( int32 j = 0; j < 33; j++ ) - { - (*maskVert).x = (float)i * 2.0f; - (*maskVert).y = (float)j * 2.0f; - (*maskVert).z = 0.0f; - - (*maskNormal).x = 0.0f; - (*maskNormal).y = 0.0f; - (*maskNormal).z = 1.0f; - - maskVert++; - maskNormal++; - } - } - - RpMorphTargetCalcBoundingSphere(maskMorphTarget, &boundingSphere); - RpMorphTargetSetBoundingSphere(maskMorphTarget, &boundingSphere); - RpGeometryUnlock(maskGeometry); - } - - { - wavyFrame = RwFrameCreate(); - ms_pWavyAtomic = RpAtomicCreate(); - RpAtomicSetGeometry(ms_pWavyAtomic, wavyGeometry, 0); - RpAtomicSetFrame(ms_pWavyAtomic, wavyFrame); - RpMaterialDestroy(wavyMaterial); - RpGeometryDestroy(wavyGeometry); - } - - { - maskFrame = RwFrameCreate(); - ms_pMaskAtomic = RpAtomicCreate(); - RpAtomicSetGeometry(ms_pMaskAtomic, maskGeometry, 0); - RpAtomicSetFrame(ms_pMaskAtomic, maskFrame); - RpMaterialDestroy(maskMaterial); - RpGeometryDestroy(maskGeometry); - } - - static RwFrame *wakeEnvFrame; - - if ( wakeEnvFrame == nil ) - { - wakeEnvFrame = RwFrameCreate(); - RwMatrixSetIdentity(RwFrameGetMatrix(wakeEnvFrame)); - RwFrameUpdateObjects(wakeEnvFrame); - } - - RpMatFXMaterialSetEffects(maskMaterial, rpMATFXEFFECTENVMAP); - RpMatFXMaterialSetupEnvMap(maskMaterial, gpWaterEnvTex, wakeEnvFrame, TRUE, fEnvScale); - RpMatFXAtomicEnableEffects(ms_pMaskAtomic); -} - -void -CWaterLevel::DestroyWavyAtomic() -{ -#define _DELETE_ATOMIC(a) \ - { \ - RwFrame *frame; \ - frame = RpAtomicGetFrame(a); \ - RpAtomicDestroy(a); \ - RwFrameDestroy(frame); \ - } - - _DELETE_ATOMIC(ms_pWavyAtomic); - _DELETE_ATOMIC(ms_pMaskAtomic); - -#undef _DELETE_ATOMIC -} - -#ifndef MASTER -void -CWaterLevel::AddWaterLevel(float fXLeft, float fYBottom, float fXRight, float fYTop, float fLevel) -{ - ms_aWaterRects[ms_nNoOfWaterLevels] = CRect(fXLeft, fYBottom, fXRight, fYTop); - ms_aWaterZs[ms_nNoOfWaterLevels] = fLevel; - ms_nNoOfWaterLevels++; -} - -bool -CWaterLevel::WaterLevelAccordingToRectangles(float fX, float fY, float *pfOutLevel) -{ - if (ms_nNoOfWaterLevels <= 0) return false; - - for (int32 i = 0; i < ms_nNoOfWaterLevels; i++) - { - if (fX >= ms_aWaterRects[i].left && fX <= ms_aWaterRects[i].right - && fY >= ms_aWaterRects[i].top && fY <= ms_aWaterRects[i].bottom) - { - if (pfOutLevel) *pfOutLevel = ms_aWaterZs[i]; - - return true; - } - } - - return false; -} - -bool -CWaterLevel::TestVisibilityForFineWaterBlocks(const CVector &worldPos) -{ - static CVector2D tab[] = - { - { 50.0f, 50.0f }, - { -50.0f, 50.0f }, - { -50.0f, -50.0f }, - { 50.0f, -50.0f }, - { 50.0f, 0.0f }, - { -50.0f, 0.0f }, - { 0.0f, -50.0f }, - { 0.0f, 50.0f }, - }; - - CEntity *entity; - CColPoint col; - CVector lineStart, lineEnd; - - lineStart = worldPos; - - if (!CWorld::ProcessVerticalLine(lineStart, lineStart.z + 100.0f, col, entity, true, false, false, false, true, false, nil)) - { - lineStart.x += 0.4f; - lineStart.y += 0.4f; - - if (!CWorld::ProcessVerticalLine(lineStart, lineStart.z + 100.0f, col, entity, true, false, false, false, true, false, nil)) - { - return false; - } - } - - for (int32 i = 0; i < ARRAY_SIZE(tab); i++) - { - lineStart = worldPos; - lineEnd = worldPos; - - lineEnd.x += tab[i].x; - lineEnd.y += tab[i].y; - lineEnd.z += 100.0f; - - if ((lineEnd.x > WORLD_MIN_X && lineEnd.x < WORLD_MAX_X) && (lineEnd.y > WORLD_MIN_Y && lineEnd.y < WORLD_MAX_Y)) - { - if (!CWorld::ProcessLineOfSight(lineStart, lineEnd, col, entity, true, false, false, false, true, false)) - { - lineStart.x += 0.4f; - lineStart.y += 0.4f; - lineEnd.x += 0.4f; - lineEnd.y += 0.4f; - - if (!CWorld::ProcessLineOfSight(lineStart, lineEnd, col, entity, true, false, false, false, true, false)) - { - return false; - } - } - } - } - - return true; -} - -void -CWaterLevel::RemoveIsolatedWater() -{ - bool (*isConnected)[MAX_SMALL_SECTORS] = new bool[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS]; - - for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) - { - for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) - { - isConnected[x][y] = false; - } - } - - isConnected[0][0] = true; - bool keepGoing; - - do - { - keepGoing = false; - - for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) - { - for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) - { - if (aWaterFineBlockList[x][y] < 0 || isConnected[x][y]) - continue; - - if (x > 0 && isConnected[x - 1][y]) - { - isConnected[x][y] = true; - keepGoing = true; - } - - if (y > 0 && isConnected[x][y - 1]) - { - isConnected[x][y] = true; - keepGoing = true; - } - - if (x + 1 < MAX_SMALL_SECTORS && isConnected[x + 1][y]) - { - isConnected[x][y] = true; - keepGoing = true; - } - - if (y + 1 < MAX_SMALL_SECTORS && isConnected[x][y + 1]) - { - isConnected[x][y] = true; - keepGoing = true; - } - } - } - } - while (keepGoing); - - int32 numRemoved = 0; - - for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) - { - for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) - { - if (aWaterFineBlockList[x][y] >= 0 && !isConnected[x][y] && ms_aWaterZs[aWaterFineBlockList[x][y]] == 6.0f) - { - numRemoved++; - aWaterFineBlockList[x][y] = NO_WATER; - } - } - } - - printf("Removed %d isolated patches of water\n", numRemoved); - - delete[] isConnected; -} -#endif - -bool -CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool bDontCheckZ) -{ - int32 x = WATER_TO_SMALL_SECTOR_X(fX + WATER_X_OFFSET); - int32 y = WATER_TO_SMALL_SECTOR_Y(fY); - -#ifdef FIX_BUGS - if ( x < 0 || x >= MAX_SMALL_SECTORS ) return false; - if ( y < 0 || y >= MAX_SMALL_SECTORS ) return false; -#endif - - int8 nBlock = aWaterFineBlockList[x][y]; - - if ( nBlock == NO_WATER ) - return false; - - ASSERT( pfOutLevel != nil ); - *pfOutLevel = ms_aWaterZs[nBlock]; - - float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f); - - float fWave = Sin - ( - ( WATER_UNSIGN_Y(fY) - y*SMALL_SECTOR_SIZE - + WATER_UNSIGN_X(fX + WATER_X_OFFSET) - x*SMALL_SECTOR_SIZE ) - - * (TWOPI / SMALL_SECTOR_SIZE ) + fAngle - ); - - float fWindFactor = CWeather::WindClipped * 0.4f + 0.2f; - - *pfOutLevel += fWave * fWindFactor; - - if ( bDontCheckZ == false && (*pfOutLevel - fZ) > 3.0f ) - { - *pfOutLevel = 0.0f; - return false; - } - - return true; -} - -bool -CWaterLevel::GetWaterLevelNoWaves(float fX, float fY, float fZ, float *pfOutLevel) -{ - int32 x = WATER_TO_SMALL_SECTOR_X(fX + WATER_X_OFFSET); - int32 y = WATER_TO_SMALL_SECTOR_Y(fY); - -#ifdef FIX_BUGS - if ( x < 0 || x >= MAX_SMALL_SECTORS ) return false; - if ( y < 0 || y >= MAX_SMALL_SECTORS ) return false; -#endif - - int8 nBlock = aWaterFineBlockList[x][y]; - - if ( nBlock == NO_WATER ) - return false; - - ASSERT( pfOutLevel != nil ); - *pfOutLevel = ms_aWaterZs[nBlock]; - - return true; -} - -float -CWaterLevel::GetWaterWavesOnly(short x, short y) -{ - float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f); - - float fWindFactor = CWeather::WindClipped * 0.7f + 0.3f; - - float fWave = Sin( float(float(4 * y + 4 * x) * (TWOPI / SMALL_SECTOR_SIZE )) + fAngle ); - - return fWave * fWindFactor; -} - -CVector -CWaterLevel::GetWaterNormal(float fX, float fY) -{ - //TODO: BUG ? no x offset - - int32 x = WATER_TO_SMALL_SECTOR_X(fX); - int32 y = WATER_TO_SMALL_SECTOR_Y(fY); - - float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f); - float fWindFactor = CWeather::WindClipped * 0.4f + 0.2f; - - float _fWave = (WATER_UNSIGN_Y(fY) - y*SMALL_SECTOR_SIZE + WATER_UNSIGN_X(fX) - x*SMALL_SECTOR_SIZE) - * (TWOPI / SMALL_SECTOR_SIZE ) + fAngle; - - CVector vA(1.0f, 0.0f, fWindFactor * (TWOPI / SMALL_SECTOR_SIZE ) * Cos(_fWave)); - CVector vB(0.0f, 1.0f, fWindFactor * (TWOPI / SMALL_SECTOR_SIZE ) * Cos(_fWave)); - - CVector norm = CrossProduct(vA, vB); - - norm.Normalise(); - - return norm; -} - - -inline float -_GetWaterDrawDist() -{ - if ( TheCamera.GetPosition().z < 15.0f ) return 1200.0f; - if ( TheCamera.GetPosition().z > 60.0f ) return 2000.0f; - return ( TheCamera.GetPosition().z + -15.0f ) * 800.0f / 45.0f + 1200.0f; -} - -inline float -_GetWavyDrawDist() -{ - if ( FindPlayerVehicle() && FindPlayerVehicle()->IsBoat() ) - return 120.0f; - else - return 70.0f; -} - -inline void -_GetCamBounds(bool *bUseCamStartY, bool *bUseCamEndY, bool *bUseCamStartX, bool *bUseCamEndX) -{ - if ( TheCamera.GetForward().z > -0.8f ) - { - if ( Abs(TheCamera.GetForward().x) > Abs(TheCamera.GetForward().y) ) - { - if ( TheCamera.GetForward().x > 0.0f ) - *bUseCamStartX = true; - else - *bUseCamEndX = true; - } - else - { - if ( TheCamera.GetForward().y > 0.0f ) - *bUseCamStartY = true; - else - *bUseCamEndY = true; - } - } -} - - -inline bool -_IsColideWithBlock(int32 x, int32 y, int32 &block) -{ - block = CWaterLevel::aWaterFineBlockList[x + 0][y + 0]; - if (block >= 0) - return true; - - block = CWaterLevel::aWaterFineBlockList[x + 0][y + 1]; - if (block >= 0) - { - block = CWaterLevel::aWaterFineBlockList[x + 0][y + 2]; - if (block >= 0) - return true; - } - - block = CWaterLevel::aWaterFineBlockList[x + 1][y + 0]; - if (block >= 0) - return true; - - block = CWaterLevel::aWaterFineBlockList[x + 1][y + 1]; - if (block >= 0) - { - block = CWaterLevel::aWaterFineBlockList[x + 1][y + 2]; - if (block >= 0) - return true; - } - - block = CWaterLevel::aWaterFineBlockList[x + 2][y + 0]; - if (block >= 0) - return true; - - block = CWaterLevel::aWaterFineBlockList[x + 2][y + 1]; - if (block >= 0) - { - block = CWaterLevel::aWaterFineBlockList[x + 2][y + 2]; - if (block >= 0) - return true; - } - - return false; -} - -inline float -SectorRadius(float fSize) -{ - return Sqrt(Pow(fSize, 2) + Pow(fSize, 2)); -} - -void -CWaterLevel::RenderWater() -{ -//"Custom" Don't Render Water Toggle -#ifndef MASTER - if (gbDontRenderWater) - return; -#endif - bool bUseCamEndX = false; - bool bUseCamStartY = false; - - bool bUseCamStartX = false; - bool bUseCamEndY = false; - - if ( !CGame::CanSeeWaterFromCurrArea() ) - return; - - _GetCamBounds(&bUseCamStartY, &bUseCamEndY, &bUseCamStartX, &bUseCamEndX); - - float fHugeSectorMaxRenderDist = _GetWaterDrawDist(); - float fHugeSectorMaxRenderDistSqr = SQR(fHugeSectorMaxRenderDist); - - float windAddUV = CWeather::WindClipped * 0.0005f + 0.0006f; - - float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f); - - if ( !CTimer::GetIsPaused() ) - { - TEXTURE_ADDU += windAddUV; - TEXTURE_ADDV += windAddUV; - - _TEXTURE_MASK_ADDU += Sin(fAngle) * 0.0005f + 1.1f * windAddUV; - _TEXTURE_MASK_ADDV -= Cos(fAngle * 1.3f) * 0.0005f + 1.2f * windAddUV; - - _TEXTURE_WAKE_ADDU -= Sin(fAngle) * 0.0003f + windAddUV; - _TEXTURE_WAKE_ADDV += Cos(fAngle * 0.7f) * 0.0003f + windAddUV; - } - - if ( _TEXTURE_MASK_ADDU >= 1.0f ) - _TEXTURE_MASK_ADDU = 0.0f; - if ( _TEXTURE_MASK_ADDV >= 1.0f ) - _TEXTURE_MASK_ADDV = 0.0f; - - if ( _TEXTURE_WAKE_ADDU >= 1.0f ) - _TEXTURE_WAKE_ADDU = 0.0f; - if ( _TEXTURE_WAKE_ADDV >= 1.0f ) - _TEXTURE_WAKE_ADDV = 0.0f; - - if ( TEXTURE_ADDU >= 1.0f ) - TEXTURE_ADDU = 0.0f; - if ( TEXTURE_ADDV >= 1.0f ) - TEXTURE_ADDV = 0.0f; - -#ifdef PC_WATER - _fWaterZOffset = CWeather::WindClipped * 0.5f + 0.25f; -#endif - - RwRGBA color = { 0, 0, 0, 255 }; - - color.red = CTimeCycle::GetWaterRed(); - color.green = CTimeCycle::GetWaterGreen(); - color.blue = CTimeCycle::GetWaterBlue(); - -#ifndef PC_WATER - RwRGBA colorUnderwater = { 0, 0, 0, 255 }; - colorUnderwater.red = (uint32)(0.8f * (float)colorUnderwater.red); - colorUnderwater.green = (uint32)(0.8f * (float)colorUnderwater.green); - colorUnderwater.blue = (uint32)(0.8f * (float)colorUnderwater.blue); -#endif - - TempBufferVerticesStored = 0; - TempBufferIndicesStored = 0; - -#ifndef PC_WATER - WavesCalculatedThisFrame = false; -#endif - - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpWaterRaster); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO); - - CVector2D camPos(TheCamera.GetPosition().x, TheCamera.GetPosition().y); - - int32 nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x - fHugeSectorMaxRenderDist + WATER_X_OFFSET); - int32 nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x + fHugeSectorMaxRenderDist + WATER_X_OFFSET) + 1; - int32 nStartY = WATER_TO_HUGE_SECTOR_Y(camPos.y - fHugeSectorMaxRenderDist); - int32 nEndY = WATER_TO_HUGE_SECTOR_Y(camPos.y + fHugeSectorMaxRenderDist) + 1; - - if ( bUseCamStartX ) - nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x + WATER_X_OFFSET); - if ( bUseCamEndX ) - nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x + WATER_X_OFFSET); - if ( bUseCamStartY ) - nStartY = WATER_TO_HUGE_SECTOR_Y(camPos.y); - if ( bUseCamEndY ) - nEndY = WATER_TO_HUGE_SECTOR_Y(camPos.y); - - nStartX = Clamp(nStartX, 0, MAX_HUGE_SECTORS - 1); - nEndX = Clamp(nEndX, 0, MAX_HUGE_SECTORS - 1); - nStartY = Clamp(nStartY, 0, MAX_HUGE_SECTORS - 1); - nEndY = Clamp(nEndY, 0, MAX_HUGE_SECTORS - 1); - - for ( int32 x = nStartX; x <= nEndX; x++ ) - { - for ( int32 y = nStartY; y <= nEndY; y++ ) - { - if ( aWaterBlockList[2*x+0][2*y+0] >= 0 - || aWaterBlockList[2*x+1][2*y+0] >= 0 - || aWaterBlockList[2*x+0][2*y+1] >= 0 - || aWaterBlockList[2*x+1][2*y+1] >= 0 ) - { - float fX = WATER_FROM_HUGE_SECTOR_X(x) - WATER_X_OFFSET; - float fY = WATER_FROM_HUGE_SECTOR_Y(y); - - CVector2D vecHugeSectorCentre(fX + HUGE_SECTOR_SIZE/2,fY + HUGE_SECTOR_SIZE/2); - - float fHugeSectorDistToCamSqr = (camPos - vecHugeSectorCentre).MagnitudeSqr(); - - if ( fHugeSectorMaxRenderDistSqr > fHugeSectorDistToCamSqr ) - { - if ( TheCamera.IsSphereVisible(CVector(vecHugeSectorCentre.x, vecHugeSectorCentre.y, 0.0f), SectorRadius(HUGE_SECTOR_SIZE)) ) - { -#ifndef PC_WATER - WavesCalculatedThisFrame = true; -#endif - - - float fZ; - - if ( aWaterBlockList[2*x+0][2*y+0] >= 0 ) - fZ = ms_aWaterZs[ aWaterBlockList[2*x+0][2*y+0] ]; - - if ( aWaterBlockList[2*x+1][2*y+0] >= 0 ) - fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+0] ]; - - if ( aWaterBlockList[2*x+0][2*y+1] >= 0 ) - fZ = ms_aWaterZs[ aWaterBlockList[2*x+0][2*y+1] ]; - - if ( aWaterBlockList[2*x+1][2*y+1] >= 0 ) - fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+1] ]; - - if ( fHugeSectorDistToCamSqr >= SQR(500.0f) ) - { - RenderOneFlatHugeWaterPoly(fX, fY, fZ, color); - } - else - { -#ifndef PC_WATER - if (m_bRenderSeaBed) - RenderOneSlopedUnderWaterPoly(fX, fY, fZ, colorUnderwater); -#endif - // see RenderTransparentWater() - ; - } - } - } - } - } - } - - /* - ----------- ---------------------- ---------------------- - | [N] | | [ EndY ] | | [ top ] | - | | | | | | - |[W] [0] [E]| |[StartX] [] [ EndX ]| |[ left ] [] [ right]| - | | | | | | - | [S] | | [StartY] | | [bottom] | - ----------- ---------------------- ---------------------- - - - [S] [StartY] [bottom] - [N] [EndY] [top] - [W] [StartX] [left] - [E] [EndX] [right] - - [S] -> [N] && [W] -> [E] - bottom -> top && left -> right - */ - - for ( int32 x = 0; x < 26; x++ ) - { - for ( int32 y = 0; y < 5; y++ ) - { - float fX = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f - WATER_X_OFFSET; - float fY = WATER_SIGN_Y(float(y) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f; - - if ( !bUseCamStartY ) - { - CVector2D vecExtraHugeSectorCentre(fX + EXTRAHUGE_SECTOR_SIZE/2, fY + EXTRAHUGE_SECTOR_SIZE/2); - - float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude(); - - if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr ) - { - if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) ) - { - RenderOneFlatExtraHugeWaterPoly( - vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2, - vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2, - 0.0f, - color); - } - } - } - - if ( !bUseCamEndY ) - { - CVector2D vecExtraHugeSectorCentre(fX + EXTRAHUGE_SECTOR_SIZE/2, -(fY + EXTRAHUGE_SECTOR_SIZE/2)); - - float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude(); - - if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr ) - { - if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) ) - { - RenderOneFlatExtraHugeWaterPoly( - vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2, - vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2, - 0.0f, - color); - } - } - } - } - } - - for ( int32 y = 5; y < 21; y++ ) - { - for ( int32 x = 0; x < 5; x++ ) - { - float fX = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f - WATER_X_OFFSET; - float fX2 = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f + WATER_X_OFFSET; - float fY = WATER_SIGN_Y(float(y) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f; - - if ( !bUseCamStartX ) - { - CVector2D vecExtraHugeSectorCentre(fX + EXTRAHUGE_SECTOR_SIZE/2, fY + EXTRAHUGE_SECTOR_SIZE/2); - - float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude(); - - if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr ) - { - if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) ) - { - RenderOneFlatExtraHugeWaterPoly( - vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2, - vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2, - 0.0f, - color); - } - } - } - - if ( !bUseCamEndX ) - { - CVector2D vecExtraHugeSectorCentre(-(fX2 + EXTRAHUGE_SECTOR_SIZE/2), fY + EXTRAHUGE_SECTOR_SIZE/2); - - float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude(); - - if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr ) - { - if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.x, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) ) - { - RenderOneFlatExtraHugeWaterPoly( - vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2, - vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2, - 0.0f, - color); - } - } - } - } - } - - RenderAndEmptyRenderBuffer(); - - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA); - - if ( WavesCalculatedThisFrame ) - { - RenderSeaBirds(); - RenderShipsOnHorizon(); - CParticle::HandleShipsAtHorizonStuff(); - HandleBeachToysStuff(); - } - - if ( _bSeaLife ) - HandleSeaLifeForms(); - - DefinedState(); -} - - -void -CWaterLevel::RenderTransparentWater(void) -{ - bool bUseCamEndX = false; - bool bUseCamStartY = false; - - bool bUseCamStartX = false; - bool bUseCamEndY = false; - - _bSeaLife = false; - - if ( !CGame::CanSeeWaterFromCurrArea() ) - return; - - PUSH_RENDERGROUP("CWaterLevel::RenderTransparentWater"); - - float fWaterDrawDist = _GetWavyDrawDist(); - float fWaterDrawDistLarge = fWaterDrawDist + 90.0f; - float fWavySectorMaxRenderDistSqr = SQR(fWaterDrawDist); - - _GetCamBounds(&bUseCamStartY, &bUseCamEndY, &bUseCamStartX, &bUseCamEndX); - - float fHugeSectorMaxRenderDist = _GetWaterDrawDist(); - float fHugeSectorMaxRenderDistSqr = SQR(fHugeSectorMaxRenderDist); - - RenderBoatWakes(); - - RwRGBA color; - - color.red = CTimeCycle::GetWaterRed(); - color.green = CTimeCycle::GetWaterGreen(); - color.blue = CTimeCycle::GetWaterBlue(); - color.alpha = 255; - - RwRGBA colorTrans; - - colorTrans.red = CTimeCycle::GetWaterRed(); - colorTrans.green = CTimeCycle::GetWaterGreen(); - colorTrans.blue = CTimeCycle::GetWaterBlue(); - colorTrans.alpha = CTimeCycle::GetWaterAlpha(); - - TempBufferVerticesStored = 0; - TempBufferIndicesStored = 0; - -#ifndef PC_WATER - WavesCalculatedThisFrame = false; -#endif - - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpWaterRaster); -#ifndef PC_WATER - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA); -#endif - - CVector2D camPos(TheCamera.GetPosition().x, TheCamera.GetPosition().y); - - int32 nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x - fHugeSectorMaxRenderDist + WATER_X_OFFSET); - int32 nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x + fHugeSectorMaxRenderDist + WATER_X_OFFSET) + 1; - int32 nStartY = WATER_TO_HUGE_SECTOR_Y(camPos.y - fHugeSectorMaxRenderDist ); - int32 nEndY = WATER_TO_HUGE_SECTOR_Y(camPos.y + fHugeSectorMaxRenderDist ) + 1; - - if ( bUseCamStartX ) - nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x + WATER_X_OFFSET); - if ( bUseCamEndX ) - nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x + WATER_X_OFFSET); - if ( bUseCamStartY ) - nStartY = WATER_TO_HUGE_SECTOR_Y(camPos.y ); - if ( bUseCamEndY ) - nEndY = WATER_TO_HUGE_SECTOR_Y(camPos.y ); - - nStartX = Clamp(nStartX, 0, MAX_HUGE_SECTORS - 1); - nEndX = Clamp(nEndX, 0, MAX_HUGE_SECTORS - 1); - nStartY = Clamp(nStartY, 0, MAX_HUGE_SECTORS - 1); - nEndY = Clamp(nEndY, 0, MAX_HUGE_SECTORS - 1); - - - for ( int32 x = nStartX; x <= nEndX; x++ ) - { - for ( int32 y = nStartY; y <= nEndY; y++ ) - { - if ( aWaterBlockList[2*x+0][2*y+0] >= 0 - || aWaterBlockList[2*x+1][2*y+0] >= 0 - || aWaterBlockList[2*x+0][2*y+1] >= 0 - || aWaterBlockList[2*x+1][2*y+1] >= 0 ) - { - float fX = WATER_FROM_HUGE_SECTOR_X(x) - WATER_X_OFFSET; - float fY = WATER_FROM_HUGE_SECTOR_Y(y); - - CVector2D vecHugeSectorCentre - ( - fX + HUGE_SECTOR_SIZE/2, - fY + HUGE_SECTOR_SIZE/2 - ); - - float fHugeSectorDistToCamSqr = (camPos - vecHugeSectorCentre).MagnitudeSqr(); - - if ( fHugeSectorMaxRenderDistSqr > fHugeSectorDistToCamSqr ) - { - if ( TheCamera.IsSphereVisible(CVector(vecHugeSectorCentre.x, vecHugeSectorCentre.y, 0.0f), SectorRadius(HUGE_SECTOR_SIZE)) ) - { - if ( fHugeSectorDistToCamSqr >= SQR(500.0f) ) - { - // see RenderWater() - ; - } - else - { - for ( int32 x2 = 2*x; x2 <= 2*x+1; x2++ ) - { - for ( int32 y2 = 2*y; y2 <= 2*y+1; y2++ ) - { - if ( aWaterBlockList[x2][y2] >= 0 ) - { - float fLargeX = WATER_FROM_LARGE_SECTOR_X(x2) - WATER_X_OFFSET; - float fLargeY = WATER_FROM_LARGE_SECTOR_Y(y2); - - CVector2D vecLargeSectorCentre(fLargeX + LARGE_SECTOR_SIZE/2, fLargeY + LARGE_SECTOR_SIZE/2); - - float fLargeSectorDistToCamSqr = (camPos - vecLargeSectorCentre).MagnitudeSqr(); - - if ( fLargeSectorDistToCamSqr < fHugeSectorMaxRenderDistSqr ) - { - if ( TheCamera.IsSphereVisible(CVector(vecLargeSectorCentre.x, vecLargeSectorCentre.y, 0.0f), SectorRadius(LARGE_SECTOR_SIZE)) ) - { - // Render four small(32x32) sectors, or one large(64x64). - - // - // [N] - // --------- - // |0x1|1x1| - // [W] --------- [E] - // |0x0|1x0| - // --------- - // [S] - // - - float fLargeSectorDrawDistSqr = SQR((fWaterDrawDistLarge + 16.0f)); - - if ( fLargeSectorDistToCamSqr < fLargeSectorDrawDistSqr ) - { - _bSeaLife = true; - - float fZ; - - // WS - if ( aWaterFineBlockList[2*x2+0][2*y2+0] >= 0 ) - { - float fSmallX = fLargeX; - float fSmallY = fLargeY; - - CVector2D vecSmallSectorCentre(fSmallX + SMALL_SECTOR_SIZE/2, fSmallY + SMALL_SECTOR_SIZE/2); - - float fSmallSectorDistToCamSqr = (camPos - vecSmallSectorCentre).MagnitudeSqr(); - fZ = ms_aWaterZs[ aWaterFineBlockList[2*x2+0][2*y2+0] ]; - - if ( fSmallSectorDistToCamSqr < fWavySectorMaxRenderDistSqr ) - RenderOneWavySector(fSmallX, fSmallY, fZ, colorTrans); - else - RenderOneFlatSmallWaterPolyBlended(fSmallX, fSmallY, fZ, camPos.x, camPos.y, color, colorTrans, fWaterDrawDist); - } - - // SE - if ( aWaterFineBlockList[2*x2+1][2*y2+0] >= 0 ) - { - float fSmallX = fLargeX + (LARGE_SECTOR_SIZE/2); - float fSmallY = fLargeY; - - CVector2D vecSmallSectorCentre(fSmallX + SMALL_SECTOR_SIZE/2, fSmallY + SMALL_SECTOR_SIZE/2); - - float fSmallSectorDistToCamSqr = (camPos - vecSmallSectorCentre).MagnitudeSqr(); - fZ = ms_aWaterZs[ aWaterFineBlockList[2*x2+1][2*y2+0] ]; - - if ( fSmallSectorDistToCamSqr < fWavySectorMaxRenderDistSqr ) - RenderOneWavySector(fSmallX, fSmallY, fZ, colorTrans); - else - RenderOneFlatSmallWaterPolyBlended(fSmallX, fSmallY, fZ, camPos.x, camPos.y, color, colorTrans, fWaterDrawDist); - } - - // WN - if ( aWaterFineBlockList[2*x2+0][2*y2+1] >= 0 ) - { - float fSmallX = fLargeX; - float fSmallY = fLargeY + (LARGE_SECTOR_SIZE/2); - - CVector2D vecSmallSectorCentre(fSmallX + SMALL_SECTOR_SIZE/2,fSmallY + SMALL_SECTOR_SIZE/2); - - float fSmallSectorDistToCamSqr = (camPos - vecSmallSectorCentre).MagnitudeSqr(); - fZ = ms_aWaterZs[ aWaterFineBlockList[2*x2+0][2*y2+1] ]; - - if ( fSmallSectorDistToCamSqr < fWavySectorMaxRenderDistSqr ) - RenderOneWavySector(fSmallX, fSmallY, fZ, colorTrans); - else - RenderOneFlatSmallWaterPolyBlended(fSmallX, fSmallY, fZ, camPos.x, camPos.y, color, colorTrans, fWaterDrawDist); - } - - //NE - if ( aWaterFineBlockList[2*x2+1][2*y2+1] >= 0 ) - { - float fSmallX = fLargeX + (LARGE_SECTOR_SIZE/2); - float fSmallY = fLargeY + (LARGE_SECTOR_SIZE/2); - - CVector2D vecSmallSectorCentre(fSmallX + SMALL_SECTOR_SIZE/2, fSmallY + SMALL_SECTOR_SIZE/2); - - float fSmallSectorDistToCamSqr = (camPos - vecSmallSectorCentre).MagnitudeSqr(); - fZ = ms_aWaterZs[ aWaterFineBlockList[2*x2+1][2*y2+1] ]; - - if ( fSmallSectorDistToCamSqr < fWavySectorMaxRenderDistSqr ) - RenderOneWavySector(fSmallX, fSmallY, fZ, colorTrans); - else - RenderOneFlatSmallWaterPolyBlended(fSmallX, fSmallY, fZ, camPos.x, camPos.y, color, colorTrans, fWaterDrawDist); - } - } - else - { - float fZ; - - fZ = ms_aWaterZs[ aWaterBlockList[x2][y2] ]; - - RenderOneFlatLargeWaterPoly(fLargeX, fLargeY, fZ, color); - } - } - } - } - } - } - } - } - } - } - } - } - - RenderAndEmptyRenderBuffer(); - -#ifdef PC_WATER - if ( MaskCalculatedThisFrame - && (m_nRenderWaterLayers == 0 || m_nRenderWaterLayers == 2 || m_nRenderWaterLayers == 3) ) - { - RwV3d pos = { 0.0f, 0.0f, 0.0f }; - - pos.x = PreCalculatedMaskPosn.x; - pos.y = PreCalculatedMaskPosn.y; - pos.z = PreCalculatedMaskPosn.z; - - RpMatFXMaterialSetEnvMapFrame(RpGeometryGetMaterial(RpAtomicGetGeometry(ms_pMaskAtomic), 0), - RwCameraGetFrame(RwCameraGetCurrentCamera())); - - RwFrameTranslate(RpAtomicGetFrame(ms_pMaskAtomic), &pos, rwCOMBINEREPLACE); - - RpAtomicRender(ms_pMaskAtomic); - } -#else - if (!CCullZones::WaterFudge()) - { - int32 signX = 0; - int32 signY = 0; - - float fCamX = camPos.x - SMALL_SECTOR_SIZE; - float fCamY = camPos.y - SMALL_SECTOR_SIZE; - - if (TheCamera.GetForward().x > 0.3f) - signX = 1; - else if (TheCamera.GetForward().x < -0.3f) - signX = -1; - - fCamX += 0.3f * (float)signX * float(SMALL_SECTOR_SIZE * 2.0f); // 19.2f - - if (TheCamera.GetForward().y > 0.3f) - signY = 1; - else if (TheCamera.GetForward().y < -0.3f) - signY = -1; - - fCamY += 0.3f * (float)signY * float(SMALL_SECTOR_SIZE * 2.0f); // 19.2f - - int32 nBlock; - - int32 BlockX = WATER_TO_SMALL_SECTOR_X(fCamX + WATER_X_OFFSET) + 1; - int32 BlockY = WATER_TO_SMALL_SECTOR_Y(fCamY) + 1; - - if (_IsColideWithBlock(BlockX, BlockY, nBlock)) - { - if (m_nRenderWaterLayers != 1 && m_nRenderWaterLayers != 6) - { - float fMaskX = Floor(fCamX / 2.0f) * 2.0f; - float fMaskY = Floor(fCamY / 2.0f) * 2.0f; - float fWaterZ = CWaterLevel::ms_aWaterZs[nBlock]; - float fSectorX = WATER_FROM_SMALL_SECTOR_X(BlockX) - WATER_X_OFFSET; - float fSectorY = WATER_FROM_SMALL_SECTOR_Y(BlockY); - - RenderWavyMask(fMaskX, fMaskY, fWaterZ, - fSectorX, fSectorY, - signX, signY, colorTrans); - } - } - } - - DefinedState(); -#endif - - POP_RENDERGROUP(); -} - -void CWaterLevel::RenderOneFlatSmallWaterPoly(float fX, float fY, float fZ, RwRGBA const &color) -{ - if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 ) - RenderAndEmptyRenderBuffer(); - - int32 vidx = TempBufferVerticesStored; - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 0], color); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + SMALL_SECTOR_SIZE, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 1.0f); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 1], color); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + SMALL_SECTOR_SIZE, fY + SMALL_SECTOR_SIZE, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 1.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 1.0f); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 2], color); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + SMALL_SECTOR_SIZE, fY, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 1.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 3], color); - - - int32 iidx = TempBufferIndicesStored; - - TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2; - TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1; - TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3; - TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2; - - TempBufferVerticesStored += 4; - TempBufferIndicesStored += 6; -} - -void -CWaterLevel::RenderOneFlatLargeWaterPoly(float fX, float fY, float fZ, RwRGBA const &color) -{ - if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 ) - RenderAndEmptyRenderBuffer(); - - int32 vidx = TempBufferVerticesStored; - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 0], color); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + LARGE_SECTOR_SIZE, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 2.0f); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 1], color); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + LARGE_SECTOR_SIZE, fY + LARGE_SECTOR_SIZE, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 2.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 2.0f); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 2], color); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + LARGE_SECTOR_SIZE, fY, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 2.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 3], color); - - - int32 iidx = TempBufferIndicesStored; - - TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2; - TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1; - TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3; - TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2; - - TempBufferVerticesStored += 4; - TempBufferIndicesStored += 6; -} - -void -CWaterLevel::RenderOneFlatHugeWaterPoly(float fX, float fY, float fZ, RwRGBA const &color) -{ - if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 ) - RenderAndEmptyRenderBuffer(); - - int32 vidx = TempBufferVerticesStored; - - RwRGBA c; - - c.red = color.red; - c.green = color.green; - c.blue = color.blue; - c.alpha = 255; - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 0], c); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + HUGE_SECTOR_SIZE, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 4.0f); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 1], c); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + HUGE_SECTOR_SIZE, fY + HUGE_SECTOR_SIZE, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 4.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 4.0f); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 2], c); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + HUGE_SECTOR_SIZE, fY, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 4.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 3], c); - - - int32 iidx = TempBufferIndicesStored; - - TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2; - TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1; - TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3; - TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2; - - TempBufferVerticesStored += 4; - TempBufferIndicesStored += 6; -} - -void -CWaterLevel::RenderOneFlatExtraHugeWaterPoly(float fX, float fY, float fZ, RwRGBA const &color) -{ - if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 ) - RenderAndEmptyRenderBuffer(); - - int32 vidx = TempBufferVerticesStored; - - RwRGBA c; - - c.red = color.red; - c.green = color.green; - c.blue = color.blue; - c.alpha = 255; - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 0], c); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + EXTRAHUGE_SECTOR_SIZE, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 8.0f); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 1], c); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + EXTRAHUGE_SECTOR_SIZE, fY + EXTRAHUGE_SECTOR_SIZE, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 8.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 8.0f); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 2], c); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + EXTRAHUGE_SECTOR_SIZE, fY, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 8.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV); - RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 3], c); - - - int32 iidx = TempBufferIndicesStored; - - TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2; - TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1; - TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3; - TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2; - - TempBufferVerticesStored += 4; - TempBufferIndicesStored += 6; -} - -void -CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &color, bool bDontRender) -{ - CVector vecSectorPos(fX + (SMALL_SECTOR_SIZE/2), fY + (SMALL_SECTOR_SIZE/2), fZ + 2.0f); - - if ( COcclusion::IsAABoxOccluded(vecSectorPos, SMALL_SECTOR_SIZE, SMALL_SECTOR_SIZE, 4.0f) ) - return; - -#ifdef PC_WATER - RequireWavySector = true; -#else - if (!WavesCalculatedThisFrame) - { - WavesCalculatedThisFrame = true; - - float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f); - - RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic); - RwTexCoords *wavyTexCoords = RpGeometryGetVertexTexCoords(wavyGeometry, rwTEXTURECOORDINATEINDEX0); - RpMorphTarget *wavyMorph = RpGeometryGetMorphTarget(wavyGeometry, 0); - RwRGBA *wavyPreLight = RpGeometryGetPreLightColors(wavyGeometry); - RwV3d *wavyMorphVerts = RpMorphTargetGetVertices(wavyMorph); - RwV3d *wavyMorphNormals = RpMorphTargetGetVertexNormals(wavyMorph); - - RpGeometryLock(wavyGeometry, rpGEOMETRYLOCKVERTICES | rpGEOMETRYLOCKNORMALS | rpGEOMETRYLOCKPRELIGHT | rpGEOMETRYLOCKTEXCOORDS); - - RwMatrix *camMat = RwFrameGetLTM(RwCameraGetFrame(RwCameraGetCurrentCamera())); //or curWorld - - float randomDampInv2 = (1.0f - fRandomDamp) * 2.0f; - - float move = 1.0f / 16.0f; - float randomMove = 1.0f / (16.0f * fRandomMoveDiv); - - float vertMul = 0.5f; - - float wind = CWeather::WindClipped * 0.4f + 0.2f; - float waveWind = CWeather::WindClipped * fWave2Ampl + 0.05f; - - float waveA = (TWOPI / 16.0f) - * ((fNormalDirectionScalar1 * Abs(camMat->at.x + camMat->at.y) + fNormMult) * (CWeather::WindClipped * 0.4f + 0.2f)); - - float waveB = TWOPI / (16.0f * fWave2NormScale) - * ((fNormalDirectionScalar2 * Abs(camMat->at.y - camMat->at.x) + fNormMultB) * (CWeather::WindClipped * 0.2f + 0.1f)); - - CVector vA(1.0f, 0.0f, 0.0f); - CVector vB(0.0f, 1.0f, 0.0f); - - for ( int32 i = 0; i < 17; i++ ) - { - for ( int32 j = 0; j < 17; j++ ) - { - wavyTexCoords->u = float(i) * move + TEXTURE_ADDV; - wavyTexCoords->v = float(j) * move + TEXTURE_ADDU; - - RwRGBAAssign(wavyPreLight, &color); - - if (i > 0 && i < 16 && j > 0 && j < 16) - { - wavyMorphVerts->x += CGeneral::GetRandomNumberInRange(-1.0f, 1.0f) * randomMove; - wavyMorphVerts->x *= fRandomDamp; - wavyMorphVerts->x += float(i) * randomDampInv2; - - wavyMorphVerts->y += CGeneral::GetRandomNumberInRange(-1.0f, 1.0f) * randomMove; - wavyMorphVerts->y *= fRandomDamp; - wavyMorphVerts->y += float(j) * randomDampInv2; - } - - float morphVertXHalf = (i == 16) ? 0.0f : vertMul * wavyMorphVerts->x; - float morphVertYHalf = (j == 16) ? 0.0f : vertMul * wavyMorphVerts->y; - - float waveMulA = (morphVertYHalf + morphVertXHalf) * (TWOPI / 16.0f) + fAngle; - float waveMulB = (morphVertYHalf - morphVertXHalf) * (TWOPI / (16.0f * fWave2InvLength)) + fAngle; - - wavyMorphVerts->z = wind * Sin(waveMulA) + waveWind * Sin(waveMulB); - - vA.z = (waveA * Cos(waveMulA)) - (waveB * Cos(waveMulB)); - vB.z = (waveA * Cos(waveMulA)) + (waveB * Cos(waveMulB)); - - CVector norm = CrossProduct(vA, vB); - norm.Normalise(); - - wavyMorphNormals->x = norm.x; - wavyMorphNormals->y = norm.y; - wavyMorphNormals->z = norm.z; - - ++wavyPreLight; - ++wavyTexCoords; - - ++wavyMorphVerts; - ++wavyMorphNormals; - } - } - - RpGeometryUnlock(wavyGeometry); - } - - float fCentreX = fX + (SMALL_SECTOR_SIZE / 2); - float fCentreY = fY + (SMALL_SECTOR_SIZE / 2); -#endif - -#ifdef PC_WATER - if ( WavesCalculatedThisFrame ) -#endif - { - if (bDontRender == false - && m_nRenderWaterLayers != 2 - && m_nRenderWaterLayers != 4 - && m_nRenderWaterLayers != 6 ) - { - RwV3d pos = { 0.0f, 0.0f, 0.0f }; - - pos.x = fX; - pos.y = fY; - pos.z = fZ; - - RwFrameTranslate(RpAtomicGetFrame(ms_pWavyAtomic), &pos, rwCOMBINEREPLACE); - - RpAtomicRender(ms_pWavyAtomic); - } - } -} - -int16 -_RoundValue(int32 v) -{ - int16 result = v; - - while ( result < 0 ) result += 16; - while ( result > 16 ) result -= 16; - - return result; -} - -void -CWaterLevel::RenderWavyMask(float fX, float fY, float fZ, - float fSectorX, float fSectorY, -#ifdef PC_WATER - float fCamPosX, float fCamPosY, - float fCamDirX, float fCamDirY, RwRGBA const&color) -#else - int32 nCamDirX, int32 nCamDirY, RwRGBA const&color) -#endif -{ -#ifndef PC_WATER - bool bRender = true; - if (m_nRenderWaterLayers != 0 && m_nRenderWaterLayers != 2 && m_nRenderWaterLayers != 3) - bRender = false; -#endif - CVector vecSectorPos(fX + (LARGE_SECTOR_SIZE/2), fY + (LARGE_SECTOR_SIZE/2), fZ + 2.0f); - - if ( COcclusion::IsAABoxOccluded(vecSectorPos, LARGE_SECTOR_SIZE, LARGE_SECTOR_SIZE, 4.0f) ) - return; - -#ifndef PC_WATER - float fUOffset = fX - (MAX_LARGE_SECTORS * (int32)Floor(fX / MAX_LARGE_SECTORS)); - float fVOffset = fY - (MAX_LARGE_SECTORS * (int32)Floor(fY / MAX_LARGE_SECTORS)); - - int32 nSecsX = (int32)((fX - fSectorX) / 2.0f); - int32 nSecsY = (int32)((fY - fSectorY) / 2.0f); -#endif - - RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic); - RpMorphTarget *wavyMorph = RpGeometryGetMorphTarget(wavyGeometry, 0); - RwV3d *wavyMorphVerts = RpMorphTargetGetVertices(wavyMorph); - RwV3d *wavyMorphNormals = RpMorphTargetGetVertexNormals(wavyMorph); - - RpGeometry *maskGeometry = RpAtomicGetGeometry(ms_pMaskAtomic); - RwTexCoords *maskTexCoords = RpGeometryGetVertexTexCoords(maskGeometry, rwTEXTURECOORDINATEINDEX0); - RwRGBA *maskPreLight = RpGeometryGetPreLightColors(maskGeometry); - RpMorphTarget *maskMorph = RpGeometryGetMorphTarget(maskGeometry, 0); - RwV3d *maskMorphVerts = RpMorphTargetGetVertices(maskMorph); - RwV3d *maskMorphNormals = RpMorphTargetGetVertexNormals(maskMorph); - - RpGeometryLock(maskGeometry, rpGEOMETRYLOCKVERTICES|rpGEOMETRYLOCKNORMALS|rpGEOMETRYLOCKPRELIGHT|rpGEOMETRYLOCKTEXCOORDS); - -#ifndef PC_WATER - RpMaterial *maskMat = RpGeometryGetMaterial(maskGeometry, 0); - RpMatFXMaterialSetEnvMapFrame(maskMat, RwCameraGetFrame(RwCameraGetCurrentCamera())); - RpMatFXMaterialSetEnvMapCoefficient(maskMat, fEnvScale); - RpMatFXMaterialSetEnvMapFrameBufferAlpha(maskMat, TRUE); -#endif - -#ifndef PC_WATER - float fMinSparkZ = (CWeather::WindClipped * fWave2Ampl + 0.05f + - CWeather::WindClipped * 0.4f + 0.2) * (1.0f - 0.04f * CWeather::SunGlare); - - int32 randval = CGeneral::GetRandomNumber(); - - float fUVStep = 0.125f; - float f27 = 2.0f; - - float fMinU = (fUOffset / 16.0f) + _TEXTURE_MASK_ADDU; - float fMinV = (fVOffset / 16.0f) + _TEXTURE_MASK_ADDV; - - float fAlphaMul = ((float)color.alpha * 0.4f) / 16.0f; - - float fXOffset = 16.0f; - if (nCamDirX > 0) - fXOffset = 6.4f; - else if (nCamDirX < 0) - fXOffset = 25.6f; - - float fYOffset = 16.0f; - if (nCamDirY > 0) - fYOffset = 6.4f; - else if (nCamDirY < 0) - fYOffset = 25.6f; - - int16 nX = _RoundValue(nSecsX - 1); - int16 nY = _RoundValue(nSecsY - 1); -#else - float fMinSparkZ = (fWave2Ampl * CWeather::WindClipped + 0.05f + - 0.4f * CWeather::WindClipped + 0.2) * (1.0f - 0.02f * CWeather::SunGlare); - - int32 randval = CGeneral::GetRandomNumber() & 255; - - int16 nX = _RoundValue((int32)((fX - fSectorX) * 0.5f) - 1); - int16 nY = _RoundValue((int32)((fY - fSectorY) * 0.5f) - 1); -#endif - int16 idxX = nX; - - for ( int32 i = 0; i < 17; i++ ) - { - int16 idxY = nY; - - if ( ++idxX > 16 ) - idxX -= 16; - - for ( int32 j = 0; j < 17; j++ ) - { - if ( ++idxY > 16 ) - idxY -= 16; - - const int32 a = (0*16); - const int32 b = (1*16); - const int32 c = (33*16); - const int32 d = (34*16); - - int32 base = (i*33+j); - -#ifndef PC_WATER - maskTexCoords[base + a].u = fMinU + ((float)i * fUVStep); - maskTexCoords[base + a].v = fMinV + ((float)j * fUVStep); - - maskTexCoords[base + b].u = maskTexCoords[base + a].u; - maskTexCoords[base + b].v = maskTexCoords[base + a].v + (16.0f * fUVStep); - - maskTexCoords[base + c].u = maskTexCoords[base + a].u + (16.0f * fUVStep); - maskTexCoords[base + c].v = maskTexCoords[base + a].v; - - maskTexCoords[base + d].u = maskTexCoords[base + a].u + (16.0f * fUVStep); - maskTexCoords[base + d].v = maskTexCoords[base + a].v + (16.0f * fUVStep); -#else - maskTexCoords[base+a].v = float(j) / SMALL_SECTOR_SIZE + ((fCamPosY - fY) / 64); - maskTexCoords[base+c].v = maskTexCoords[base+a].v; - maskTexCoords[base+d].v = maskTexCoords[base+a].v + 0.5f; - maskTexCoords[base+b].v = maskTexCoords[base+d].v; - - maskTexCoords[base+a].u = float(i) / SMALL_SECTOR_SIZE + ((fCamPosX - fX) / 64); - maskTexCoords[base+b].u = maskTexCoords[base+a].u; - maskTexCoords[base+d].u = maskTexCoords[base+a].u + 0.5f; - maskTexCoords[base+c].u = maskTexCoords[base+d].u; -#endif - - maskMorphVerts[base+a].x = (wavyMorphVerts[idxY + (17 * idxX)].x - (float)idxX * 2.0f) + (float(i) * 2.0f); - maskMorphVerts[base+b].x = maskMorphVerts[base+a].x; - maskMorphVerts[base+c].x = maskMorphVerts[base+a].x + SMALL_SECTOR_SIZE; - maskMorphVerts[base+d].x = maskMorphVerts[base+c].x; - - maskMorphVerts[base+a].y = (wavyMorphVerts[idxY + (17 * idxX)].y - (float)idxY * 2.0f) + (float(j) * 2.0f); - maskMorphVerts[base+c].y = maskMorphVerts[base+a].y; - maskMorphVerts[base+b].y = maskMorphVerts[base+a].y + SMALL_SECTOR_SIZE; - maskMorphVerts[base+d].y = maskMorphVerts[base+b].y; - - maskMorphVerts[base+a].z = wavyMorphVerts[idxY + (17 * idxX)].z; - maskMorphVerts[base+d].z = maskMorphVerts[base+a].z; - maskMorphVerts[base+c].z = maskMorphVerts[base+d].z; - maskMorphVerts[base+b].z = maskMorphVerts[base+c].z; - -#ifndef PC_WATER - if (maskMorphVerts[base].z >= fMinSparkZ) -#else - if ( maskMorphVerts[base].z > fMinSparkZ ) -#endif - { - switch ( (i + j + randval) & 3 ) - { - case 0: - { - CVector vecPos - ( - fX + maskMorphVerts[base+a].x, - fY + maskMorphVerts[base+a].y, - fZ + maskMorphVerts[base+a].z + 0.12f - ); - - vecPos -= 0.05f * TheCamera.GetForward(); - - CParticle::AddParticle(PARTICLE_WATER_SPARK, - vecPos, - CVector(0.0f, 0.0f, 0.0f), - nil, - 0.0f, - 15, - CGeneral::GetRandomNumberInRange(-90, 90), - 0, - 0); - } - break; - - case 1: - { - CVector vecPos - ( - fX + maskMorphVerts[base+c].x, - fY + maskMorphVerts[base+c].y, - fZ + maskMorphVerts[base+c].z + 0.12f - ); - - vecPos -= 0.05f * TheCamera.GetForward(); - - CParticle::AddParticle(PARTICLE_WATER_SPARK, - vecPos, - CVector(0.0f, 0.0f, 0.0f), - nil, - 0.0f, - 15, - CGeneral::GetRandomNumberInRange(-90, 90), - 0, - 0); - } - break; - - case 2: - { - CVector vecPos - ( - fX + maskMorphVerts[base+b].x, - fY + maskMorphVerts[base+b].y, - fZ + maskMorphVerts[base+b].z + 0.12f - ); - - vecPos -= 0.05f * TheCamera.GetForward(); - - CParticle::AddParticle(PARTICLE_WATER_SPARK, - vecPos, - CVector(0.0f, 0.0f, 0.0f), - nil, - 0.0f, - 15, - CGeneral::GetRandomNumberInRange(-90, 90), - 0, - 0); - } - break; - - case 3: - { - CVector vecPos - ( - fX + maskMorphVerts[base+d].x, - fY + maskMorphVerts[base+d].y, - fZ + maskMorphVerts[base+d].z + 0.12f - ); - - vecPos -= 0.05f * TheCamera.GetForward(); - - CParticle::AddParticle(PARTICLE_WATER_SPARK, - vecPos, - CVector(0.0f, 0.0f, 0.0f), - nil, - 0.0f, - 15, - CGeneral::GetRandomNumberInRange(-90, 90), - 0, - 0); - } - break; - } - } - - maskMorphNormals[base+a].x = wavyMorphNormals[idxY + (17 * idxX)].x; - maskMorphNormals[base+a].y = wavyMorphNormals[idxY + (17 * idxX)].y; - maskMorphNormals[base+a].z = wavyMorphNormals[idxY + (17 * idxX)].z; - - maskMorphNormals[base+d].x = maskMorphNormals[base+a].x; - maskMorphNormals[base+d].y = maskMorphNormals[base+a].y; - maskMorphNormals[base+d].z = maskMorphNormals[base+a].z; - - maskMorphNormals[base+c].x = maskMorphNormals[base+d].x; - maskMorphNormals[base+c].y = maskMorphNormals[base+d].y; - maskMorphNormals[base+c].z = maskMorphNormals[base+d].z; - - maskMorphNormals[base+b].x = maskMorphNormals[base+c].x; - maskMorphNormals[base+b].y = maskMorphNormals[base+c].y; - maskMorphNormals[base+b].z = maskMorphNormals[base+c].z; - - maskPreLight[base+a].red = color.red; - maskPreLight[base+a].green = color.green; - maskPreLight[base+a].blue = color.blue; - maskPreLight[base+a].alpha = color.alpha; - - maskPreLight[base+d].red = maskPreLight[base+a].red; - maskPreLight[base+d].green = maskPreLight[base+a].green; - maskPreLight[base+d].blue = maskPreLight[base+a].blue; - maskPreLight[base+d].alpha = maskPreLight[base+a].alpha; - - maskPreLight[base+c].red = maskPreLight[base+d].red; - maskPreLight[base+c].green = maskPreLight[base+d].green; - maskPreLight[base+c].blue = maskPreLight[base+d].blue; - maskPreLight[base+c].alpha = maskPreLight[base+d].alpha; - - maskPreLight[base+b].red = maskPreLight[base+c].red; - maskPreLight[base+b].green = maskPreLight[base+c].green; - maskPreLight[base+b].blue = maskPreLight[base+c].blue; - maskPreLight[base+b].alpha = maskPreLight[base+c].alpha; - -#ifndef PC_WATER - maskPreLight[base + a].alpha = Max(0, (int32)((float)color.alpha - (fAlphaMul * (Abs((float)i - fXOffset) + Abs((float)j - fYOffset))))); - maskPreLight[base + b].alpha = Max(0, (int32)((float)color.alpha - (fAlphaMul * (Abs((float)i - fXOffset) + Abs(16.0f + (float)j - fYOffset))))); - maskPreLight[base + c].alpha = Max(0, (int32)((float)color.alpha - (fAlphaMul * (Abs(16.0f + (float)i - fXOffset) + Abs((float)j - fYOffset))))); - maskPreLight[base + d].alpha = Max(0, (int32)((float)color.alpha - (fAlphaMul * (Abs(16.0f + (float)i - fXOffset) + Abs(16.0f + (float)j - fYOffset))))); -#endif - } - } - - RpGeometryUnlock(maskGeometry); - -#ifndef PC_WATER - { - RwV3d pos = { 0.0f, 0.0f, 0.0f }; - - pos.x = fX; - pos.y = fY; - pos.z = fZ + 0.05f; - - RwFrameTranslate(RpAtomicGetFrame(ms_pMaskAtomic), &pos, rwCOMBINEREPLACE); - - if (bRender) - { -#ifdef PS2 - RpSkyTexCacheFlush(); -#endif - RpAtomicRender(ms_pMaskAtomic); - } - } -#endif -} - -#ifdef PC_WATER -void -CWaterLevel::PreCalcWaterGeometry(void) -{ - if ( !RequireWavySector ) - { - WavesCalculatedThisFrame = false; - MaskCalculatedThisFrame = false; - return; - } - - RequireWavySector = false; - WavesCalculatedThisFrame = true; - - RwRGBA color; - - color.red = CTimeCycle::GetWaterRed(); - color.green = CTimeCycle::GetWaterGreen(); - color.blue = CTimeCycle::GetWaterBlue(); - color.alpha = CTimeCycle::GetWaterAlpha(); - - PreCalcWavySector(color); - - if ( CCullZones::WaterFudge() ) - { - MaskCalculatedThisFrame = false; - return; - } - - CVector CamFwdDir = TheCamera.GetForward(); - CamFwdDir.z = 0.0f; - CamFwdDir.Normalise(); - - float fCamX = TheCamera.GetPosition().x - SMALL_SECTOR_SIZE; - float fCamY = TheCamera.GetPosition().y - SMALL_SECTOR_SIZE; - - //1.4144272f; 1.4144f; - float signX = CamFwdDir.x * 1.4144272f; - float signY = CamFwdDir.y * 1.4144272f; - - signX = Clamp(signX, -1.0f, 1.0f); - fCamX += 0.4f * signX * float(SMALL_SECTOR_SIZE * 2.0f); - - signY = Clamp(signY, -1.0f, 1.0f); - fCamY += 0.4f * signY * float(SMALL_SECTOR_SIZE * 2.0f); - - int32 nBlock; - - int32 BlockX = WATER_TO_SMALL_SECTOR_X(fCamX + WATER_X_OFFSET) + 1; - int32 BlockY = WATER_TO_SMALL_SECTOR_Y(fCamY ) + 1; - - ASSERT( BlockX >= 0 && BlockX < MAX_SMALL_SECTORS ); - ASSERT( BlockY >= 0 && BlockY < MAX_SMALL_SECTORS ); - - if ( _IsColideWithBlock(BlockX, BlockY, nBlock) ) - { - float fMaskX = Floor(fCamX / 2.0f) * 2.0f; - float fMaskY = Floor(fCamY / 2.0f) * 2.0f; - - float fSectorX = WATER_FROM_SMALL_SECTOR_X(BlockX) - WATER_X_OFFSET; - float fSectorY = WATER_FROM_SMALL_SECTOR_Y(BlockY); - - if ( PreCalcWavyMask( fMaskX, fMaskY, ms_aWaterZs[nBlock], - fSectorX, fSectorY, fCamX, fCamY, CamFwdDir.x, CamFwdDir.y, color ) ) - { - PreCalculatedMaskPosn.x = fMaskX; - PreCalculatedMaskPosn.y = fMaskY; - PreCalculatedMaskPosn.z = ms_aWaterZs[nBlock] + 0.05f; - - MaskCalculatedThisFrame = true; - } - else - MaskCalculatedThisFrame = false; - } - else - MaskCalculatedThisFrame = false; -} - -bool -CWaterLevel::PreCalcWavySector(RwRGBA const &color) -{ - float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f); - - RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic); - - RwTexCoords *wavyTexCoords = RpGeometryGetVertexTexCoords(wavyGeometry, rwTEXTURECOORDINATEINDEX0); - RpMorphTarget *wavyMorph = RpGeometryGetMorphTarget(wavyGeometry, 0); - - RwRGBA *wavyPreLight = RpGeometryGetPreLightColors(wavyGeometry); - RwV3d *wavyMorphVerts = RpMorphTargetGetVertices(wavyMorph); - RwV3d *wavyMorphNormals = RpMorphTargetGetVertexNormals(wavyMorph); - - if ( !m_bRenderSeaBed ) - RpGeometryLock(wavyGeometry, rpGEOMETRYLOCKVERTICES - |rpGEOMETRYLOCKNORMALS - |rpGEOMETRYLOCKPRELIGHT - |rpGEOMETRYLOCKTEXCOORDS); - - CVector camPosUp = TheCamera.GetForward(); - - float randomDampInv2 = (1.0f - fRandomDamp) * 2.0f; - - float randomMove = 1.0f / (16.0f * fRandomMoveDiv); - - float wind = CWeather::WindClipped * 0.4f + 0.2f; - float waveWind = CWeather::WindClipped * fWave2Ampl + 0.05f; - - float waveA = (TWOPI / 16.0f) - * ((CWeather::WindClipped * 0.4f + 0.2f) * (fNormalDirectionScalar1 * Abs(camPosUp.x + camPosUp.y) + fNormMult)); - - float waveB = TWOPI / (16.0f * fWave2NormScale) - * ((CWeather::WindClipped * 0.2f + 0.1f) * (fNormalDirectionScalar2 * Abs(camPosUp.y - camPosUp.x) + fNormMultB)); - - - CVector vA(1.0f, 0.0f, 0.0f); - CVector vB(0.0f, 1.0f, 0.0f); - - for ( int32 i = 0; i < 17; i++ ) - { - for ( int32 j = 0; j < 17; j++ ) - { - wavyTexCoords->u = (float(i) / 16.0f) + TEXTURE_ADDV; - wavyTexCoords->v = (float(j) / 16.0f) + TEXTURE_ADDU; - - RwRGBAAssign(wavyPreLight, &color); - - if ( i > 0 && i < 16 && j > 0 && j < 16 ) - { - wavyMorphVerts->x += CGeneral::GetRandomNumberInRange(-1.0f, 1.0f) * randomMove; - wavyMorphVerts->x *= fRandomDamp; - wavyMorphVerts->x += float(i) * randomDampInv2; - - wavyMorphVerts->y += CGeneral::GetRandomNumberInRange(-1.0f, 1.0f) * randomMove; - wavyMorphVerts->y *= fRandomDamp; - wavyMorphVerts->y += float(j) * randomDampInv2; - } - - float morphVertXHalf = ( i == 16 ) ? 0.0f : 0.5f * wavyMorphVerts->x; - float morphVertYHalf = ( j == 16 ) ? 0.0f : 0.5f * wavyMorphVerts->y; - - float waveMulA = (morphVertYHalf + morphVertXHalf) * (TWOPI / 16.0f) + fAngle; - float waveMulB = (morphVertYHalf - morphVertXHalf) * (TWOPI / (16.0f * fWave2InvLength)) + fAngle; - - wavyMorphVerts->z = wind * Sin(waveMulA) + waveWind * Sin(waveMulB); - - vA.z = (waveA * Cos(waveMulA)) - (waveB * Cos(waveMulB)); - vB.z = (waveA * Cos(waveMulA)) + (waveB * Cos(waveMulB)); - - CVector norm = CrossProduct(vA, vB); - norm.Normalise(); - - wavyMorphNormals->x = norm.x; - wavyMorphNormals->y = norm.y; - wavyMorphNormals->z = norm.z; - - ++wavyPreLight; - ++wavyTexCoords; - - ++wavyMorphVerts; - ++wavyMorphNormals; - } - } - - RpGeometryUnlock(wavyGeometry); - - return true; -} - -bool -CWaterLevel::PreCalcWavyMask(float fX, float fY, float fZ, - float fSectorX, float fSectorY, - float fCamPosX, float fCamPosY, - float fCamDirX, float fCamDirY, - RwRGBA const&color) -{ - CVector vecSectorPos(fX + (MAX_LARGE_SECTORS/2), fY + (MAX_LARGE_SECTORS/2), fZ + 2.0f); - - if ( COcclusion::IsAABoxOccluded(vecSectorPos, MAX_LARGE_SECTORS, MAX_LARGE_SECTORS, 4.0f) ) - return false; - - Floor(fX / MAX_LARGE_SECTORS); - Floor(fY / MAX_LARGE_SECTORS); - - RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic); - RpMorphTarget *wavyMorph = RpGeometryGetMorphTarget(wavyGeometry, 0); - RwV3d *wavyMorphVerts = RpMorphTargetGetVertices(wavyMorph); - RwV3d *wavyMorphNormals = RpMorphTargetGetVertexNormals(wavyMorph); - - RpGeometry *maskGeometry = RpAtomicGetGeometry(ms_pMaskAtomic); - RwTexCoords *maskTexCoords = RpGeometryGetVertexTexCoords(maskGeometry, rwTEXTURECOORDINATEINDEX0); - RwRGBA *maskPreLight = RpGeometryGetPreLightColors(maskGeometry); - RpMorphTarget *maskMorph = RpGeometryGetMorphTarget(maskGeometry, 0); - RwV3d *maskMorphVerts = RpMorphTargetGetVertices(maskMorph); - RwV3d *maskMorphNormals = RpMorphTargetGetVertexNormals(maskMorph); - - if ( !m_bRenderSeaBed ) - RpGeometryLock(maskGeometry, rpGEOMETRYLOCKVERTICES | rpGEOMETRYLOCKNORMALS | rpGEOMETRYLOCKPRELIGHT | rpGEOMETRYLOCKTEXCOORDS); - - - float fMinSparkZ = (fWave2Ampl * CWeather::WindClipped + 0.05f + - 0.4f * CWeather::WindClipped + 0.2) * (1.0f - 0.02f * CWeather::SunGlare); - - int32 randval = CGeneral::GetRandomNumber() & 255; - - int16 nX = _RoundValue((int32)((fX - fSectorX) * 0.5f) - 1); - int16 nY = _RoundValue((int32)((fY - fSectorY) * 0.5f) - 1); - - int16 idxX = nX; - - for ( int32 i = 0; i < 17; i++ ) - { - int16 idxY = nY; - - if ( ++idxX > 16 ) - idxX -= 16; - - for ( int32 j = 0; j < 17; j++ ) - { - if ( ++idxY > 16 ) - idxY -= 16; - - const int32 a = (0*16); - const int32 b = (1*16); - const int32 c = (33*16); - const int32 d = (34*16); - - int32 base = (i*33+j); - - maskTexCoords[base+a].v = float(j) / 32 + ((fCamPosY - fY) / 64); - maskTexCoords[base+c].v = maskTexCoords[base+a].v; - maskTexCoords[base+d].v = maskTexCoords[base+a].v + 0.5f; - maskTexCoords[base+b].v = maskTexCoords[base+d].v; - - maskTexCoords[base+a].u = float(i) / 32 + ((fCamPosX - fX) / 64); - maskTexCoords[base+b].u = maskTexCoords[base+a].u; - maskTexCoords[base+d].u = maskTexCoords[base+a].u + 0.5f; - maskTexCoords[base+c].u = maskTexCoords[base+d].u; - - maskMorphVerts[base+a].x = (wavyMorphVerts[idxY + (17 * idxX)].x - (float)idxX * 2.0f) + (float(i) * 2.0f); - maskMorphVerts[base+b].x = maskMorphVerts[base+a].x; - maskMorphVerts[base+c].x = maskMorphVerts[base+a].x + SMALL_SECTOR_SIZE; - maskMorphVerts[base+d].x = maskMorphVerts[base+c].x; - - maskMorphVerts[base+a].y = (wavyMorphVerts[idxY + (17 * idxX)].y - (float)idxY * 2.0f) + (float(j) * 2.0f); - maskMorphVerts[base+c].y = maskMorphVerts[base+a].y; - maskMorphVerts[base+b].y = maskMorphVerts[base+a].y + SMALL_SECTOR_SIZE; - maskMorphVerts[base+d].y = maskMorphVerts[base+b].y; - - maskMorphVerts[base+a].z = wavyMorphVerts[idxY + (17 * idxX)].z; - maskMorphVerts[base+d].z = maskMorphVerts[base+a].z; - maskMorphVerts[base+c].z = maskMorphVerts[base+d].z; - maskMorphVerts[base+b].z = maskMorphVerts[base+c].z; - - if ( maskMorphVerts[base].z > fMinSparkZ ) - { - switch ( (i + j + randval) & 3 ) - { - case 0: - { - CVector vecPos - ( - fX + maskMorphVerts[base+a].x, - fY + maskMorphVerts[base+a].y, - fZ + maskMorphVerts[base+a].z + 0.12f - ); - - vecPos -= 0.05f * TheCamera.GetForward(); - - CParticle::AddParticle(PARTICLE_WATER_SPARK, - vecPos, - CVector(0.0f, 0.0f, 0.0f), - nil, - 0.0f, - 15, - CGeneral::GetRandomNumberInRange(-90, 90), - 0, - 0); - } - break; - - case 1: - { - CVector vecPos - ( - fX + maskMorphVerts[base+c].x, - fY + maskMorphVerts[base+c].y, - fZ + maskMorphVerts[base+c].z + 0.12f - ); - - vecPos -= 0.05f * TheCamera.GetForward(); - - CParticle::AddParticle(PARTICLE_WATER_SPARK, - vecPos, - CVector(0.0f, 0.0f, 0.0f), - nil, - 0.0f, - 15, - CGeneral::GetRandomNumberInRange(-90, 90), - 0, - 0); - } - break; - - case 2: - { - CVector vecPos - ( - fX + maskMorphVerts[base+b].x, - fY + maskMorphVerts[base+b].y, - fZ + maskMorphVerts[base+b].z + 0.12f - ); - - vecPos -= 0.05f * TheCamera.GetForward(); - - CParticle::AddParticle(PARTICLE_WATER_SPARK, - vecPos, - CVector(0.0f, 0.0f, 0.0f), - nil, - 0.0f, - 15, - CGeneral::GetRandomNumberInRange(-90, 90), - 0, - 0); - } - break; - - case 3: - { - CVector vecPos - ( - fX + maskMorphVerts[base+d].x, - fY + maskMorphVerts[base+d].y, - fZ + maskMorphVerts[base+d].z + 0.12f - ); - - vecPos -= 0.05f * TheCamera.GetForward(); - - CParticle::AddParticle(PARTICLE_WATER_SPARK, - vecPos, - CVector(0.0f, 0.0f, 0.0f), - nil, - 0.0f, - 15, - CGeneral::GetRandomNumberInRange(-90, 90), - 0, - 0); - } - break; - } - } - - maskMorphNormals[base+a].x = wavyMorphNormals[idxY + (17 * idxX)].x; - maskMorphNormals[base+a].y = wavyMorphNormals[idxY + (17 * idxX)].y; - maskMorphNormals[base+a].z = wavyMorphNormals[idxY + (17 * idxX)].z; - - maskMorphNormals[base+d].x = maskMorphNormals[base+a].x; - maskMorphNormals[base+d].y = maskMorphNormals[base+a].y; - maskMorphNormals[base+d].z = maskMorphNormals[base+a].z; - - maskMorphNormals[base+c].x = maskMorphNormals[base+d].x; - maskMorphNormals[base+c].y = maskMorphNormals[base+d].y; - maskMorphNormals[base+c].z = maskMorphNormals[base+d].z; - - maskMorphNormals[base+b].x = maskMorphNormals[base+c].x; - maskMorphNormals[base+b].y = maskMorphNormals[base+c].y; - maskMorphNormals[base+b].z = maskMorphNormals[base+c].z; - - maskPreLight[base+a].red = color.red; - maskPreLight[base+a].green = color.green; - maskPreLight[base+a].blue = color.blue; - maskPreLight[base+a].alpha = color.alpha; - - maskPreLight[base+d].red = maskPreLight[base+a].red; - maskPreLight[base+d].green = maskPreLight[base+a].green; - maskPreLight[base+d].blue = maskPreLight[base+a].blue; - maskPreLight[base+d].alpha = maskPreLight[base+a].alpha; - - maskPreLight[base+c].red = maskPreLight[base+d].red; - maskPreLight[base+c].green = maskPreLight[base+d].green; - maskPreLight[base+c].blue = maskPreLight[base+d].blue; - maskPreLight[base+c].alpha = maskPreLight[base+d].alpha; - - maskPreLight[base+b].red = maskPreLight[base+c].red; - maskPreLight[base+b].green = maskPreLight[base+c].green; - maskPreLight[base+b].blue = maskPreLight[base+c].blue; - maskPreLight[base+b].alpha = maskPreLight[base+c].alpha; - } - } - - RpGeometryUnlock(maskGeometry); - return true; -} -#endif - -void -CWaterLevel::RenderBoatWakes(void) -{ - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpWaterWakeRaster); -#ifndef PC_WATER - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA); -#endif - -#ifdef _XBOX - // TODO save and restore rwRENDERSTATESRCBLEND rwRENDERSTATEDESTBLEND -#endif - - CBoat::FillBoatList(); - - float fWakeZ = 5.97f; - float fWakeLifeTimeMult = 0.01f / CBoat::WAKE_LIFETIME; - - for ( int32 idx = 0; idx < ARRAY_SIZE(CBoat::apFrameWakeGeneratingBoats); idx++ ) - { - CBoat *pBoat = CBoat::apFrameWakeGeneratingBoats[idx]; - - if ( pBoat == nil ) - break; - - CVector2D vecDistA(pBoat->GetForward().x, pBoat->GetForward().y); - - - float fSize = pBoat->GetColModel()->boundingBox.max.z - * 0.65f; - - if ( pBoat->GetModelIndex() == MI_SKIMMER) - fSize *= 0.4f; - - float fAplhaA = 255.0f; - float fSizeA = fSize; - float fAplhaB; - float fSizeB; - - for ( int32 wake = 1; wake < pBoat->m_nNumWakePoints; wake++ ) - { - bool bRender = true; - - float fTimeleft = CBoat::WAKE_LIFETIME - pBoat->m_afWakePointLifeTime[wake]; - - float fWakeSizeB = ((float)wake * 0.19f) + fSize - fWakeLifeTimeMult * Max(fTimeleft, 0.0f); - - fSizeB = fWakeSizeB / CBoat::MIN_WAKE_INTERVAL; - if ( fSizeB < 0.0f ) - fSizeB = 1.0f; - - if ( wake == pBoat->m_nNumWakePoints - 1 ) - { - // set alpha to 0 if it's last point - fAplhaB = 0.0f; - } - else - { - // clip (-100, 500), less lifetime - less val - float val = 500.0f - (CBoat::WAKE_LIFETIME - pBoat->m_afWakePointLifeTime[wake]) - * 600.0f / CBoat::WAKE_LIFETIME; - - fAplhaB = Clamp(val, 0.0f, 255.0f); - } - - CVector2D vecDistB = pBoat->m_avec2dWakePoints[wake - 1] - pBoat->m_avec2dWakePoints[wake]; - - float fScal = vecDistB.MagnitudeSqr(); - - // normalize if distance between points is greater than 3 - - if ( fScal > SQR(3.0f) ) - { - float fNorm = 1.0f / sqrt(fScal); - - vecDistB.x *= fNorm; - vecDistB.y *= fNorm; - - // disable render if distance between points too big - - if ( sqrt(fScal) > 13.0f ) - bRender = false; - } - - CVector2D vecAA - ( - pBoat->m_avec2dWakePoints[wake - 1].x - (fSizeA * vecDistA.y), - pBoat->m_avec2dWakePoints[wake - 1].y + (fSizeA * vecDistA.x) - ); - CVector2D vecAB - ( - pBoat->m_avec2dWakePoints[wake - 1].x + (fSizeA * vecDistA.y), - pBoat->m_avec2dWakePoints[wake - 1].y - (fSizeA * vecDistA.x) - ); - CVector2D vecBA - ( - pBoat->m_avec2dWakePoints[wake].x + (fSizeB * vecDistB.y), - pBoat->m_avec2dWakePoints[wake].y - (fSizeB * vecDistB.x) - ); - CVector2D vecBB - ( - pBoat->m_avec2dWakePoints[wake].x - (fSizeB * vecDistB.y), - pBoat->m_avec2dWakePoints[wake].y + (fSizeB * vecDistB.x) - ); - - if ( bRender ) - RenderWakeSegment(vecAA, vecAB, vecBA, vecBB, fSizeA, fSizeB, fAplhaA, fAplhaB, fWakeZ); - - vecDistA = vecDistB; - fSizeA = fSizeB; - - fAplhaB = fAplhaA; - } - } - - RenderAndEmptyRenderBuffer(); -} - -inline float -_GetWindedWave(float fX, float fY) -{ - float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f); - float x = WATER_HUGE_X(fX + WATER_X_OFFSET); - float y = WATER_HUGE_Y(fY); - - float fWindFactor (CWeather::WindClipped * 0.4f + 0.2f); - float fWave = Sin(( (x - Floor(x)) + (y - Floor(y)) ) * TWOPI + fAngle); - - return fWindFactor * fWave; -} - -void -CWaterLevel::RenderWakeSegment(CVector2D &vecA, CVector2D &vecB, CVector2D &vecC, CVector2D &vecD, - float &fSizeA, float &fSizeB, - float &fAlphaA, float &fAlphaB, - float &fWakeZ) -{ - for ( int32 i = 0; i < 4; i++ ) - { - if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 ) - RenderAndEmptyRenderBuffer(); - - float fCurStep = (float)i / 4; - float fNxtStep = (float)(i + 1) / 4; - - float fLeftCurStep = 1.0f - fCurStep; - float fLeftNxtStep = 1.0f - fNxtStep; - - uint8 AlphaA = (uint32)(fAlphaA * aAlphaFade[i] ); - uint8 AlphaB = (uint32)(fAlphaA * aAlphaFade[i + 1]); - uint8 AlphaC = (uint32)(fAlphaB * aAlphaFade[i + 1]); - uint8 AlphaD = (uint32)(fAlphaB * aAlphaFade[i] ); - - CVector2D PosA = vecB*fCurStep + vecA*fLeftCurStep; - CVector2D PosB = vecB*fNxtStep + vecA*fLeftNxtStep; - CVector2D PosC = vecC*fNxtStep + vecD*fLeftNxtStep; - CVector2D PosD = vecC*fCurStep + vecD*fLeftCurStep; - - float fUA = (PosA.x / 4) + _TEXTURE_WAKE_ADDU; - float fVA = (PosA.y / 4) + _TEXTURE_WAKE_ADDV; - - float fUB = (PosB.x / 4) + _TEXTURE_WAKE_ADDU; - float fVB = (PosB.y / 4) + _TEXTURE_WAKE_ADDV; - - float fUC = (PosC.x / 4) + _TEXTURE_WAKE_ADDU; - float fVC = (PosC.y / 4) + _TEXTURE_WAKE_ADDV; - - float fUD = (PosD.x / 4) + _TEXTURE_WAKE_ADDU; - float fVD = (PosD.y / 4) + _TEXTURE_WAKE_ADDV; - -#define MIN4(a, b, c, d) (Min((a), Min((b), Min((c), (d))))) - float fMinU = Floor(MIN4(fUA, fUB, fUC, fUD)); - float fMinV = Floor(MIN4(fVA, fVB, fVC, fVD)); -#undef MIN4 - - float fZA = _GetWindedWave(PosA.x, PosA.y) + fWakeZ; - float fZB = _GetWindedWave(PosB.x, PosB.y) + fWakeZ; - float fZC = _GetWindedWave(PosC.x, PosC.y) + fWakeZ; - float fZD = _GetWindedWave(PosD.x, PosD.y) + fWakeZ; - - int32 vidx = TempBufferVerticesStored; - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], PosA.x, PosA.y, fZA); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], fUA - fMinU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], fVA - fMinV); - RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 0], 255, 255, 255, AlphaA); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], PosB.x, PosB.y, fZB); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], fUB - fMinU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], fVB - fMinV); - RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 1], 255, 255, 255, AlphaB); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], PosC.x, PosC.y, fZC); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], fUC - fMinU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], fVC - fMinV); - RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 2], 255, 255, 255, AlphaC); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], PosD.x, PosD.y, fZD); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], fUD - fMinU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], fVD - fMinV); - RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 3], 255, 255, 255, AlphaD); - - int32 iidx = TempBufferIndicesStored; - - TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2; - TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1; - TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3; - TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2; - - TempBufferVerticesStored += 4; - - TempBufferIndicesStored += 6; - } -} - -void -CWaterLevel::RenderOneSlopedUnderWaterPoly(float fX, float fY, float fZ, RwRGBA const&color) -{ - CVector2D camPos(TheCamera.GetPosition().x, TheCamera.GetPosition().y); - - float fDistA = (CVector2D(fX, fY) - camPos).Magnitude() + -140.0f; - float fDistB = (CVector2D(fX, fY + HUGE_SECTOR_SIZE) - camPos).Magnitude() + -140.0f; - float fDistC = (CVector2D(fX + HUGE_SECTOR_SIZE, fY + HUGE_SECTOR_SIZE) - camPos).Magnitude() + -140.0f; - float fDistD = (CVector2D(fX + HUGE_SECTOR_SIZE, fY) - camPos).Magnitude() + -140.0f; - -#ifndef PC_WATER -#define CALCSEABED(v, d) \ - { \ - if ( d < 0.0f ) \ - v = 0.1f + fSeaBedZ; \ - else if ( d > 240.0f ) \ - v = 0.1f; \ - else \ - v = 0.1f + ((fSeaBedZ * (240.0f - d)) / 240.0f); \ - } -#else - #define CALCSEABED(v, d) \ - { \ - v = 0.1f; \ - if ( d < 0.0f ) \ - v += fSeaBedZ; \ - else if ( d <= 240.0f ) \ - v += (fSeaBedZ / 240.0f) * (240.0f - d); \ - } -#endif - float fSeaBedA, fSeaBedB, fSeaBedC, fSeaBedD; - - CALCSEABED(fSeaBedA, fDistA); - CALCSEABED(fSeaBedB, fDistB); - CALCSEABED(fSeaBedC, fDistC); - CALCSEABED(fSeaBedD, fDistD); - - #undef CALCSEABED - - if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 ) - RenderAndEmptyRenderBuffer(); - - int32 vidx = TempBufferVerticesStored; - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - _fWaterZOffset - fSeaBedA); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], 0.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], 0.0f); - RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 0], color.red, color.green, color.blue, 255); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + HUGE_SECTOR_SIZE, fZ - _fWaterZOffset - fSeaBedB); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], 0.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], 4.0f); - RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 1], color.red, color.green, color.blue, 255); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + HUGE_SECTOR_SIZE, fY + HUGE_SECTOR_SIZE, fZ - _fWaterZOffset - fSeaBedC); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], 4.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], 4.0f); - RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 2], color.red, color.green, color.blue, 255); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + HUGE_SECTOR_SIZE, fY, fZ - _fWaterZOffset - fSeaBedD); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], 4.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], 0.0f); - RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 3], color.red, color.green, color.blue, 255); - - int32 iidx = TempBufferIndicesStored; - - TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2; - TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1; - TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3; - TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2; - - TempBufferVerticesStored += 4; - - TempBufferIndicesStored += 6; -} - -void -CWaterLevel::RenderOneFlatSmallWaterPolyBlended(float fX, float fY, float fZ, float fCamX, float fCamY, - RwRGBA const &color, RwRGBA const &colorTrans, - float fDrawDist) -{ - if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 ) - RenderAndEmptyRenderBuffer(); - - int32 vidx = TempBufferVerticesStored; - - float fBlendDrawDist = fDrawDist + fStartBlendDistanceAdd; - - float fDistStartX = SQR(fX - fCamX); - float fDistStartY = SQR(fY - fCamY); - float fDistEndX = SQR((fX + SMALL_SECTOR_SIZE) - fCamX); - float fDistEndY = SQR((fY + SMALL_SECTOR_SIZE) - fCamY); - - - float fAlphaBlendMulA - = Min(fFlatWaterBlendRange * Max(sqrt(fDistStartX + fDistStartY) - fBlendDrawDist, fMinWaterAlphaMult), 1.0f); - float fAlphaBlendMulB - = Min(fFlatWaterBlendRange * Max(sqrt(fDistStartX + fDistEndY ) - fBlendDrawDist, fMinWaterAlphaMult), 1.0f); - float fAlphaBlendMulC - = Min(fFlatWaterBlendRange * Max(sqrt(fDistEndX + fDistEndY ) - fBlendDrawDist, fMinWaterAlphaMult), 1.0f); - float fAlphaBlendMulD - = Min(fFlatWaterBlendRange * Max(sqrt(fDistEndX + fDistStartY) - fBlendDrawDist, fMinWaterAlphaMult), 1.0f); - - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV); - RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 0], color.red, color.green, color.blue, - (colorTrans.alpha + (color.alpha - colorTrans.alpha) * (uint8)(int32)fAlphaBlendMulA)); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + SMALL_SECTOR_SIZE, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 1.0f); - RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 1], color.red, color.green, color.blue, - (colorTrans.alpha + (color.alpha - colorTrans.alpha) * (uint8)(int32)fAlphaBlendMulB)); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + SMALL_SECTOR_SIZE, fY + SMALL_SECTOR_SIZE, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 1.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 1.0f); - RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 2], color.red, color.green, color.blue, - (colorTrans.alpha + (color.alpha - colorTrans.alpha) * (uint8)(int32)fAlphaBlendMulC)); - - RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + SMALL_SECTOR_SIZE, fY, fZ - _fWaterZOffset); - RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 1.0f); - RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV); - RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 3], color.red, color.green, color.blue, - (colorTrans.alpha + (color.alpha - colorTrans.alpha) * (uint8)(int32)fAlphaBlendMulD)); - - - int32 iidx = TempBufferIndicesStored; - - TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2; - TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1; - TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0; - TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3; - TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2; - - TempBufferVerticesStored += 4; - - TempBufferIndicesStored += 6; -} - -float -CWaterLevel::CalcDistanceToWater(float fX, float fY) -{ - const float fSectorMaxRenderDist = 250.0f; - - int32 nStartX = WATER_TO_SMALL_SECTOR_X(fX - fSectorMaxRenderDist + WATER_X_OFFSET) - 1; - int32 nEndX = WATER_TO_SMALL_SECTOR_X(fX + fSectorMaxRenderDist + WATER_X_OFFSET) + 1; - int32 nStartY = WATER_TO_SMALL_SECTOR_Y(fY - fSectorMaxRenderDist) - 1; - int32 nEndY = WATER_TO_SMALL_SECTOR_Y(fY + fSectorMaxRenderDist) + 1; - - nStartX = Clamp(nStartX, 0, MAX_SMALL_SECTORS - 1); - nEndX = Clamp(nEndX, 0, MAX_SMALL_SECTORS - 1); - nStartY = Clamp(nStartY, 0, MAX_SMALL_SECTORS - 1); - nEndY = Clamp(nEndY, 0, MAX_SMALL_SECTORS - 1); - - float fDistSqr = 1.0e10f; - - for ( int32 x = nStartX; x <= nEndX; x++ ) - { - for ( int32 y = nStartY; y <= nEndY; y++ ) - { - if ( aWaterFineBlockList[x][y] >= 0 ) - { - float fSectorX = WATER_FROM_SMALL_SECTOR_X(x) - WATER_X_OFFSET; - float fSectorY = WATER_FROM_SMALL_SECTOR_Y(y); - - CVector2D vecDist - ( - fSectorX + SMALL_SECTOR_SIZE - fX, - fSectorY + SMALL_SECTOR_SIZE - fY - ); - - fDistSqr = Min(vecDist.MagnitudeSqr(), fDistSqr); - } - } - } - - return Clamp(Sqrt(fDistSqr) - 23.0f, 0.0f, fSectorMaxRenderDist); -} - -void -CWaterLevel::RenderAndEmptyRenderBuffer() -{ - if ( TempBufferVerticesStored ) - { - LittleTest(); - - if ( RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV) ) - { - RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored); - RwIm3DEnd(); - } - } - - TempBufferIndicesStored = 0; - TempBufferVerticesStored = 0; -} - -bool -CWaterLevel::GetGroundLevel(CVector const &vecPosn, float *pfOutLevel, ColData *pData, float fDistance) -{ - CColPoint point; - CEntity *entity; - - if ( !CWorld::ProcessVerticalLine(vecPosn + CVector(0.0f, 0.0f, fDistance), - -fDistance, point, entity, true, false, false, false, true, false, nil) ) - return false; - - *pfOutLevel = point.point.z; - - if ( pData != nil ) - { - pData->SurfaceType = point.surfaceB; - pData->PieceType = point.pieceB; - } - - return true; -} - -bool -CWaterLevel::IsLocationOutOfWorldBounds_WS(CVector const &vecPosn, int nOffset) -{ - int32 x = int32((vecPosn.x / 50.0f) + 48.0f); - int32 y = int32((vecPosn.y / 50.0f) + 40.0f); - - return x < nOffset || x >= 80 - nOffset || y < nOffset || y >= 80 - nOffset; -} - -bool -CWaterLevel::GetGroundLevel_WS(CVector const &vecPosn, float *pfOutLevel, ColData *pData, float fDistance) -{ - if ( IsLocationOutOfWorldBounds_WS(vecPosn, 0) ) - return false; - else - return GetGroundLevel(vecPosn, pfOutLevel, pData, fDistance); -} - -bool -CWaterLevel::GetWaterDepth(CVector const &vecPosn, float *pfDepth, float *pfLevelNoWaves, float *pfGroundLevel) -{ - float fLevelNoWaves; - float fGroundLevel; - - if ( !GetWaterLevelNoWaves(vecPosn.x, vecPosn.y, vecPosn.z, &fLevelNoWaves) ) - return false; - - if ( !GetGroundLevel(vecPosn, &fGroundLevel, nil, 30.0f) ) - fGroundLevel = -100.0; - - if ( pfDepth != nil ) - *pfDepth = fLevelNoWaves - fGroundLevel; - - if ( pfLevelNoWaves != nil ) - *pfLevelNoWaves = fLevelNoWaves; - - if ( pfGroundLevel != nil ) - *pfGroundLevel = fGroundLevel; - - return true; -} - -void -CWaterLevel::RenderSeaBirds() -{ - CVector cur_pos = TheCamera.GetPosition(); - - if ( !CCullZones::CamNoRain() - && !CCullZones::PlayerNoRain() - && (CWeather::NewWeatherType == WEATHER_SUNNY || CWeather::NewWeatherType == WEATHER_EXTRA_SUNNY) - && CClock::ms_nGameClockHours > 6 && CClock::ms_nGameClockHours < 20 ) - { - static CVector prev_pos(0.0f, 0.0f, 0.0f); - static CVector prev_front(0.0f, 0.0f, 0.0f); - static int32 timecounter; - - if ( Abs(prev_pos.x - cur_pos.x) + Abs(prev_pos.y - cur_pos.y) + Abs(prev_pos.z - cur_pos.z) > 1.5f ) - { - prev_pos = cur_pos; - timecounter = CTimer::GetTimeInMilliseconds(); - } - else if ( (CTimer::GetTimeInMilliseconds() - timecounter) > 5000 ) - { - static int32 birdgenTime = 0; - - if ( (CTimer::GetTimeInMilliseconds() - birdgenTime) > 1000 ) - { - birdgenTime = CTimer::GetTimeInMilliseconds(); - - CVector vecPos = cur_pos; - - float fAngle = CGeneral::GetRandomNumberInRange(90.0f, 150.0f); - - uint16 nSinCosIdx = CGeneral::GetRandomNumber() % (CParticle::SIN_COS_TABLE_SIZE-1); - - float fCos = CParticle::Cos(nSinCosIdx); - float fSin = CParticle::Sin(nSinCosIdx); - - vecPos.x += (fCos - fSin) * fAngle; - vecPos.y += (fSin + fCos) * fAngle; - vecPos.z += CGeneral::GetRandomNumberInRange(10.0f, 30.0f); - - CVector vecDir(CGeneral::GetRandomNumberInRange(-1.0f, 1.0f), - CGeneral::GetRandomNumberInRange(-1.0f, 1.0f), - 0.0f); - - CParticle::AddParticle(PARTICLE_BIRD_FRONT, vecPos, vecDir, nil, 0.0f, 0, 0, 0, 0); - } - } - } -} - -void -CWaterLevel::RenderShipsOnHorizon() -{ -#ifdef FIX_BUGS - CVector cur_pos = FindPlayerCoors(); -#else - CVector cur_pos = FindPlayerPed()->GetPosition(); -#endif - - static CVector prev_pos(0.0f, 0.0f, 0.0f); - static CVector prev_front(0.0f, 0.0f, 0.0f); - static int32 timecounter; - - if ( Abs(prev_pos.x - cur_pos.x) + Abs(prev_pos.y - cur_pos.y) + Abs(prev_pos.z - cur_pos.z) > 1.5f ) - { - prev_pos = cur_pos; - timecounter = CTimer::GetTimeInMilliseconds(); - } - else if ( (CTimer::GetTimeInMilliseconds() - timecounter) > 5000 ) - { - static int32 shipgenTime = 0; - - if ( (CTimer::GetTimeInMilliseconds() - shipgenTime) > 4000 ) - { - shipgenTime = CTimer::GetTimeInMilliseconds(); - - CVector vecPos = cur_pos; - - float fAngle = CGeneral::GetRandomNumberInRange(450.0f, 750.0f); - - uint16 nSinCosIdx = CGeneral::GetRandomNumber() % (CParticle::SIN_COS_TABLE_SIZE-1); - - float fCos = CParticle::Cos(nSinCosIdx); - float fSin = CParticle::Sin(nSinCosIdx); - - vecPos.x += (fCos - fSin) * fAngle; - vecPos.y += (fSin + fCos) * fAngle; - - float fLevelNoWaves; - - if ( GetWaterLevelNoWaves(vecPos.x, vecPos.y, vecPos.z, &fLevelNoWaves) ) - { - if ( IsLocationOutOfWorldBounds_WS(vecPos, 1) ) - { - vecPos.z = fLevelNoWaves + 9.5f; - - CVector vecDir - ( - CGeneral::GetRandomNumberInRange(-0.1f, 0.1f), - 0.0f, - 0.0f - ); - - CParticle::AddParticle(PARTICLE_SHIP_SIDE, vecPos, vecDir, - nil, 0.0f, 0, 0, CGeneral::GetRandomNumber() & 7, 0); - } - } - } - } -} - -void -CWaterLevel::HandleSeaLifeForms() -{ - if ( CReplay::IsPlayingBack() ) - return; - - CVector cur_pos = FindPlayerPed()->GetPosition(); - - static CVector prev_pos(0.0f, 0.0f, 0.0f); - static int32 timecounter; - - if ( Abs(prev_pos.x - cur_pos.x) + Abs(prev_pos.y - cur_pos.y) + Abs(prev_pos.z - cur_pos.z) > 1.5f ) - { - prev_pos = cur_pos; - timecounter = CTimer::GetTimeInMilliseconds(); - } - else if ( (CTimer::GetTimeInMilliseconds() - timecounter) > 5000 ) - { - if ( CWaterCreatures::IsSpaceForMoreWaterCreatures() ) - { - for ( int32 i = 0; i < 3; i++ ) - { - CVector vecPos = cur_pos; - - float fAngle = CGeneral::GetRandomNumberInRange(15.0f, 30.0f); - - uint16 nSinCosIdx = CGeneral::GetRandomNumber() % (CParticle::SIN_COS_TABLE_SIZE-1); - - float fCos = CParticle::Cos(nSinCosIdx); - float fSin = CParticle::Sin(nSinCosIdx); - - vecPos.x += (fCos - fSin) * fAngle; - vecPos.y += (fSin + fCos) * fAngle; - - CWaterCreatures::CreateOne(vecPos, -1); - } - } - } - - CWaterCreatures::UpdateAll(); -} - -void -CWaterLevel::HandleBeachToysStuff(void) -{ -#ifdef FIX_BUGS - CVector cur_pos = FindPlayerCoors(); -#else - CVector cur_pos = FindPlayerPed()->GetPosition(); -#endif - - static bool bBeachBallInit = true; - static CVector FirstBeachBallPos = cur_pos; - static bool bLoungeInit = true; - static CVector FirstLoungePos = cur_pos; - static CVector prev_pos(0.0f, 0.0f, 0.0f); - static int32 timecounter; - - if ( Abs(prev_pos.x - cur_pos.x) + Abs(prev_pos.y - cur_pos.y) + Abs(prev_pos.z - cur_pos.z) > 1.5f ) - { - prev_pos = cur_pos; - timecounter = CTimer::GetTimeInMilliseconds(); - } - else if ( (CTimer::GetTimeInMilliseconds() - timecounter) > 5000 ) - { - static int32 toygenTime = CTimer::GetTimeInMilliseconds(); - - if ( (CTimer::GetTimeInMilliseconds() - toygenTime) > 20000 ) - { - toygenTime = CTimer::GetTimeInMilliseconds(); - - if ( bBeachBallInit || (cur_pos - FirstBeachBallPos).MagnitudeSqr() > 6400.0f ) - { - for ( int32 i = 0; i < 3; i++ ) - { - CVector vecPos = cur_pos; - - float fAngle = CGeneral::GetRandomNumberInRange(20.0f, 35.0f); - - uint16 nSinCosIdx = CGeneral::GetRandomNumber() % (CParticle::SIN_COS_TABLE_SIZE-1); - - float fCos = CParticle::Cos(nSinCosIdx); - float fSin = CParticle::Sin(nSinCosIdx); - - vecPos.x += (fCos - fSin) * fAngle; - vecPos.y += (fSin + fCos) * fAngle; - - if ( TheCamera.IsSphereVisible(vecPos, 1.0f) ) - { - float fWaterLevel; - - if ( !GetWaterLevel(vecPos.x, vecPos.y, vecPos.z, &fWaterLevel, false) ) - { - float fGroundLevel; - ColData coldata; - - if ( GetGroundLevel(vecPos, &fGroundLevel, &coldata, 30.0f) ) - { - if ( coldata.SurfaceType == SURFACE_SAND ) - { - CEntity *toy = CreateBeachToy(vecPos, BEACHTOY_BALL); - - if ( toy ) - { - FirstBeachBallPos = cur_pos; - bBeachBallInit = false; - i = 10; - } - } - } - } - } - } - } - - if ( bLoungeInit || (cur_pos - FirstLoungePos).MagnitudeSqr() > 6400.0f ) - { - for ( int32 i = 0; i < 5; i++ ) - { - CVector vecPos = cur_pos; - - float fAngle = CGeneral::GetRandomNumberInRange(20.0f, 35.0f); - - uint16 nSinCosIdx = CGeneral::GetRandomNumber() % (CParticle::SIN_COS_TABLE_SIZE-1); - - float fCos = CParticle::Cos(nSinCosIdx); - float fSin = CParticle::Sin(nSinCosIdx); - - vecPos.x += (fCos - fSin) * fAngle; - vecPos.y += (fSin + fCos) * fAngle; - - if ( TheCamera.IsSphereVisible(vecPos, 2.0f) ) - { - float fWaterLevel; - - if ( !GetWaterLevel(vecPos.x, vecPos.y, vecPos.z, &fWaterLevel, false) ) - { - float fGroundLevel; - ColData coldata; - - if ( GetGroundLevel(vecPos, &fGroundLevel, &coldata, 30.0f) ) - { - if ( coldata.SurfaceType == SURFACE_SAND ) - { - CEntity *toy = CreateBeachToy(vecPos, BEACHTOY_ANY_LOUNGE); - if ( toy ) - { - toy->SetHeading(DEGTORAD(CGeneral::GetRandomNumberInRange(0.0f, 359.0f))); - FirstLoungePos = cur_pos; - bLoungeInit = false; - } - } - } - } - } - } - } - } - } -} - -CEntity * -CWaterLevel::CreateBeachToy(CVector const &vec, eBeachToy beachtoy) -{ - if (CObject::nNoTempObjects >= NUMTEMPOBJECTS) - return nil; - - int finalToy = beachtoy; - bool isStatic = false; - int model = MI_BEACHBALL; - switch (beachtoy) { - case BEACHTOY_ANY_LOUNGE: - switch ( CGeneral::GetRandomNumber() & 7 ) { - case 1: - case 7: - finalToy = BEACHTOY_LOUNGE_WOOD_UP; - break; - case 3: - case 5: - finalToy = BEACHTOY_LOUNGE_TOWEL_UP; - break; - default: - finalToy = BEACHTOY_LOUNGE_WOOD_ON; - break; - } - break; - case BEACHTOY_ANY_TOWEL: - switch ( CGeneral::GetRandomNumber() & 7 ) { - case 1: - case 7: - finalToy = BEACHTOY_TOWEL2; - break; - case 2: - case 6: - finalToy = BEACHTOY_TOWEL3; - break; - case 3: - case 5: - finalToy = BEACHTOY_TOWEL4; - break; - default: - finalToy = BEACHTOY_TOWEL1; - break; - } - if (CObject::nNoTempObjects >= 35) { - return nil; - } - default: - break; - } - switch (finalToy) { - case BEACHTOY_BALL: - isStatic = false; - model = MI_BEACHBALL; - break; - case BEACHTOY_LOUNGE_WOOD_UP: - isStatic = false; - model = MI_LOUNGE_WOOD_UP; - break; - case BEACHTOY_LOUNGE_TOWEL_UP: - isStatic = false; - model = MI_LOUNGE_TOWEL_UP; - break; - case BEACHTOY_LOUNGE_WOOD_ON: - isStatic = false; - model = MI_LOUNGE_WOOD_DN; - break; - case BEACHTOY_LOTION: - model = MI_LOTION; - isStatic = true; - break; - case BEACHTOY_TOWEL1: - model = MI_BEACHTOWEL01; - isStatic = true; - break; - case BEACHTOY_TOWEL2: - model = MI_BEACHTOWEL02; - isStatic = true; - break; - case BEACHTOY_TOWEL3: - model = MI_BEACHTOWEL03; - isStatic = true; - break; - case BEACHTOY_TOWEL4: - model = MI_BEACHTOWEL04; - isStatic = true; - break; - default: - break; - } - CObject *toy = new CObject(model, true); - if (toy) { - toy->SetPosition(vec); - toy->GetMatrix().UpdateRW(); - toy->m_vecMoveSpeed = CVector(0.f, 0.f, 0.f); - toy->m_vecTurnSpeed = CVector(0.f, 0.f, 0.f); - toy->ObjectCreatedBy = TEMP_OBJECT; - toy->bIsStatic = isStatic; - CObject::nNoTempObjects++; - toy->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 43200000; - CWorld::Add(toy); - return toy; - } else - return nil; -}
\ No newline at end of file |