Added code for more DLC skin geometry

Added code to DLCSkinFile.cpp to store skin box scale value. Added code to HumanoidModel.cpp and HumanoidModel.h to handle skin boxes added to the armor layer of skin. Added another float value to SkinBox.h
This commit is contained in:
Langtanium 2026-04-09 17:59:13 -07:00
parent bb5fa50615
commit fd2fd65908
9 changed files with 248 additions and 16 deletions

View file

@ -110,15 +110,15 @@ void DLCSkinFile::addParameter(DLCManager::EDLCParameterType type, const wstring
break;
case DLCManager::e_DLCParamType_Box:
{
WCHAR wchBodyPart[10];
WCHAR wchBodyPart[11];
SKIN_BOX *pSkinBox = new SKIN_BOX;
ZeroMemory(pSkinBox,sizeof(SKIN_BOX));
#ifdef __PS3__
// 4J Stu - The Xbox version used swscanf_s which isn't available in GCC.
swscanf(value.c_str(), L"%10ls%f%f%f%f%f%f%f%f%f%f", wchBodyPart,
swscanf(value.c_str(), L"%10ls%f%f%f%f%f%f%f%f%f%f%f", wchBodyPart,
#else
swscanf_s(value.c_str(), L"%9ls%f%f%f%f%f%f%f%f%f%f", wchBodyPart,10,
swscanf_s(value.c_str(), L"%9ls%f%f%f%f%f%f%f%f%f%f%f", wchBodyPart,11,
#endif
&pSkinBox->fX,
&pSkinBox->fY,
@ -129,7 +129,8 @@ void DLCSkinFile::addParameter(DLCManager::EDLCParameterType type, const wstring
&pSkinBox->fU,
&pSkinBox->fV,
&pSkinBox->fA,
&pSkinBox->fM);
&pSkinBox->fM,
&pSkinBox->fS);
if(wcscmp(wchBodyPart,L"HEAD")==0)
{

View file

@ -1,8 +1,6 @@
#pragma once
#include "DLCFile.h"
#include "..\..\..\Minecraft.Client\HumanoidModel.h"
// This is added to prevent a building failure, probably should move it to HumanoidModel.h later - Langtanium
#include "..\..\..\Minecraft.Client\SkinOffset.h"
class DLCSkinFile : public DLCFile
{

View file

@ -31,6 +31,9 @@ ModelPart * HumanoidModel::AddOrRetrievePart(SKIN_BOX *pBox)
case eBodyPart_Leg1:
pAttachTo=leg1;
break;
case eBodyPart_Headwear:
pAttachTo=hair;
break;
case eBodyPart_Jacket:
pAttachTo=jacket;
scale=0.25;
@ -51,7 +54,42 @@ ModelPart * HumanoidModel::AddOrRetrievePart(SKIN_BOX *pBox)
pAttachTo=pants1;
scale=0.25;
break;
case eBodyPart_Waist:
pAttachTo=waist;
break;
case eBodyPart_Belt:
pAttachTo=belt;
break;
case eBodyPart_BodyArmor:
pAttachTo=bodyArmor;
break;
case eBodyPart_ArmArmor0:
pAttachTo=armArmor0;
break;
case eBodyPart_ArmArmor1:
pAttachTo=armArmor1;
break;
case eBodyPart_Legging0:
pAttachTo=legging0;
break;
case eBodyPart_Legging1:
pAttachTo=legging1;
break;
case eBodyPart_Sock0:
pAttachTo=sock0;
break;
case eBodyPart_Sock1:
pAttachTo=sock1;
break;
case eBodyPart_Boot0:
pAttachTo=boot0;
break;
case eBodyPart_Boot1:
pAttachTo=boot1;
break;
}
// check if this box has a declared scale
if (pBox->fS > 0) scale = pBox->fS;
// first check this box doesn't already exist
ModelPart *pNewBox = pAttachTo->retrieveChild(pBox);
@ -70,7 +108,7 @@ ModelPart * HumanoidModel::AddOrRetrievePart(SKIN_BOX *pBox)
pNewBox = new ModelPart(this, static_cast<int>(pBox->fU), static_cast<int>(pBox->fV));
pNewBox->visible=false;
if (pBox->fM > 0) pNewBox->bMirror = true;
if (pBox->fM > 0) pNewBox->bMirror = true; // check if this box has the mirror flag
pNewBox->addHumanoidBox(pBox->fX, pBox->fY, pBox->fZ, pBox->fW, pBox->fH, pBox->fD, scale);
// 4J-PB - don't compile here, since the lighting isn't set up. It'll be compiled on first use.
//pNewBox->compile(1.0f/16.0f);
@ -90,6 +128,18 @@ void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, b
sleeve1 = nullptr;
pants0 = nullptr;
pants1 = nullptr;
waist = nullptr;
belt = nullptr;
bodyArmor = nullptr;
armArmor0 = nullptr;
armArmor1 = nullptr;
legging0 = nullptr;
legging1 = nullptr;
sock0 = nullptr;
sock1 = nullptr;
boot0 = nullptr;
boot1 = nullptr;
m_fYOffset=yOffset;
cloak = new ModelPart(this, 0, 0);
@ -115,6 +165,40 @@ void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, b
jacket = new ModelPart(this, 16, 32);
jacket->addHumanoidBox(-4, 0, -2, 8, 12, 4, g + 0.25); // Jacket
jacket->setPos(0, 0 + yOffset, 0);
waist = new ModelPart(this, 0, 0);
waist->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Waist
waist->setPos(0, 0 + yOffset, 0);
belt = new ModelPart(this, 0, 0);
belt->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Belt
belt->setPos(0, 0 + yOffset, 0);
bodyArmor = new ModelPart(this, 0, 0);
bodyArmor->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // BodyArmor
bodyArmor->setPos(0, 0 + yOffset, 0);
armArmor0 = new ModelPart(this, 0, 0);
armArmor0->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // ArmArmor0
armArmor0->setPos(-5, 2 + yOffset, 0);
armArmor1 = new ModelPart(this, 0, 0);
armArmor1->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // ArmArmor1
armArmor1->setPos(5, 2 + yOffset, 0);
legging0 = new ModelPart(this, 0, 0);
legging0->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Legging0
legging0->setPos(-1.9, 12 + yOffset, 0);
legging1 = new ModelPart(this, 0, 0);
legging1->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Legging1
legging1->setPos(1.9, 12 + yOffset, 0);
sock0 = new ModelPart(this, 0, 0);
sock0->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Sock0
sock0->setPos(-1.9, 12 + yOffset, 0);
sock1 = new ModelPart(this, 0, 0);
sock1->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Sock1
sock1->setPos(1.9, 12 + yOffset, 0);
boot0 = new ModelPart(this, 0, 0);
boot0->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Boot0
boot0->setPos(-1.9, 12 + yOffset, 0);
boot1 = new ModelPart(this, 0, 0);
boot1->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Boot1
boot1->setPos(1.9, 12 + yOffset, 0);
}
if (texHeight == 64)
@ -207,6 +291,28 @@ void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, b
pants0->compile(1.0f/16.0f);
if (pants1 != 0)
pants1->compile(1.0f/16.0f);
if (waist != 0)
waist->compile(1.0f/16.0f);
if (belt != 0)
belt->compile(1.0f/16.0f);
if (bodyArmor != 0)
bodyArmor->compile(1.0f/16.0f);
if (armArmor0 != 0)
armArmor0->compile(1.0f/16.0f);
if (armArmor1 != 0)
armArmor1->compile(1.0f/16.0f);
if (legging0 != 0)
legging0->compile(1.0f/16.0f);
if (legging1 != 0)
legging1->compile(1.0f/16.0f);
if (sock0 != 0)
sock0->compile(1.0f/16.0f);
if (sock1 != 0)
sock1->compile(1.0f/16.0f);
if (boot0 != 0)
boot0->compile(1.0f/16.0f);
if (boot1 != 0)
boot1->compile(1.0f/16.0f);
holdingLeftHand=0;
holdingRightHand=0;
@ -295,6 +401,28 @@ void HumanoidModel::render(shared_ptr<Entity> entity, float time, float r, float
pants0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderPants0))>0);
if (pants1 != 0)
pants1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderPants1))>0);
if (waist != 0)
waist->render(scale, usecompiled);
if (belt != 0)
belt->render(scale, usecompiled);
if (bodyArmor != 0)
bodyArmor->render(scale, usecompiled);
if (armArmor0 != 0)
armArmor0->render(scale, usecompiled);
if (armArmor1 != 0)
armArmor1->render(scale, usecompiled);
if (legging0 != 0)
legging0->render(scale, usecompiled);
if (legging1 != 0)
legging1->render(scale, usecompiled);
if (sock0 != 0)
sock0->render(scale, usecompiled);
if (sock1 != 0)
sock1->render(scale, usecompiled);
if (boot0 != 0)
boot0->render(scale, usecompiled);
if (boot1 != 0)
boot1->render(scale, usecompiled);
}
}
@ -603,6 +731,105 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float
pants1->yRot = leg1->yRot;
pants1->zRot = leg1->zRot;
}
if (waist != 0)
{
waist->x = body->x;
waist->y = body->y;
waist->z = body->z;
waist->xRot = body->xRot;
waist->yRot = body->yRot;
waist->zRot = body->zRot;
}
if (belt != 0)
{
belt->x = body->x;
belt->y = body->y;
belt->z = body->z;
belt->xRot = body->xRot;
belt->yRot = body->yRot;
belt->zRot = body->zRot;
}
if (bodyArmor != 0)
{
bodyArmor->x = body->x;
bodyArmor->y = body->y;
bodyArmor->z = body->z;
bodyArmor->xRot = body->xRot;
bodyArmor->yRot = body->yRot;
bodyArmor->zRot = body->zRot;
}
if (armArmor0 != 0)
{
armArmor0->x = arm0->x;
armArmor0->y = arm0->y;
armArmor0->z = arm0->z;
armArmor0->xRot = arm0->xRot;
armArmor0->yRot = arm0->yRot;
armArmor0->zRot = arm0->zRot;
}
if (armArmor1 != 0)
{
armArmor1->x = arm1->x;
armArmor1->y = arm1->y;
armArmor1->z = arm1->z;
armArmor1->xRot = arm1->xRot;
armArmor1->yRot = arm1->yRot;
armArmor1->zRot = arm1->zRot;
}
if (legging0 != 0)
{
legging0->x = leg0->x;
legging0->y = leg0->y;
legging0->z = leg0->z;
legging0->xRot = leg0->xRot;
legging0->yRot = leg0->yRot;
legging0->zRot = leg0->zRot;
}
if (legging1 != 0)
{
legging1->x = leg1->x;
legging1->y = leg1->y;
legging1->z = leg1->z;
legging1->xRot = leg1->xRot;
legging1->yRot = leg1->yRot;
legging1->zRot = leg1->zRot;
}
if (sock0 != 0)
{
sock0->x = leg0->x;
sock0->y = leg0->y;
sock0->z = leg0->z;
sock0->xRot = leg0->xRot;
sock0->yRot = leg0->yRot;
sock0->zRot = leg0->zRot;
}
if (sock1 != 0)
{
sock1->x = leg1->x;
sock1->y = leg1->y;
sock1->z = leg1->z;
sock1->xRot = leg1->xRot;
sock1->yRot = leg1->yRot;
sock1->zRot = leg1->zRot;
}
if (boot0 != 0)
{
boot0->x = leg0->x;
boot0->y = leg0->y;
boot0->z = leg0->z;
boot0->xRot = leg0->xRot;
boot0->yRot = leg0->yRot;
boot0->zRot = leg0->zRot;
}
if (boot1 != 0)
{
boot1->x = leg1->x;
boot1->y = leg1->y;
boot1->z = leg1->z;
boot1->xRot = leg1->xRot;
boot1->yRot = leg1->yRot;
boot1->zRot = leg1->zRot;
}
}
}

