feat(daynight): add DNSky class

This commit is contained in:
VDm 2025-07-27 23:06:12 +04:00
parent 45ceb6354b
commit add79bdc94
9 changed files with 369 additions and 2 deletions

View File

@ -58,6 +58,7 @@ void CWorld::Render() {
CRect rect;
CGWorldFrame::s_currentWorldFrame->GetRect(&rect);
CGWorldFrame::GetActiveCamera()->SetGxProjectionAndView(rect);
DayNight::Update();
DayNight::RenderSky();
GxRsPop();
}

View File

@ -0,0 +1 @@
#include "world/daynight/DNInfo.hpp"

View File

@ -0,0 +1,148 @@
#ifndef WORLD_DAY_NIGHT_INFO_HPP
#define WORLD_DAY_NIGHT_INFO_HPP
#include <cstdint>
#include <tempest/Vector.hpp>
class CM2Scene;
class CM2Model;
namespace DayNight {
class DNInfo {
public:
uint32_t unk0;
float dayProgression = 0.0f;
float day = 0.0f;
uint32_t unk3;
uint32_t unk4;
uint32_t unk5;
C3Vector cameraPos;
uint32_t unk9;
uint32_t unk10;
uint32_t unk11;
C3Vector cameraDir;
float faceAngle = 0.0f;
uint32_t unk16;
uint32_t unk17;
uint32_t unk18;
uint32_t unk19;
uint32_t unk20;
uint32_t unk21;
uint32_t unk22;
uint32_t unk23;
uint32_t unk24;
uint32_t unk25;
uint32_t unk26;
uint32_t unk27;
uint32_t unk28;
uint32_t unk29;
uint32_t unk30;
uint32_t unk31;
uint32_t unk32;
uint32_t unk33;
uint32_t unk34;
uint32_t unk35;
uint32_t unk36;
uint32_t unk37;
uint32_t unk38;
uint32_t unk39;
uint32_t unk40;
uint32_t unk41;
uint32_t unk42;
uint32_t unk43;
uint32_t unk44;
uint32_t unk45;
uint32_t unk46;
uint32_t unk47;
uint32_t unk48;
uint32_t unk49;
uint32_t unk50;
uint32_t unk51;
uint32_t unk52;
uint32_t unk53;
uint32_t unk54;
uint32_t unk55;
uint32_t unk56;
uint32_t unk57;
uint32_t unk58;
uint32_t unk59;
uint32_t unk60;
uint32_t unk61;
uint32_t unk62;
uint32_t unk63;
uint32_t unk64;
uint32_t unk65;
uint32_t unk66;
uint32_t unk67;
uint32_t unk68;
uint32_t unk69;
uint32_t unk70;
uint32_t unk71;
uint32_t unk72;
uint32_t unk73;
uint32_t unk74;
uint32_t unk75;
uint32_t unk76;
uint32_t unk77;
uint32_t unk78;
uint32_t unk79;
uint32_t unk80;
uint32_t unk81;
uint32_t unk82;
uint32_t unk83;
uint32_t unk84;
uint32_t unk85;
uint32_t unk86;
uint32_t unk87;
uint32_t unk88;
uint32_t unk89;
uint32_t unk90;
uint32_t unk91;
uint32_t unk92;
uint32_t unk93;
uint32_t unk94;
uint32_t unk95;
uint32_t unk96;
uint32_t unk97;
uint32_t unk98;
uint32_t unk99;
uint32_t unk100;
uint32_t unk101;
uint32_t unk102;
uint32_t unk103;
uint32_t unk104;
uint32_t unk105;
uint32_t unk106;
uint32_t unk107;
uint32_t unk108;
uint32_t unk109;
uint32_t unk110;
uint32_t unk111;
uint32_t unk112;
uint32_t unk113;
uint32_t unk114;
uint32_t showSky = 0;
uint32_t unk116;
uint32_t unk117;
float sunMoonPath = 0.0f;
uint32_t unk119;
uint32_t unk120;
uint32_t unk121;
uint32_t unk122;
uint32_t unk123;
uint32_t unk124;
uint32_t unk125;
uint32_t unk126;
uint32_t unk127;
uint32_t unk128;
uint32_t unk129;
uint32_t unk130;
uint32_t unk131;
uint32_t unk132;
};
} // namespace DayNight
#endif

View File

