Beispiel #1
0
void ANIM::ANIM2::write(athena::io::IStreamWriter& writer) const
{
    Header head;
    head.evnt = evnt;
    head.unk0 = 1;
    head.interval = mainInterval;
    head.unk1 = 3;
    head.unk2 = 0;
    head.unk3 = 1;

    WordBitmap keyBmp;
    size_t frameCount = 0;
    for (atUint32 frame : frames)
    {
        while (keyBmp.getBit(frame))
            ++frame;
        keyBmp.setBit(frame);
        frameCount = frame + 1;
    }
    head.keyBitmapBitCount = frameCount;
    head.duration = frameCount * mainInterval;
    head.boneChannelCount = bones.size();

    size_t keyframeCount = frames.size();
    std::vector<DNAANIM::Channel> qChannels = channels;
    DNAANIM::BitstreamWriter bsWriter;
    size_t bsSize;
    std::unique_ptr<atUint8[]> bsData = bsWriter.write(chanKeys, keyframeCount, qChannels,
                                                       head.rotDiv, head.translationMult, bsSize);

    /* TODO: Figure out proper scratch size computation */
    head.scratchSize = keyframeCount * channels.size() * 16;

    head.write(writer);
    keyBmp.write(writer);
    writer.writeUint32Big(head.boneChannelCount);
    writer.writeUint32Big(head.boneChannelCount);
    auto cit = qChannels.begin();
    for (const std::pair<atUint32, bool>& bone : bones)
    {
        ChannelDesc desc;
        desc.id = bone.first;
        DNAANIM::Channel& chan = *cit++;
        desc.keyCount1 = keyframeCount;
        desc.initRX = chan.i[0];
        desc.qRX = chan.q[0];
        desc.initRY = chan.i[1];
        desc.qRY = chan.q[1];
        desc.initRZ = chan.i[2];
        desc.qRZ = chan.q[2];
        if (bone.second)
        {
            DNAANIM::Channel& chan = *cit++;
            desc.keyCount2 = keyframeCount;
            desc.initTX = chan.i[0];
            desc.qTX = chan.q[0];
            desc.initTY = chan.i[1];
            desc.qTY = chan.q[1];
            desc.initTZ = chan.i[2];
            desc.qTZ = chan.q[2];
        }
        desc.write(writer);
    }

    writer.writeUBytes(bsData.get(), bsSize);
}
Beispiel #2
0
void ANIM::ANIM2::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
  /* TODO: conform to MP1 ANIM3 */
  Header head;
  head.unk1 = 1;
  head.looping = looping;
  head.interval = mainInterval;
  head.rootBoneId = 0;
  head.scaleMult = 0.f;

  WordBitmap keyBmp;
  size_t frameCount = 0;
  for (atUint32 frame : frames) {
    while (keyBmp.getBit(frame))
      ++frame;
    keyBmp.setBit(frame);
    frameCount = frame + 1;
  }
  head.keyBitmapBitCount = keyBmp.getBitCount();
  head.duration = frameCount * mainInterval;
  head.boneChannelCount = bones.size();

  size_t keyframeCount = frames.size();
  std::vector<DNAANIM::Channel> qChannels = channels;
  DNAANIM::BitstreamWriter bsWriter;
  size_t bsSize;
  std::unique_ptr<atUint8[]> bsData =
      bsWriter.write(chanKeys, keyframeCount, qChannels, m_version == 3 ? 0x7fffff : 0x7fff, head.rotDiv,
                     head.translationMult, head.scaleMult, bsSize);

  /* TODO: Figure out proper scratch size computation */
  head.scratchSize = keyframeCount * channels.size() * 16;

  head.write(writer);
  keyBmp.write(writer);
  writer.writeUint32Big(head.boneChannelCount);
  auto cit = qChannels.begin();
  for (const std::pair<atUint32, std::tuple<bool, bool, bool>>& bone : bones) {
    ChannelDesc desc;
    if (std::get<0>(bone.second)) {
      DNAANIM::Channel& chan = *cit++;
      desc.keyCount1 = keyframeCount;
      desc.initRX = chan.i[0];
      desc.qRX = chan.q[0];
      desc.initRY = chan.i[1];
      desc.qRY = chan.q[1];
      desc.initRZ = chan.i[2];
      desc.qRZ = chan.q[2];
    }
    if (std::get<1>(bone.second)) {
      DNAANIM::Channel& chan = *cit++;
      desc.keyCount2 = keyframeCount;
      desc.initTX = chan.i[0];
      desc.qTX = chan.q[0];
      desc.initTY = chan.i[1];
      desc.qTY = chan.q[1];
      desc.initTZ = chan.i[2];
      desc.qTZ = chan.q[2];
    }
    if (std::get<2>(bone.second)) {
      DNAANIM::Channel& chan = *cit++;
      desc.keyCount3 = keyframeCount;
      desc.initSX = chan.i[0];
      desc.qSX = chan.q[0];
      desc.initSY = chan.i[1];
      desc.qSY = chan.q[1];
      desc.initSZ = chan.i[2];
      desc.qSZ = chan.q[2];
    }
  }

  writer.writeUBytes(bsData.get(), bsSize);
}