Skip to content

Commit

Permalink
Initial lights
Browse files Browse the repository at this point in the history
  • Loading branch information
Lyuu17 committed Jun 27, 2024
1 parent bf66760 commit 3e31e8c
Show file tree
Hide file tree
Showing 15 changed files with 198 additions and 36 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ target_sources(${PROJECT_NAME}
"SWBF2/Native/Chunks/ChunkProcessor.cpp"
"SWBF2/Native/Chunks/ConfigReader.cpp"
"SWBF2/Native/Chunks/LevelChunk.cpp"
"SWBF2/Native/Chunks/LightChunk.cpp"
"SWBF2/Native/Chunks/LoclChunk.cpp"
"SWBF2/Native/Chunks/ModelChunk.cpp"
"SWBF2/Native/Chunks/ModelSegmentChunk.cpp"
Expand Down
2 changes: 1 addition & 1 deletion src/SWBF2/FNVHash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace SWBF2::Native
{
enum class FNVHash : uint32_t;
typedef uint32_t FNVHash;

constexpr FNVHash FNVGenerateHash(const std::string &str)
{
Expand Down
52 changes: 41 additions & 11 deletions src/SWBF2/Level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
#include <godot_cpp/classes/world_environment.hpp>
#include <godot_cpp/classes/sky.hpp>
#include <godot_cpp/classes/procedural_sky_material.hpp>
#include <godot_cpp/classes/directional_light3d.hpp>
#include <godot_cpp/variant/color.hpp>

#include "Native/Chunks/ChunkProcessor.hpp"
#include "Native/Models/ModelUtils.hpp"
#include "Native/Hashes.hpp"
#include "Native/SWBF2.hpp"

#include "Level.hpp"
Expand All @@ -25,7 +27,8 @@ namespace SWBF2
throw std::runtime_error{ "failed to load the game level" };

LoadLevelInstances();
LoadSkybox();
LoadWorldEnvironment();
LoadLights();
}

godot::MeshInstance3D *Level::LoadModel(const std::string &id)
Expand Down Expand Up @@ -139,27 +142,54 @@ namespace SWBF2
}
}

void Level::LoadSkybox()
void Level::LoadWorldEnvironment()
{
godot::WorldEnvironment *worldEnv = memnew(godot::WorldEnvironment);
godot::Environment *env = memnew(godot::Environment);
godot::Sky *sky = memnew(godot::Sky);
{
worldEnv->set_name("WorldEnvironment");

godot::Environment *env = memnew(godot::Environment);
{
godot::Sky *sky = memnew(godot::Sky);
{
auto &texture = Native::SWBF2::m_tex[Native::SWBF2::m_skyDome.m_texture].m_formats[0].m_faceLevels[0].m_gdTexture;
godot::ProceduralSkyMaterial *procSkyMaterial = memnew(godot::ProceduralSkyMaterial);
procSkyMaterial->set_sky_cover(texture);

auto &texture = Native::SWBF2::m_tex[Native::SWBF2::m_skyDome.m_texture].m_formats[0].m_faceLevels[0].m_gdTexture;
godot::ProceduralSkyMaterial *procSkyMaterial = memnew(godot::ProceduralSkyMaterial);
procSkyMaterial->set_sky_cover(texture);
sky->set_material(procSkyMaterial);
}

sky->set_material(procSkyMaterial);
env->set_background(godot::Environment::BG_SKY);
env->set_sky(sky);
}

env->set_background(godot::Environment::BG_SKY);
env->set_sky(sky);
worldEnv->set_environment(env);
worldEnv->set_environment(env);
}

add_child(worldEnv);

worldEnv->set_owner(this->get_parent());
}

void Level::LoadLights()
{
for (const auto &[id, light] : SWBF2::Native::SWBF2::m_lights)
{
godot::DirectionalLight3D *directionalLight3D = memnew(godot::DirectionalLight3D);
directionalLight3D->set_name(light.m_name.c_str());
directionalLight3D->set_position(light.m_position);
directionalLight3D->set_rotation(light.m_rotation.get_euler());
directionalLight3D->set_color(light.m_color);
directionalLight3D->set_shadow(light.m_castShadow);
directionalLight3D->set_param(godot::Light3D::PARAM_SPECULAR, light.m_castSpecular);
directionalLight3D->set_param(godot::Light3D::PARAM_RANGE, light.m_range);

add_child(directionalLight3D);

directionalLight3D->set_owner(get_parent());
}
}

