Tons of animation bug fixes

This commit is contained in:
Jack Andersen 2016-09-05 19:52:51 -10:00
parent 668c4f7eee
commit 9b436b4b23
21 changed files with 168 additions and 85 deletions

View File

@ -325,8 +325,8 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
float quantRangeF = float(quantRange);
/* Pre-pass to calculate translation multiplier */
float maxTransDiff = 0.0f;
float maxScaleDiff = 0.0f;
float maxTransVal = 0.0f;
float maxScaleVal = 0.0f;
auto kit = chanKeys.begin();
for (Channel& chan : channels)
{
@ -334,31 +334,27 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
{
case Channel::Type::Translation:
{
const Value* last = &(*kit)[0];
for (auto it=kit->begin() + 1;
for (auto it=kit->begin();
it != kit->end();
++it)
{
const Value* current = &*it;
maxTransDiff = std::max(maxTransDiff, current->v3.vec[0] - last->v3.vec[0]);
maxTransDiff = std::max(maxTransDiff, current->v3.vec[1] - last->v3.vec[1]);
maxTransDiff = std::max(maxTransDiff, current->v3.vec[2] - last->v3.vec[2]);
last = current;
const Value* key = &*it;
maxTransVal = std::max(maxTransVal, std::fabs(key->v3.vec[0]));
maxTransVal = std::max(maxTransVal, std::fabs(key->v3.vec[1]));
maxTransVal = std::max(maxTransVal, std::fabs(key->v3.vec[2]));
}
break;
}
case Channel::Type::Scale:
{
const Value* last = &(*kit)[0];
for (auto it=kit->begin() + 1;
for (auto it=kit->begin();
it != kit->end();
++it)
{
const Value* current = &*it;
maxScaleDiff = std::max(maxScaleDiff, current->v3.vec[0] - last->v3.vec[0]);
maxScaleDiff = std::max(maxScaleDiff, current->v3.vec[1] - last->v3.vec[1]);
maxScaleDiff = std::max(maxScaleDiff, current->v3.vec[2] - last->v3.vec[2]);
last = current;
const Value* key = &*it;
maxScaleVal = std::max(maxScaleVal, std::fabs(key->v3.vec[0]));
maxScaleVal = std::max(maxScaleVal, std::fabs(key->v3.vec[1]));
maxScaleVal = std::max(maxScaleVal, std::fabs(key->v3.vec[2]));
}
break;
}
@ -366,8 +362,8 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
}
++kit;
}
transMultOut = maxTransDiff / quantRangeF;
scaleMultOut = maxScaleDiff / quantRangeF;
transMultOut = maxTransVal / quantRangeF;
scaleMultOut = maxScaleVal / quantRangeF;
/* Output channel inits */
std::vector<QuantizedValue> initVals;

View File

@ -1148,6 +1148,7 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
});
std::unordered_map<std::string, atInt32> boneIdMap;
std::experimental::optional<CINF> rigCinf;
std::experimental::optional<DNAANIM::RigInverter<CINF>> rigInv;
/* Write out CINF resources */
@ -1164,8 +1165,9 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
if (!rigInv)
{
rigCinf.emplace(cinf);
auto matrices = ds.getBoneMatrices(arm.name);
rigInv.emplace(cinf, matrices);
rigInv.emplace(*rigCinf, matrices);
}
}
ds.close();

View File

