Fixed a few issues and added more functionality

Fixed player not rendering in third person and armor arm0 not moving with 64x64 skins. Added offsets to held item (main hand) and armor (boots).
This commit is contained in:
Langtanium 2026-04-18 11:41:06 -07:00
parent 0c50f9982c
commit cef65c8df3
8 changed files with 306 additions and 39 deletions

View file

@ -88,8 +88,8 @@ ModelPart * HumanoidModel::AddOrRetrievePart(SKIN_BOX *pBox)
pAttachTo=boot1;
break;
}
// check if this box has a declared scale
if (pBox->fS > 0) scale = pBox->fS;
// check if this box has a declared scale then add it
if (pBox->fS != 0) scale = pBox->fS;
// first check this box doesn't already exist
ModelPart *pNewBox = pAttachTo->retrieveChild(pBox);
@ -109,7 +109,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; // check if this box has the mirror flag
if (pBox->fA > 0) pNewBox->hideWithHelmet = true; // check if this box has the "hide when helmet" is worn flag
if (pBox->fA > 0) pNewBox->hideWithHelmet = true; // check if this box has the "hide when helmet is worn" 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);
@ -329,7 +329,6 @@ void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, b
m_isArmor = isArmor;
}
HumanoidModel::HumanoidModel() : Model()
{
_init(0, 0, 64, 32, false, false);
@ -355,8 +354,8 @@ HumanoidModel::HumanoidModel(float g, float yOffset, int texWidth, int texHeight
_init(g,yOffset,texWidth,texHeight, slim, false);
}
void HumanoidModel::render(shared_ptr<Entity> entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled, vector<SKIN_OFFSET *> *modelOffsets)
{
void HumanoidModel::render(shared_ptr<Entity> entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled)
{
if(entity != nullptr)
{
m_uiAnimOverrideBitmask=entity->getAnimOverrideBitmask();
@ -395,8 +394,6 @@ void HumanoidModel::render(shared_ptr<Entity> entity, float time, float r, float
vector<SKIN_OFFSET *>* pModelOffsets = nullptr;
if (player != nullptr)
pModelOffsets = player->GetModelOffsets();
else if (modelOffsets != nullptr)
pModelOffsets = modelOffsets;
if (pModelOffsets != nullptr)
{
for( SKIN_OFFSET *pModelOffset : *pModelOffsets )
@ -405,91 +402,309 @@ void HumanoidModel::render(shared_ptr<Entity> entity, float time, float r, float
{
case eBodyOffset_Head:
if(pModelOffset->fD == 1)
headOffsets[0] = pModelOffset->fO;
headOffsets[0] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
headOffsets[1] = pModelOffset->fO;
headOffsets[1] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
headOffsets[2] = pModelOffset->fO;
headOffsets[2] = pModelOffset->fO / 16.0f;
break;
case eBodyOffset_Body:
if(pModelOffset->fD == 1)
bodyOffsets[0] = pModelOffset->fO;
bodyOffsets[0] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
bodyOffsets[1] = pModelOffset->fO;
bodyOffsets[1] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
bodyOffsets[2] = pModelOffset->fO;
bodyOffsets[2] = pModelOffset->fO / 16.0f;
break;
case eBodyOffset_Arm0:
if(pModelOffset->fD == 1)
arm0Offsets[0] = pModelOffset->fO;
arm0Offsets[0] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
arm0Offsets[1] = pModelOffset->fO;
arm0Offsets[1] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
arm0Offsets[2] = pModelOffset->fO;
arm0Offsets[2] = pModelOffset->fO / 16.0f;
break;
case eBodyOffset_Arm1:
if(pModelOffset->fD == 1)
arm1Offsets[0] = pModelOffset->fO;
arm1Offsets[0] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
arm1Offsets[1] = pModelOffset->fO;
arm1Offsets[1] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
arm1Offsets[2] = pModelOffset->fO;
arm1Offsets[2] = pModelOffset->fO / 16.0f;
break;
case eBodyOffset_Leg0:
if(pModelOffset->fD == 1)
leg0Offsets[0] = pModelOffset->fO;
leg0Offsets[0] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
leg0Offsets[1] = pModelOffset->fO;
leg0Offsets[1] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
leg0Offsets[2] = pModelOffset->fO;
leg0Offsets[2] = pModelOffset->fO / 16.0f;
break;
case eBodyOffset_Leg1:
if(pModelOffset->fD == 1)
leg1Offsets[0] = pModelOffset->fO;
leg1Offsets[0] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
leg1Offsets[1] = pModelOffset->fO;
leg1Offsets[1] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
leg1Offsets[2] = pModelOffset->fO;
leg1Offsets[2] = pModelOffset->fO / 16.0f;
break;
}
}
if (m_isArmor) // Set offsets for armor
{
for( SKIN_OFFSET *pModelOffset : *pModelOffsets )
{
switch (pModelOffset->ePart)
{
case eBodyOffset_Boot0:
if (leg0->isArmorPart1)
{
if(pModelOffset->fD == 1)
leg0Offsets[0] += pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
leg0Offsets[1] += pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
leg0Offsets[2] += pModelOffset->fO / 16.0f;
}
break;
case eBodyOffset_Boot1:
if (leg1->isArmorPart1)
{
if(pModelOffset->fD == 1)
leg1Offsets[0] += pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
leg1Offsets[1] += pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
leg1Offsets[2] += pModelOffset->fO / 16.0f;
}
break;
}
}
}
}
glPushMatrix();
glTranslatef(headOffsets[0]/16.0f, headOffsets[1]/16.0f, headOffsets[2]/16.0f);
glTranslatef(headOffsets[0], headOffsets[1], headOffsets[2]);
head->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderHead))>0&&(!(m_uiAnimOverrideBitmask&(1<<eAnim_RenderArmorHead))>0||!m_isArmor));
glPopMatrix();
glPushMatrix();
glTranslatef(bodyOffsets[0]/16.0f, bodyOffsets[1]/16.0f, bodyOffsets[2]/16.0f);
glTranslatef(bodyOffsets[0], bodyOffsets[1], bodyOffsets[2]);
body->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderTorso))>0&&(!(m_uiAnimOverrideBitmask&(1<<eAnim_RenderArmorTorso))>0||!m_isArmor));
glPopMatrix();
glPushMatrix();
glTranslatef(arm0Offsets[0]/16.0f, arm0Offsets[1]/16.0f, arm0Offsets[2]/16.0f);
glTranslatef(arm0Offsets[0], arm0Offsets[1], arm0Offsets[2]);
arm0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderArm0))>0&&(!(m_uiAnimOverrideBitmask&(1<<eAnim_RenderArmorArm0))>0||!m_isArmor));
glPopMatrix();
glPushMatrix();
glTranslatef(arm1Offsets[0]/16.0f, arm1Offsets[1]/16.0f, arm1Offsets[2]/16.0f);
glTranslatef(arm1Offsets[0], arm1Offsets[1], arm1Offsets[2]);
arm1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderArm1))>0&&(!(m_uiAnimOverrideBitmask&(1<<eAnim_RenderArmorArm1))>0||!m_isArmor));
glPopMatrix();
glPushMatrix();
glTranslatef(leg0Offsets[0]/16.0f, leg0Offsets[1]/16.0f, leg0Offsets[2]/16.0f);
glTranslatef(leg0Offsets[0], leg0Offsets[1], leg0Offsets[2]);
leg0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderLeg0))>0&&(!(m_uiAnimOverrideBitmask&(1<<eAnim_RenderArmorLeg0))>0||!m_isArmor));
glPopMatrix();
glPushMatrix();
glTranslatef(leg1Offsets[0]/16.0f, leg1Offsets[1]/16.0f, leg1Offsets[2]/16.0f);
glTranslatef(leg1Offsets[0], leg1Offsets[1], leg1Offsets[2]);
leg1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderLeg1))>0&&(!(m_uiAnimOverrideBitmask&(1<<eAnim_RenderArmorLeg1))>0||!m_isArmor));
glPopMatrix();
glPushMatrix();
glTranslatef(headOffsets[0], headOffsets[1], headOffsets[2]);
hair->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderHair))>0);
glPopMatrix();
if (jacket != 0)
{
glPushMatrix();
glTranslatef(bodyOffsets[0], bodyOffsets[1], bodyOffsets[2]);
jacket->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderJacket))>0);
glPopMatrix();
}
if (sleeve0 != 0)
{
glPushMatrix();
glTranslatef(arm0Offsets[0], arm0Offsets[1], arm0Offsets[2]);
sleeve0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderSleeve0))>0);
glPopMatrix();
}
if (sleeve1 != 0)
{
glPushMatrix();
glTranslatef(arm1Offsets[0], arm1Offsets[1], arm1Offsets[2]);
sleeve1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderSleeve1))>0);
glPopMatrix();
}
if (pants0 != 0)
{
glPushMatrix();
glTranslatef(leg0Offsets[0], leg0Offsets[1], leg0Offsets[2]);
pants0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderPants0))>0);
glPopMatrix();
}
if (pants1 != 0)
{
glPushMatrix();
glTranslatef(leg0Offsets[0], leg0Offsets[1], leg0Offsets[2]);
pants1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderPants1))>0);
glPopMatrix();
}
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);
}
}
// This code is the same as above but allows for skin offsets to work in the skin select menu - Langtanium
void HumanoidModel::renderUIOffset(float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled, vector<SKIN_OFFSET *> *modelOffsets)
{
setupAnim(time, r, bob, yRot, xRot, scale, nullptr, m_uiAnimOverrideBitmask);
vector<float> headOffsets = {0, 0, 0};
vector<float> bodyOffsets = {0, 0, 0};
vector<float> arm0Offsets = {0, 0, 0};
vector<float> arm1Offsets = {0, 0, 0};
vector<float> leg0Offsets = {0, 0, 0};
vector<float> leg1Offsets = {0, 0, 0};
vector<SKIN_OFFSET *>* pModelOffsets = nullptr;
if (modelOffsets != nullptr)
pModelOffsets = modelOffsets;
if (pModelOffsets != nullptr)
{
for( SKIN_OFFSET *pModelOffset : *pModelOffsets )
{
switch (pModelOffset->ePart)
{
case eBodyOffset_Head:
if(pModelOffset->fD == 1)
headOffsets[0] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
headOffsets[1] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
headOffsets[2] = pModelOffset->fO / 16.0f;
break;
case eBodyOffset_Body:
if(pModelOffset->fD == 1)
bodyOffsets[0] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
bodyOffsets[1] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
bodyOffsets[2] = pModelOffset->fO / 16.0f;
break;
case eBodyOffset_Arm0:
if(pModelOffset->fD == 1)
arm0Offsets[0] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
arm0Offsets[1] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
arm0Offsets[2] = pModelOffset->fO / 16.0f;
break;
case eBodyOffset_Arm1:
if(pModelOffset->fD == 1)
arm1Offsets[0] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
arm1Offsets[1] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
arm1Offsets[2] = pModelOffset->fO / 16.0f;
break;
case eBodyOffset_Leg0:
if(pModelOffset->fD == 1)
leg0Offsets[0] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
leg0Offsets[1] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
leg0Offsets[2] = pModelOffset->fO / 16.0f;
break;
case eBodyOffset_Leg1:
if(pModelOffset->fD == 1)
leg1Offsets[0] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 2)
leg1Offsets[1] = pModelOffset->fO / 16.0f;
else if(pModelOffset->fD == 3)
leg1Offsets[2] = pModelOffset->fO / 16.0f;
break;
}
}
glPushMatrix();
glTranslatef(headOffsets[0], headOffsets[1], headOffsets[2]);
head->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderHead))>0&&(!(m_uiAnimOverrideBitmask&(1<<eAnim_RenderArmorHead))>0||!m_isArmor));
glPopMatrix();
glPushMatrix();
glTranslatef(bodyOffsets[0], bodyOffsets[1], bodyOffsets[2]);
body->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderTorso))>0&&(!(m_uiAnimOverrideBitmask&(1<<eAnim_RenderArmorTorso))>0||!m_isArmor));
glPopMatrix();
glPushMatrix();
glTranslatef(arm0Offsets[0], arm0Offsets[1], arm0Offsets[2]);
arm0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderArm0))>0&&(!(m_uiAnimOverrideBitmask&(1<<eAnim_RenderArmorArm0))>0||!m_isArmor));
glPopMatrix();
glPushMatrix();
glTranslatef(arm1Offsets[0], arm1Offsets[1], arm1Offsets[2]);
arm1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderArm1))>0&&(!(m_uiAnimOverrideBitmask&(1<<eAnim_RenderArmorArm1))>0||!m_isArmor));
glPopMatrix();
glPushMatrix();
glTranslatef(leg0Offsets[0], leg0Offsets[1], leg0Offsets[2]);
leg0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderLeg0))>0&&(!(m_uiAnimOverrideBitmask&(1<<eAnim_RenderArmorLeg0))>0||!m_isArmor));
glPopMatrix();
glPushMatrix();
glTranslatef(leg1Offsets[0], leg1Offsets[1], leg1Offsets[2]);
leg1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderLeg1))>0&&(!(m_uiAnimOverrideBitmask&(1<<eAnim_RenderArmorLeg1))>0||!m_isArmor));
glPopMatrix();
glPushMatrix();
glTranslatef(headOffsets[0], headOffsets[1], headOffsets[2]);
hair->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderHair))>0);
glPopMatrix();
if (jacket != 0)
{
glPushMatrix();
glTranslatef(bodyOffsets[0], bodyOffsets[1], bodyOffsets[2]);
jacket->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderJacket))>0);
glPopMatrix();
}
if (sleeve0 != 0)
{
glPushMatrix();
glTranslatef(arm0Offsets[0], arm0Offsets[1], arm0Offsets[2]);
sleeve0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderSleeve0))>0);
glPopMatrix();
}
if (sleeve1 != 0)
{
glPushMatrix();
glTranslatef(arm1Offsets[0], arm1Offsets[1], arm1Offsets[2]);
sleeve1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderSleeve1))>0);
glPopMatrix();
}
if (pants0 != 0)
{
glPushMatrix();
glTranslatef(leg0Offsets[0], leg0Offsets[1], leg0Offsets[2]);
pants0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderPants0))>0);
glPopMatrix();
}
if (pants1 != 0)
{
glPushMatrix();
glTranslatef(leg0Offsets[0], leg0Offsets[1], leg0Offsets[2]);
pants1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderPants1))>0);
glPopMatrix();
}
if (waist != 0)
waist->render(scale, usecompiled);
if (belt != 0)