Skip to content

Instantly share code, notes, and snippets.

@rezoner
Last active August 20, 2019 09:37
Show Gist options
  • Save rezoner/3928eb5d100ec9f7758b89caeef454f7 to your computer and use it in GitHub Desktop.
Save rezoner/3928eb5d100ec9f7758b89caeef454f7 to your computer and use it in GitHub Desktop.

Example model

Open any ZIP file exported with spritestack. You will find a model.json there.

{
    "formatVersion": 2,
    "fileType": "SpriteStackModel",
    "parts": [
    {
        "name": "part1",
        "bounds": [56, 71, 62, 65, 0, 15],
        "size": [128, 128, 128],
        "data": [-7997, 0, -6, 10, -122, 0, -6, 10, -122, 0, -6, 10, -122, 0, -6, 10, -15992, 0, -2, 10, -6, 6, -2, 10, -118, 0, -2, 10, -6, 6, -2, 10, -118, 0, -2, 10, -6, 6, -2, 10, -118, 0, -2, 10, -6, 6, -2, 10, -15989, 0, 10, -2, 6, -6, 0, -2, 6, 10, -116, 0, 10, -2, 6, -6, 10, -2, 6, 10, -116, 0, 10, -2, 6, -6, 10, -2, 6, 10, -116, 0, 10, -2, 6, -6, 0, -2, 6, 10, -15987, 0, 10, 6, -10, 0, 6, 10, -114, 0, 10, 6, -10, 10, 6, 10, -114, 0, 10, 6, -10, 10, 6, 10, -114, 0, 10, 6, -10, 0, 6, 10, -15986, 0, 10, 6, -10, 0, 6, 10, -114, 0, 10, 6, -10, 10, 6, 10, -114, 0, 10, 6, -10, 10, 6, 10, -114, 0, 10, 6, -10, 0, 6, 10, -15985, 0, 10, 6, -4, 0, -3, 12, -5, 0, 6, 10, -112, 0, 10, 6, -12, 10, 6, 10, -112, 0, 10, 6, -12, 10, 6, 10, -112, 0, 10, 6, -4, 0, 12, -7, 0, 6, 10, -15984, 0, 10, 6, -7, 0, 12, -4, 0, 6, 10, -112, 0, 10, 6, -12, 10, 6, 10, -112, 0, 10, 6, -12, 10, 6, 10, -112, 0, 10, 6, -4, 0, 12, -7, 0, 6, 10, -15984, 0, 10, 6, -7, 0, 12, -4, 0, 6, 10, -112, 0, 10, 6, -12, 10, 6, 10, -112, 0, 10, 6, -12, 10, 6, 10, -112, 0, 10, 6, -4, 0, -4, 12, -4, 0, 6, 10, -15984, 0, 10, 6, -7, 0, 12, -4, 0, 6, 10, -112, 0, 10, 6, -12, 10, 6, 10, -112, 0, 10, 6, -12, 10, 6, 10, -112, 0, 10, 6, -4, 0, 12, -7, 0, 6, 10, -15984, 0, 10, 6, -7, 0, 12, -4, 0, 6, 10, -112, 0, 10, 6, -12, 10, 6, 10, -112, 0, 10, 6, -12, 10, 6, 10, -112, 0, 10, 6, -4, 0, 12, -7, 0, 6, 10, -15984, 0, 10, 6, -4, 0, -3, 12, -5, 0, 6, 10, -112, 0, 10, 6, -12, 10, 6, 10, -112, 0, 10, 6, -12, 10, 6, 10, -112, 0, 10, 6, -4, 0, -4, 12, -4, 0, 6, 10, -15985, 0, 10, 6, -10, 0, 6, 10, -114, 0, 10, 6, -10, 10, 6, 10, -114, 0, 10, 6, -10, 10, 6, 10, -114, 0, 10, 6, -10, 0, 6, 10, -15986, 0, 10, 6, -10, 0, 6, 10, -114, 0, 10, 6, -10, 10, 6, 10, -114, 0, 10, 6, -10, 10, 6, 10, -114, 0, 10, 6, -10, 0, 6, 10, -15987, 0, 10, -2, 6, -6, 0, -2, 6, 10, -116, 0, 10, -2, 6, -6, 10, -2, 6, 10, -116, 0, 10, -2, 6, -6, 10, -2, 6, 10, -116, 0, 10, -2, 6, -6, 0, -2, 6, 10, -15989, 0, -2, 10, -6, 6, -2, 10, -118, 0, -2, 10, -6, 6, -2, 10, -118, 0, -2, 10, -6, 6, -2, 10, -118, 0, -2, 10, -6, 6, -2, 10, -15992, 0, -6, 10, -122, 0, -6, 10, -122, 0, -6, 10, -122, 0, -6, 10, -1843005, 0],
        "uuid": "77DA7F97-B0D3-40C6-A7AC-4F65FC98ABDD",
        "hidden": false
    }],
    "size": [128, 128, 128],
    "palette": [0, 2236468, 4532284, 6699313, 9393723, 16419072, 14262374, 15647642, 16777215, 16511542, 16768770, 13462277, 3642478, 4942127, 5393188, 3292217, 4145012, 3170434, 5992161, 6527999, 6278628, 13360124, 10202551, 8683143, 6908522, 5854802, 7750282, 11285042, 14243683, 14121914, 9410378, 9072432],
    "bounds": [56, 71, 62, 65, 0, 15]
}

1. Unfolding data array

All you need to decode a model is to unfold data array for each part.

[-4, 1, 2] means [1, 1, 1, 1, 2]
[1, 2, 3] means [1, 2, 3]
[-2, 4, -2, 3] means [4, 4, 3, 3]

So the negative X number means use the next value X times

If the number is positive and it's not preceeded by negative it means that the X is 1

example: [3, 2] simply means [3, 2]

Now that you have unfolded array

2. Reading the cube

Spritestack model is 64x64x64 or 128x128x128 cube of indexed palette colors

  • Where 0 means there is nothing
  • Where 1 means first color in palette
  • Where 2 means second color in palette

To decipher X, Y, Z use this formula

for(i = 0; i < cube.length; i++) {

    colorIndex = cube[i] - 1;

    if(colorIndex < 0) continue;

    index = i;
    
    z = floor(index / (size * size));

    index -= (z * size * size);

    y = floor(index / size);
    x = index % size;

    color = palette[colorIndex];

}

Color format

It's just standard RGB encoded into an integer

/* This for example is 0xFF0000 which means pure red */

color = 16711680;

r = floor(color / 65536 | 0);
g = floor(color / 256) % 256
b = color % 256;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment