Initial MaterialSet constructor

This commit is contained in:
Jack Andersen 2015-10-16 16:07:38 -10:00
parent 33b7889208
commit 6bd5c42a9e
5 changed files with 367 additions and 297 deletions

View File

@ -1040,17 +1040,25 @@ bool WriteCMDL(const HECL::ProjectPath& outPath, const HECL::ProjectPath& inPath
head.secSizes.reserve(head.secCount);
/* Build material sets */
std::vector<MaterialSet> matSets;
matSets.reserve(mesh.materialSets.size());
{
HECL::Frontend::Frontend FE;
FE.getDiagnostics().setBackend("GX");
for (const std::vector<Mesh::Material>& mset : mesh.materialSets)
{
matSets.emplace_back();
MaterialSet& targetMSet = matSets.back();
std::vector<HECL::ProjectPath> texPaths;
for (const Mesh::Material& mat : mset)
{
std::string diagName = HECL::Format("%s:%s", inPath.getLastComponentUTF8(), mat.name.c_str());
HECL::Frontend::IR matIR = FE.compileSource(mat.source, diagName);
HECL::Backend::GX matGX;
matGX.reset(matIR, FE.getDiagnostics());
targetMSet.materials.emplace_back(matGX, mat.iprops, mat.texs, texPaths,
mesh.colorLayerCount, mesh.uvLayerCount,
false, false, 0);
}
}
}

View File

@ -1,270 +1,7 @@
#ifndef _DNACOMMON_GX_HPP_
#define _DNACOMMON_GX_HPP_
#include "DNACommon.hpp"
namespace GX
{
/* RGBA8 structure (GXColor) */
struct Color : Retro::BigDNA
{
Value<atUint8> r;
Value<atUint8> g;
Value<atUint8> b;
Value<atUint8> a;
Delete expl;
void read(Athena::io::IStreamReader& reader)
{reader.readUBytesToBuf(&r, 4);}
void write(Athena::io::IStreamWriter& writer) const
{writer.writeUBytes(&r, 4);}
};
/* GX enums */
enum AttrType
{
NONE,
DIRECT,
INDEX8,
INDEX16
};
enum TevColorArg
{
CC_CPREV = 0, /*!< Use the color value from previous TEV stage */
CC_APREV = 1, /*!< Use the alpha value from previous TEV stage */
CC_C0 = 2, /*!< Use the color value from the color/output register 0 */
CC_A0 = 3, /*!< Use the alpha value from the color/output register 0 */
CC_C1 = 4, /*!< Use the color value from the color/output register 1 */
CC_A1 = 5, /*!< Use the alpha value from the color/output register 1 */
CC_C2 = 6, /*!< Use the color value from the color/output register 2 */
CC_A2 = 7, /*!< Use the alpha value from the color/output register 2 */
CC_TEXC = 8, /*!< Use the color value from texture */
CC_TEXA = 9, /*!< Use the alpha value from texture */
CC_RASC = 10, /*!< Use the color value from rasterizer */
CC_RASA = 11, /*!< Use the alpha value from rasterizer */
CC_ONE = 12,
CC_HALF = 13,
CC_KONST = 14,
CC_ZERO = 15 /*!< Use to pass zero value */
};
enum TevAlphaArg
{
CA_APREV = 0, /*!< Use the alpha value from previous TEV stage */
CA_A0 = 1, /*!< Use the alpha value from the color/output register 0 */
CA_A1 = 2, /*!< Use the alpha value from the color/output register 1 */
CA_A2 = 3, /*!< Use the alpha value from the color/output register 2 */
CA_TEXA = 4, /*!< Use the alpha value from texture */
CA_RASA = 5, /*!< Use the alpha value from rasterizer */
CA_KONST = 6,
CA_ZERO = 7 /*!< Use to pass zero value */
};
enum TevKColorSel
{
TEV_KCSEL_8_8 = 0x00,
TEV_KCSEL_7_8 = 0x01,
TEV_KCSEL_6_8 = 0x02,
TEV_KCSEL_5_8 = 0x03,
TEV_KCSEL_4_8 = 0x04,
TEV_KCSEL_3_8 = 0x05,
TEV_KCSEL_2_8 = 0x06,
TEV_KCSEL_1_8 = 0x07,
TEV_KCSEL_1 = TEV_KCSEL_8_8,
TEV_KCSEL_3_4 = TEV_KCSEL_6_8,
TEV_KCSEL_1_2 = TEV_KCSEL_4_8,
TEV_KCSEL_1_4 = TEV_KCSEL_2_8,
TEV_KCSEL_K0 = 0x0C,
TEV_KCSEL_K1 = 0x0D,
TEV_KCSEL_K2 = 0x0E,
TEV_KCSEL_K3 = 0x0F,
TEV_KCSEL_K0_R = 0x10,
TEV_KCSEL_K1_R = 0x11,
TEV_KCSEL_K2_R = 0x12,
TEV_KCSEL_K3_R = 0x13,
TEV_KCSEL_K0_G = 0x14,
TEV_KCSEL_K1_G = 0x15,
TEV_KCSEL_K2_G = 0x16,
TEV_KCSEL_K3_G = 0x17,
TEV_KCSEL_K0_B = 0x18,
TEV_KCSEL_K1_B = 0x19,
TEV_KCSEL_K2_B = 0x1A,
TEV_KCSEL_K3_B = 0x1B,
TEV_KCSEL_K0_A = 0x1C,
TEV_KCSEL_K1_A = 0x1D,
TEV_KCSEL_K2_A = 0x1E,
TEV_KCSEL_K3_A = 0x1F
};
enum TevKAlphaSel
{
TEV_KASEL_8_8 = 0x00,
TEV_KASEL_7_8 = 0x01,
TEV_KASEL_6_8 = 0x02,
TEV_KASEL_5_8 = 0x03,
TEV_KASEL_4_8 = 0x04,
TEV_KASEL_3_8 = 0x05,
TEV_KASEL_2_8 = 0x06,
TEV_KASEL_1_8 = 0x07,
TEV_KASEL_1 = TEV_KASEL_8_8,
TEV_KASEL_3_4 = TEV_KASEL_6_8,
TEV_KASEL_1_2 = TEV_KASEL_4_8,
TEV_KASEL_1_4 = TEV_KASEL_2_8,
TEV_KASEL_K0_R = 0x10,
TEV_KASEL_K1_R = 0x11,
TEV_KASEL_K2_R = 0x12,
TEV_KASEL_K3_R = 0x13,
TEV_KASEL_K0_G = 0x14,
TEV_KASEL_K1_G = 0x15,
TEV_KASEL_K2_G = 0x16,
TEV_KASEL_K3_G = 0x17,
TEV_KASEL_K0_B = 0x18,
TEV_KASEL_K1_B = 0x19,
TEV_KASEL_K2_B = 0x1A,
TEV_KASEL_K3_B = 0x1B,
TEV_KASEL_K0_A = 0x1C,
TEV_KASEL_K1_A = 0x1D,
TEV_KASEL_K2_A = 0x1E,
TEV_KASEL_K3_A = 0x1F
};
enum TevOp
{
TEV_ADD = 0,
TEV_SUB = 1,
TEV_COMP_R8_GT = 8,
TEV_COMP_R8_EQ = 9,
TEV_COMP_GR16_GT = 10,
TEV_COMP_GR16_EQ = 11,
TEV_COMP_BGR24_GT = 12,
TEV_COMP_BGR24_EQ = 13,
TEV_COMP_RGB8_GT = 14,
TEV_COMP_RGB8_EQ = 15,
TEV_COMP_A8_GT = TEV_COMP_RGB8_GT, // for alpha channel
TEV_COMP_A8_EQ = TEV_COMP_RGB8_EQ // for alpha channel
};
enum TevBias
{
TB_ZERO = 0,
TB_ADDHALF = 1,
TB_SUBHALF = 2,
};
enum TevScale
{
CS_SCALE_1 = 0,
CS_SCALE_2 = 1,
CS_SCALE_4 = 2,
CS_DIVIDE_2 = 3
};
enum TevRegID
{
TEVPREV = 0,
TEVREG0 = 1,
TEVREG1 = 2,
TEVREG2 = 3
};
enum TexGenType
{
TG_MTX3x4 = 0,
TG_MTX2x4,
TG_BUMP0,
TG_BUMP1,
TG_BUMP2,
TG_BUMP3,
TG_BUMP4,
TG_BUMP5,
TG_BUMP6,
TG_BUMP7,
TG_SRTG
};
enum TexGenSrc
{
TG_POS = 0,
TG_NRM,
TG_BINRM,
TG_TANGENT,
TG_TEX0,
TG_TEX1,
TG_TEX2,
TG_TEX3,
TG_TEX4,
TG_TEX5,
TG_TEX6,
TG_TEX7,
TG_TEXCOORD0,
TG_TEXCOORD1,
TG_TEXCOORD2,
TG_TEXCOORD3,
TG_TEXCOORD4,
TG_TEXCOORD5,
TG_TEXCOORD6,
TG_COLOR0,
TG_COLOR1
};
enum TexMtx
{
TEXMTX0 = 30,
TEXMTX1 = 33,
TEXMTX2 = 36,
TEXMTX3 = 39,
TEXMTX4 = 42,
TEXMTX5 = 45,
TEXMTX6 = 48,
TEXMTX7 = 51,
TEXMTX8 = 54,
TEXMTX9 = 57,
IDENTITY = 60
};
enum PTTexMtx
{
PTTEXMTX0 = 64,
PTTEXMTX1 = 67,
PTTEXMTX2 = 70,
PTTEXMTX3 = 73,
PTTEXMTX4 = 76,
PTTEXMTX5 = 79,
PTTEXMTX6 = 82,
PTTEXMTX7 = 85,
PTTEXMTX8 = 88,
PTTEXMTX9 = 91,
PTTEXMTX10 = 94,
PTTEXMTX11 = 97,
PTTEXMTX12 = 100,
PTTEXMTX13 = 103,
PTTEXMTX14 = 106,
PTTEXMTX15 = 109,
PTTEXMTX16 = 112,
PTTEXMTX17 = 115,
PTTEXMTX18 = 118,
PTTEXMTX19 = 121,
PTIDENTITY = 125
};
enum Primitive
{
POINTS = 0xb8,
LINES = 0xa8,
LINESTRIP = 0xb0,
TRIANGLES = 0x90,
TRIANGLESTRIP = 0x98,
TRIANGLEFAN = 0xa0,
QUADS = 0x80
};
}
#include "HECL/Backend/GX.hpp"
using GX = HECL::Backend::GX;
#endif // _DNACOMMON_GX_HPP_

View File

@ -248,10 +248,10 @@ void Material::AddKcolor(Stream& out, const GX::Color& col, unsigned idx)
"kcolor_nodes.append((kc_node,ka_node))\n"
"\n",
idx,
(float)col.r / (float)0xff, (float)col.g / (float)0xff,
(float)col.b / (float)0xff, (float)col.a / (float)0xff,
(float)col.color[0] / (float)0xff, (float)col.color[1] / (float)0xff,
(float)col.color[2] / (float)0xff, (float)col.color[3] / (float)0xff,
idx,
(float)col.a / (float)0xff);
(float)col.color[3] / (float)0xff);
}
void Material::AddDynamicColor(Stream& out, unsigned idx)
@ -860,6 +860,296 @@ void MaterialSet::ConstructMaterial(Stream& out,
unsigned matIdx)
{_ConstructMaterial(out, material, groupIdx, matIdx);}
MaterialSet::Material::Material(const HECL::Backend::GX& gx,
const std::unordered_map<std::string, int32_t>& iprops,
const std::vector<HECL::ProjectPath>& texPathsIn,
std::vector<HECL::ProjectPath>& texPathsOut,
int colorCount,
int uvCount,
bool lightmapUVs,
bool matrixSkinning,
atUint32 setIdxIn)
{
if (gx.m_kcolorCount)
{
flags.setKonstValuesEnabled(true);
konstCount.push_back(gx.m_kcolorCount);
}
auto search = iprops.find("retro_depth_sort");
if (search != iprops.end())
flags.setDepthSorting(search->second != 0);
search = iprops.find("retro_punchthrough_alpha");
if (search != iprops.end())
flags.setPunchthroughAlpha(search->second != 0);
search = iprops.find("retro_samus_reflection");
if (search != iprops.end())
flags.setSamusReflection(search->second != 0);
search = iprops.find("retro_depth_write");
if (search != iprops.end())
flags.setDepthWrite(search->second != 0);
search = iprops.find("retro_samus_reflection_persp");
if (search != iprops.end())
flags.setSamusReflectionSurfaceEye(search->second != 0);
search = iprops.find("retro_shadow_occluder");
if (search != iprops.end())
flags.setShadowOccluderMesh(search->second != 0);
search = iprops.find("retro_samus_reflection_indirect");
if (search != iprops.end())
flags.setSamusReflectionIndirectTexture(search->second != 0);
search = iprops.find("retro_lightmapped");
if (search != iprops.end())
flags.setLightmap(search->second != 0);
flags.setLightmapUVArray(lightmapUVs);
atUint16 texFlags = 0;
for (int i=0 ; i<gx.m_tevCount ; ++i)
if (gx.m_tevs[i].m_texMapIdx != -1)
{
const HECL::ProjectPath& texPath = texPathsIn.at(gx.m_tevs[i].m_texMapIdx);
texFlags |= 1 << i;
++textureCount;
bool found = false;
for (size_t t=0 ; t<texPathsOut.size() ; ++t)
{
if (texPath == texPathsOut[t])
{
found = true;
texureIdxs.push_back(t);
break;
}
}
if (!found)
{
texureIdxs.push_back(texPathsOut.size());
texPathsOut.push_back(texPath);
}
}
flags.setTextureSlots(texFlags);
vaFlags.setPosition(GX::INDEX16);
vaFlags.setNormal(GX::INDEX16);
if (0 < colorCount)
vaFlags.setColor0(GX::INDEX16);
if (1 < colorCount)
vaFlags.setColor1(GX::INDEX16);
if (0 < uvCount)
vaFlags.setTex0(GX::INDEX16);
if (1 < uvCount)
vaFlags.setTex1(GX::INDEX16);
if (2 < uvCount)
vaFlags.setTex2(GX::INDEX16);
if (3 < uvCount)
vaFlags.setTex3(GX::INDEX16);
if (4 < uvCount)
vaFlags.setTex4(GX::INDEX16);
if (5 < uvCount)
vaFlags.setTex5(GX::INDEX16);
if (6 < uvCount)
vaFlags.setTex6(GX::INDEX16);
if (matrixSkinning)
{
vaFlags.setPnMatIdx(GX::DIRECT);
if (0 < uvCount)
vaFlags.setTex0MatIdx(GX::DIRECT);
if (1 < uvCount)
vaFlags.setTex1MatIdx(GX::DIRECT);
if (2 < uvCount)
vaFlags.setTex2MatIdx(GX::DIRECT);
if (3 < uvCount)
vaFlags.setTex3MatIdx(GX::DIRECT);
if (4 < uvCount)
vaFlags.setTex4MatIdx(GX::DIRECT);
if (5 < uvCount)
vaFlags.setTex5MatIdx(GX::DIRECT);
if (6 < uvCount)
vaFlags.setTex6MatIdx(GX::DIRECT);
}
groupIdx = setIdxIn;
for (int i=0 ; i<gx.m_kcolorCount ; ++i)
konstColors.emplace_back(gx.m_kcolors[i]);
blendDstFac = BlendFactor(gx.m_blendDst);
blendSrcFac = BlendFactor(gx.m_blendSrc);
if (flags.samusReflectionIndirectTexture())
indTexSlot.push_back(texureIdxs.size());
colorChannelCount = 1;
colorChannels.emplace_back();
ColorChannel& ch = colorChannels.back();
for (int i=0 ; i<gx.m_tevCount ; ++i)
{
const HECL::Backend::GX::TEVStage& stage = gx.m_tevs[i];
for (int c=0 ; c<4 ; ++c)
if (stage.m_color[c] == HECL::Backend::GX::CC_RASC ||
stage.m_color[c] == HECL::Backend::GX::CC_RASA ||
stage.m_alpha[c] == HECL::Backend::GX::CA_RASA)
{
ch.setLighting(true);
break;
}
if (ch.lighting())
break;
}
ch.setDiffuseFn(GX::DF_CLAMP);
ch.setAttenuationFn(GX::AF_SPOT);
tevStageCount = gx.m_tevCount;
for (int i=0 ; i<gx.m_tevCount ; ++i)
{
const HECL::Backend::GX::TEVStage& stage = gx.m_tevs[i];
tevStages.emplace_back();
TEVStage& target = tevStages.back();
target.setColorInA(stage.m_color[0]);
target.setColorInB(stage.m_color[1]);
target.setColorInC(stage.m_color[2]);
target.setColorInD(stage.m_color[3]);
target.setAlphaInA(stage.m_alpha[0]);
target.setAlphaInB(stage.m_alpha[1]);
target.setAlphaInC(stage.m_alpha[2]);
target.setAlphaInD(stage.m_alpha[3]);
target.setColorOp(stage.m_cop);
target.setColorOpBias(GX::TB_ZERO);
target.setColorOpScale(GX::CS_SCALE_1);
target.setColorOpClamp(true);
target.setColorOpOutReg(stage.m_cRegOut);
target.setAlphaOp(stage.m_aop);
target.setAlphaOpBias(GX::TB_ZERO);
target.setAlphaOpScale(GX::CS_SCALE_1);
target.setAlphaOpClamp(true);
target.setAlphaOpOutReg(stage.m_aRegOut);
target.setKColorIn(stage.m_kColor);
target.setKAlphaIn(stage.m_kAlpha);
tevStageTexInfo.emplace_back();
TEVStageTexInfo& texInfo = tevStageTexInfo.back();
texInfo.texSlot = -1;
if (stage.m_texMapIdx != -1)
texInfo.texSlot = stage.m_texMapIdx;
texInfo.tcgSlot = -1;
if (stage.m_texGenIdx != -1)
texInfo.tcgSlot = stage.m_texGenIdx;
}
tcgCount = gx.m_tcgCount;
for (int i=0 ; i<gx.m_tcgCount ; ++i)
{
const HECL::Backend::GX::TexCoordGen& tcg = gx.m_tcgs[i];
tcgs.emplace_back();
TexCoordGen& target = tcgs.back();
target.setType(GX::TG_MTX3x4);
target.setSource(tcg.m_src);
target.setMtx(tcg.m_mtx);
target.setPostMtx(GX::PTIDENTITY);
if (tcg.m_gameFunction.size() && tcg.m_mtx != GX::IDENTITY)
{
if (!tcg.m_gameFunction.compare("RetroUVMode0Node") ||
!tcg.m_gameFunction.compare("RetroUVMode1Node") ||
!tcg.m_gameFunction.compare("RetroUVMode7Node"))
{
target.setNormalize(true);
target.setPostMtx(GX::PTTexMtx(GX::PTTEXMTX0 - GX::TEXMTX0 + tcg.m_mtx));
}
}
}
uvAnimsSize = 4;
uvAnimsCount = 0;
for (; uvAnimsCount<8 ;)
{
bool found = false;
for (int t=0 ; t<gx.m_tcgCount ; ++t)
{
const HECL::Backend::GX::TexCoordGen& tcg = gx.m_tcgs[t];
if (tcg.m_mtx == GX::IDENTITY)
continue;
if ((tcg.m_mtx - GX::TEXMTX0) / 3 == uvAnimsCount)
{
found = true;
++uvAnimsCount;
uvAnims.emplace_back(tcg);
uvAnimsSize += uvAnims.back().binarySize();
break;
}
}
if (!found)
break;
}
}
MaterialSet::Material::UVAnimation::UVAnimation(const HECL::Backend::GX::TexCoordGen& tcg)
{
if (!tcg.m_gameFunction.compare("RetroUVMode0Node"))
mode = ANIM_MV_INV_NOTRANS;
else if (!tcg.m_gameFunction.compare("RetroUVMode1Node"))
mode = ANIM_MV_INV;
else if (!tcg.m_gameFunction.compare("RetroUVMode2Node"))
{
mode = ANIM_SCROLL;
if (tcg.m_gameArgs.size() < 4)
Log.report(LogVisor::FatalError, "Mode2 UV anim requires 4 arguments");
vals[0] = tcg.m_gameArgs[0].vec[0];
vals[1] = tcg.m_gameArgs[1].vec[0];
vals[2] = tcg.m_gameArgs[2].vec[0];
vals[3] = tcg.m_gameArgs[3].vec[0];
}
else if (!tcg.m_gameFunction.compare("RetroUVMode3Node"))
{
mode = ANIM_ROTATION;
if (tcg.m_gameArgs.size() < 2)
Log.report(LogVisor::FatalError, "Mode3 UV anim requires 2 arguments");
vals[0] = tcg.m_gameArgs[0].vec[0];
vals[1] = tcg.m_gameArgs[1].vec[0];
}
else if (!tcg.m_gameFunction.compare("RetroUVMode4Node"))
{
mode = ANIM_HSTRIP;
if (tcg.m_gameArgs.size() < 4)
Log.report(LogVisor::FatalError, "Mode4 UV anim requires 4 arguments");
vals[0] = tcg.m_gameArgs[0].vec[0];
vals[1] = tcg.m_gameArgs[1].vec[0];
vals[2] = tcg.m_gameArgs[2].vec[0];
vals[3] = tcg.m_gameArgs[3].vec[0];
}
else if (!tcg.m_gameFunction.compare("RetroUVMode5Node"))
{
mode = ANIM_VSTRIP;
if (tcg.m_gameArgs.size() < 4)
Log.report(LogVisor::FatalError, "Mode5 UV anim requires 4 arguments");
vals[0] = tcg.m_gameArgs[0].vec[0];
vals[1] = tcg.m_gameArgs[1].vec[0];
vals[2] = tcg.m_gameArgs[2].vec[0];
vals[3] = tcg.m_gameArgs[3].vec[0];
}
else if (!tcg.m_gameFunction.compare("RetroUVMode6Node"))
mode = ANIM_MODEL;
else if (!tcg.m_gameFunction.compare("RetroUVMode7Node"))
{
mode = ANIM_MODE_WHO_MUST_NOT_BE_NAMED;
if (tcg.m_gameArgs.size() < 2)
Log.report(LogVisor::FatalError, "Mode7 UV anim requires 2 arguments");
vals[0] = tcg.m_gameArgs[0].vec[0];
vals[1] = tcg.m_gameArgs[1].vec[0];
}
else
Log.report(LogVisor::FatalError, "unsupported UV anim '%s'", tcg.m_gameFunction.c_str());
}
}
}

