MP3 ANIM updates

This commit is contained in:
Jack Andersen 2015-09-26 16:24:03 -10:00
parent 60142602fd
commit bffb491769
9 changed files with 85 additions and 36 deletions

View File

@ -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);
} }

View File

@ -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;

View File

@ -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));
} }
} }

View File

@ -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)

View File

@ -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));
} }
} }

View File

@ -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);
} }
} }
} }

View File

@ -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();

View File

@ -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

@ -1 +1 @@
Subproject commit 7cb3419155242dd4fae867dc052af101fdb857f6 Subproject commit f4d17c323d2801ec76d1126c8fe1931b5e88c12c