summaryrefslogtreecommitdiffstats
path: root/src/render/WaterLevel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/WaterLevel.cpp')
-rw-r--r--src/render/WaterLevel.cpp3377
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