mirror of https://github.com/AxioDL/metaforce.git
MP3 ANIM updates
This commit is contained in:
parent
60142602fd
commit
bffb491769
|
@ -18,6 +18,7 @@ struct CharacterResInfo
|
||||||
IDTYPE cmdl;
|
IDTYPE cmdl;
|
||||||
IDTYPE cskr;
|
IDTYPE cskr;
|
||||||
IDTYPE cinf;
|
IDTYPE cinf;
|
||||||
|
std::vector<std::pair<HECL::FourCC, std::pair<IDTYPE, IDTYPE>>> overlays;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class PAKRouter, class ANCSDNA, class MaterialSet, class SurfaceHeader, atUint32 CMDLVersion>
|
template <class PAKRouter, class ANCSDNA, class MaterialSet, class SurfaceHeader, atUint32 CMDLVersion>
|
||||||
|
@ -124,6 +125,28 @@ bool ReadANCSToBlender(HECL::BlenderConnection& conn,
|
||||||
"obj.parent_type = 'ARMATURE'\n"
|
"obj.parent_type = 'ARMATURE'\n"
|
||||||
"actor_subtype.linked_mesh = obj.name\n\n";
|
"actor_subtype.linked_mesh = obj.name\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Link overlays */
|
||||||
|
for (const auto& overlay : info.overlays)
|
||||||
|
{
|
||||||
|
os << "overlay = actor_subtype.overlays.add()\n";
|
||||||
|
os.format("overlay.name = '%s'\n", overlay.first.toString().c_str());
|
||||||
|
|
||||||
|
/* Link CMDL */
|
||||||
|
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(overlay.second.first, nullptr, true);
|
||||||
|
if (cmdlE)
|
||||||
|
{
|
||||||
|
HECL::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
|
||||||
|
os.linkBlend(cmdlPath.getAbsolutePathUTF8(), pakRouter.getBestEntryName(*cmdlE), true);
|
||||||
|
|
||||||
|
/* Attach CMDL to CINF */
|
||||||
|
os << "if obj.name not in bpy.context.scene.objects:\n"
|
||||||
|
" bpy.context.scene.objects.link(obj)\n"
|
||||||
|
"obj.parent = arm_obj\n"
|
||||||
|
"obj.parent_type = 'ARMATURE'\n"
|
||||||
|
"overlay.linked_mesh = obj.name\n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get animation primitives */
|
/* Get animation primitives */
|
||||||
|
@ -136,8 +159,6 @@ bool ReadANCSToBlender(HECL::BlenderConnection& conn,
|
||||||
{
|
{
|
||||||
os.format("act = bpy.data.actions.new('%s')\n"
|
os.format("act = bpy.data.actions.new('%s')\n"
|
||||||
"act.use_fake_user = True\n", id.second.first.c_str());
|
"act.use_fake_user = True\n", id.second.first.c_str());
|
||||||
if (id.second.second.toString() == std::string("6DD5CB1DC42BFBB3"))
|
|
||||||
printf("");
|
|
||||||
anim.sendANIMToBlender(os, cinf);
|
anim.sendANIMToBlender(os, cinf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,10 @@ static inline Value DequantizeRotation_3(const QuantizedValue& v, atUint32 div)
|
||||||
v.v[2] * q,
|
v.v[2] * q,
|
||||||
v.v[3] * q
|
v.v[3] * q
|
||||||
};
|
};
|
||||||
|
if (retval.v4.vec[0] < 0)
|
||||||
|
retval.v4.vec[0] = -1.0 - retval.v4.vec[0];
|
||||||
|
else
|
||||||
|
retval.v4.vec[0] = 1.0 - retval.v4.vec[0];
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +93,7 @@ bool BitstreamReader::dequantizeBit(const atUint8* data)
|
||||||
|
|
||||||
/* Fill 32 bit buffer with region containing bits */
|
/* Fill 32 bit buffer with region containing bits */
|
||||||
/* Make them least significant */
|
/* Make them least significant */
|
||||||
atUint32 tempBuf = HECL::SBig(*(atUint32*)(data + byteCur)) >> bitRem;
|
atUint32 tempBuf = HECL::SBig(*reinterpret_cast<const atUint32*>(data + byteCur)) >> bitRem;
|
||||||
|
|
||||||
/* That's it */
|
/* That's it */
|
||||||
m_bitCur += 1;
|
m_bitCur += 1;
|
||||||
|
@ -103,28 +107,28 @@ atInt16 BitstreamReader::dequantize(const atUint8* data, atUint8 q)
|
||||||
|
|
||||||
/* Fill 32 bit buffer with region containing bits */
|
/* Fill 32 bit buffer with region containing bits */
|
||||||
/* Make them least significant */
|
/* Make them least significant */
|
||||||
atUint32 tempBuf = HECL::SBig(*(atUint32*)(data + byteCur)) >> bitRem;
|
atUint32 tempBuf = HECL::SBig(*reinterpret_cast<const atUint32*>(data + byteCur)) >> bitRem;
|
||||||
|
|
||||||
/* If this shift underflows the value, buffer the next 32 bits */
|
/* If this shift underflows the value, buffer the next 32 bits */
|
||||||
/* And tack onto shifted buffer */
|
/* And tack onto shifted buffer */
|
||||||
if ((bitRem + q) > 32)
|
if ((bitRem + q) > 32)
|
||||||
{
|
{
|
||||||
atUint32 tempBuf2 = HECL::SBig(*(atUint32*)(data + byteCur + 4));
|
atUint32 tempBuf2 = HECL::SBig(*reinterpret_cast<const atUint32*>(data + byteCur + 4));
|
||||||
tempBuf |= (tempBuf2 << (32 - bitRem));
|
tempBuf |= (tempBuf2 << (32 - bitRem));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pick out sign */
|
/* Mask it */
|
||||||
|
atUint32 mask = (1 << q) - 1;
|
||||||
|
tempBuf &= mask;
|
||||||
|
|
||||||
|
/* Sign extend */
|
||||||
atUint32 sign = (tempBuf >> (q - 1)) & 0x1;
|
atUint32 sign = (tempBuf >> (q - 1)) & 0x1;
|
||||||
if (sign)
|
if (sign)
|
||||||
tempBuf = ~tempBuf;
|
tempBuf |= ~0 << q;
|
||||||
|
|
||||||
/* mask it (excluding sign bit) */
|
|
||||||
atUint32 mask = (1 << (q - 1)) - 1;
|
|
||||||
tempBuf &= mask;
|
|
||||||
|
|
||||||
/* Return delta value */
|
/* Return delta value */
|
||||||
m_bitCur += q;
|
m_bitCur += q;
|
||||||
return atInt32(sign ? (tempBuf + 1) * -1 : tempBuf);
|
return atInt32(tempBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::vector<Value>>
|
std::vector<std::vector<Value>>
|
||||||
|
@ -141,8 +145,7 @@ BitstreamReader::read(const atUint8* data,
|
||||||
chanAccum.reserve(channels.size());
|
chanAccum.reserve(channels.size());
|
||||||
for (const Channel& chan : channels)
|
for (const Channel& chan : channels)
|
||||||
{
|
{
|
||||||
chanAccum.push_back({chan.i[0], chan.i[1], chan.i[2]});
|
chanAccum.push_back(chan.i);
|
||||||
QuantizedValue& accum = chanAccum.back();
|
|
||||||
|
|
||||||
chanKeys.emplace_back();
|
chanKeys.emplace_back();
|
||||||
std::vector<Value>& keys = chanKeys.back();
|
std::vector<Value>& keys = chanKeys.back();
|
||||||
|
@ -171,7 +174,7 @@ BitstreamReader::read(const atUint8* data,
|
||||||
}
|
}
|
||||||
case Channel::ROTATION_MP3:
|
case Channel::ROTATION_MP3:
|
||||||
{
|
{
|
||||||
QuantizedRot qr = {{chan.i[1], chan.i[2], chan.i[3]}, chan.i[0] != 0};
|
QuantizedRot qr = {{chan.i[1], chan.i[2], chan.i[3]}, bool(chan.i[0] & 0x1)};
|
||||||
keys.emplace_back(DequantizeRotation(qr, rotDiv));
|
keys.emplace_back(DequantizeRotation(qr, rotDiv));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -199,9 +202,12 @@ BitstreamReader::read(const atUint8* data,
|
||||||
}
|
}
|
||||||
case Channel::TRANSLATION:
|
case Channel::TRANSLATION:
|
||||||
{
|
{
|
||||||
p[0] += dequantize(data, chan.q[0]);
|
atInt16 val1 = dequantize(data, chan.q[0]);
|
||||||
p[1] += dequantize(data, chan.q[1]);
|
p[0] += val1;
|
||||||
p[2] += dequantize(data, chan.q[2]);
|
atInt16 val2 = dequantize(data, chan.q[1]);
|
||||||
|
p[1] += val2;
|
||||||
|
atInt16 val3 = dequantize(data, chan.q[2]);
|
||||||
|
p[2] += val3;
|
||||||
kit->push_back({p[0] * transMult, p[1] * transMult, p[2] * transMult});
|
kit->push_back({p[0] * transMult, p[1] * transMult, p[2] * transMult});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -220,15 +226,16 @@ BitstreamReader::read(const atUint8* data,
|
||||||
}
|
}
|
||||||
case Channel::ROTATION_MP3:
|
case Channel::ROTATION_MP3:
|
||||||
{
|
{
|
||||||
p[0] += dequantize(data, chan.q[0]);
|
atInt16 val1 = dequantize(data, chan.q[0]);
|
||||||
p[1] += dequantize(data, chan.q[1]);
|
p[0] += val1;
|
||||||
p[2] += dequantize(data, chan.q[2]);
|
atInt16 val2 = dequantize(data, chan.q[1]);
|
||||||
p[3] += dequantize(data, chan.q[3]);
|
p[1] += val2;
|
||||||
#if 0
|
atInt16 val3 = dequantize(data, chan.q[2]);
|
||||||
kit->emplace_back(DequantizeRotation_3(p, rotDiv));
|
p[2] += val3;
|
||||||
#else
|
atInt16 val4 = dequantize(data, chan.q[3]);
|
||||||
kit->emplace_back(DequantizeRotation({p[1], p[2], p[3]}, p[0] < 0));
|
p[3] += val4;
|
||||||
#endif
|
QuantizedRot qr = {{p[1], p[2], p[3]}, bool(p[0] & 0x1)};
|
||||||
|
kit->emplace_back(DequantizeRotation(qr, rotDiv));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
|
|
|
@ -361,6 +361,9 @@ struct ANCS : BigYAML
|
||||||
chOut.cmdl = ci.cmdl;
|
chOut.cmdl = ci.cmdl;
|
||||||
chOut.cskr = ci.cskr;
|
chOut.cskr = ci.cskr;
|
||||||
chOut.cinf = ci.cinf;
|
chOut.cinf = ci.cinf;
|
||||||
|
|
||||||
|
if (ci.cmdlOverlay)
|
||||||
|
chOut.overlays.emplace_back(FOURCC('OVER'), std::make_pair(ci.cmdlOverlay, ci.cskrOverlay));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ void ANCS::CharacterSet::CharacterInfo::read(Athena::io::IStreamReader& reader)
|
||||||
if (sectionCount > 3)
|
if (sectionCount > 3)
|
||||||
{
|
{
|
||||||
cmdlOverlay.read(reader);
|
cmdlOverlay.read(reader);
|
||||||
cskrOverley.read(reader);
|
cskrOverlay.read(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
animIdxs.clear();
|
animIdxs.clear();
|
||||||
|
@ -144,7 +144,7 @@ void ANCS::CharacterSet::CharacterInfo::write(Athena::io::IStreamWriter& writer)
|
||||||
if (sectionCount > 3)
|
if (sectionCount > 3)
|
||||||
{
|
{
|
||||||
cmdlOverlay.write(writer);
|
cmdlOverlay.write(writer);
|
||||||
cskrOverley.write(writer);
|
cskrOverlay.write(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sectionCount > 4)
|
if (sectionCount > 4)
|
||||||
|
@ -213,8 +213,8 @@ void ANCS::CharacterSet::CharacterInfo::fromYAML(Athena::io::YAMLDocReader& read
|
||||||
|
|
||||||
if (sectionCount > 3)
|
if (sectionCount > 3)
|
||||||
{
|
{
|
||||||
reader.enumerate("cmdlOverride", cmdlOverlay);
|
reader.enumerate("cmdlOverlay", cmdlOverlay);
|
||||||
reader.enumerate("cskrOverride", cskrOverley);
|
reader.enumerate("cskrOverlay", cskrOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
animIdxs.clear();
|
animIdxs.clear();
|
||||||
|
@ -299,8 +299,8 @@ void ANCS::CharacterSet::CharacterInfo::toYAML(Athena::io::YAMLDocWriter& writer
|
||||||
|
|
||||||
if (sectionCount > 3)
|
if (sectionCount > 3)
|
||||||
{
|
{
|
||||||
writer.enumerate("cmdlOverride", cmdlOverlay);
|
writer.enumerate("cmdlOverlay", cmdlOverlay);
|
||||||
writer.enumerate("cskrOverride", cskrOverley);
|
writer.enumerate("cskrOverlay", cskrOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sectionCount > 4)
|
if (sectionCount > 4)
|
||||||
|
|
|
@ -86,7 +86,7 @@ struct ANCS : BigYAML
|
||||||
std::vector<Effect> effects;
|
std::vector<Effect> effects;
|
||||||
|
|
||||||
UniqueID32 cmdlOverlay;
|
UniqueID32 cmdlOverlay;
|
||||||
UniqueID32 cskrOverley;
|
UniqueID32 cskrOverlay;
|
||||||
|
|
||||||
std::vector<atUint32> animIdxs;
|
std::vector<atUint32> animIdxs;
|
||||||
|
|
||||||
|
@ -198,6 +198,9 @@ struct ANCS : BigYAML
|
||||||
chOut.cmdl = ci.cmdl;
|
chOut.cmdl = ci.cmdl;
|
||||||
chOut.cskr = ci.cskr;
|
chOut.cskr = ci.cskr;
|
||||||
chOut.cinf = ci.cinf;
|
chOut.cinf = ci.cinf;
|
||||||
|
|
||||||
|
if (ci.cmdlOverlay)
|
||||||
|
chOut.overlays.emplace_back(FOURCC('OVER'), std::make_pair(ci.cmdlOverlay, ci.cskrOverlay));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ void PAKBridge::addCMDLRigPairs(std::unordered_map<UniqueID32, std::pair<UniqueI
|
||||||
{
|
{
|
||||||
addTo[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
|
addTo[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
|
||||||
if (ci.cmdlOverlay)
|
if (ci.cmdlOverlay)
|
||||||
addTo[ci.cmdlOverlay] = std::make_pair(ci.cskrOverley, ci.cinf);
|
addTo[ci.cmdlOverlay] = std::make_pair(ci.cskrOverlay, ci.cinf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,20 @@ void ANIM::IANIM::sendANIMToBlender(HECL::BlenderConnection::PyOutStream& os, co
|
||||||
os.format("act.hecl_fps = round(%f)\n", (1.0f / mainInterval));
|
os.format("act.hecl_fps = round(%f)\n", (1.0f / mainInterval));
|
||||||
|
|
||||||
auto kit = chanKeys.begin() + 1;
|
auto kit = chanKeys.begin() + 1;
|
||||||
|
int idx = 1;
|
||||||
for (const std::pair<atUint32, std::tuple<bool,bool,bool>>& bone : bones)
|
for (const std::pair<atUint32, std::tuple<bool,bool,bool>>& bone : bones)
|
||||||
{
|
{
|
||||||
const std::string* bName = cinf.getBoneNameFromId(bone.first);
|
const std::string* bName = cinf.getBoneNameFromId(bone.first);
|
||||||
if (!bName)
|
if (!bName)
|
||||||
|
{
|
||||||
|
if (std::get<0>(bone.second))
|
||||||
|
++kit;
|
||||||
|
if (std::get<1>(bone.second))
|
||||||
|
++kit;
|
||||||
|
if (std::get<2>(bone.second))
|
||||||
|
++kit;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
os.format("bone_string = '%s'\n", bName->c_str());
|
os.format("bone_string = '%s'\n", bName->c_str());
|
||||||
os << "action_group = act.groups.new(bone_string)\n"
|
os << "action_group = act.groups.new(bone_string)\n"
|
||||||
|
@ -59,6 +68,7 @@ void ANIM::IANIM::sendANIMToBlender(HECL::BlenderConnection::PyOutStream& os, co
|
||||||
if (std::get<0>(bone.second))
|
if (std::get<0>(bone.second))
|
||||||
{
|
{
|
||||||
const std::vector<DNAANIM::Value>& rotKeys = *kit++;
|
const std::vector<DNAANIM::Value>& rotKeys = *kit++;
|
||||||
|
++idx;
|
||||||
for (int c=0 ; c<4 ; ++c)
|
for (int c=0 ; c<4 ; ++c)
|
||||||
{
|
{
|
||||||
auto frameit = frames.begin();
|
auto frameit = frames.begin();
|
||||||
|
@ -71,6 +81,7 @@ void ANIM::IANIM::sendANIMToBlender(HECL::BlenderConnection::PyOutStream& os, co
|
||||||
if (std::get<1>(bone.second))
|
if (std::get<1>(bone.second))
|
||||||
{
|
{
|
||||||
const std::vector<DNAANIM::Value>& transKeys = *kit++;
|
const std::vector<DNAANIM::Value>& transKeys = *kit++;
|
||||||
|
++idx;
|
||||||
for (int c=0 ; c<3 ; ++c)
|
for (int c=0 ; c<3 ; ++c)
|
||||||
{
|
{
|
||||||
auto frameit = frames.begin();
|
auto frameit = frames.begin();
|
||||||
|
@ -83,6 +94,7 @@ void ANIM::IANIM::sendANIMToBlender(HECL::BlenderConnection::PyOutStream& os, co
|
||||||
if (std::get<2>(bone.second))
|
if (std::get<2>(bone.second))
|
||||||
{
|
{
|
||||||
const std::vector<DNAANIM::Value>& scaleKeys = *kit++;
|
const std::vector<DNAANIM::Value>& scaleKeys = *kit++;
|
||||||
|
++idx;
|
||||||
for (int c=0 ; c<3 ; ++c)
|
for (int c=0 ; c<3 ; ++c)
|
||||||
{
|
{
|
||||||
auto frameit = frames.begin();
|
auto frameit = frames.begin();
|
||||||
|
|
|
@ -290,6 +290,9 @@ struct CHAR : BigYAML
|
||||||
chOut.cmdl = characterInfo.cmdl;
|
chOut.cmdl = characterInfo.cmdl;
|
||||||
chOut.cskr = characterInfo.cskr;
|
chOut.cskr = characterInfo.cskr;
|
||||||
chOut.cinf = characterInfo.cinf;
|
chOut.cinf = characterInfo.cinf;
|
||||||
|
|
||||||
|
for (const CharacterInfo::Overlay& overlay : characterInfo.overlays)
|
||||||
|
chOut.overlays.emplace_back(overlay.type, std::make_pair(overlay.cmdl, overlay.cskr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void getAnimationResInfo(std::map<atUint32, std::pair<std::string, UniqueID64>>& out) const
|
void getAnimationResInfo(std::map<atUint32, std::pair<std::string, UniqueID64>>& out) const
|
||||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit 7cb3419155242dd4fae867dc052af101fdb857f6
|
Subproject commit f4d17c323d2801ec76d1126c8fe1931b5e88c12c
|
Loading…
Reference in New Issue