@ -10,7 +10,9 @@ using ANIMOutStream = hecl::BlenderConnection::PyOutStream::ANIMOutStream;
void ANIM::IANIM::sendANIMToBlender(hecl::BlenderConnection::PyOutStream& os, const DNAANIM::RigInverter<CINF>& rig) const
{
os.format("act.hecl_fps = round(%f)\n", (1.0f / mainInterval));
os.format("act.hecl_fps = round(%f)\n"
"act.hecl_looping = %s\n",
(1.0f / mainInterval), looping ? "True" : "False");
auto kit = chanKeys.begin();
@ -270,6 +272,7 @@ void ANIM::ANIM2::read(athena::io::IStreamReader& reader)
head.read(reader);
evnt = head.evnt;
mainInterval = head.interval;
looping = bool(head.looping);
WordBitmap keyBmp;
keyBmp.read(reader, head.keyBitmapBitCount);
@ -379,7 +382,7 @@ void ANIM::ANIM2::write(athena::io::IStreamWriter& writer) const
head.unk0 = 1;
head.interval = mainInterval;
head.rootBoneId = 3;
head.looping = 0;
head.looping = looping;
head.unk3 = 1;
WordBitmap keyBmp;
@ -530,6 +533,7 @@ ANIM::ANIM(const BlenderAction& act,
{
m_anim.reset(new struct ANIM2(pc));
IANIM& newAnim = *m_anim;
newAnim.looping = act.looping;
newAnim.bones.reserve(act.channels.size());
size_t extChanCount = 0;

View File

@ -28,6 +28,7 @@ struct ANIM : BigDNA
std::vector<std::vector<DNAANIM::Value>> chanKeys;
float mainInterval = 0.0;
UniqueID32 evnt;
bool looping = false;
void sendANIMToBlender(hecl::BlenderConnection::PyOutStream&, const DNAANIM::RigInverter<CINF>& rig) const;
};
@ -235,6 +236,13 @@ struct ANIM : BigDNA
m_anim->sendANIMToBlender(os, rig);
}
bool isLooping() const
{
if (!m_anim)
return false;
return m_anim->looping;
}
using BlenderAction = hecl::BlenderConnection::DataStream::Actor::Action;
ANIM() = default;

View File

@ -135,7 +135,7 @@ CINF::CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& i
if (bone->children.size())
{
int curId = 4;
RecursiveAddArmatureBone(armature, bone, 3, curId, idMap, nameMap);
RecursiveAddArmatureBone(armature, armature.getChild(bone, 0), 3, curId, idMap, nameMap);
}
bones.emplace_back();
@ -144,6 +144,7 @@ CINF::CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& i
boneOut.id = 3;
boneOut.parentId = 2;
boneOut.origin = bone->origin;
idMap.emplace(std::make_pair(bone->name, 3));
if (bone->children.size())
{

View File

@ -9,7 +9,9 @@ using ANIMOutStream = hecl::BlenderConnection::PyOutStream::ANIMOutStream;
void ANIM::IANIM::sendANIMToBlender(hecl::BlenderConnection::PyOutStream& os, const DNAANIM::RigInverter<CINF>& rig) const
{
os.format("act.hecl_fps = round(%f)\n", (1.0f / mainInterval));
os.format("act.hecl_fps = round(%f)\n"
"act.hecl_looping = %s\n",
(1.0f / mainInterval), looping ? "True" : "False");
auto kit = chanKeys.begin();
@ -398,6 +400,7 @@ void ANIM::ANIM2::read(athena::io::IStreamReader& reader)
Header head;
head.read(reader);
mainInterval = head.interval;
looping = bool(head.looping);
WordBitmap keyBmp;
keyBmp.read(reader, head.keyBitmapBitCount);
@ -476,7 +479,7 @@ void ANIM::ANIM2::write(athena::io::IStreamWriter& writer) const
/* TODO: conform to MP1 ANIM3 */
Header head;
head.unk1 = 1;
head.looping = 1;
head.looping = looping;
head.interval = mainInterval;
head.rootBoneId = 0;
head.scaleMult = 0.f;

View File

@ -27,6 +27,7 @@ struct ANIM : BigDNA
std::vector<DNAANIM::Channel> channels;
std::vector<std::vector<DNAANIM::Value>> chanKeys;
float mainInterval = 0.0;
bool looping = false;
void sendANIMToBlender(hecl::BlenderConnection::PyOutStream&, const DNAANIM::RigInverter<CINF>& rig) const;
};

View File

@ -9,11 +9,14 @@ namespace DNAMP3
using ANIMOutStream = hecl::BlenderConnection::PyOutStream::ANIMOutStream;
void ANIM::IANIM::sendANIMToBlender(hecl::BlenderConnection::PyOutStream& os, const DNAANIM::RigInverter<CINF>& rig, bool additive) const
void ANIM::IANIM::sendANIMToBlender(hecl::BlenderConnection::PyOutStream& os,
const DNAANIM::RigInverter<CINF>& rig,
bool additive) const
{
os.format("act.hecl_fps = round(%f)\n"
"act.hecl_additive = %s\n",
1.0f / mainInterval, additive ? "True" : "False");
"act.hecl_additive = %s\n"
"act.hecl_looping = %s\n",
1.0f / mainInterval, additive ? "True" : "False", looping ? "True" : "False");
auto kit = chanKeys.begin() + 1;
@ -47,13 +50,11 @@ void ANIM::IANIM::sendANIMToBlender(hecl::BlenderConnection::PyOutStream& os, co
"\n";
if (std::get<1>(bone.second))
{
os << "transCurves = []\n"
"transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=0, action_group=bone_string))\n"
"transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=1, action_group=bone_string))\n"
"transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=2, action_group=bone_string))\n"
"\n";
}
if (std::get<2>(bone.second))
os << "scaleCurves = []\n"

View File

@ -27,8 +27,11 @@ struct ANIM : BigDNA
std::vector<DNAANIM::Channel> channels;
std::vector<std::vector<DNAANIM::Value>> chanKeys;
float mainInterval = 0.0;
bool looping = false;
void sendANIMToBlender(hecl::BlenderConnection::PyOutStream&, const DNAANIM::RigInverter<CINF>& rig, bool additive) const;
void sendANIMToBlender(hecl::BlenderConnection::PyOutStream&,
const DNAANIM::RigInverter<CINF>& rig,
bool additive) const;
};
struct ANIM0 : IANIM
@ -111,7 +114,9 @@ struct ANIM : BigDNA
return m_anim->binarySize(__isz + 4);
}
void sendANIMToBlender(hecl::BlenderConnection::PyOutStream& os, const DNAANIM::RigInverter<CINF>& rig, bool additive) const
void sendANIMToBlender(hecl::BlenderConnection::PyOutStream& os,
const DNAANIM::RigInverter<CINF>& rig,
bool additive) const
{
m_anim->sendANIMToBlender(os, rig, additive);
}

View File

@ -47,18 +47,18 @@ CAnimData::CAnimData(ResId id,
const std::shared_ptr<CAnimationManager>& animMgr,
const std::shared_ptr<CTransitionManager>& transMgr,
const TLockedToken<CCharacterFactory>& charFactory)
: x0_charFactory(charFactory),
xc_charInfo(character),
xcc_layoutData(layout),
xd8_modelData(model),
xfc_animCtx(ctx.lock()),
x100_animMgr(animMgr),
x1d8_selfId(id),
x1fc_transMgr(transMgr),
x204_charIdx(charIdx),
x208_defaultAnim(defaultAnim),
x224_pose(layout->GetSegIdList().GetList().size()),
x2fc_poseBuilder(layout)
: x0_charFactory(charFactory),
xc_charInfo(character),
xcc_layoutData(layout),
xd8_modelData(model),
xfc_animCtx(ctx.lock()),
x100_animMgr(animMgr),
x1d8_selfId(id),
x1fc_transMgr(transMgr),
x204_charIdx(charIdx),
x208_defaultAnim(defaultAnim),
x224_pose(layout->GetSegIdList().GetList().size()),
x2fc_poseBuilder(layout)
{
x220_25_loop = loop;

View File

@ -16,6 +16,12 @@ zeus::CVector3f CCharLayoutInfo::GetFromParentUnrotated(const CSegId& id) const
}
}
zeus::CVector3f CCharLayoutInfo::GetFromRootUnrotated(const CSegId& id) const
{
const CCharLayoutNode::Bone& bone = x0_node->GetBoneMap()[id];
return bone.x4_origin;
}
CSegId CCharLayoutInfo::GetSegIdFromString(const std::string& name) const
{
auto it = x18_segIdMap.find(name);

View File

@ -37,6 +37,7 @@ public:
const std::shared_ptr<CCharLayoutNode>& GetRootNode() const {return x0_node;}
const CSegIdList& GetSegIdList() const {return x8_segIdList;}
zeus::CVector3f GetFromParentUnrotated(const CSegId& id) const;
zeus::CVector3f GetFromRootUnrotated(const CSegId& id) const;
CSegId GetSegIdFromString(const std::string& name) const;
};

