Dump material info from constants

This commit is contained in:
Jan 2022-05-14 16:09:11 +02:00
parent 38dedaf894
commit 0105c0d1bd
3 changed files with 331 additions and 61 deletions

View File

@ -21,6 +21,11 @@ namespace IW4
return result; return result;
} }
static constexpr uint32_t R_HashString(const char* string)
{
return R_HashString(string, 0u);
}
static int StringTable_HashString(const char* str); static int StringTable_HashString(const char* str);
static PackedTexCoords Vec2PackTexCoords(const vec2_t* in); static PackedTexCoords Vec2PackTexCoords(const vec2_t* in);

View File

@ -10,6 +10,7 @@
#include "Utils/ClassUtils.h" #include "Utils/ClassUtils.h"
#include "Game/IW4/MaterialConstantsIW4.h" #include "Game/IW4/MaterialConstantsIW4.h"
#include "Game/IW4/TechsetConstantsIW4.h" #include "Game/IW4/TechsetConstantsIW4.h"
#include "Math/Vector.h"
#define DUMP_AS_JSON 1 #define DUMP_AS_JSON 1
#define DUMP_AS_GDT 1 #define DUMP_AS_GDT 1
@ -534,12 +535,10 @@ namespace IW4
bool m_has_detail_normal_map = false; bool m_has_detail_normal_map = false;
bool m_has_specular_map = false; bool m_has_specular_map = false;
bool m_zfeather = false; bool m_zfeather = false;
float m_zfeather_depth = 0.0f;
bool m_use_spot_light = false; bool m_use_spot_light = false;
bool m_falloff = false; bool m_falloff = false;
bool m_dist_falloff = false; bool m_dist_falloff = false;
bool m_outdoor_only = false; bool m_outdoor_only = false;
float m_eye_offset_depth = 0.0f;
// TODO: Find out what p0 in techset name actually means, seems like it only does stuff for techsets using a specular texture though // TODO: Find out what p0 in techset name actually means, seems like it only does stuff for techsets using a specular texture though
// TODO: Find out what o0 in techset name actually means, seems like it gives the colormap a blue/whiteish tint and is almost exclusively used on snow-related materials // TODO: Find out what o0 in techset name actually means, seems like it gives the colormap a blue/whiteish tint and is almost exclusively used on snow-related materials
@ -577,12 +576,43 @@ namespace IW4
StencilOp_e m_stencil_back_pass = StencilOp_e::UNKNOWN; StencilOp_e m_stencil_back_pass = StencilOp_e::UNKNOWN;
}; };
class ConstantsInfo
{
public:
Vector4f m_color_tint = Vector4f(1.0f, 1.0f, 1.0f, 1.0f);
float m_env_map_min = 0.2f;
float m_env_map_max = 1.0f;
float m_env_map_exponent = 2.5f;
float m_zfeather_depth = 40.0f;
float m_eye_offset_depth = 0.0f;
float m_falloff_begin_angle = 35.0f;
float m_falloff_end_angle = 65.0f;
float m_dist_falloff_begin_distance = 200.0f;
float m_dist_falloff_end_distance = 10.0f;
Vector4f m_falloff_begin_color = Vector4f(1.0f, 1.0f, 1.0f, 1.0f);
Vector4f m_falloff_end_color = Vector4f(0.5f, 0.5f, 0.5f, 0.5f);
Vector2f m_detail_scale = Vector2f(8.0f, 8.0f);
Vector2f m_distortion_scale = Vector2f(0.5f, 0.5f);
Vector4f m_color_obj_min = Vector4f(0.0f, 0.0f, 0.0f, 0.0f);
Vector4f m_color_obj_max = Vector4f(1.0f, 1.0f, 1.0f, 1.0f);
// Speed in which the wave animation is played
float m_flag_speed = 1.0f;
// Offset of the wave animation
float m_flag_phase = 0.0f;
float m_uv_scroll_x = 0.0f;
float m_uv_scroll_y = 0.0f;
float m_uv_rotate = 0.0f;
};
class MaterialGdtDumper class MaterialGdtDumper
{ {
std::ostream& m_stream; std::ostream& m_stream;
TechsetInfo m_techset_info; TechsetInfo m_techset_info;
StateBitsInfo m_state_bits_info; StateBitsInfo m_state_bits_info;
ConstantsInfo m_constants_info;
const Material* m_material; const Material* m_material;
GdtEntry m_entry; GdtEntry m_entry;
@ -597,10 +627,10 @@ namespace IW4
m_entry.m_properties.emplace(std::make_pair(key, std::move(value))); m_entry.m_properties.emplace(std::make_pair(key, std::move(value)));
} }
void SetValue(const std::string& key, const float (&value)[4]) void SetValue(const std::string& key, const Vector4f& v)
{ {
std::ostringstream ss; std::ostringstream ss;
ss << value[0] << " " << value[1] << " " << value[2] << " " << value[3]; ss << v.x() << " " << v.y() << " " << v.z() << " " << v.w();
m_entry.m_properties.emplace(std::make_pair(key, ss.str())); m_entry.m_properties.emplace(std::make_pair(key, ss.str()));
} }
@ -616,36 +646,6 @@ namespace IW4
m_entry.m_properties.emplace(std::make_pair(key, std::to_string(value))); m_entry.m_properties.emplace(std::make_pair(key, std::to_string(value)));
} }
_NODISCARD int FindConstant(const std::string& constantName) const
{
const auto constantHash = Common::R_HashString(constantName.c_str(), 0u);
if (m_material->constantTable)
{
for (auto i = 0; i < m_material->constantCount; i++)
{
if (m_material->constantTable[i].nameHash == constantHash)
return i;
}
}
return -1;
}
void SetConstantValues(const Material* material)
{
const auto colorTintIndex = FindConstant("colorTint");
if (colorTintIndex >= 0)
SetValue("colorTint", material->constantTable[colorTintIndex].literal);
const auto envMapParmsIndex = FindConstant("envMapParms");
if (envMapParmsIndex >= 0)
{
const auto& constant = material->constantTable[colorTintIndex];
SetValue("envMapMin", constant.literal[0]);
}
}
void SetCommonValues() void SetCommonValues()
{ {
SetValue("textureAtlasRowCount", m_material->info.textureAtlasRowCount); SetValue("textureAtlasRowCount", m_material->info.textureAtlasRowCount);
@ -743,9 +743,9 @@ namespace IW4
else else
{ {
if (namePart != "add" && namePart != "replace" && namePart != "blend" && namePart != "eyeoffset" && namePart != "screen" && namePart != "effect" && namePart != "unlit" if (namePart != "add" && namePart != "replace" && namePart != "blend" && namePart != "eyeoffset" && namePart != "screen" && namePart != "effect" && namePart != "unlit"
&& namePart != "multiply") && namePart != "multiply" && namePart != "sm")
{ {
std::cout << "Namepart: " << namePart << "\n"; assert(false);
} }
} }
} }
@ -758,6 +758,11 @@ namespace IW4
void ExamineLitTechsetInfo() void ExamineLitTechsetInfo()
{ {
if (!m_techset_info.m_techset_prefix.empty() && m_techset_info.m_techset_prefix[0] == 'm')
m_techset_info.m_gdt_material_type = GdtMaterialType::MATERIAL_TYPE_MODEL_PHONG;
else
m_techset_info.m_gdt_material_type = GdtMaterialType::MATERIAL_TYPE_WORLD_PHONG;
const auto nameParts = GetTechsetNameParts(m_techset_info.m_techset_base_name); const auto nameParts = GetTechsetNameParts(m_techset_info.m_techset_base_name);
bool inCustomName = false; bool inCustomName = false;
bool customNameStart = true; bool customNameStart = true;
@ -1171,10 +1176,141 @@ namespace IW4
ExamineBlendFunc(); ExamineBlendFunc();
} }
_NODISCARD int FindConstant(const std::string& constantName) const
{
const auto constantHash = Common::R_HashString(constantName.c_str(), 0u);
if (m_material->constantTable)
{
for (auto i = 0; i < m_material->constantCount; i++)
{
if (m_material->constantTable[i].nameHash == constantHash)
return i;
}
}
return -1;
}
_NODISCARD int FindTexture(const std::string& textureTypeName) const
{
const auto textureTypeHash = Common::R_HashString(textureTypeName.c_str(), 0u);
if (m_material->textureTable)
{
for (auto i = 0; i < m_material->textureCount; i++)
{
if (m_material->textureTable[i].nameHash == textureTypeHash)
return i;
}
}
return -1;
}
void ExamineConstants()
{
if (!m_material->constantTable)
return;
for (auto i = 0u; i < m_material->constantCount; i++)
{
const auto& constant = m_material->constantTable[i];
if (constant.nameHash == Common::R_HashString("colorTint"))
{
m_constants_info.m_color_tint = Vector4f(constant.literal);
}
else if (constant.nameHash == Common::R_HashString("envMapParms"))
{
// TODO: Wrong, fix
m_constants_info.m_env_map_min = constant.literal[0];
}
else if (constant.nameHash == Common::R_HashString("featherParms"))
{
m_constants_info.m_zfeather_depth = constant.literal[1];
}
else if (constant.nameHash == Common::R_HashString("falloffBeginColor"))
{
m_constants_info.m_falloff_begin_color = Vector4f(constant.literal);
}
else if (constant.nameHash == Common::R_HashString("falloffEndColor"))
{
m_constants_info.m_falloff_end_color = Vector4f(constant.literal);
}
else if (constant.nameHash == Common::R_HashString("eyeOffsetParms"))
{
m_constants_info.m_eye_offset_depth = constant.literal[0];
}
else if (constant.nameHash == Common::R_HashString("detailScale"))
{
const auto materialType = m_techset_info.m_gdt_material_type;
const auto colorMapIndex = FindTexture("colorMap");
const auto detailMapIndex = FindTexture("detailMap");
const auto hasColorMap = colorMapIndex >= 0 && m_material->textureTable[colorMapIndex].semantic != TS_WATER_MAP && m_material->textureTable[colorMapIndex].u.image;
const auto hasDetailMap = detailMapIndex >= 0 && m_material->textureTable[detailMapIndex].semantic != TS_WATER_MAP && m_material->textureTable[detailMapIndex].u.image;
if ((materialType == GdtMaterialType::MATERIAL_TYPE_MODEL_PHONG || materialType == GdtMaterialType::MATERIAL_TYPE_WORLD_PHONG)
&& hasColorMap && hasDetailMap)
{
const auto colorMapTexture = m_material->textureTable[colorMapIndex].u.image;
const auto detailMapTexture = m_material->textureTable[detailMapIndex].u.image;
if(colorMapTexture->width != 0 && colorMapTexture->height != 0
&& detailMapTexture->width != 0 && detailMapTexture->height != 0)
{
const auto detailScaleFactorX = static_cast<float>(colorMapTexture->width) / static_cast<float>(detailMapTexture->width);
const auto detailScaleFactorY = static_cast<float>(colorMapTexture->height) / static_cast<float>(detailMapTexture->height);
m_constants_info.m_detail_scale = Vector2f(constant.literal[0] / detailScaleFactorX, constant.literal[1] / detailScaleFactorY);
}
else
m_constants_info.m_detail_scale = Vector2f(constant.literal[0], constant.literal[1]);
}
else
{
m_constants_info.m_detail_scale = Vector2f(constant.literal[0], constant.literal[1]);
}
}
else if (constant.nameHash == Common::R_HashString("flagParms"))
{
m_constants_info.m_flag_speed = constant.literal[0];
m_constants_info.m_flag_phase = constant.literal[1];
}
else if (constant.nameHash == Common::R_HashString("falloffParms"))
{
__asm nop;
}
else if (constant.nameHash == Common::R_HashString("distortionScale"))
{
m_constants_info.m_distortion_scale = Vector2f(constant.literal[0], constant.literal[1]);
}
else if (constant.nameHash == Common::R_HashString("uvAnimParms"))
{
m_constants_info.m_uv_scroll_x = constant.literal[0];
m_constants_info.m_uv_scroll_y = constant.literal[1];
m_constants_info.m_uv_rotate = constant.literal[2];
}
else if (constant.nameHash == Common::R_HashString("colorObjMin"))
{
m_constants_info.m_color_obj_min = Vector4f(constant.literal);
}
else if (constant.nameHash == Common::R_HashString("colorObjMax"))
{
m_constants_info.m_color_obj_max = Vector4f(constant.literal);
}
else
{
std::string constantNamePart(constant.name, strnlen(constant.name, std::extent_v<decltype(constant.name)>));
std::cout << "Unknown constant: " << constantNamePart << "\n";
}
}
}
void SetMaterialTypeValues() void SetMaterialTypeValues()
{ {
ExamineTechsetInfo(); ExamineTechsetInfo();
ExamineStateBitsInfo(); ExamineStateBitsInfo();
ExamineConstants();
SetValue("materialType", GdtMaterialTypeNames[static_cast<size_t>(m_techset_info.m_gdt_material_type)]); SetValue("materialType", GdtMaterialTypeNames[static_cast<size_t>(m_techset_info.m_gdt_material_type)]);
SetValue("customTemplate", GdtCustomMaterialTypeNames[static_cast<size_t>(m_techset_info.m_gdt_custom_material_type)]); SetValue("customTemplate", GdtCustomMaterialTypeNames[static_cast<size_t>(m_techset_info.m_gdt_custom_material_type)]);
@ -1185,12 +1321,12 @@ namespace IW4
SetValue("texScroll", m_techset_info.m_tex_scroll); SetValue("texScroll", m_techset_info.m_tex_scroll);
SetValue("uvAnim", m_techset_info.m_uv_anim); SetValue("uvAnim", m_techset_info.m_uv_anim);
SetValue("zFeather", m_techset_info.m_zfeather); SetValue("zFeather", m_techset_info.m_zfeather);
SetValue("zFeatherDepth", m_techset_info.m_zfeather_depth); SetValue("zFeatherDepth", m_constants_info.m_zfeather_depth);
SetValue("useSpotLight", m_techset_info.m_use_spot_light); SetValue("useSpotLight", m_techset_info.m_use_spot_light);
SetValue("falloff", m_techset_info.m_falloff); SetValue("falloff", m_techset_info.m_falloff);
SetValue("distFalloff", m_techset_info.m_dist_falloff); SetValue("distFalloff", m_techset_info.m_dist_falloff);
SetValue("outdoorOnly", m_techset_info.m_outdoor_only); SetValue("outdoorOnly", m_techset_info.m_outdoor_only);
SetValue("eyeOffsetDepth", m_techset_info.m_eye_offset_depth); SetValue("eyeOffsetDepth", m_constants_info.m_eye_offset_depth);
// TODO: These are not good names, change when known what they do // TODO: These are not good names, change when known what they do
@ -1223,6 +1359,23 @@ namespace IW4
SetValue("stencilOpPass2", GdtStencilOpNames[static_cast<size_t>(m_state_bits_info.m_stencil_back_pass)]); SetValue("stencilOpPass2", GdtStencilOpNames[static_cast<size_t>(m_state_bits_info.m_stencil_back_pass)]);
SetValue("stencilOpFail2", GdtStencilOpNames[static_cast<size_t>(m_state_bits_info.m_stencil_back_fail)]); SetValue("stencilOpFail2", GdtStencilOpNames[static_cast<size_t>(m_state_bits_info.m_stencil_back_fail)]);
SetValue("stencilOpZFail2", GdtStencilOpNames[static_cast<size_t>(m_state_bits_info.m_stencil_back_zfail)]); SetValue("stencilOpZFail2", GdtStencilOpNames[static_cast<size_t>(m_state_bits_info.m_stencil_back_zfail)]);
SetValue("colorTint", m_constants_info.m_color_tint);
SetValue("envMapMin", m_constants_info.m_env_map_min);
SetValue("envMapMax", m_constants_info.m_env_map_max);
SetValue("envMapExponent", m_constants_info.m_env_map_exponent);
SetValue("zFeatherDepth", m_constants_info.m_zfeather_depth);
SetValue("eyeOffsetDepth", m_constants_info.m_eye_offset_depth);
SetValue("falloffBeginColor", m_constants_info.m_falloff_begin_color);
SetValue("falloffEndColor", m_constants_info.m_falloff_end_color);
SetValue("detailScaleX", m_constants_info.m_detail_scale.x());
SetValue("detailScaleY", m_constants_info.m_detail_scale.y());
SetValue("distortionScaleX", m_constants_info.m_distortion_scale.x());
SetValue("distortionScaleY", m_constants_info.m_distortion_scale.y());
SetValue("colorObjMin", m_constants_info.m_color_obj_min);
SetValue("colorObjMax", m_constants_info.m_color_obj_max);
SetValue("flagSpeed", m_constants_info.m_flag_speed);
SetValue("flagPhase", m_constants_info.m_flag_phase);
} }
void SetTextureTableValues() void SetTextureTableValues()

