mirror of
				https://github.com/AxioDL/metaforce.git
				synced 2025-10-27 15:30:23 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			480 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			480 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "Runtime/World/CFluidPlane.hpp"
 | |
| 
 | |
| #include "Runtime/CSimplePool.hpp"
 | |
| #include "Runtime/CStateManager.hpp"
 | |
| #include "Runtime/GameGlobalObjects.hpp"
 | |
| #include "Runtime/World/CRipple.hpp"
 | |
| #include "Runtime/World/CScriptWater.hpp"
 | |
| 
 | |
| namespace metaforce {
 | |
| 
 | |
| CFluidPlane::CFluidPlane(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, float alpha,
 | |
|                          EFluidType fluidType, float rippleIntensity, const CFluidUVMotion& motion)
 | |
| : x4_texPattern1Id(texPattern1)
 | |
| , x8_texPattern2Id(texPattern2)
 | |
| , xc_texColorId(texColor)
 | |
| , x40_alpha(alpha)
 | |
| , x44_fluidType(fluidType)
 | |
| , x48_rippleIntensity(rippleIntensity)
 | |
| , x4c_uvMotion(motion) {
 | |
|   if (g_ResFactory->GetResourceTypeById(texPattern1) == FOURCC('TXTR'))
 | |
|     x10_texPattern1 = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), texPattern1});
 | |
|   if (g_ResFactory->GetResourceTypeById(texPattern2) == FOURCC('TXTR'))
 | |
|     x20_texPattern2 = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), texPattern2});
 | |
|   if (g_ResFactory->GetResourceTypeById(texColor) == FOURCC('TXTR'))
 | |
|     x30_texColor = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), texColor});
 | |
| }
 | |
| 
 | |
| float CFluidPlane::ProjectRippleVelocity(float baseI, float velDot) const {
 | |
|   float tmp = 0.5f * baseI * velDot * velDot;
 | |
|   if (tmp != 0.f)
 | |
|     tmp = std::sqrt(tmp);
 | |
|   if (tmp >= 160.f)
 | |
|     return 1.f;
 | |
|   return tmp / 160.f;
 | |
| }
 | |
| 
 | |