@ -0,0 +1,101 @@
#include "world/daynight/DNSky.hpp"
#include "gx/Device.hpp"
#include "gx/Transform.hpp"
#include "gx/RenderState.hpp"
#include "gx/Draw.hpp"
#include <tempest/Math.hpp>
#include <tempest/Matrix.hpp>
namespace DayNight {
float DNSky::m_stripSizes[SKY_NUMBANDS] = { 0.0f, 0.17f, 0.2f, 0.23f, 0.23999999f, 0.25f, 1.0f };
float DNSky::m_fadeAngle[SKY_NUMBANDS];
float DNSky::m_darkAngle[SKY_NUMBANDS];
void DNSky::Render() {
C44Matrix worldScale;
worldScale.Scale(6.6666665f);
GxXformPush(GxXform_World, worldScale);
GxRsPush();
GxRsSet(GxRs_Lighting, 0);
GxRsSet(GxRs_Fog, 0);
GxRsSet(GxRs_Culling, 0);
GxRsSet(GxRs_DepthWrite, 0);
GxRsSet(GxRs_BlendingMode, GxBlend_Add);
GxRsSetAlphaRef();
GxPrimVertexPtr(
this->m_nVerts, this->m_geoVerts.Ptr(), 12,
nullptr, 0,
this->m_clrVerts.Ptr(), 4,
nullptr, 0,
nullptr, 0);
GxDrawLockedElements(GxPrim_TriangleStrip, this->m_nIndices, this->m_indices.Ptr());
GxXformPop(GxXform_World);
GxRsPop();
}
void DNSky::GenSphere(float sphRadius) {
const int32_t geoSize = 24;
const int32_t idxSize = 25 * 2;
this->m_sphThetaTess = geoSize;
this->m_geoVerts.SetCount(SKY_NUMBANDS * geoSize); // 168
this->m_clrVerts.SetCount(SKY_NUMBANDS * geoSize); // 168
this->m_indices.SetCount(idxSize * (SKY_NUMBANDS - 1)); // 300
uint16_t lastGeoIndex = 0;
uint16_t lastIndex = 0;
for (int32_t i = 0; i < SKY_NUMBANDS; ++i) {
float phi = DNSky::m_stripSizes[i] * CMath::PI;
float v10 = 0.31830987f * phi;
int64_t v11 = static_cast<int64_t>(v10);
if (v10 <= 0.0f) {
v11 -= 1;
}
float v12 = 1.0f - (v10 - v11) * ((6.0f - (v10 - v11) * 4.0f) * (v10 - v11));
if (v11 & 1) {
v12 = -v12;
}
float v13 = 0.31830987f * phi - 0.5f;
int64_t v14 = static_cast<int64_t>(v13);
if (v13 <= 0.0f) {
v14 -= 1;
}
float v16 = 1.0f - (6.0f - 4.0f * (v13 - v14)) * (v13 - v14) * (v13 - v14);
if (v14 & 1) {
v16 = -v16;
}
for (int32_t j = 0; j < geoSize; ++j) {
auto& vertex = this->m_geoVerts[lastGeoIndex++];
float v19 = static_cast<float>(j) * 0.041666668f * 6.2831855f;
vertex.x = CMath::sinf(v19) * v16 * sphRadius;
vertex.y = v16 * CMath::cosf(v19) * sphRadius0;
vertex.z = sphRadius * v12 - CMath::cosf(0.7853981852531433f);
if (CMath::fequal(phi, 0.0f) || CMath::fequal(phi, CMath::PI)) {
break;
}
}
if (i > 0) {
for (uint16_t k = 0; k < 25; ++k) {
uint16_t idx1 = CMath::fequal(phi, 0.0f) ? 0 : (k % 24);
uint16_t idx2 = CMath::fequal(phi, CMath::PI) ? 0 : (k % 24);
this->m_indices[lastIndex++] = idx1 + lastGeoIndex;
this->m_indices[lastIndex++] = idx2 + lastGeoIndex;
}
}
}
this->m_nVerts = lastGeoIndex;
this->m_nIndices = lastIndex; // Should be always equal to 300
}
} // namespace DayNight

View File

