Re: Boiling Point: Road to Hell *.RF2
Posted: Wed Feb 09, 2022 10:50 pm
From what I gathered in BipedBones section of the RF2 file, each bone has the following properties:grandshot wrote: ↑Wed Feb 09, 2022 8:39 pm Trying to research bone anim format. By reverse engineering the verender2.dll file with included *.pdb, managed to get bone structures. Turned out what they having the following format:
PACKED_ANIM structure is next:Code: Select all
struct BONE { char name[20]; byte parentID; byte groupID; byte rootGroupID; uint32 packedAnimSize; if( packedAnimSize ) { PACKED_ANIM packedVectors; PACKED_ANIM packedQuats; }; };Array structure in turn:Code: Select all
struct PACKED_ANIM( int itemType ) { uint32 numPackedItems; PACKED_VECTOR3 item[numPackedItems]; //Vectors or Quats packed to 3x uint16 per item. Unpacking functions is included. ARRAY packedIDs; ARRAY originalIDs; uint16 numFrames; //total frame count for bone. Often same value as in header. Useful for determine structure ending. };Main problem here is how to allocate correct size of items in array. No matter how I tried, I cant figure out. Obvious things such as numItems mul to numBits and align to ceil bytes dont fit here.Code: Select all
struct ARRAY { uint16 numItems; uint16 numBits; //per item uint64 item : numBits // in the count of numItems. uint64 because numBits can be 48. Bitfield padding off ubyte numBitsKey : 8; uint64 mask : numBits; //not used? };
This is the last frontier in the fully research of the format. In attch I privide my 010 editor template for parsing bones and verender2.dll & pdb.
ve_boneanim_research.zip
Code: Select all
char* name (Always 0x15)
byte parent;
byte group;
byte rootGroupID (I think this is supposed to be for special bone names);
uint32 MemoryCommitSize;
uint32 array_count
packed3DVector* v
packedQuat* q
I still have not figured out the operations needed to turn it into a standard animation format, but I think it requires using Slerp(quat) and Lerp(vector), several unknown math operations, then converting the resultant 4x3 Matrix into a TAnimKey structure.
That's all I know so far. I've been busy writing tools to decompress the *.dt textures in the cache folder, parsing the map format, and documenting (and eventually writing tools to decompile) the LV2 file structure. I'm still trying to figure out the layer masks and the detail object layer but it's coming along.
EDIT: Upon further inspection, I was looking at the wrong place for this. I see that the sequence of data where i assumed the Quats were is actually a TShrinkedArray of elements or struct ARRAY in the quoted data structure.
According to IDA Pro, allocating a TShrinkedArray may look like this:
Code: Select all
void __usercall TShrinkedArray::Allocate(TShrinkedArray *this@<esi>, int s@<ebx>)
{
__int64 v2; // rax
int v3; // ecx
unsigned int *element; // edi
unsigned int *v5; // eax
size_t v6; // [esp-8h] [ebp-Ch]
v2 = s * this->nBits + 31;
v3 = ((BYTE4(v2) & 0x1F) + (int)v2) >> 5;
if ( v3 != (this->nBits * this->array_size + 31) / 32 )
{
element = this->element;
this->array_size = s;
v5 = (unsigned int *)operator new(4 * v3);
v6 = 4 * ((this->nBits * this->num + 31) / 32);
this->element = v5;
memmove(v5, element, v6);
if ( element )
operator delete(element);
}
}
