| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- /*
- * Copyright (C) 2022 The V-Gears Team
- *
- * This file is part of V-Gears
- *
- * V-Gears is free software: you can redistribute it and/or modify it under
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, version 3.0 (GPLv3) of the License.
- *
- * V-Gears is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
- #pragma once
- #include <vector>
- #include "common/File.h"
- #include "common/TypeDefine.h"
- /**
- * Represents a compiled animations file.
- *
- * Da files are bundled into battle.lgp. They contain information about a skeleton animation. They
- * are heavily compressed, and involve a lot of bit reading to decompile.
- */
- class DaFile{
- public:
- /**
- * Constructor.
- *
- * Reads the file.
- *
- * @param[in, out] file The file to read from. The file contents will not be altered, but
- * it's offset will be changed while reading it.
- */
- DaFile(File file);
- /**
- * Generates .a files from the da file.
- *
- * A file will be generated for each animation in the da file. See {@see VGearsAFile.h} for
- * more info about .a files. Files will be created in the specified path, and will be named
- * like the model id, followed by an underscore, followed a two-digit animation index
- * (starting from 0) followed by the ".a extension". For example, if path is
- * "/home/user/.v-gears", the model id is "ac", and the da file contains three animations,
- * the following files will be generated: "/home/user/.v-gears/ac_00.a",
- * "/home/user/.v-gears/ac_01.a" and "/home/user/.v-gears/ac_02.a".
- *
- * @param[in] model_id ID of the model the animation belongs to, usually a two letter
- * character. Used to generate the file name.
- * @param[in] path Path to the directory where the files will be saved.
- * @return A list of the generated files. They include the path and the extension.
- */
- std::vector<std::string> GenerateAFiles(std::string model_id, std::string path);
- private:
- /**
- * A bone rotation, with all it's values calculated.
- */
- struct Rotation{
- /**
- * Rotation in the X axis, in degrees.
- */
- float x;
- /**
- * Rotation in the Y axis, in degrees.
- */
- float y;
- /**
- * Rotation in the Z axis, in degrees.
- */
- float z;
- };
- /**
- * Processed frame data, to be written to .a files.
- */
- struct FrameData{
- /**
- * Position offset for the frame.
- */
- Rotation position_offset;
- /**
- * List of bone rotations, one per bone.
- */
- std::vector<Rotation> rotations;
- };
- /**
- * Processed animation data, to be written to.a files.
- */
- struct Animation{
- /**
- * Number of frames in the animation.
- */
- unsigned int frame_count;
- /**
- * Number of bones involved in the animation.
- */
- unsigned int bone_count;
- /**
- * Each frame in the animation.
- */
- std::vector<FrameData> frames;
- };
- /**
- * Header for animations. 12 bytes, at the start of each animation.
- */
- struct AnimationHeader {
- /**
- * Number of bones + 1 in the animation.
- *
- * It's not always reliable, the number of bones in the skeleton is the real one. If
- * dealing with a weapon animation, the value will always be 1.
- */
- u32 bone_count;
- /**
- * Number of frames in the animation.
- */
- u32 frame_count;
- /**
- * Size, in bytes, of the animation data.
- */
- u32 data_size;
- };
- /**
- * Mini header for each animation. 5 bytes, immediately after each main header.
- */
- struct AnimationMiniHeader {
- /**
- * Number of frames in the animation.
- *
- * It may not match {@see AnimationHeader.frame_count}.
- */
- u16 frame_count;
- /**
- * Size of the animation data.
- *
- * It should be 6 bytes less than {@see AnimationHeader.data_size}.
- */
- u16 data_size;
- /**
- * Key used for decoding bone data.
- *
- * It indicates how many bits are to be read to get a bone rotation. Not to be used in
- * the first frame, which is not compressed.
- *
- * 0: 12 bits per bone rotation, 36 bits per bone.
- * 2: 10 bits per bone rotation, 30 bits per bone.
- * 4: 8 bits per bone rotation, 30 bits per bone.
- */
- u8 key;
- };
- /**
- * Bone rotation.
- */
- struct BoneRotation {
- /**
- * X axis rotation, as read from the da file.
- */
- u16 s_x;
- /**
- * Y axis rotation, as read from the da file.
- */
- u16 s_y;
- /**
- * Z axis rotation, as read from the da file.
- */
- u16 s_z; // Signed short versions. 0x00
- /**
- * X axis rotation, converted to integer. Rotation between 0 and 4096.
- */
- int i_x;
- /**
- * Y axis rotation, converted to integer. Rotation between 0 and 4096.
- */
- int i_y;
- /**
- * Z axis rotation, converted to integer. Rotation between 0 and 4096.
- */
- int i_z;
- /**
- * X axis rotation, in degrees.
- */
- float f_x;
- /**
- * Y axis rotation, in degrees.
- */
- float f_y;
- /**
- * Z axis rotation, in degrees.
- */
- float f_z;
- };
- /**
- * A frame of an animation.
- *
- * Stores all bone rotations for a frame.
- */
- struct Frame{
- /**
- * Number of bones in the animation frame.
- */
- u32 bone_count;
- /**
- * Position offset.
- *
- * @todo Verify if it's the previous frame?
- */
- BoneRotation position_offset;
- /**
- * Bone rotations for the frame.
- */
- BoneRotation* rotations;
- /**
- * Constructor. Initializes data.
- */
- Frame(){
- bone_count = 0;
- rotations = NULL;
- }
- /**
- * Destructor.
- */
- ~Frame(){
- bone_count = 0;
- delete [] rotations;
- rotations = NULL;
- }
- /**
- * Sets the number of bones and initializes data arrays.
- *
- * @param[in] bones The number of bones.
- */
- void SetBones(u32 bones){
- // Delete the old.
- bone_count = 0;
- delete [] rotations;
- // Create the new.
- rotations = new BoneRotation[bones];
- if (rotations != NULL) bone_count = bones;
- }
- };
- /**
- * Reads the Da file and extracts all the data.
- *
- * @param[in, out] file The file to read from. The file contents will not be altered, but
- * it's offset will be changed while reading it.
- */
- void Read(File file);
- /**
- * Retrieves a value of dynamic size from the byte stream.
- *
- * The first read bit will determine the length of the read data. If it's 1, 7 more bits of
- * data will be read and returned. It it isn't, 16 more bits of data will be read and
- * returned. In total, either 17 or 8 bits of data will be read.
- *
- * @param[in] bytes The byte stream to read from.
- * @param[in,out] stream_bit_offset The bit at which to start reading. For each bit read,
- * it will be advanced by one.
- * @return The read value.
- */
- u16 GetValueFromStream(u8* bytes, u32 &stream_bit_offset);
- /**
- * Reads 2 bytes from the stream as a little endian value.
- *
- * @param[in] bytes The byte stream to read from.
- * @param[in,out] stream_bit_offset The bit at which to start reading. It will be advanced
- * by 16.
- * @return The read value.
- */
- u16 ReadU16LE(u8* bytes, u32 &stream_bit_offset);
- /**
- * Reads an arbitrary length of bits from the stream.
- *
- * @param[in] bytes The byte stream to read from.
- * @param[in,out] stream_bit_offset The bit at which to start reading. It will be advanced
- * by one per read bit.
- * @param[in] bits Number of bits to read.
- * @return The read value.
- */
- int GetBitsFromStream(u8* bytes, u32 &stream_bit_offset, int bits);
- /**
- * Decodes a delta rotation read from the stream.
- *
- * @param[in] bytes The byte stream to read from.
- * @param[in,out] stream_bit_offset The bit at which to start reading. It will be advanced
- * by one per read bit.
- * @param lowered_precision_bits How many bits to sift the read value.
- * @return The decoded value.
- */
- u16 GetCompressedDeltaFromStream(
- u8* bytes, u32& stream_bit_offset, int lowered_precision_bits
- );
- /**
- * Loads the frames in an animation.
- *
- * @param[out] frame Read frame data will be set here.
- * @param[in] bones The number of bones in the animation.
- * @param[in] bit_start Bit to start reading from animation_buffer at.
- * @param[in] animation_buffer The animation data.
- */
- u32 LoadFrames(Frame* frame, int bones, int bit_start, u8* animation_buffer);
- /**
- * List of animations.
- */
- std::vector<Animation> animations_;
- };
|