@ -0,0 +1,34 @@
#ifndef WORLD_DAY_NIGHT_SKY_HPP
#define WORLD_DAY_NIGHT_SKY_HPP
#include <cstdint>
#include <storm/Array.hpp>
#include <tempest/Vector.hpp>
namespace DayNight {
class DNSky {
public:
enum {
SKY_NUMBANDS = 7
};
void Render();
void GenSphere(float sphRadius);
static float m_stripSizes[SKY_NUMBANDS];
static float m_fadeAngle[SKY_NUMBANDS];
static float m_darkAngle[SKY_NUMBANDS];
TSFixedArray<C3Vector> m_geoVerts;
TSFixedArray<CImVector> m_clrVerts;
TSFixedArray<uint16_t> m_indices;
int32_t m_sphThetaTess = 0;
uint16_t m_nVerts = 0;
uint16_t m_nIndices = 0;
float m_sphRadius = 0.0f;
};
} // namespace DayNight
#endif

View File

@ -1,9 +1,18 @@
#include "world/daynight/DNStars.hpp"
#include "world/daynight/DayNight.hpp"
#include "world/daynight/DNInfo.hpp"
#include "model/Model2.hpp"
#include <common/Time.hpp>
namespace DayNight {
C2Vector DNStars::m_fadeTable[4] = {
{ 0.1250f, 1.0f },
{ 0.1875f, 0.0f },
{ 0.9375f, 0.0f },
{ 1.0000f, 1.0f }
};
void DNStars::Initialize() {
this->m_scene = M2CreateScene();
this->m_model = this->m_scene->CreateModel("Environments\\Stars\\stars.mdl", 0);
@ -23,12 +32,17 @@ void DNStars::Destroy() {
}
void DNStars::Update() {
// TODO
auto info = DayNight::GetInfo();
this->m_pos = info->cameraPos;
auto fade = DayNight::InterpTable(DNStars::m_fadeTable, 4, info->dayProgression);
this->m_color.a = static_cast<uint8_t>(fade * 254.0 + 1.0);
}
void DNStars::Render() {
if (this->m_color.a < 2) {
//return;
return;
}
this->m_model->SetAnimating(1);
@ -36,6 +50,9 @@ void DNStars::Render() {
// TODO: this->m_model->SetSomething(1);
float alpha = static_cast<float>(this->m_color.a);
// TODO: this->m_model->SetAlpha(alpha * 0.0039215689f)
uint32_t elapsed = OsGetAsyncTimeMs() - this->m_time;
this->m_time += elapsed;
this->m_scene->AdvanceTime(elapsed);

View File

@ -19,6 +19,8 @@ class DNStars {
void Update();
void Render();
static C2Vector m_fadeTable[4];
CM2Scene* m_scene = nullptr;
CM2Model* m_model = nullptr;
CImVector m_color { 0 };

View File

@ -1,20 +1,72 @@
#include "world/daynight/DayNight.hpp"
#include "world/daynight/DNInfo.hpp"
#include "world/daynight/DNStars.hpp"
#include "world/daynight/DNSky.hpp"
#include "gx/Transform.hpp"
#include "gx/RenderState.hpp"
#include "gx/Draw.hpp"
#include "storm/Error.hpp"
namespace DayNight {
static DNInfo g_dnInfo;
static DNStars g_stars;
static DNSky g_sky;
float InterpTable(const C2Vector* table, uint32_t size, float key) {
STORM_ASSERT(size);
uint32_t i = 0;
uint32_t j = 0;
for (i = 0; i < size; ++i) {
if (key <= table[i].x) {
break;
}
}
if (i == size) {
i = 0;
j = size - 1;
} else if (i > 0) {
j = i - 1;
} else {
j = size - 1;
}
float v5 = table[i].x - table[j].x;
if (v5 < 0.0) {
v5 = v5 + 1.0;
}
float v6 = key - table[j].x;
if (v6 < 0.0) {
v6 = v6 + 1.0;
}
float v7 = v6 / v5;
if (table[i].y < table[j].y) {
return table[j].y - v7 * (table[j].y - table[i].y);
} else {
return table[j].y + v7 * (table[i].y - table[j].y);
}
}
void LoadMap(int32_t zoneID) {
// TODO
g_sky.GenSphere(1.0f);
g_stars.Initialize();
}
void Update() {
// TODO
g_stars.Update();
g_sky.Render();
}
void RenderSky() {
// TODO
@ -36,4 +88,8 @@ void RenderSky() {
g_stars.Render();
}
DNInfo* GetInfo() {
return &g_dnInfo;
}
} // namespace DayNight

View File

@ -3,10 +3,17 @@
#include <cstdint>
class C2Vector;
namespace DayNight {
class DNInfo;
float InterpTable(const C2Vector* table, uint32_t size, float key);
void LoadMap(int32_t zoneID);
void Update();
void RenderSky();
DNInfo* GetInfo();
} // namespace DayNight