A sprite rigger & animator desktop application.
Clone the project
git clone https://github.com/JoshBot-Debug/SpriteRigger.git
cd SpriteRiggerInitialize all submodules
git submodule update --init --recursive
cd vendor/imgui
git checkout docking
cd ../..Install dependencies like glm, opengl
sudo apt update
sudo apt install \
libgl1-mesa-dev \
libglu1-mesa-dev \
mesa-common-dev \
libglfw3-dev \
libopengl-dev \
libglx-dev \
libglm-dev \
libstb-devBuild the project
cmake -B build -DCMAKE_BUILD_TYPE=Debug && cmake --build buildRun the project
./build/SpriteRiggerThe project state is stored in a single container file with extension .sprig.
filename.sprig
┌───────────────────────────────────────────────┐
│ Header │
│ - magic (x bytes) │
│ - version (uint32_t) │
│ - manifestSize (uint64_t) │
│ - chunksSize (uint64_t) │
├───────────────────────────────────────────────┤
│ Manifest (binary) │
│ - entries: { key, offset, size } │
├───────────────────────────────────────────────┤
│ Chunk 1 (raw/compressed bytes) │
├───────────────────────────────────────────────┤
│ Chunk 2 (raw/compressed bytes) │
├───────────────────────────────────────────────┤
│ ... │
└───────────────────────────────────────────────┘
-
Header
magic: identifies the file type (e.g.,"SPRIG\0\0").version: save file format version.manifestSize: size of the manifest block in bytes.
-
Manifest Describes all chunks in the file. Each entry includes:
name: logical name of the chunk (e.g.,"settings","svo")type: data type (e.g.,json,binary)offset: byte offset from start of filesize: length of the chunk in bytes
-
Chunks Contain the actual serialized data. Each chunk may be stored raw or compressed.
- Compression: Add per-chunk compression (LZ4/zlib).
- Header: Include magic string + version for compatibility checks.
- Manifest: Store
{ name, type, offset, size }for all chunks. - Future versions: Allow migration between file format versions.
- Atomic save: Write to
.tmpfile, then rename on success.
- Implement serializer/deserializer
- Add compression/decompression layer
- Add checksum per chunk for corruption detection
- Support incremental save if necessary
- Need to add Deferred deletion
- Animation system store a raw pointer, this may pose a problem, may want to use Weak Handles (Generation IDs)
- Add light theme support
- Remove tinyfd from the main thread, it's blocking.
- Every parent can have multiple children, a dynamic amount of children is an issue for serialization, to keep it simple a node can keep track only of it's parent, we can remove the
CHierarchychildfield. The problem is that when deleting or doing an work on the entire chain, searching for children is O(n^2).- We could add a fixed amount of children. Each Bone can have x children, memory will be allocated upfront so it will be
x * uint64_t. For few children this is reasonable in this project but maybe we want to have unlimited children attached to a single bone? Like rays of light from a point... - We could allow dynamic amount of children and begin the work on serializer to be able to handle vectors. More dev time but saves memory and allows
$n$ children. Solution Chosen: Choose to go with the pointer to parent stored in each Bone, selecting the entire hierarchy may be expensive but I can optimise that down the line if needed.
- We could add a fixed amount of children. Each Bone can have x children, memory will be allocated upfront so it will be
-
CHierarchyhas attach, need more memory to properly define that relationship. Attached head to head, head to tail, tail to tail, etc.
-
There is an issue, when you create a bone save the file, then open a new file and hit Ctr+S, you get an out-of-bounds index. This is because the
GetEntityTypeId<E>()in Registry.h is static. When the project reopens, since the program did not stop, all global statics remain cached. I don't want to use RTTI to keep track of entity types so this is pending until I find a better solution. The name of the bone disappears because the id returned int State.cppState::Restore()registry->CreateEntity<EBone>()is 2, then 3. The id I extract from the save file is unused atm. Need to fix this.- Okay, I finally ended up using RTTI, Performance here is not as important as the voxel engine so I'll let this go for now.
Issue resolved: Used RTTI, remove the static behaviour of
Animation, added it to theServiceLocator. Reworked: Remove RTTI, if the existing EntityTypeId does not exist, resize the container so that it does.