View file

@ -1,10 +1,16 @@
#pragma once
#include "Model.h"
#include "SkinOffset.h"
class HumanoidModel : public Model
{
public:
ModelPart *head, *hair, *body, *jacket, *arm0, *sleeve0, *arm1, *sleeve1, *leg0, *pants0, *leg1, *pants1, *ear, *cloak;
// Base geometry
ModelPart *head, *hair, *body, *arm0, *arm1, *leg0, *leg1, *ear, *cloak;
// Second layer/64x64 skin geometry
ModelPart *jacket, *sleeve0, *sleeve1, *pants0, *pants1;
// Extra geometry for DLC skins
ModelPart *waist, *belt, *bodyArmor, *armArmor0, *armArmor1, *legging0, *legging1, *sock0, *sock1, *boot0, *boot1;
//ModelPart *hat;
int holdingLeftHand;

View file

@ -20,16 +20,14 @@ LivingEntityRenderer::LivingEntityRenderer(Model *model, float shadow)
armor = nullptr;
}
LivingEntityRenderer::LivingEntityRenderer(Model *model, float shadow, bool slimHands, bool is64x64)
LivingEntityRenderer::LivingEntityRenderer(Model *model, float shadow, bool is64x64)
{
this->model = model;
if (is64x64)
{
this->modelClassic = new HumanoidModel(0, 0, 64, 64, false);
if (slimHands == true)
this->modelSlim = new HumanoidModel(0, 0, 64, 64, true);
this->modelSlim = new HumanoidModel(0, 0, 64, 64, true);
}
shadowRadius = shadow;

View file

@ -20,7 +20,7 @@ protected:
public:
LivingEntityRenderer(Model *model, float shadow);
LivingEntityRenderer(Model *model, float shadow, bool slimHands, bool is64x64);
LivingEntityRenderer(Model *model, float shadow, bool is64x64);
virtual void render(shared_ptr<Entity> mob, double x, double y, double z, float rot, float a);
virtual void setArmor(Model *armor);

View file

@ -55,7 +55,7 @@ static unsigned int nametagColorForIndex(int index)
ResourceLocation PlayerRenderer::DEFAULT_LOCATION = ResourceLocation(TN_MOB_CHAR);
PlayerRenderer::PlayerRenderer() : LivingEntityRenderer( new HumanoidModel(0), 0.5f, true, true )
PlayerRenderer::PlayerRenderer() : LivingEntityRenderer( new HumanoidModel(0), 0.5f, true )
{
humanoidModel = static_cast<HumanoidModel *>(model);
humanoidModelClassic = static_cast<HumanoidModel *>(modelClassic);
@ -557,7 +557,7 @@ void PlayerRenderer::renderHand()
resModel->sleeve0->render(1 / 16.0f,true);
//Render custom skin boxes on viewmodel - Botch
vector<ModelPart*>* additionalModelParts = Minecraft::GetInstance()->player->GetAdditionalModelParts();
vector<ModelPart*>* additionalModelParts = player->GetAdditionalModelParts();
if (!additionalModelParts) return; //If there are no custom boxes, return. This fixes bug where the game will crash if you select a skin with no additional boxes.
std::unordered_set<ModelPart*> additionalModelPartSet(additionalModelParts->begin(), additionalModelParts->end());
vector<ModelPart*> armchildren = resModel->arm0->children;

View file

@ -31,6 +31,6 @@ enum eBodyPart
typedef struct
{
eBodyPart ePart;
float fX,fY,fZ,fW,fH,fD,fU,fV,fA,fM;
float fX,fY,fZ,fW,fH,fD,fU,fV,fA,fM,fS;
}
SKIN_BOX;

View file

@ -179,6 +179,7 @@ void TextureAndGeometryPacket::read(DataInputStream *dis) //throws IOException
this->BoxDataA[i].fV = dis->readFloat();
this->BoxDataA[i].fA = dis->readFloat();
this->BoxDataA[i].fM = dis->readFloat();
this->BoxDataA[i].fS = dis->readFloat();
}
}
@ -207,6 +208,7 @@ void TextureAndGeometryPacket::write(DataOutputStream *dos) //throws IOException
dos->writeFloat(this->BoxDataA[i].fV);
dos->writeFloat(this->BoxDataA[i].fA);
dos->writeFloat(this->BoxDataA[i].fM);
dos->writeFloat(this->BoxDataA[i].fS);
}
}