View File

@ -32,7 +32,7 @@ struct MaterialSet : BigDNA
struct Flags : BigDNA
{
DECL_DNA
Value<atUint32> flags;
Value<atUint32> flags = 0;
bool konstValuesEnabled() const {return (flags & 0x8) != 0;}
void setKonstValuesEnabled(bool enabled) {flags &= ~0x8; flags |= atUint32(enabled) << 3;}
bool depthSorting() const {return (flags & 0x10) != 0;}
@ -58,12 +58,12 @@ struct MaterialSet : BigDNA
} flags;
const Flags& getFlags() const {return flags;}
Value<atUint32> textureCount;
Value<atUint32> textureCount = 0;
Vector<atUint32, DNA_COUNT(textureCount)> texureIdxs;
struct VAFlags : BigDNA
{
DECL_DNA
Value<atUint32> vaFlags;
Value<atUint32> vaFlags = 0;
GX::AttrType position() const {return GX::AttrType(vaFlags & 0x3);}
void setPosition(GX::AttrType val) {vaFlags &= ~0x3; vaFlags |= atUint32(val);}
GX::AttrType normal() const {return GX::AttrType(vaFlags >> 2 & 0x3);}
@ -125,11 +125,11 @@ struct MaterialSet : BigDNA
Value<BlendFactor> blendSrcFac;
Vector<atUint32, DNA_COUNT(flags.samusReflectionIndirectTexture())> indTexSlot;
Value<atUint32> colorChannelCount;
Value<atUint32> colorChannelCount = 0;
struct ColorChannel : BigDNA
{
DECL_DNA
Value<atUint32> flags;
Value<atUint32> flags = 0;
bool lighting() const {return (flags & 0x1) != 0;}
void setLighting(bool enabled) {flags &= ~0x1; flags |= atUint32(enabled);}
bool useAmbient() const {return (flags & 0x2) != 0;}
@ -138,25 +138,25 @@ struct MaterialSet : BigDNA
void setUseMaterial(bool enabled) {flags &= ~0x4; flags |= atUint32(enabled) << 2;}
atUint8 lightmask() const {return atUint8(flags >> 3 & 0xff);}
void setLightmask(atUint8 mask) {flags &= ~0x7f8; flags |= atUint32(mask) << 3;}
atUint8 diffuseFn() const {return atUint8(flags >> 11 & 0x3);}
void setDiffuseFn(atUint8 fn) {flags &= ~0x1800; flags |= atUint32(fn) << 11;}
atUint8 attenuationFn() const {return atUint8(flags >> 13 & 0x3);}
void setAttenuationFn(atUint8 fn) {flags &= ~0x6000; flags |= atUint32(fn) << 13;}
GX::DiffuseFn diffuseFn() const {return GX::DiffuseFn(flags >> 11 & 0x3);}
void setDiffuseFn(GX::DiffuseFn fn) {flags &= ~0x1800; flags |= atUint32(fn) << 11;}
GX::AttnFn attenuationFn() const {return GX::AttnFn(flags >> 13 & 0x3);}
void setAttenuationFn(GX::AttnFn fn) {flags &= ~0x6000; flags |= atUint32(fn) << 13;}
};
Vector<ColorChannel, DNA_COUNT(colorChannelCount)> colorChannels;
Value<atUint32> tevStageCount;
Value<atUint32> tevStageCount = 0;
struct TEVStage : BigDNA
{
DECL_DNA
Value<atUint32> ciFlags;
Value<atUint32> aiFlags;
Value<atUint32> ccFlags;
Value<atUint32> acFlags;
Value<atUint8> pad;
Value<atUint8> kaInput;
Value<atUint8> kcInput;
Value<atUint8> rascInput;
Value<atUint32> ciFlags = 0;
Value<atUint32> aiFlags = 0;
Value<atUint32> ccFlags = 0;
Value<atUint32> acFlags = 0;
Value<atUint8> pad = 0;
Value<atUint8> kaInput = 0;
Value<atUint8> kcInput = 0;
Value<atUint8> rascInput = 0;
GX::TevColorArg colorInA() const {return GX::TevColorArg(ciFlags & 0xf);}
void setColorInA(GX::TevColorArg val) {ciFlags &= ~0x1f; ciFlags |= atUint32(val);}
@ -199,23 +199,25 @@ struct MaterialSet : BigDNA
void setAlphaOpOutReg(GX::TevRegID val) {acFlags &= ~0x600; acFlags |= atUint32(val) << 9;}
GX::TevKColorSel kColorIn() const {return GX::TevKColorSel(kcInput);}
void setKColorIn(GX::TevKColorSel val) {kcInput = val;}
GX::TevKAlphaSel kAlphaIn() const {return GX::TevKAlphaSel(kaInput);}
void setKAlphaIn(GX::TevKAlphaSel val) {kaInput = val;}
};
Vector<TEVStage, DNA_COUNT(tevStageCount)> tevStages;
struct TEVStageTexInfo : BigDNA
{
DECL_DNA
Value<atUint16> pad;
Value<atUint8> texSlot;
Value<atUint8> tcgSlot;
Value<atUint16> pad = 0;
Value<atUint8> texSlot = 0;
Value<atUint8> tcgSlot = 0;
};
Vector<TEVStageTexInfo, DNA_COUNT(tevStageCount)> tevStageTexInfo;
Value<atUint32> tcgCount;
Value<atUint32> tcgCount = 0;
struct TexCoordGen : BigDNA
{
DECL_DNA
Value<atUint32> flags;
Value<atUint32> flags = 0;
GX::TexGenType type() const {return GX::TexGenType(flags & 0xf);}
void setType(GX::TexGenType val) {flags &= ~0xf; flags |= atUint32(val);}
@ -230,8 +232,8 @@ struct MaterialSet : BigDNA
};
Vector<TexCoordGen, DNA_COUNT(tcgCount)> tcgs;
Value<atUint32> uvAnimsSize;
Value<atUint32> uvAnimsCount;
Value<atUint32> uvAnimsSize = 4;
Value<atUint32> uvAnimsCount = 0;
struct UVAnimation : BigDNA
{
Delete expl;
@ -318,6 +320,30 @@ struct MaterialSet : BigDNA
break;
}
}
atUint32 binarySize() const
{
switch (mode)
{
case ANIM_MV_INV_NOTRANS:
case ANIM_MV_INV:
case ANIM_MODEL:
return 4;
case ANIM_SCROLL:
case ANIM_HSTRIP:
case ANIM_VSTRIP:
return 20;
break;
case ANIM_ROTATION:
case ANIM_MODE_WHO_MUST_NOT_BE_NAMED:
return 12;
case ANIM_MODE_8:
return 40;
}
return 4;
}
UVAnimation() = default;
UVAnimation(const HECL::Backend::GX::TexCoordGen& tcg);
};
Vector<UVAnimation, DNA_COUNT(uvAnimsCount)> uvAnims;
@ -330,6 +356,17 @@ struct MaterialSet : BigDNA
const GX::Color& col, unsigned idx);
static void AddDynamicColor(HECL::BlenderConnection::PyOutStream& out, unsigned idx);
static void AddDynamicAlpha(HECL::BlenderConnection::PyOutStream& out, unsigned idx);
Material() = default;
Material(const HECL::Backend::GX& gx,
const std::unordered_map<std::string, int32_t>& iprops,
const std::vector<HECL::ProjectPath>& texPathsIn,
std::vector<HECL::ProjectPath>& texPathsOut,
int colorCount,
int uvCount,
bool lightmapUVs,
bool matrixSkinning,
atUint32 grpIdx);
};
Vector<Material, DNA_COUNT(head.materialCount)> materials;
@ -346,8 +383,6 @@ struct MaterialSet : BigDNA
DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx);
}
MaterialSet() = default;
MaterialSet(const HECL::Backend::GX& gx);
};
}

2
hecl

@ -1 +1 @@
Subproject commit d1f705688720f01ae5694cc34e94fecd2b39001b
Subproject commit 8604f405026cd53774b7dac524badd2a5e0884b5