| float CFluidPlane::CalculateRippleIntensity(float baseI) const {
 | |
|   float mul = 0.0f;
 | |
|   switch (x44_fluidType) {
 | |
|   case EFluidType::NormalWater:
 | |
|     mul = g_tweakGame->GetRippleIntensityNormal();
 | |
|     break;
 | |
|   case EFluidType::PoisonWater:
 | |
|     mul = g_tweakGame->GetRippleIntensityPoison();
 | |
|     break;
 | |
|   case EFluidType::Lava:
 | |
|     mul = g_tweakGame->GetRippleIntensityLava();
 | |
|     break;
 | |
|   case EFluidType::PhazonFluid:
 | |
|   case EFluidType::Four:
 | |
|     mul = 0.8f;
 | |
|     break;
 | |
|   case EFluidType::ThickLava:
 | |
|     mul = 1.f;
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   return zeus::clamp(0.f, baseI * mul * (1.f - x48_rippleIntensity + 0.5f), 1.f);
 | |
| }
 | |
| 
 | |
| void CFluidPlane::AddRipple(float mag, TUniqueId rippler, const zeus::CVector3f& center, CScriptWater& water,
 | |
|                             CStateManager& mgr) {
 | |
|   if (!water.CanRippleAtPoint(center))
 | |
|     return;
 | |
| 
 | |
|   mag = CalculateRippleIntensity(mag);
 | |
|   mgr.GetFluidPlaneManager()->RippleManager().AddRipple(CRipple(rippler, center, mag));
 | |
| }
 | |
| 
 | |
| void CFluidPlane::AddRipple(float intensity, TUniqueId rippler, const zeus::CVector3f& center,
 | |
|                             const zeus::CVector3f& velocity, const CScriptWater& water, CStateManager& mgr,
 | |
|                             const zeus::CVector3f& upVec) {
 | |
|   if (!water.CanRippleAtPoint(center))
 | |
|     return;
 | |
| 
 | |
|   intensity = CalculateRippleIntensity(ProjectRippleVelocity(intensity, upVec.dot(velocity)));
 | |
|   mgr.GetFluidPlaneManager()->RippleManager().AddRipple(CRipple(rippler, center, intensity));
 | |
| }
 | |
| 
 | |
| void CFluidPlane::AddRipple(const CRipple& ripple, const CScriptWater& water, CStateManager& mgr) {
 | |
|   if (!water.CanRippleAtPoint(ripple.GetCenter()))
 | |
|     return;
 | |
|   mgr.GetFluidPlaneManager()->RippleManager().AddRipple(ripple);
 | |
| }
 | |
| 
 | |
| void CFluidPlane::RenderStripWithRipples(float curY, const Heights& heights, const Flags& flags, int startYDiv,
 | |
|                                          const CFluidPlaneRender::SPatchInfo& info,
 | |
|                                          std::vector<CFluidPlaneShader::Vertex>& vOut,
 | |
|                                          std::vector<CFluidPlaneShader::PatchVertex>& pvOut) {
 | |
|   m_shader->bindRegular();
 | |
| 
 | |
|   int yTile = (startYDiv + CFluidPlaneRender::numSubdivisionsInTile - 1) / CFluidPlaneRender::numSubdivisionsInTile;
 | |
|   int endXTile =
 | |
|       (info.x0_xSubdivs + CFluidPlaneRender::numSubdivisionsInTile - 4) / CFluidPlaneRender::numSubdivisionsInTile;
 | |
| 
 | |
|   int midDiv = CFluidPlaneRender::numSubdivisionsInTile / 2;
 | |
|   float tileMid = info.x18_rippleResolution * midDiv;
 | |
|   float yMin = curY;
 | |
|   float yMid = curY + tileMid;
 | |
| 
 | |
|   float curX = info.x4_localMin.x();
 | |
|   int gridCell = info.x28_tileX + info.x2a_gridDimX * (info.x2e_tileY + yTile - 1);
 | |
|   int xTile = 1;
 | |
|   int tileSpan;
 | |
|   for (int i = 1; i < info.x0_xSubdivs - 2; i += CFluidPlaneRender::numSubdivisionsInTile * tileSpan,
 | |
|            gridCell += tileSpan, xTile += tileSpan, curX += info.x14_tileSize * tileSpan) {
 | |
|     tileSpan = 1;
 | |
|     if (info.x30_gridFlags && !info.x30_gridFlags[gridCell])
 | |
|       continue;
 | |
| 
 | |
|     if ((flags[yTile][xTile] & 0x1f) == 0x1f) {
 | |
|       for (; xTile + tileSpan <= endXTile; ++tileSpan) {
 | |
|         if ((flags[yTile][xTile + tileSpan] & 0x1f) != 0x1f)
 | |
|           break;
 | |
|         if (info.x30_gridFlags && !info.x30_gridFlags[gridCell + tileSpan])
 | |
|           break;
 | |
|       }
 | |
| 
 | |
|       int stripDivCount = tileSpan * CFluidPlaneRender::numSubdivisionsInTile + 1;
 | |
|       int remSubdivs = CFluidPlaneRender::numSubdivisionsInTile;
 | |
|       std::function<void(float x, float y, const CFluidPlaneRender::SHFieldSample& samp)> func;
 | |
| 
 | |
|       switch (info.x37_normalMode) {
 | |
|       case CFluidPlaneRender::NormalMode::None:
 | |
|         func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp) {
 | |
|           vOut.emplace_back(zeus::CVector3f(x, y, samp.height));
 | |
|         };
 | |
|         break;
 | |
|       case CFluidPlaneRender::NormalMode::NoNormals:
 | |
|         func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp) {
 | |
|           vOut.emplace_back(zeus::CVector3f(x, y, samp.height), samp.MakeColor(info));
 | |
|         };
 | |
|         break;
 | |
|       case CFluidPlaneRender::NormalMode::Normals:
 | |
|         func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp) {
 | |
|           vOut.emplace_back(zeus::CVector3f(x, y, samp.height), samp.MakeNormal(), samp.MakeColor(info));
 | |
|         };
 | |
|         break;
 | |
|       case CFluidPlaneRender::NormalMode::NBT:
 | |
|         func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp) {
 | |
|           vOut.emplace_back(zeus::CVector3f(x, y, samp.height), samp.MakeNormal(), samp.MakeBinormal(),
 | |
|                             samp.MakeTangent(), samp.MakeColor(info));
 | |
|         };
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       float curTileY = yMin;
 | |
|       int curYDiv = startYDiv;
 | |
|       for (; remSubdivs > 0; --remSubdivs, ++curYDiv, curTileY += info.x18_rippleResolution) {
 | |
|         size_t start = vOut.size();
 | |
|         float curTileX = curX;
 | |
|         for (int v = 0; v < stripDivCount; ++v) {
 | |
|           func(curTileX, curTileY, heights[curYDiv][i + v]);
 | |
|           func(curTileX, curTileY + info.x18_rippleResolution, heights[curYDiv + 1][i + v]);
 | |
|           curTileX += info.x18_rippleResolution;
 | |
|         }
 | |
| //        CGraphics::DrawArray(start, vOut.size() - start);
 | |
|       }
 | |
|     } else {
 | |
|       bool r19 = (flags[yTile + 1][xTile] & 0x2) != 0; // North
 | |
|       bool r16 = (flags[yTile][xTile - 1] & 0x8) != 0; // West
 | |
|       bool r18 = (flags[yTile][xTile + 1] & 0x4) != 0; // East
 | |
|       bool r17 = (flags[yTile - 1][xTile] & 0x1) != 0; // South
 | |
| 
 | |
|       int r6 = (r19 ? CFluidPlaneRender::numSubdivisionsInTile : 1) + 2;
 | |
|       r6 += r18 ? CFluidPlaneRender::numSubdivisionsInTile : 1;
 | |
|       r6 += r17 ? CFluidPlaneRender::numSubdivisionsInTile : 1;
 | |
|       r6 += r16 ? CFluidPlaneRender::numSubdivisionsInTile : 1;
 | |
| 
 | |
|       if (r6 == 6 && (info.x37_normalMode == CFluidPlaneRender::NormalMode::Normals ||
 | |
|                       info.x37_normalMode == CFluidPlaneRender::NormalMode::NBT)) {
 | |
|         for (; xTile + tileSpan <= endXTile; ++tileSpan) {
 | |
|           if ((flags[yTile][xTile + tileSpan] & 0x1f) == 0x1f)
 | |
|             break;
 | |
|           if (info.x30_gridFlags && !info.x30_gridFlags[gridCell + tileSpan])
 | |
|             break;
 | |
|           if ((flags[yTile + 1][xTile + tileSpan] & 0x2) != 0x0)
 | |
|             break;
 | |
|           if ((flags[yTile][xTile + tileSpan + 1] & 0x4) != 0x0)
 | |
|             break;
 | |
|           if ((flags[yTile - 1][xTile + tileSpan] & 0x1) != 0x0)
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         int stripDivCount = tileSpan + 1;
 | |
|         size_t start = vOut.size();
 | |
|         switch (info.x37_normalMode) {
 | |
|         case CFluidPlaneRender::NormalMode::Normals: {
 | |
|           int curYDiv0 = startYDiv;
 | |
|           int curYDiv1 = startYDiv + CFluidPlaneRender::numSubdivisionsInTile;
 | |
|           float curTileX = curX;
 | |
|           for (int v = 0; v < stripDivCount; ++v) {
 | |
|             int curXDiv = v * CFluidPlaneRender::numSubdivisionsInTile + i;
 | |
|             const CFluidPlaneRender::SHFieldSample& samp0 = heights[curYDiv0][curXDiv];
 | |
|             const CFluidPlaneRender::SHFieldSample& samp1 = heights[curYDiv1][curXDiv];
 | |
|             vOut.emplace_back(zeus::CVector3f(curTileX, yMin, samp0.height), samp0.MakeNormal(), samp0.MakeColor(info));
 | |
|             vOut.emplace_back(zeus::CVector3f(curTileX, yMin + info.x14_tileSize, samp1.height), samp1.MakeNormal(),
 | |
|                               samp1.MakeColor(info));
 | |
|             curTileX += info.x14_tileSize;
 | |
|           }
 | |
|           break;
 | |
|         }
 | |
|         case CFluidPlaneRender::NormalMode::NBT: {
 | |
|           int curYDiv0 = startYDiv;
 | |
|           int curYDiv1 = startYDiv + CFluidPlaneRender::numSubdivisionsInTile;
 | |
|           float curTileX = curX;
 | |
|           for (int v = 0; v < stripDivCount; ++v) {
 | |
|             int curXDiv = v * CFluidPlaneRender::numSubdivisionsInTile + i;
 | |
|             const CFluidPlaneRender::SHFieldSample& samp0 = heights[curYDiv0][curXDiv];
 | |
|             const CFluidPlaneRender::SHFieldSample& samp1 = heights[curYDiv1][curXDiv];
 | |
|             vOut.emplace_back(zeus::CVector3f(curTileX, yMin, samp0.height), samp0.MakeNormal(), samp0.MakeBinormal(),
 | |
|                               samp0.MakeTangent(), samp0.MakeColor(info));
 | |
|             vOut.emplace_back(zeus::CVector3f(curTileX, yMin + info.x14_tileSize, samp1.height), samp1.MakeNormal(),
 | |
|                               samp1.MakeBinormal(), samp1.MakeTangent(), samp1.MakeColor(info));
 | |
|             curTileX += info.x14_tileSize;
 | |
|           }
 | |
|           break;
 | |
|         }
 | |
|         default:
 | |
|           break;
 | |
|         }
 | |
| //        CGraphics::DrawArray(start, vOut.size() - start);
 | |
|       } else {
 | |
|         TriFanToStrip<CFluidPlaneShader::Vertex> toStrip(vOut);
 | |
|         std::function<void(float x, float y, const CFluidPlaneRender::SHFieldSample& samp)> func;
 | |
| 
 | |
|         switch (info.x37_normalMode) {
 | |
|         case CFluidPlaneRender::NormalMode::None:
 | |
|           func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp) {
 | |
|             toStrip.EmplaceVert(zeus::CVector3f(x, y, samp.height));
 | |
|           };
 | |
|           break;
 | |
|         case CFluidPlaneRender::NormalMode::NoNormals:
 | |
|           func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp) {
 | |
|             toStrip.EmplaceVert(zeus::CVector3f(x, y, samp.height), samp.MakeColor(info));
 | |
|           };
 | |
|           break;
 | |
|         case CFluidPlaneRender::NormalMode::Normals:
 | |
|           func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp) {
 | |
|             toStrip.EmplaceVert(zeus::CVector3f(x, y, samp.height), samp.MakeNormal(), samp.MakeColor(info));
 | |
|           };
 | |
|           break;
 | |
|         case CFluidPlaneRender::NormalMode::NBT:
 | |
|           func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp) {
 | |
|             toStrip.EmplaceVert(zeus::CVector3f(x, y, samp.height), samp.MakeNormal(), samp.MakeBinormal(),
 | |
|                                 samp.MakeTangent(), samp.MakeColor(info));
 | |
|           };
 | |
