mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
Material loading base
This commit is contained in:
parent
bc91738ee9
commit
82349d3432
@ -960,9 +960,9 @@ namespace IW4
|
||||
struct GfxImage
|
||||
{
|
||||
GfxTexture texture;
|
||||
char mapType;
|
||||
char semantic;
|
||||
char category;
|
||||
unsigned char mapType;
|
||||
unsigned char semantic;
|
||||
unsigned char category;
|
||||
bool useSrgbReads;
|
||||
Picmip picmip;
|
||||
bool noPicmip;
|
||||
|
@ -12,6 +12,7 @@ namespace IW4
|
||||
static constexpr const char* INFO_STRING_PREFIX_VEHICLE = "VEHICLEFILE";
|
||||
static constexpr const char* INFO_STRING_PREFIX_WEAPON = "WEAPONFILE";
|
||||
|
||||
static constexpr const char* GDF_FILENAME_MATERIAL = "material.gdf";
|
||||
static constexpr const char* GDF_FILENAME_PHYS_PRESET = "physpreset.gdf";
|
||||
static constexpr const char* GDF_FILENAME_TRACER = "tracer.gdf";
|
||||
static constexpr const char* GDF_FILENAME_VEHICLE = "vehicle.gdf";
|
||||
|
82
src/ObjLoading/AssetLoading/AbstractGdtEntryReader.cpp
Normal file
82
src/ObjLoading/AssetLoading/AbstractGdtEntryReader.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include "AbstractGdtEntryReader.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
GdtReadingException::GdtReadingException(std::string message)
|
||||
: exception(message.c_str()),
|
||||
m_message(std::move(message))
|
||||
{
|
||||
}
|
||||
|
||||
const char* GdtReadingException::what() const
|
||||
{
|
||||
return m_message.c_str();
|
||||
}
|
||||
|
||||
AbstractGdtEntryReader::AbstractGdtEntryReader(const GdtEntry& entry)
|
||||
: m_entry(entry)
|
||||
{
|
||||
}
|
||||
|
||||
std::string AbstractGdtEntryReader::ReadStringProperty(const std::string& propertyName, std::string defaultValue) const
|
||||
{
|
||||
const auto foundProperty = m_entry.m_properties.find(propertyName);
|
||||
if (foundProperty == m_entry.m_properties.end())
|
||||
return defaultValue;
|
||||
|
||||
return foundProperty->second;
|
||||
}
|
||||
|
||||
bool AbstractGdtEntryReader::ReadBoolProperty(const std::string& propertyName, const bool defaultValue) const
|
||||
{
|
||||
const auto foundProperty = m_entry.m_properties.find(propertyName);
|
||||
if (foundProperty == m_entry.m_properties.end())
|
||||
return defaultValue;
|
||||
|
||||
char* endPtr = nullptr;
|
||||
const auto result = std::strtol(foundProperty->second.c_str(), &endPtr, 10);
|
||||
if (endPtr != &foundProperty->second[foundProperty->second.size()])
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "\"" << foundProperty->second << "\" is not a valid boolean value";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
|
||||
return result != 0;
|
||||
}
|
||||
|
||||
int AbstractGdtEntryReader::ReadIntegerProperty(const std::string& propertyName, const int defaultValue) const
|
||||
{
|
||||
const auto foundProperty = m_entry.m_properties.find(propertyName);
|
||||
if (foundProperty == m_entry.m_properties.end())
|
||||
return defaultValue;
|
||||
|
||||
char* endPtr = nullptr;
|
||||
const auto result = std::strtol(foundProperty->second.c_str(), &endPtr, 10);
|
||||
if (endPtr != &foundProperty->second[foundProperty->second.size()])
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "\"" << foundProperty->second << "\" is not a valid integer value";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float AbstractGdtEntryReader::ReadFloatProperty(const std::string& propertyName, const float defaultValue) const
|
||||
{
|
||||
const auto foundProperty = m_entry.m_properties.find(propertyName);
|
||||
if (foundProperty == m_entry.m_properties.end())
|
||||
return defaultValue;
|
||||
|
||||
char* endPtr = nullptr;
|
||||
const auto result = std::strtof(foundProperty->second.c_str(), &endPtr);
|
||||
if (endPtr != &foundProperty->second[foundProperty->second.size()])
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "\"" << foundProperty->second << "\" is not a valid float value";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
29
src/ObjLoading/AssetLoading/AbstractGdtEntryReader.h
Normal file
29
src/ObjLoading/AssetLoading/AbstractGdtEntryReader.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "Obj/Gdt/GdtEntry.h"
|
||||
|
||||
class GdtReadingException : public std::exception
|
||||
{
|
||||
public:
|
||||
explicit GdtReadingException(std::string message);
|
||||
_NODISCARD const char* what() const override;
|
||||
|
||||
private:
|
||||
std::string m_message;
|
||||
};
|
||||
|
||||
class AbstractGdtEntryReader
|
||||
{
|
||||
protected:
|
||||
explicit AbstractGdtEntryReader(const GdtEntry& entry);
|
||||
|
||||
_NODISCARD std::string ReadStringProperty(const std::string& propertyName, std::string defaultValue = std::string()) const;
|
||||
_NODISCARD bool ReadBoolProperty(const std::string& propertyName, bool defaultValue = false) const;
|
||||
_NODISCARD int ReadIntegerProperty(const std::string& propertyName, int defaultValue = 0) const;
|
||||
_NODISCARD float ReadFloatProperty(const std::string& propertyName, float defaultValue = 0.0f) const;
|
||||
|
||||
const GdtEntry& m_entry;
|
||||
};
|
@ -1,13 +1,309 @@
|
||||
#include "AssetLoaderMaterial.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "ObjLoading.h"
|
||||
#include "AssetLoading/AbstractGdtEntryReader.h"
|
||||
#include "Game/IW4/CommonIW4.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Game/IW4/ObjConstantsIW4.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class MaterialGdtLoader : AbstractGdtEntryReader
|
||||
{
|
||||
public:
|
||||
MaterialGdtLoader(const GdtEntry& entry, MemoryManager* memory, IAssetLoadingManager* manager)
|
||||
: AbstractGdtEntryReader(entry),
|
||||
m_memory(memory),
|
||||
m_manager(manager),
|
||||
m_material(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
bool Load()
|
||||
{
|
||||
m_material = m_memory->Create<Material>();
|
||||
memset(m_material, 0, sizeof(Material));
|
||||
|
||||
m_material->info.name = m_memory->Dup(m_entry.m_name.c_str());
|
||||
material_template();
|
||||
|
||||
FinalizeMaterial();
|
||||
return true;
|
||||
}
|
||||
|
||||
_NODISCARD Material* GetMaterial() const
|
||||
{
|
||||
return m_material;
|
||||
}
|
||||
|
||||
_NODISCARD std::vector<XAssetInfoGeneric*> GetDependencies()
|
||||
{
|
||||
return std::move(m_dependencies);
|
||||
}
|
||||
|
||||
private:
|
||||
void material_template()
|
||||
{
|
||||
const auto materialType = ReadStringProperty("materialType");
|
||||
|
||||
if (materialType == "model phong" || materialType == "world phong" || materialType == "impact mark")
|
||||
{
|
||||
mtl_phong_template();
|
||||
}
|
||||
else if (materialType == "model ambient")
|
||||
{
|
||||
mtl_ambient_template();
|
||||
}
|
||||
else if (materialType == "2d")
|
||||
{
|
||||
mtl_2d_template();
|
||||
}
|
||||
else if (materialType == "model unlit" || materialType == "world unlit")
|
||||
{
|
||||
mtl_unlit_template();
|
||||
}
|
||||
else if (materialType == "unlit")
|
||||
{
|
||||
mtl_unlit_deprecated_template();
|
||||
}
|
||||
else if (materialType == "effect")
|
||||
{
|
||||
mtl_effect_template();
|
||||
}
|
||||
else if (materialType == "distortion")
|
||||
{
|
||||
mtl_distortion_template();
|
||||
}
|
||||
else if (materialType == "particle cloud")
|
||||
{
|
||||
mtl_particlecloud_template();
|
||||
}
|
||||
else if (materialType == "tools")
|
||||
{
|
||||
mtl_tools_template();
|
||||
}
|
||||
else if (materialType == "sky")
|
||||
{
|
||||
mtl_sky_template();
|
||||
}
|
||||
else if (materialType == "water")
|
||||
{
|
||||
mtl_water_template();
|
||||
}
|
||||
else if (materialType == "objective")
|
||||
{
|
||||
mtl_objective_template();
|
||||
}
|
||||
else if (materialType == "custom")
|
||||
{
|
||||
custom_template();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Unknown material type: \"" << materialType << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
void mtl_phong_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_ambient_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_2d_template()
|
||||
{
|
||||
commonsetup_template();
|
||||
|
||||
SetTechniqueSet("2d");
|
||||
|
||||
const auto colorMapName = ReadStringProperty("colorMap");
|
||||
|
||||
if (!colorMapName.empty())
|
||||
AddMapTexture("colorMap", TS_2D, colorMapName);
|
||||
else
|
||||
throw GdtReadingException("ColorMap may not be blank in 2d materials");
|
||||
}
|
||||
|
||||
void mtl_unlit_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_unlit_deprecated_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_effect_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_distortion_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_particlecloud_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_tools_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_sky_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_water_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_objective_template()
|
||||
{
|
||||
}
|
||||
|
||||
void custom_template()
|
||||
{
|
||||
const auto customTemplate = ReadStringProperty("customTemplate");
|
||||
|
||||
if (customTemplate == "mtl_custom")
|
||||
{
|
||||
mtl_custom_template();
|
||||
}
|
||||
else if (customTemplate == "mtl_phong_flag")
|
||||
{
|
||||
mtl_phong_flag_template();
|
||||
}
|
||||
else if (customTemplate == "mtl_grain_overlay")
|
||||
{
|
||||
mtl_grain_overlay_template();
|
||||
}
|
||||
else if (customTemplate == "mtl_effect_eyeoffset")
|
||||
{
|
||||
mtl_effect_eyeoffset_template();
|
||||
}
|
||||
else if (customTemplate == "mtl_reflexsight")
|
||||
{
|
||||
mtl_reflexsight_template();
|
||||
}
|
||||
else if (customTemplate == "mtl_shadowclear")
|
||||
{
|
||||
mtl_shadowclear_template();
|
||||
}
|
||||
else if (customTemplate == "mtl_shadowoverlay")
|
||||
{
|
||||
mtl_shadowoverlay_template();
|
||||
}
|
||||
else if (customTemplate == "mtl_splatter")
|
||||
{
|
||||
mtl_splatter_template();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Unknown custom template: \"" << customTemplate << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
void mtl_custom_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_phong_flag_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_grain_overlay_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_effect_eyeoffset_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_reflexsight_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_shadowclear_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_shadowoverlay_template()
|
||||
{
|
||||
}
|
||||
|
||||
void mtl_splatter_template()
|
||||
{
|
||||
}
|
||||
|
||||
void commonsetup_template()
|
||||
{
|
||||
}
|
||||
|
||||
void SetTechniqueSet(const std::string& techsetName)
|
||||
{
|
||||
auto* techset = reinterpret_cast<XAssetInfo<MaterialTechniqueSet>*>(m_manager->LoadDependency(ASSET_TYPE_TECHNIQUE_SET, techsetName));
|
||||
|
||||
if (techset == nullptr)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Could not load techset: \"" << techsetName << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
|
||||
m_dependencies.push_back(techset);
|
||||
m_material->techniqueSet = techset->Asset();
|
||||
}
|
||||
|
||||
void AddMapTexture(const std::string& typeName, const TextureSemantic semantic, const std::string& textureName)
|
||||
{
|
||||
MaterialTextureDef textureDef{};
|
||||
textureDef.nameHash = Common::R_HashString(typeName.c_str());
|
||||
textureDef.nameStart = typeName[0];
|
||||
textureDef.nameEnd = typeName[typeName.size() - 1];
|
||||
textureDef.samplerState = 0; // TODO
|
||||
textureDef.semantic = static_cast<unsigned char>(semantic);
|
||||
|
||||
auto* image = reinterpret_cast<XAssetInfo<GfxImage>*>(m_manager->LoadDependency(ASSET_TYPE_IMAGE, textureName));
|
||||
|
||||
if (image == nullptr)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Could not load image: \"" << textureName << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
|
||||
m_dependencies.push_back(image);
|
||||
textureDef.u.image = image->Asset();
|
||||
|
||||
m_texture.push_back(textureDef);
|
||||
}
|
||||
|
||||
void FinalizeMaterial()
|
||||
{
|
||||
// TODO Realloc all arrays and assign to material
|
||||
}
|
||||
|
||||
MemoryManager* m_memory;
|
||||
IAssetLoadingManager* m_manager;
|
||||
std::vector<XAssetInfoGeneric*> m_dependencies;
|
||||
|
||||
Material* m_material;
|
||||
std::vector<MaterialTextureDef> m_texture;
|
||||
};
|
||||
}
|
||||
|
||||
void* AssetLoaderMaterial::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* material = memory->Create<Material>();
|
||||
@ -15,3 +311,30 @@ void* AssetLoaderMaterial::CreateEmptyAsset(const std::string& assetName, Memory
|
||||
material->info.name = memory->Dup(assetName.c_str());
|
||||
return material;
|
||||
}
|
||||
|
||||
bool AssetLoaderMaterial::CanLoadFromGdt() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderMaterial::LoadFromGdt(const std::string& assetName, IGdtQueryable* gdtQueryable, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto* entry = gdtQueryable->GetGdtEntryByGdfAndName(ObjConstants::GDF_FILENAME_MATERIAL, assetName);
|
||||
if (!entry)
|
||||
return false;
|
||||
|
||||
MaterialGdtLoader loader(*entry, memory, manager);
|
||||
|
||||
try
|
||||
{
|
||||
if (loader.Load())
|
||||
manager->AddAsset(ASSET_TYPE_MATERIAL, assetName, loader.GetMaterial(), loader.GetDependencies(), std::vector<scr_string_t>());
|
||||
}
|
||||
catch (const GdtReadingException& e)
|
||||
{
|
||||
std::cerr << "Error while trying to load material from gdt: " << e.what() << " @ GdtEntry \"" << entry->m_name << "\"\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -10,5 +10,7 @@ namespace IW4
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
_NODISCARD bool CanLoadFromGdt() const override;
|
||||
bool LoadFromGdt(const std::string& assetName, IGdtQueryable* gdtQueryable, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
};
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "Game/IW4/MaterialConstantsIW4.h"
|
||||
#include "Game/IW4/ObjConstantsIW4.h"
|
||||
#include "Game/IW4/TechsetConstantsIW4.h"
|
||||
#include "Math/Vector.h"
|
||||
|
||||
@ -1431,7 +1432,7 @@ namespace IW4
|
||||
GdtEntry& CreateGdtEntry()
|
||||
{
|
||||
m_entry = GdtEntry();
|
||||
m_entry.m_gdf_name = "material.gdf";
|
||||
m_entry.m_gdf_name = ObjConstants::GDF_FILENAME_MATERIAL;
|
||||
m_entry.m_name = m_material->info.name;
|
||||
|
||||
SetCommonValues();
|
||||
|
Loading…
x
Reference in New Issue
Block a user