View File

@ -35,9 +35,10 @@ void CFBStreamedAnimReaderTotals::Initialize(const CFBStreamedCompression& sourc
s32* cumulativesOut = &x4_cumulativeInts32[8*b];
const s32* cumulativesIn = reinterpret_cast<const s32*>(chans);
cumulativesOut[0] = cumulativesIn[0] >> 8;
cumulativesOut[1] = cumulativesIn[1] >> 8;
cumulativesOut[2] = cumulativesIn[2] >> 8;
cumulativesOut[0] = 0;
cumulativesOut[1] = cumulativesIn[0] >> 8;
cumulativesOut[2] = cumulativesIn[1] >> 8;
cumulativesOut[3] = cumulativesIn[2] >> 8;
chans += 12;
u32 tCount = *reinterpret_cast<const u32*>(chans);
@ -46,9 +47,9 @@ void CFBStreamedAnimReaderTotals::Initialize(const CFBStreamedCompression& sourc
{
x8_hasTrans1[b] = true;
const s32* cumulativesIn = reinterpret_cast<const s32*>(chans);
cumulativesOut[3] = cumulativesIn[0] >> 8;
cumulativesOut[4] = cumulativesIn[1] >> 8;
cumulativesOut[5] = cumulativesIn[2] >> 8;
cumulativesOut[4] = cumulativesIn[0] >> 8;
cumulativesOut[5] = cumulativesIn[1] >> 8;
cumulativesOut[6] = cumulativesIn[2] >> 8;
chans += 12;
}
else
@ -63,9 +64,10 @@ void CFBStreamedAnimReaderTotals::Initialize(const CFBStreamedCompression& sourc
chans += 6;
s32* cumulativesOut = &x4_cumulativeInts32[8*b];
cumulativesOut[0] = *reinterpret_cast<const s16*>(chans);
cumulativesOut[1] = *reinterpret_cast<const s16*>(chans + 3);
cumulativesOut[2] = *reinterpret_cast<const s16*>(chans + 6);
cumulativesOut[0] = 0;
cumulativesOut[1] = *reinterpret_cast<const s16*>(chans);
cumulativesOut[2] = *reinterpret_cast<const s16*>(chans + 3);
cumulativesOut[3] = *reinterpret_cast<const s16*>(chans + 6);
chans += 9;
u16 tCount = *reinterpret_cast<const u16*>(chans);
@ -73,9 +75,9 @@ void CFBStreamedAnimReaderTotals::Initialize(const CFBStreamedCompression& sourc
if (tCount)
{
x8_hasTrans1[b] = true;
cumulativesOut[3] = *reinterpret_cast<const s16*>(chans);
cumulativesOut[4] = *reinterpret_cast<const s16*>(chans + 3);
cumulativesOut[5] = *reinterpret_cast<const s16*>(chans + 6);
cumulativesOut[4] = *reinterpret_cast<const s16*>(chans);
cumulativesOut[5] = *reinterpret_cast<const s16*>(chans + 3);
cumulativesOut[6] = *reinterpret_cast<const s16*>(chans + 6);
chans += 9;
}
else
@ -491,8 +493,9 @@ SAdvancementResults CFBStreamedAnimReader::VAdvanceView(const CCharAnimTime& dt)
nextTime = animDur;
res.x0_remTime = nextTime - animDur;
}
xc_curTime = nextTime;
x7c_totals.SetTime(x108_bitLoader, nextTime);
x7c_totals.SetTime(x108_bitLoader, xc_curTime);
UpdatePOIStates();
zeus::CQuaternion nextQ = GetRotation(3);
zeus::CVector3f nextV = GetOffset(3);

View File

@ -16,17 +16,18 @@ void CHierarchyPoseBuilder::BuildIntoHierarchy(const CCharLayoutInfo& layout,
xcec_rootId = boneId;
xcf0_hasRoot = true;
zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId);
x38_treeMap[boneId] = CTreeNode(origin);
CTreeNode& node = x38_treeMap[boneId];
node.x14_offset = origin;
}
else
{
BuildIntoHierarchy(layout, bone.x0_parentId, nullId);
zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId);
CTreeNode& pNode = x38_treeMap[bone.x0_parentId];
CTreeNode node(origin);
CTreeNode& node = x38_treeMap[boneId];
node.x14_offset = origin;
node.x1_sibling = pNode.x0_child;
pNode.x0_child = boneId;
x38_treeMap[boneId] = node;
}
}
}
@ -35,10 +36,19 @@ void CHierarchyPoseBuilder::RecursivelyBuildNoScale(const CSegId& boneId, const
CPoseAsTransforms& pose, const zeus::CQuaternion& parentRot,
const zeus::CMatrix3f& parentXf, const zeus::CVector3f& parentOffset) const
{
zeus::CVector3f bindOffset;
if (x0_layoutDesc.GetScaledLayoutDescription())
{
const CLayoutDescription::CScaledLayoutDescription& desc = *x0_layoutDesc.GetScaledLayoutDescription();
bindOffset = desc.GetCharLayoutInfo()->GetFromRootUnrotated(boneId);
}
else
bindOffset = x0_layoutDesc.GetCharLayoutInfo()->GetFromRootUnrotated(boneId);
zeus::CQuaternion quat = parentRot * node.x4_rotation;
zeus::CMatrix3f xf = quat;
zeus::CVector3f xfOffset = parentXf * node.x14_offset + parentOffset;
pose.Insert(boneId, quat, xfOffset);
pose.Insert(boneId, quat, xfOffset, bindOffset);
CSegId curBone = node.x0_child;
while (curBone != 0)
@ -56,19 +66,27 @@ void CHierarchyPoseBuilder::RecursivelyBuild(const CSegId& boneId, const CTreeNo
zeus::CQuaternion quat = parentRot * node.x4_rotation;
float scale;
zeus::CVector3f bindOffset;
if (x0_layoutDesc.GetScaledLayoutDescription())
scale = x0_layoutDesc.GetScaledLayoutDescription()->GetScale();
{
const CLayoutDescription::CScaledLayoutDescription& desc = *x0_layoutDesc.GetScaledLayoutDescription();
scale = desc.GetScale();
bindOffset = desc.GetCharLayoutInfo()->GetFromRootUnrotated(boneId);
}
else
{
scale = 1.f;
bindOffset = x0_layoutDesc.GetCharLayoutInfo()->GetFromRootUnrotated(boneId);
}
zeus::CMatrix3f mtxXf;
if (scale == 1.f)
mtxXf = quat;
else
mtxXf = parentXf * quat * zeus::CMatrix3f(scale);
mtxXf = parentXf * zeus::CMatrix3f(scale);
zeus::CVector3f xfOffset = parentXf * node.x14_offset + parentOffset;
pose.Insert(boneId, mtxXf, xfOffset);
pose.Insert(boneId, mtxXf, xfOffset, bindOffset);
CSegId curBone = node.x0_child;
while (curBone != 0)
@ -137,12 +155,15 @@ void CHierarchyPoseBuilder::BuildNoScale(CPoseAsTransforms& pose)
void CHierarchyPoseBuilder::Insert(const CSegId& boneId, const zeus::CQuaternion& quat)
{
x38_treeMap[boneId] = CTreeNode(quat);
CTreeNode& node = x38_treeMap[boneId];
node.x4_rotation = quat;
}
void CHierarchyPoseBuilder::Insert(const CSegId& boneId, const zeus::CQuaternion& quat, const zeus::CVector3f& offset)
{
x38_treeMap[boneId] = CTreeNode(quat, offset);
CTreeNode& node = x38_treeMap[boneId];
node.x4_rotation = quat;
node.x14_offset = offset;
}
CHierarchyPoseBuilder::CHierarchyPoseBuilder(const CLayoutDescription& layout)

View File

@ -1,10 +1,11 @@
#include "CPoseAsTransforms.hpp"
#include "CCharLayoutInfo.hpp"
namespace urde
{
CPoseAsTransforms::CPoseAsTransforms(u8 boneCount)
: x1_count(boneCount), xd0_transformArr(new zeus::CTransform[boneCount])
: x1_count(boneCount), xd0_transformArr(new Transform[boneCount])
{}
bool CPoseAsTransforms::ContainsDataFor(const CSegId& id) const
@ -33,26 +34,38 @@ void CPoseAsTransforms::AccumulateScaledTransform(const CSegId& id,
const zeus::CTransform& CPoseAsTransforms::GetTransform(const CSegId& id) const
{
const std::pair<CSegId, CSegId>& link = x8_links[id];
return xd0_transformArr[link.second];
return xd0_transformArr[link.second].m_originToAccum;
}
const zeus::CTransform& CPoseAsTransforms::GetRestToAccumTransform(const CSegId& id) const
{
const std::pair<CSegId, CSegId>& link = x8_links[id];
return xd0_transformArr[link.second].m_restPoseToAccum;
}
const zeus::CVector3f& CPoseAsTransforms::GetOffset(const CSegId& id) const
{
const std::pair<CSegId, CSegId>& link = x8_links[id];
return xd0_transformArr[link.second].origin;
return xd0_transformArr[link.second].m_originToAccum.origin;
}
const zeus::CMatrix3f& CPoseAsTransforms::GetRotation(const CSegId& id) const
{
const std::pair<CSegId, CSegId>& link = x8_links[id];
return xd0_transformArr[link.second].basis;
return xd0_transformArr[link.second].m_originToAccum.basis;
}
void CPoseAsTransforms::Insert(const CSegId& id,
const zeus::CMatrix3f& rotation,
const zeus::CVector3f& offset)
const zeus::CVector3f& offset,
const zeus::CVector3f& restOffset)
{
xd0_transformArr[x0_nextId] = zeus::CTransform(rotation, offset);
Transform& xfOut = xd0_transformArr[x0_nextId];
xfOut.m_originToAccum = zeus::CTransform(rotation, offset);
xfOut.m_restPoseToAccum = xfOut.m_originToAccum * zeus::CTransform::Translate(-restOffset);
printf("INSBONE %d\n", int(id));
xfOut.m_originToAccum.printMatrix();
std::pair<CSegId, CSegId>& link = x8_links[id];
link.first = xd4_lastInserted;
link.second = x0_nextId;

View File

@ -7,13 +7,21 @@
namespace urde
{
class CCharLayoutInfo;
class CPoseAsTransforms
{
public:
struct Transform
{
zeus::CTransform m_originToAccum;
zeus::CTransform m_restPoseToAccum;
};
private:
CSegId x0_nextId = 0;
CSegId x1_count;
std::pair<CSegId, CSegId> x8_links[100];
std::unique_ptr<zeus::CTransform[]> xd0_transformArr;
std::unique_ptr<Transform[]> xd0_transformArr;
CSegId xd4_lastInserted = 0;
public:
CPoseAsTransforms(u8 boneCount);
@ -21,9 +29,13 @@ public:
void Clear();
void AccumulateScaledTransform(const CSegId& id, zeus::CMatrix3f& rotation, float scale) const;
const zeus::CTransform& GetTransform(const CSegId& id) const;
const zeus::CTransform& GetRestToAccumTransform(const CSegId& id) const;
const zeus::CVector3f& GetOffset(const CSegId& id) const;
const zeus::CMatrix3f& GetRotation(const CSegId& id) const;
void Insert(const CSegId& id, const zeus::CMatrix3f& rotation, const zeus::CVector3f& offset);
void Insert(const CSegId& id,
const zeus::CMatrix3f& rotation,
const zeus::CVector3f& offset,
const zeus::CVector3f& restOffset);
};
}

View File

@ -16,7 +16,12 @@ void CSkinBank::GetBankTransforms(std::vector<const zeus::CTransform*>& out,
const CPoseAsTransforms& pose) const
{
for (CSegId id : x0_segments)
out.push_back(&pose.GetTransform(id));
{
const zeus::CTransform& xf = pose.GetRestToAccumTransform(id);
//printf("BONE %d\n", int(id));
//xf.printMatrix();
out.push_back(&xf);
}
}
}

View File

@ -474,14 +474,15 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags,
{
/* Skinned */
std::vector<const zeus::CTransform*> bankTransforms;
bankTransforms.reserve(m_weightVecCount*4);
size_t weightCount = m_weightVecCount * 4;
bankTransforms.reserve(weightCount);
for (size_t i=0 ; i<m_skinBankCount ; ++i)
{
if (cskr && pose)
{
cskr->GetBankTransforms(bankTransforms, *pose, i);
for (size_t w=0 ; w<m_weightVecCount*4 ; ++w)
for (size_t w=0 ; w<weightCount ; ++w)
{
zeus::CMatrix4f& mv = reinterpret_cast<zeus::CMatrix4f&>(*dataCur);
if (w >= bankTransforms.size())
@ -490,15 +491,15 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags,
mv = (CGraphics::g_GXModelView * *bankTransforms[w]).toMatrix4f();
dataCur += sizeof(zeus::CMatrix4f);
}
for (size_t w=0 ; w<m_weightVecCount*4 ; ++w)
for (size_t w=0 ; w<weightCount ; ++w)
{
zeus::CMatrix4f& mvinv = reinterpret_cast<zeus::CMatrix4f&>(*dataCur);
if (w >= bankTransforms.size())
mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
else
{
zeus::CTransform xf = (CGraphics::g_GXModelView * *bankTransforms[w]).inverse();
xf.origin.zeroOut();
zeus::CTransform xf = (CGraphics::g_GXModelView.basis * bankTransforms[w]->basis);
xf.basis.invert();
xf.basis.transpose();
mvinv = xf.toMatrix4f();
}
@ -509,13 +510,13 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags,
}
else
{
for (size_t w=0 ; w<m_weightVecCount*4 ; ++w)
for (size_t w=0 ; w<weightCount ; ++w)
{
zeus::CMatrix4f& mv = reinterpret_cast<zeus::CMatrix4f&>(*dataCur);
mv = CGraphics::g_GXModelView.toMatrix4f();
dataCur += sizeof(zeus::CMatrix4f);
}
for (size_t w=0 ; w<m_weightVecCount*4 ; ++w)
for (size_t w=0 ; w<weightCount ; ++w)
{
zeus::CMatrix4f& mvinv = reinterpret_cast<zeus::CMatrix4f&>(*dataCur);
mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
@ -675,7 +676,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* stor
{
hecl::Runtime::ShaderTag tag(mat.heclIr,
hmdlMeta.colorCount, hmdlMeta.uvCount, hmdlMeta.weightCount,
0, 8, boo::Primitive(hmdlMeta.topology),
hmdlMeta.weightCount * 4, 8, boo::Primitive(hmdlMeta.topology),
true, true, true);
matSet.m_shaders.push_back(CModelShaders::g_ModelShaders->buildExtendedShader(tag, mat.heclIr, "CMDL", ctx));
}

2
amuse

@ -1 +1 @@
Subproject commit af68ee61e15567e74f057964fb2b852476c1e666
Subproject commit 38f24ce3e43200a1dde31f97fa37c2cf4a816ba0

2
hecl

@ -1 +1 @@
Subproject commit 29c77ef93ca9c5102c01e4f81ef3b5b7675150dd
Subproject commit c4206ca8007bf9d0b7fd9752be932b9a285905ef

@ -1 +1 @@
Subproject commit 24414bf4d447697caa048a9346ffa9870cb530a5
Subproject commit 2ec24ac74cf269d29926c6e78372a279eeb1cd74