|           break;
 | |
|         }
 | |
| 
 | |
|         func(tileMid + curX, yMid, heights[startYDiv + midDiv][i + midDiv]);
 | |
| 
 | |
|         int curXDiv = i;
 | |
|         int curYDiv = startYDiv + CFluidPlaneRender::numSubdivisionsInTile;
 | |
|         float curTileX = curX;
 | |
|         float curTileY = yMin + info.x14_tileSize;
 | |
|         for (int v = 0; v < (r19 ? CFluidPlaneRender::numSubdivisionsInTile : 1); ++v) {
 | |
|           const CFluidPlaneRender::SHFieldSample& samp = heights[curYDiv][curXDiv + v];
 | |
|           func(curTileX, curTileY, samp);
 | |
|           curTileX += info.x18_rippleResolution;
 | |
|         }
 | |
| 
 | |
|         curXDiv = i + CFluidPlaneRender::numSubdivisionsInTile;
 | |
|         curYDiv = startYDiv + CFluidPlaneRender::numSubdivisionsInTile;
 | |
|         curTileX = curX + info.x14_tileSize;
 | |
|         curTileY = yMin + info.x14_tileSize;
 | |
|         for (int v = 0; v < (r18 ? CFluidPlaneRender::numSubdivisionsInTile : 1); ++v) {
 | |
|           const CFluidPlaneRender::SHFieldSample& samp = heights[curYDiv - v][curXDiv];
 | |
|           func(curTileX, curTileY, samp);
 | |
|           curTileY -= info.x18_rippleResolution;
 | |
|         }
 | |
| 
 | |
|         curXDiv = i + CFluidPlaneRender::numSubdivisionsInTile;
 | |
|         curYDiv = startYDiv;
 | |
|         curTileX = curX + info.x14_tileSize;
 | |
|         curTileY = yMin;
 | |
|         for (int v = 0; v < (r17 ? CFluidPlaneRender::numSubdivisionsInTile : 1); ++v) {
 | |
|           const CFluidPlaneRender::SHFieldSample& samp = heights[curYDiv][curXDiv - v];
 | |
|           func(curTileX, curTileY, samp);
 | |
|           curTileX -= info.x18_rippleResolution;
 | |
|         }
 | |
| 
 | |
|         curXDiv = i;
 | |
|         curYDiv = startYDiv;
 | |
|         curTileX = curX;
 | |
|         curTileY = yMin;
 | |
|         if (r16) {
 | |
|           for (int v = 0; v < CFluidPlaneRender::numSubdivisionsInTile + 1; ++v) {
 | |
|             const CFluidPlaneRender::SHFieldSample& samp = heights[curYDiv + v][curXDiv];
 | |
|             func(curTileX, curTileY, samp);
 | |
|             curTileY += info.x18_rippleResolution;
 | |
|           }
 | |
|         } else {
 | |
|           {
 | |
|             const CFluidPlaneRender::SHFieldSample& samp = heights[curYDiv][curXDiv];
 | |
|             func(curTileX, curTileY, samp);
 | |
|           }
 | |
|           curTileY += info.x14_tileSize;
 | |
|           {
 | |
|             const CFluidPlaneRender::SHFieldSample& samp =
 | |
|                 heights[curYDiv + CFluidPlaneRender::numSubdivisionsInTile][curXDiv];
 | |
|             func(curTileX, curTileY, samp);
 | |
|           }
 | |
|         }
 | |