void Level::_process(double delta_time)
{
}
Expand Down
3 changes: 2 additions & 1 deletion src/SWBF2/Level.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ namespace SWBF2

godot::MeshInstance3D *LoadModel(const std::string &id);
void LoadLevelInstances();
void LoadSkybox();
void LoadWorldEnvironment();
void LoadLights();

void _process(double delta_time) override;

Expand Down
4 changes: 3 additions & 1 deletion src/SWBF2/Native/Chunks/ChunkProcessor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "TextureChunk.hpp"
#include "LevelChunk.hpp"
#include "SkyChunk.hpp"
#include "LightChunk.hpp"

namespace SWBF2::Native
{
Expand All @@ -27,7 +28,8 @@ namespace SWBF2::Native
{ "Locl"_m, LoclChunk::ProcessChunk },
{ "tex_"_m, TextureChunk::ProcessChunk },
{ "lvl_"_m, LevelChunk::ProcessChunk },
{ "sky_"_m, SkyChunk::ProcessChunk }
{ "sky_"_m, SkyChunk::ProcessChunk },
{ "lght"_m, LightChunk::ProcessChunk }
};

static void ProcessChunk(StreamReader &streamReader, StreamReader &parentReader);
Expand Down
31 changes: 23 additions & 8 deletions src/SWBF2/Native/Chunks/ConfigReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,13 @@
namespace SWBF2::Native
{
ConfigReader::ConfigReader(StreamReader &streamReader)
: m_data({})
: m_nameHash(0), m_data({})
{
auto nameReaderChild = streamReader.ReadChildWithHeader<"NAME"_m>();

if (nameReaderChild.has_value())
{
uint32_t nameHash;
*nameReaderChild >> nameHash;

m_name = GameHashes.contains(nameHash) ? GameHashes.at(nameHash) : "unknown";
*nameReaderChild >> m_nameHash;
}

while (streamReader.IsNextHeader<"DATA"_m>())
Expand All @@ -31,12 +28,30 @@ namespace SWBF2::Native
{
auto dataReaderChild = streamReader.ReadChildWithHeader<"DATA"_m>();
{
FNVHash hash;
*dataReaderChild >> hash;
#pragma pack(push, 1)
struct {
FNVHash hash;
uint8_t count;
} data;
#pragma pack(pop)

*dataReaderChild >> data;

auto &node = parentConfigNode.createNode(data.hash);
if (data.count > 0)
{
uint32_t stringSize;
*dataReaderChild >> stringSize;

dataReaderChild->SkipBytes(sizeof(FNVHash) * data.count);

node.m_string.resize(stringSize);
*dataReaderChild >> node.m_string;
}

auto scopReaderChild = streamReader.ReadChildWithHeader<"SCOP"_m>();
{
ReadDataScop(*scopReaderChild, parentConfigNode.createNode(hash));
ReadDataScop(*scopReaderChild, node);
}
}
}
Expand Down
17 changes: 16 additions & 1 deletion src/SWBF2/Native/Chunks/ConfigReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ namespace SWBF2::Native
float m_float;
std::string m_string;
std::vector<float> m_vecFloat;

inline godot::Vector3 ToVector3() const
{
return godot::Vector3{ m_vecFloat.at(0), m_vecFloat.at(1), m_vecFloat.at(2) };
}

inline godot::Quaternion ToQuaternion() const
{
return godot::Quaternion{ m_vecFloat.at(0), m_vecFloat.at(1), m_vecFloat.at(2), m_vecFloat.at(3) };
}

inline godot::Color ToColor() const
{
return godot::Color{ m_vecFloat.at(0), m_vecFloat.at(1), m_vecFloat.at(2) };
}
};

class ConfigNode : public ConfigData {
Expand All @@ -42,7 +57,7 @@ namespace SWBF2::Native
public:
ConfigReader(StreamReader &streamReader);

std::string m_name;
uint32_t m_nameHash;

ConfigNode m_data;

Expand Down
69 changes: 69 additions & 0 deletions src/SWBF2/Native/Chunks/LightChunk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <godot_cpp/variant/utility_functions.hpp>

#include "Native/Chunks/ConfigReader.hpp"
#include "Native/Chunks/StreamReader.hpp"
#include "Native/Chunks/LightChunk.hpp"
#include "Native/SWBF2.hpp"

namespace SWBF2::Native
{
void LightChunk::ProcessChunk(StreamReader &streamReader)
{
ConfigReader configReader{ streamReader };

for (auto const &[id, node] : configReader.m_data.getNodes())
{
Light light{};
light.m_name = node->m_string;

for (auto const &[attr, val] : node->getNodes())
{
switch (attr)
{
case "Position"_fnv:
{
light.m_position = val->ToVector3();
break;
}

case "Rotation"_fnv:
{
light.m_rotation = val->ToQuaternion();
break;
}

case "Color"_fnv:
{
light.m_color = val->ToColor();
break;
}

case 0xe7e90aee: // CastShadow
{
light.m_castShadow = true;
break;
}

case 0x489162bb: // Specular
{
light.m_castSpecular = (bool)val->m_float;
break;
}

case 0xd290c23b: // Static
{
light.m_static = true;
break;
}

case 0x84e26526: // PS2BlendMode
case 0xbfe60da6: // TileUV
case 0x6ac627c1: // OffsetUV
break;
}
}

SWBF2::m_lights.emplace(light.m_name, light);
}
}
}
12 changes: 12 additions & 0 deletions src/SWBF2/Native/Chunks/LightChunk.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include "StreamReader.hpp"

namespace SWBF2::Native
{
class LightChunk {
public:
static void ProcessChunk(StreamReader &streamReader);
};

}
4 changes: 2 additions & 2 deletions src/SWBF2/Native/Hashes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ namespace SWBF2::Native
{
// taken from swbf2-unmunge

std::pair<std::uint32_t, std::string_view> operator""_fnvp(const char *str, std::size_t length)
std::pair<std::uint32_t, std::string> operator""_fnvp(const char *str, std::size_t length)
{
return { (uint32_t)FNVGenerateHash({str, length}), {str, length} };
}

const std::unordered_map<std::uint32_t, std::string_view> GameHashes
const std::unordered_map<std::uint32_t, std::string> GameHashes
{
"--AttachOdf"_fnvp,
"--AttachToHardPoint"_fnvp,
Expand Down
10 changes: 1 addition & 9 deletions src/SWBF2/Native/Hashes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,5 @@

namespace SWBF2::Native
{
// TODO?
enum class FNVHash : uint32_t
{
TEXTURE = "Texture"_fnv,
DOME_INFO = "DomeInfo"_fnv,
DOME_MODEL = "DomeModel"_fnv,
};

extern const std::unordered_map<uint32_t, std::string_view> GameHashes;
extern const std::unordered_map<uint32_t, std::string> GameHashes;
}
23 changes: 23 additions & 0 deletions src/SWBF2/Native/Light.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

#pragma once

#include "Models/Model.hpp"
#include "Texture/Texture.hpp"

#include "World.hpp"

namespace SWBF2::Native
{
class Light {
public:
std::string m_name;
godot::Vector3 m_position;
godot::Quaternion m_rotation;
uint32_t m_type;
godot::Color m_color;
bool m_castShadow;
bool m_static;
bool m_castSpecular;
float m_range;
};
}
1 change: 1 addition & 0 deletions src/SWBF2/Native/SWBF2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace SWBF2::Native

std::unordered_map<std::string, Level> SWBF2::m_levels;
std::unordered_map<std::string, World> SWBF2::m_worlds;
std::unordered_map<std::string, Light> SWBF2::m_lights;
std::unordered_map<std::string, Model> SWBF2::m_models;
std::unordered_map<std::string, Texture> SWBF2::m_tex;
std::unordered_map<std::string, SWBF2::LoclEntriesMap> SWBF2::m_locl;
Expand Down
3 changes: 2 additions & 1 deletion src/SWBF2/Native/SWBF2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Native/Texture/Texture.hpp"
#include "Native/Level.hpp"
#include "Native/SkyDome.hpp"
#include "Native/Light.hpp"

namespace SWBF2::Native
{
Expand All @@ -16,7 +17,7 @@ namespace SWBF2::Native

static std::unordered_map<std::string, Level> m_levels;
static std::unordered_map<std::string, World> m_worlds;

static std::unordered_map<std::string, Light> m_lights;
static std::unordered_map<std::string, Model> m_models;
static std::unordered_map<std::string, Texture> m_tex;

Expand Down
2 changes: 1 addition & 1 deletion src/SWBF2/Types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
namespace SWBF2
{
typedef uint32_t ChunkSize;

typedef uint32_t FNVHash;
typedef uint16_t SWBF2Handle;

constexpr auto SWBF2HANDLE_INVALID = 0xffff;
Expand Down

0 comments on commit 3e31e8c

Please sign in to comment.