View File

@ -1,40 +1,152 @@
#pragma once #pragma once
#include <cassert>
template<typename T> #include "Utils/ClassUtils.h"
template <typename T>
class Vector2
{
T m_value[2];
public:
Vector2()
: m_value{ T(0), T(0)}
{
}
Vector2(T x, T y)
: m_value{ x, y }
{
}
explicit Vector2(const T* value)
: m_value{ value[0], value[1] }
{
}
_NODISCARD T& operator()(const size_t index)
{
assert(index < 2);
return m_value[index];
}
_NODISCARD const T& operator()(const size_t index) const
{
assert(index < 2);
return m_value[index];
}
_NODISCARD T& x() { return m_value[0]; }
_NODISCARD T& y() { return m_value[1]; }
_NODISCARD const T& x() const { return m_value[0]; }
_NODISCARD const T& y() const { return m_value[1]; }
};
typedef Vector2<float> Vector2f;
typedef Vector2<double> Vector2d;
template <typename T>
class Vector3 class Vector3
{ {
T m_value[3];
public: public:
union Vector3()
: m_value{ T(0), T(0), T(0) }
{ {
struct }
{
T m_x; Vector3(T x, T y, T z)
T m_y; : m_value{ x, y, z }
T m_z; {
}; }
T m_data[3];
} u; explicit Vector3(const T* value)
: m_value{ value[0], value[1], value[2] }
{
}
_NODISCARD T& operator()(const size_t index)
{
assert(index < 3);
return m_value[index];
}
_NODISCARD const T& operator()(const size_t index) const
{
assert(index < 3);
return m_value[index];
}
_NODISCARD T& x() { return m_value[0]; }
_NODISCARD T& y() { return m_value[1]; }
_NODISCARD T& z() { return m_value[2]; }
_NODISCARD const T& x() const { return m_value[0]; }
_NODISCARD const T& y() const { return m_value[1]; }
_NODISCARD const T& z() const { return m_value[2]; }
_NODISCARD T& r() { return m_value[0]; }
_NODISCARD T& g() { return m_value[1]; }
_NODISCARD T& b() { return m_value[2]; }
_NODISCARD const T& r() const { return m_value[0]; }
_NODISCARD const T& g() const { return m_value[1]; }
_NODISCARD const T& b() const { return m_value[2]; }
}; };
typedef Vector3<float> Vector3f; typedef Vector3<float> Vector3f;
typedef Vector3<double> Vector3d; typedef Vector3<double> Vector3d;
template<typename T> template <typename T>
class Vector4 class Vector4
{ {
T m_value[4];
public: public:
union Vector4()
: m_value{T(0), T(0), T(0), T(0)}
{ {
struct }
{
T m_x; Vector4(T x, T y, T z, T w)
T m_y; : m_value{x, y, z, w}
T m_z; {
T m_w; }
};
T m_data[4]; explicit Vector4(const T* value)
} u; : m_value{ value[0], value[1], value[2], value[3] }
{
}
_NODISCARD T& operator()(const size_t index)
{
assert(index < 4);
return m_value[index];
}
_NODISCARD const T& operator()(const size_t index) const
{
assert(index < 4);
return m_value[index];
}
_NODISCARD T& x() { return m_value[0]; }
_NODISCARD T& y() { return m_value[1]; }
_NODISCARD T& z() { return m_value[2]; }
_NODISCARD T& w() { return m_value[3]; }
_NODISCARD const T& x() const { return m_value[0]; }
_NODISCARD const T& y() const { return m_value[1]; }
_NODISCARD const T& z() const { return m_value[2]; }
_NODISCARD const T& w() const { return m_value[3]; }
_NODISCARD T& r() { return m_value[0]; }
_NODISCARD T& g() { return m_value[1]; }
_NODISCARD T& b() { return m_value[2]; }
_NODISCARD T& a() { return m_value[3]; }
_NODISCARD const T& r() const { return m_value[0]; }
_NODISCARD const T& g() const { return m_value[1]; }
_NODISCARD const T& b() const { return m_value[2]; }
_NODISCARD const T& a() const { return m_value[3]; }
}; };
typedef Vector3<float> Vector4f; typedef Vector4<float> Vector4f;
typedef Vector3<double> Vector4d; typedef Vector4<double> Vector4d;