예제 #1
0
파일: ANIM.cpp 프로젝트: AxioDL/urde
void ANIM::ANIM2::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
  Header head;

  WordBitmap keyBmp;
  for (atUint32 frame : frames) {
    while (keyBmp.getBit(frame))
      ++frame;
    keyBmp.setBit(frame);
  }

  head.binarySize(s);
  keyBmp.binarySize(s);
  s += 4;
  for (const std::pair<atUint32, std::tuple<bool, bool, bool>>& bone : bones) {
    s += 7;
    if (std::get<0>(bone.second))
      s += 9;
    if (std::get<1>(bone.second))
      s += 9;
    if (std::get<2>(bone.second))
      s += 9;
  }

  s += DNAANIM::ComputeBitstreamSize(frames.size(), channels);
}
예제 #2
0
파일: ANIM.cpp 프로젝트: KalDragon/urde
size_t ANIM::ANIM2::binarySize(size_t __isz) const
{
    Header head;

    WordBitmap keyBmp;
    for (atUint32 frame : frames)
    {
        while (keyBmp.getBit(frame))
            ++frame;
        keyBmp.setBit(frame);
    }

    __isz = head.binarySize(__isz);
    __isz = keyBmp.binarySize(__isz);
    __isz += 8;
    for (const std::pair<atUint32, bool>& bone : bones)
    {
        __isz += 17;
        if (bone.second)
            __isz += 9;
    }

    return __isz + DNAANIM::ComputeBitstreamSize(frames.size(), channels);
}
예제 #3
0
파일: ANIM.cpp 프로젝트: KalDragon/urde
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);
}
예제 #4
0
파일: ANIM.cpp 프로젝트: KalDragon/urde
void ANIM::ANIM2::read(athena::io::IStreamReader& reader)
{
    Header head;
    head.read(reader);
    evnt = head.evnt;
    mainInterval = head.interval;

    WordBitmap keyBmp;
    keyBmp.read(reader, head.keyBitmapBitCount);
    frames.clear();
    atUint32 frameAccum = 0;
    for (bool bit : keyBmp)
    {
        if (bit)
            frames.push_back(frameAccum);
        ++frameAccum;
    }
    reader.seek(8);

    bones.clear();
    bones.reserve(head.boneChannelCount);
    channels.clear();
    channels.reserve(head.boneChannelCount);
    atUint16 keyframeCount = 0;
    for (size_t b=0 ; b<head.boneChannelCount ; ++b)
    {
        ChannelDesc desc;
        desc.read(reader);
        bones.emplace_back(desc.id, desc.keyCount2 != 0);

        if (desc.keyCount1)
        {
            channels.emplace_back();
            DNAANIM::Channel& chan = channels.back();
            chan.type = DNAANIM::Channel::Type::Rotation;
            chan.i[0] = desc.initRX;
            chan.q[0] = desc.qRX;
            chan.i[1] = desc.initRY;
            chan.q[1] = desc.qRY;
            chan.i[2] = desc.initRZ;
            chan.q[2] = desc.qRZ;
        }
        keyframeCount = std::max(keyframeCount, desc.keyCount1);

        if (desc.keyCount2)
        {
            channels.emplace_back();
            DNAANIM::Channel& chan = channels.back();
            chan.type = DNAANIM::Channel::Type::Translation;
            chan.i[0] = desc.initTX;
            chan.q[0] = desc.qTX;
            chan.i[1] = desc.initTY;
            chan.q[1] = desc.qTY;
            chan.i[2] = desc.initTZ;
            chan.q[2] = desc.qTZ;
        }
    }

    size_t bsSize = DNAANIM::ComputeBitstreamSize(keyframeCount, channels);
    std::unique_ptr<atUint8[]> bsData = reader.readUBytes(bsSize);
    DNAANIM::BitstreamReader bsReader;
    chanKeys = bsReader.read(bsData.get(), keyframeCount, channels, head.rotDiv, head.translationMult);
}
예제 #5
0
파일: ANIM.cpp 프로젝트: AxioDL/urde
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);
}
예제 #6
0
파일: ANIM.cpp 프로젝트: AxioDL/urde
void ANIM::ANIM2::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
  Header head;
  head.read(reader);
  mainInterval = head.interval;
  looping = bool(head.looping);

  WordBitmap keyBmp;
  keyBmp.read(reader, head.keyBitmapBitCount);
  frames.clear();
  atUint32 frameAccum = 0;
  for (bool bit : keyBmp) {
    if (bit)
      frames.push_back(frameAccum);
    ++frameAccum;
  }
  reader.seek(4);

  bones.clear();
  bones.reserve(head.boneChannelCount);
  channels.clear();
  channels.reserve(head.boneChannelCount);
  atUint16 keyframeCount = 0;
  for (size_t b = 0; b < head.boneChannelCount; ++b) {
    ChannelDesc desc;
    desc.read(reader);
    bones.emplace_back(desc.id, std::make_tuple(desc.keyCount1 != 0, desc.keyCount2 != 0, desc.keyCount3 != 0));

    if (desc.keyCount1) {
      channels.emplace_back();
      DNAANIM::Channel& chan = channels.back();
      chan.type = DNAANIM::Channel::Type::Rotation;
      chan.i[0] = desc.initRX;
      chan.q[0] = desc.qRX;
      chan.i[1] = desc.initRY;
      chan.q[1] = desc.qRY;
      chan.i[2] = desc.initRZ;
      chan.q[2] = desc.qRZ;
    }
    keyframeCount = std::max(keyframeCount, desc.keyCount1);

    if (desc.keyCount2) {
      channels.emplace_back();
      DNAANIM::Channel& chan = channels.back();
      chan.type = DNAANIM::Channel::Type::Translation;
      chan.i[0] = desc.initTX;
      chan.q[0] = desc.qTX;
      chan.i[1] = desc.initTY;
      chan.q[1] = desc.qTY;
      chan.i[2] = desc.initTZ;
      chan.q[2] = desc.qTZ;
    }
    keyframeCount = std::max(keyframeCount, desc.keyCount2);

    if (desc.keyCount3) {
      channels.emplace_back();
      DNAANIM::Channel& chan = channels.back();
      chan.type = DNAANIM::Channel::Type::Scale;
      chan.i[0] = desc.initSX;
      chan.q[0] = desc.qSX;
      chan.i[1] = desc.initSY;
      chan.q[1] = desc.qSY;
      chan.i[2] = desc.initSZ;
      chan.q[2] = desc.qSZ;
    }
    keyframeCount = std::max(keyframeCount, desc.keyCount3);
  }

  size_t bsSize = DNAANIM::ComputeBitstreamSize(keyframeCount, channels);
  std::unique_ptr<atUint8[]> bsData = reader.readUBytes(bsSize);
  DNAANIM::BitstreamReader bsReader;
  chanKeys = bsReader.read(bsData.get(), keyframeCount, channels, head.rotDiv, head.translationMult, head.scaleMult);
}