Jump to content

PBA

From HedgeDocs
Warning
WIP Page, just adding to start
Depicted in Blender using built-in cloth simulation, and bones constrained to corresponding vertex group
chr_sage.pba contains a node for a cloth mesh made up of only vertices and edges, interconnected in such a way to maintain shape with internal springs

Physics Based Animation ( .pba ) files are bone physics files first found in Sonic Frontiers, and first regularly used in Shadow Generations. The system is capable of using bouncy bones/jiggle physics, rag-doll physics, and cloth simulation. The format is still relatively unknown and has only been brute forced through hex analysis more than code analysis, and there are unfortunately not many examples files to reference.

List of known PBA file examples
Game Filename Description Notes
rangers chr_big.pba Big's fishing line and lure Unused
rangers chr_knucklesdrill.pba Knuckles' drill tail Unused
rangers chr_kodama01.pba Plant toppers on Koco variants Unused
rangers chr_sage.pba Dress cloth physics and self collisions with legs Unused. This is the only known file with a cloth node, and unknown if self collisions were ever in a working state when ported to Shadow Generations
rangers enm_wolf01.pba Wolf tail Unused
rangers mbo_tracker01.pba Tracker's brain stem Only used PBA file in Frontiers
miller bos_metaloverload.pba Metal Overlord's pipes/tubes
miller chr_big.pba Big's fishing line, hook and lure Has collision and more bones than Frontiers version
miller chr_shadow.pba Shadow's head quills
miller chr_shadow_dameba.pba Ameba Doom Morph's tentacles and legs
miller chr_shadow_dwing.pba Doom Wings entirety
miller chr_terios.pba Terios's head quills

Binary Structure

TODO: Decipher, clean up, explain 0_0 might have lots of wrong info!

//------------------------------------------------
//--- 010 Editor v12.0.1 Binary Template
//
//      File: 
//   Authors: Ashrindy, AdelQ
//   Version: 0.0.1
//   Purpose: Shadow Gens PhysicalSkeleton
//  Category: 
// File Mask: *.pba
//  ID Bytes: 
//   History: 
//------------------------------------------------


#include "../include.h"

local uint64 dataPos;

typedef struct{
    Vector4 rows[4];
}Matrix4x4<optimize=false>;

typedef struct{
    byte UnkB1; // Always 2 or 1, unknown flag
    byte UnkB2; // Always 0 or 1, unknown flag
    byte UnkB3[2];  // Padding?
    float Unk_f[4];    // Upper/Lower limits of something?
}LimitsStruct<optimize=false>;

typedef struct{
    SetRandomBackColor();
    StringOffset BoneName;
    int unk; // if this is related to collision, this could be an enum for the collision shape
    float unk2; // Physics dampening? Lower values make bones wobble for longer
    Matrix4x4 mat;  // Most likely not a matrix, has parameters that affect gravity, stretch, etc, and possibly capsule/collision bounds(?) but still working through
}CollisionStruct<optimize=false>;   // Has params that affect physics intensity still, maybe general physics

typedef struct{
    SetRandomBackColor();
    StringOffset BoneName;
    byte Unk1[4]; // All known examples are 01 01 14 00. could be bitflags by the looks of it
    int16 LocalParentBoneIndex;    // FF FF if no bone parent
    int16 LocalBoneIndex;
    int16 RealParentBoneIndex; // Usually the parent of this bone on the real skeleton, but can be any bone in practice. Perhaps a reference for the offset transform?
    int16 Unk3;
    LimitsStruct Limits[6]; // Unknown what these limits line up to (Pos to Neg X, Pos to Neg Y, etc)
    float Unk4<hidden=true>; // Align
    Matrix4x4 mat;  // Possibly bone offset matrix relative to RealParentBoneIndex? A: Two quaternions in row 2 and 4?
}
JiggleStruct<optimize=false>; // Handles bone chain relations for bendy/jiggle physics, as well as presumably transform limits

typedef struct{
    // Starting point needs to align to 16 bytes
    local uint64 CurPos = FTell();
    local uint64 AlignCheck = CurPos % 0x10;
    if (AlignCheck)
        FSeek(CurPos + 0x10 - AlignCheck);
    SetRandomBackColor();
    StringOffset BoneName;
    float unk0; // All known examples = 0.01
    int16 unk1<hidden=true>; // Always FF FF
    int16 if_pinned;    // 1 if no parent present. Possibly this bone controls corresponding vertex if 1, versus vertex controls cooresponding bone if 0
    int16 child_idx;    // FF if no child
    int16 parent_idx;   // FF if no parent
    int16 unk2[2]<hidden=true>;  // Always FF FF
    int16 left_idx;
    int16 right_idx;
}cloth_node<optimize=false>;    // Defines up to 4 neighboring bones in a cloth bone grid

typedef struct{
    SetRandomBackColor();
    int16 verts[2];
    float edge_length;
    float unk_factor;   // Normalized, lateral direct connections = 0.5, lateral skip connections = 0.3, vertical direct connections = 1.0. Maybe a stretch/shrink factor?
}cloth_edges<optimize=false>;   // Cloth sim edge mesh

typedef struct{
    SetRandomBackColor();
    StringOffset cloth_name;
    float unk1[10];
    int16 unk_count1[2];
    int32 cloth_node_count;
    int32 cloth_edge_count;
    int32 unk3<hidden=true>; // Align
    int64 cloth_node_ptr;
    int64 cloth_edge_ptr;
    local int64 prePos = FTell();
    FSeek(cloth_node_ptr + dataPos);
    cloth_node bones[cloth_node_count];
    FSeek(cloth_edge_ptr + dataPos);
    cloth_edges edges[cloth_edge_count];
    FSeek(prePos);
}ClothStruct<optimize=false>;   

typedef struct{
    SetRandomBackColor();
    char signature[4]<name="Signature">;
    int version <format=hex, name="Version">;
    StringOffset SkeletonName;
    uint32 CollisionCount;
    uint32 JiggleCount;
    uint64 CollisionOffset;
    uint64 JiggleOffset;
    uint32 ClothCount;
    uint32 UnkCount;
    uint64 ClothOffset;
    uint64 UnkOffset;
    FSeek(CollisionOffset + dataPos);
    CollisionStruct CollisionStructs[CollisionCount];
    FSeek(JiggleOffset + dataPos);
    JiggleStruct JiggleStructs[JiggleCount];
    FSeek(ClothOffset + dataPos);
    ClothStruct ClothStructs[ClothCount];
}
ResPhysicalSkeleton<open=true>;

ResBinaryFile file("ResPhysicalSkeleton")<name=Str("%s", FileNameGetBase(GetFileName()))>;
Cookies help us deliver our services. By using our services, you agree to our use of cookies.