| 
 | |
| //        toStrip.Draw();
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| void CFluidPlane::RenderPatch(const CFluidPlaneRender::SPatchInfo& info, const Heights& heights, const Flags& flags,
 | |
|                               bool noRipples, bool flagIs1, std::vector<CFluidPlaneShader::Vertex>& vOut,
 | |
|                               std::vector<CFluidPlaneShader::PatchVertex>& pvOut) {
 | |
|   OPTICK_EVENT();
 | |
|   if (noRipples) {
 | |
|     m_shader->bindRegular();
 | |
| 
 | |
|     float xMin = info.x4_localMin.x();
 | |
|     float yMin = info.x4_localMin.y();
 | |
|     float xMax = info.x18_rippleResolution * (info.x0_xSubdivs - 2) + xMin;
 | |
|     float yMax = info.x18_rippleResolution * (info.x1_ySubdivs - 2) + yMin;
 | |
| 
 | |
|     switch (info.x37_normalMode) {
 | |
|     case CFluidPlaneRender::NormalMode::None: {
 | |
|       size_t start = vOut.size();
 | |
|       vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f));
 | |
|       vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f));
 | |
|       vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f));
 | |
|       vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f));
 | |
| //      CGraphics::DrawArray(start, 4);
 | |
|       break;
 | |
|     }
 | |
|     case CFluidPlaneRender::NormalMode::NoNormals: {
 | |
|       size_t start = vOut.size();
 | |
|       vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f), zeus::skBlack);
 | |
|       vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f), zeus::skBlack);
 | |
|       vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f), zeus::skBlack);
 | |
|       vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::skBlack);
 | |
| //      CGraphics::DrawArray(start, 4);
 | |
|       break;
 | |
|     }
 | |
|     case CFluidPlaneRender::NormalMode::Normals: {
 | |
|       int yTiles = (info.x1_ySubdivs - 3) / CFluidPlaneRender::numSubdivisionsInTile + 1;
 | |
|       int xTiles = (info.x0_xSubdivs - 3) / CFluidPlaneRender::numSubdivisionsInTile + 1;
 | |
|       int xTileStart = info.x28_tileX + info.x2e_tileY * info.x2a_gridDimX;
 | |
|       yMax = yMin;
 | |
|       for (int curYTile = yTiles; curYTile > 0;
 | |
|            --curYTile, yMax += info.x14_tileSize, xTileStart += info.x2a_gridDimX) {
 | |
|         xMax = xMin;
 | |
|         int nextXTile;
 | |
|         for (int curXTile = 0; curXTile < xTiles; curXTile = nextXTile) {
 | |
|           if (!info.x30_gridFlags || info.x30_gridFlags[xTileStart + curXTile]) {
 | |
|             if (curYTile == yTiles || curYTile == 1 || curXTile == 0 || xTiles - 1 == curXTile) {
 | |
|               TriFanToStrip<CFluidPlaneShader::Vertex> toStrip(vOut);
 | |
| 
 | |
|               toStrip.EmplaceVert(
 | |
|                   zeus::CVector3f(xMax + 0.5f * info.x14_tileSize, yMax + 0.5f * info.x14_tileSize, 0.f), zeus::skUp,
 | |
|                   zeus::skBlack);
 | |
| 
 | |
|               float tmp = xMax;
 | |
|               for (int v = 0; v < ((curYTile == 1) ? CFluidPlaneRender::numSubdivisionsInTile : 1); ++v) {
 | |
|                 toStrip.EmplaceVert(zeus::CVector3f(tmp, yMax + info.x14_tileSize, 0.f), zeus::skUp, zeus::skBlack);
 | |
|                 tmp += info.x18_rippleResolution;
 | |
|               }
 | |
| 
 | |
|               tmp = yMax + info.x14_tileSize;
 | |
|               for (int v = 0; v < ((xTiles - 1 == curXTile) ? CFluidPlaneRender::numSubdivisionsInTile : 1); ++v) {
 | |
|                 toStrip.EmplaceVert(zeus::CVector3f(xMax + info.x14_tileSize, tmp, 0.f), zeus::skUp, zeus::skBlack);
 | |
|                 tmp -= info.x18_rippleResolution;
 | |
|               }
 | |
| 
 | |
|               tmp = xMax + info.x14_tileSize;
 | |
|               for (int v = 0; v < ((curYTile == yTiles) ? CFluidPlaneRender::numSubdivisionsInTile : 1); ++v) {
 | |
|                 toStrip.EmplaceVert(zeus::CVector3f(tmp, yMax, 0.f), zeus::skUp, zeus::skBlack);
 | |
|                 tmp -= info.x18_rippleResolution;
 | |
|               }
 | |
| 
 | |
|               tmp = yMax;
 | |
|               for (int v = 0; v < ((curXTile == 0) ? CFluidPlaneRender::numSubdivisionsInTile : 1); ++v) {
 | |
|                 toStrip.EmplaceVert(zeus::CVector3f(xMax, tmp, 0.f), zeus::skUp, zeus::skBlack);
 | |
|                 tmp += info.x18_rippleResolution;
 | |
|               }
 | |
| 
 | |
|               toStrip.EmplaceVert(zeus::CVector3f(xMax, yMax + info.x14_tileSize, 0.f), zeus::skUp, zeus::skBlack);
 | |
| 
 | |
| //              toStrip.Draw();
 | |
| 
 | |
|               nextXTile = curXTile + 1;
 | |
|               xMax += info.x14_tileSize;
 | |
|             } else {
 | |
|               nextXTile = curXTile + 1;
 | |
|               while (nextXTile < xTiles - 1 && (!info.x30_gridFlags || info.x30_gridFlags[xTileStart + nextXTile]))
 | |
|                 ++nextXTile;
 | |
| 
 | |
|               size_t start = vOut.size();
 | |
|               for (int v = 0; v < nextXTile - curXTile + 1; ++v) {
 | |
|                 vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::skUp, zeus::skBlack);
 | |
|                 vOut.emplace_back(zeus::CVector3f(xMax, yMax + info.x14_tileSize, 0.f), zeus::skUp, zeus::skBlack);
 | |
|                 xMax += info.x14_tileSize;
 | |
|               }
 | |
| //              CGraphics::DrawArray(start, vOut.size() - start);
 | |
| 
 | |
|               ++nextXTile;
 | |
|               if (nextXTile == xTiles) {
 | |
|                 --nextXTile;
 | |
|                 xMax -= info.x14_tileSize;
 | |
|               }
 | |
|             }
 | |
|           } else {
 | |
|             nextXTile = curXTile + 1;
 | |
|             xMax += info.x14_tileSize;
 | |
|             while (nextXTile < xTiles && !info.x30_gridFlags[xTileStart + nextXTile]) {
 | |
|               xMax += info.x14_tileSize;
 | |
|               ++nextXTile;
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       break;
 | |
|     }
 | |
|     case CFluidPlaneRender::NormalMode::NBT: {
 | |
|       if (flagIs1 || !info.x30_gridFlags) {
 | |
|         size_t start = vOut.size();
 | |
|         vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f), zeus::skUp, zeus::skForward, zeus::skRight, zeus::skBlack);
 | |
|         vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f), zeus::skUp, zeus::skForward, zeus::skRight, zeus::skBlack);
 | |
|         vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f), zeus::skUp, zeus::skForward, zeus::skRight, zeus::skBlack);
 | |
|         vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::skUp, zeus::skForward, zeus::skRight, zeus::skBlack);
 | |
| //        CGraphics::DrawArray(start, 4);
 | |
|       } else {
 | |
|         int xTiles = (info.x0_xSubdivs - 3) / CFluidPlaneRender::numSubdivisionsInTile + 1;
 | |
|         int yTiles = (info.x1_ySubdivs - 3) / CFluidPlaneRender::numSubdivisionsInTile + 1;
 | |
|         int xTileStart = info.x28_tileX + info.x2e_tileY * info.x2a_gridDimX;
 | |
|         for (; yTiles > 0; --yTiles, yMin += info.x14_tileSize, xTileStart += info.x2a_gridDimX) {
 | |
|           xMax = xMin;
 | |
|           int nextXTile;
 | |
|           for (int curXTile = 0; curXTile < xTiles; curXTile = nextXTile) {
 | |
|             if (info.x30_gridFlags[xTileStart + curXTile]) {
 | |
|               nextXTile = curXTile + 1;
 | |
|               int tile = xTileStart + nextXTile;
 | |
|               while (nextXTile < xTiles && info.x30_gridFlags[tile]) {
 | |
|                 ++nextXTile;
 | |
|                 ++tile;
 | |
|               }
 | |
| 
 | |
|               size_t start = vOut.size();
 | |
|               for (int v = 0; v < nextXTile - curXTile + 1; ++v) {
 | |
|                 vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f), zeus::skUp, zeus::skForward, zeus::skRight,
 | |
|                                   zeus::skBlack);
 | |
|                 vOut.emplace_back(zeus::CVector3f(xMax, yMin + info.x14_tileSize, 0.f), zeus::skUp, zeus::skForward,
 | |
|                                   zeus::skRight, zeus::skBlack);
 | |
|                 xMax += info.x14_tileSize;
 | |
|               }
 | |
| //              CGraphics::DrawArray(start, vOut.size() - start);
 | |
|             } else {
 | |
|               nextXTile = curXTile + 1;
 | |
|               xMax += info.x14_tileSize;
 | |
|               int tile = xTileStart + nextXTile;
 | |
|               while (nextXTile < xTiles && !info.x30_gridFlags[tile]) {
 | |
|                 xMax += info.x14_tileSize;
 | |
|                 ++nextXTile;
 | |
|                 ++tile;
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       break;
 | |
|     }
 | |
|     }
 | |
|   } else {
 | |
|     float curY = info.x4_localMin.y();
 | |
|     for (int startYDiv = 1; startYDiv < info.x1_ySubdivs - 2;
 | |
|          startYDiv += CFluidPlaneRender::numSubdivisionsInTile, curY += info.x14_tileSize)
 | |
|       RenderStripWithRipples(curY, heights, flags, startYDiv, info, vOut, pvOut);
 | |
|   }
 | |
| }
 | |
| 
 | |
| } // namespace metaforce
 |