├── .gitignore
├── .gitmodules
├── Dockerfile
├── README.md
├── build_cube.sh
├── build_materials.sh
├── config.ld
├── control
├── doc
├── index.html
├── ldoc.css
└── modules
│ ├── LuaScene.html
│ ├── sk_animation.html
│ ├── sk_definition_writer.html
│ ├── sk_input.html
│ ├── sk_math.html
│ ├── sk_mesh.html
│ ├── sk_scene.html
│ ├── sk_transform.html
│ └── vector3.html
├── examples
├── cube.h
├── cube.obj
├── cube_geo.c
├── image.png
├── materials.h
├── materials.skm.yaml
└── materials_mat.c
├── lua
├── sk_animation.lua
├── sk_definition_writer.lua
├── sk_math.lua
└── sk_scene.lua
├── main.cpp
├── makefile
├── schema
└── material-schema.json
├── schema_docs
├── index.html
├── schema_doc.css
└── schema_doc.min.js
├── setup_dependencies.sh
└── src
├── BoneHierarchy.cpp
├── BoneHierarchy.h
├── CFileDefinition.cpp
├── CFileDefinition.h
├── CommandLineParser.cpp
├── CommandLineParser.h
├── DisplayList.cpp
├── DisplayList.h
├── DisplayListGenerator.cpp
├── DisplayListGenerator.h
├── DisplayListSettings.cpp
├── DisplayListSettings.h
├── Enum.h
├── ErrorCode.h
├── ErrorResult.cpp
├── ErrorResult.h
├── ExtendedMesh.cpp
├── ExtendedMesh.h
├── FileUtils.cpp
├── FileUtils.h
├── MathUtil.cpp
├── MathUtl.h
├── MeshWriter.cpp
├── MeshWriter.h
├── RCPState.cpp
├── RCPState.h
├── RenderChunk.cpp
├── RenderChunk.h
├── RenderChunkOrder.cpp
├── RenderChunkOrder.h
├── SceneLoader.cpp
├── SceneLoader.h
├── SceneModification.cpp
├── SceneModification.h
├── SceneWriter.cpp
├── SceneWriter.h
├── StringUtils.h
├── StringUtls.cpp
├── definition_generator
├── AnimationGenerator.cpp
├── AnimationGenerator.h
├── CollisionGenerator.cpp
├── CollisionGenerator.h
├── CollisionQuad.cpp
├── CollisionQuad.h
├── DefinitionGenerator.cpp
├── DefinitionGenerator.h
├── MaterialGenerator.cpp
├── MaterialGenerator.h
├── MeshDefinitionGenerator.cpp
└── MeshDefinitionGenerator.h
├── definitions
├── DataChunk.cpp
├── DataChunk.h
├── FileDefinition.cpp
└── FileDefinition.h
├── lua_generator
├── LuaBasicTypes.cpp
├── LuaBasicTypes.h
├── LuaDefinitionWriter.cpp
├── LuaDefinitionWriter.h
├── LuaDisplayListSettings.cpp
├── LuaDisplayListSettings.h
├── LuaFiles.h
├── LuaGenerator.cpp
├── LuaGenerator.h
├── LuaGeometry.cpp
├── LuaGeometry.h
├── LuaMesh.cpp
├── LuaMesh.h
├── LuaNodeGroups.cpp
├── LuaNodeGroups.h
├── LuaScene.cpp
├── LuaScene.h
├── LuaTransform.cpp
├── LuaTransform.h
├── LuaUtils.cpp
└── LuaUtils.h
├── materials
├── CImgu8.cpp
├── CImgu8.h
├── CombineMode.cpp
├── CombineMode.h
├── Material.cpp
├── Material.h
├── MaterialEnums.cpp
├── MaterialEnums.h
├── MaterialParser.cpp
├── MaterialParser.h
├── MaterialState.cpp
├── MaterialState.h
├── MaterialTransitionTiming.h
├── MaterialTranslator.cpp
├── MaterialTranslator.h
├── RenderMode.cpp
├── RenderMode.h
├── TextureCache.cpp
├── TextureCache.h
├── TextureDefinition.cpp
├── TextureDefinition.h
├── TextureFormats.cpp
└── TextureFormats.h
└── math
├── LeastSquares.cpp
├── LeastSquares.h
├── MES.cpp
├── MES.h
├── Vector4.cpp
└── Vector4.h
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | *.d
3 | .vscode/
4 | assimp/
5 | cimg/
6 | yaml-cpp/
7 | output/
8 | skeletool64
9 | dna.txt
10 | build/
11 | images/
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "yaml-cpp"]
2 | path = yaml-cpp
3 | url = https://github.com/jbeder/yaml-cpp.git
4 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM debian:latest
2 |
3 | WORKDIR /usr/src/app
4 |
5 | RUN apt update
6 | RUN apt install -y libpng-dev libtiff-dev libassimp-dev git cmake build-essential wget unzip
7 |
8 | RUN git clone https://github.com/jbeder/yaml-cpp.git
9 |
10 | RUN cmake -S yaml-cpp -B yaml-cpp
11 | RUN make -C yaml-cpp
12 |
13 | RUN wget http://cimg.eu/files/CImg_latest.zip
14 | RUN unzip CImg_latest.zip
15 | RUN mv CImg-3.1.3_pre051622 cimg
16 |
17 | COPY src src
18 | COPY main.cpp main.cpp
19 | COPY makefile makefile
20 |
21 | CMD make
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Skeletool64
2 |
3 | Converts various 3d formats to a N64 display list. Will support skeletal animation
4 |
5 | # pre requisites to build
6 |
7 | libpng libtiff libassimp-dev
8 |
9 | # how to install with apt
10 |
11 | ```
12 | echo "deb [trusted=yes] https://lambertjamesd.github.io/apt/ ./" | tee /etc/apt/sources.list.d/lambertjamesd.list
13 | sudo apt install skeletool64
14 | ```
15 |
16 | ## how to use
17 |
18 | 'skeletool64 path/to/input/file.obj -o path/to/output.h`
19 |
20 | The file formats located here [https://assimp.sourceforge.net/main_features_formats.html](https://assimp.sourceforge.net/main_features_formats.html) are supported, though not all are tested
21 |
22 | will take the input model file and convert it to a header file with accompanying c file `path/to/ouptut_geo.c`
23 |
24 | Here some command line arguments
25 |
26 | | Argument | Argument Type | Description |
27 | |----------|--------|-------------|
28 | | -o | filename | where to write the output |
29 | | --name | string | The name to prefix all c definitions with |
30 | | --fixed-point-scale | number | Scales all geometry by the given number when converting from floating point to fixed point geometry defaults to 256 |
31 | | --model-scale | number | used to scale all geometry defaults to 1 |
32 | | -m | filename | used to add a materials yaml or json file more details about how materials works below. You can add mulitple material files. You can also specify a 3d model as a material source and all materials from the file will be included. |
33 | | --material-output | | if present only materials are generated instead of geometry |
34 | | -r | number,number,number | a set of euler angles used to rotate the model |
35 | | --default-material | string | the name of the material that is expected to be active when rendering this model. This is useful to reduce needed state changes between default state and the state needed to render the model defaults to `default` |
36 | | --force-material | string | if present all geometry uses the given material |
37 |
38 | ## materials
39 |
40 | skeletool64 will attempt to automatically create materials. You can override any material by name by adding them to a materials yaml file. You can find the schema for a material file here [schema/material-schema.json](schema/material-schema.json). When a material is specified by name in a materials file it will replace any materials in 3d files with the same name. An example of a materials file
41 |
42 | ```
43 | materials:
44 | default:
45 | gDPSetRenderMode: G_RM_ZB_OPA_SURF
46 | gDPSetTextureFilter: G_TF_BILERP
47 | gDPSetTexturePersp: G_TP_PERSP
48 | gDPSetCycleType: G_CYC_1CYCLE
49 | gDPSetAlphaCompare: G_AC_NONE
50 | gSPGeometryMode:
51 | set: [G_CULL_BACK, G_ZBUFFER]
52 | clear: [G_CULL_FRONT, G_TEXTURE_GEN, G_TEXTURE_GEN_LINEAR]
53 |
54 | button_base_black:
55 | gDPSetPrimColor:
56 | r: 32
57 | g: 32
58 | b: 32
59 | gSPGeometryMode:
60 | set: [G_LIGHTING, G_SHADE]
61 | gDPSetCombineMode:
62 | color: ["PRIMITIVE", "0", "SHADE", "0"]
63 |
64 | awe_total:
65 | gDPSetTile:
66 | filename: ../../portal_pak_modified/materials/models/props_animsigns/awe_total.png
67 | siz: G_IM_SIZ_4b
68 | fmt: G_IM_FMT_I
69 |
70 | gDPSetRenderMode: G_RM_ZB_OPA_DECAL
71 |
72 | gSPGeometryMode:
73 | clear: [G_LIGHTING]
74 | set: [G_SHADE]
75 | gDPSetCombineMode:
76 | color: [SHADE, PRIMITIVE, TEXEL0, PRIMITIVE]
77 | gDPSetPrimColor:
78 | r: 242
79 | g: 245
80 | b: 247
81 | gDPSetCycleType: G_CYC_1CYCLE
82 |
83 | cube_fizzled:
84 | gDPSetTile:
85 | filename:
86 | ../images/cube.png
87 | siz: G_IM_SIZ_16b
88 | fmt: G_IM_FMT_RGBA
89 | s:
90 | mirror: true
91 | t:
92 | mirror: true
93 |
94 | gDPSetRenderMode:
95 | - blend: ["G_BL_CLR_IN", "G_BL_A_IN", "G_BL_CLR_FOG", "G_BL_1MA"]
96 | - G_RM_ZB_XLU_SURF
97 |
98 | gDPSetCycleType: G_CYC_2CYCLE
99 | gSPGeometryMode:
100 | set: [G_LIGHTING, G_SHADE]
101 | gDPSetCombineMode:
102 | - color: ["SHADE", "0", "TEXEL0", "0"]
103 | alpha: ["0", "0", "0", "PRIMITIVE"]
104 | - color: ["NOISE", "COMBINED", "PRIMITIVE", "COMBINED"]
105 | alpha: ["0", "0", "0", "PRIMITIVE"]
106 |
107 | gDPSetFogColor:
108 | r: 0
109 | g: 0
110 | b: 0
111 |
112 | gDPSetPrimColor:
113 | r: 100
114 | g: 100
115 | b: 200
116 | a: 128
117 | ```
118 |
119 | there are 4 reserved material names `texture_lit`, `texture_unlit`, `solid_lit`, and `solid_unlit`. If you specify a material with one of these names then materials generated from 3d model files will use one of these 4 materials as a base.
120 |
121 | If you use the `--material-output` flag you can generate a list of materials with no geometry. Each material generated will only output the required state change to transition from the default material.
122 |
123 | ## examples
124 |
125 | See [./build_cube.sh](./build_cube.sh) and [./build_materials.sh](./build_materials.sh) as an example
--------------------------------------------------------------------------------
/build_cube.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ./skeletool64 examples/cube.obj -o examples/cube.h
--------------------------------------------------------------------------------
/build_materials.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ./skeletool64 --material-output -m examples/materials.skm.yaml -o examples/materials.h
--------------------------------------------------------------------------------
/config.ld:
--------------------------------------------------------------------------------
1 | project = "skeletool64"
2 | file = {'./src/lua_generator', './lua'}
--------------------------------------------------------------------------------
/control:
--------------------------------------------------------------------------------
1 | Package: skeletool64
2 | Version: 0.3
3 | Architecture: amd64
4 | Depends: libassimp5
5 | Maintainer: James Lambert lambertjamesd@gmail.com
6 | Description: skeletool64
7 | Converts various 3d formats to a N64 display list
8 |
--------------------------------------------------------------------------------
/doc/index.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | Reference
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
skeletool64
28 |
29 |
30 |
31 |
32 |
Modules
33 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
Modules
50 |
80 |
81 |
82 |
83 |
84 |
generated by LDoc 1.4.6
85 |
Last updated 2022-12-30 12:30:52
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/doc/modules/LuaScene.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | Reference
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
skeletool64
28 |
29 |
32 |
33 |
Contents
34 |
37 |
38 |
39 |
Modules
40 |
44 |
45 |
46 |
47 |
48 |
49 |
Module LuaScene
50 |
Scene functions
51 |
52 |
53 |
54 |
55 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | -
70 |
71 | export_default_mesh ()
72 |
73 | -
74 | Generates mesh and animation data from the current scene
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
generated by LDoc 1.4.6
90 |
Last updated 2022-10-01 11:25:20
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/doc/modules/sk_input.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | Reference
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
skeletool64
28 |
29 |
32 |
33 |
Contents
34 |
37 |
38 |
39 |
Modules
40 |
49 |
50 |
51 |
52 |
53 |
54 |
Module sk_input
55 |
56 |
57 |
58 |
59 |
60 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | -
79 |
80 | settings
81 |
82 | -
83 |
84 |
85 |
86 |
Fields:
87 |
88 | - model_transform
89 | sk_transform.Transform
90 |
91 |
92 | - fixed_point_transform
93 | sk_transform.Transform
94 |
95 |
96 | - model_scale
97 | number
98 |
99 |
100 | - fixed_point_scale
101 | number
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | -
112 |
113 | input_filename
114 |
115 | -
116 |
117 |
118 |
119 |
Fields:
120 |
121 | - bar
122 | foo
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
generated by LDoc 1.4.6
139 |
Last updated 2022-12-30 12:30:52
140 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/doc/modules/sk_transform.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | Reference
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
skeletool64
28 |
29 |
32 |
33 |
Contents
34 |
38 |
39 |
40 |
Modules
41 |
50 |
51 |
52 |
53 |
54 |
55 |
Module sk_transform
56 |
57 |
58 |
59 |
60 |
61 |
67 |
68 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | -
87 |
88 | from_pos_rot_scale (pos[, rot[, scale]])
89 |
90 | -
91 |
92 |
93 |
94 |
Parameters:
95 |
96 | - pos
97 | sk_math.Vector3
98 |
99 |
100 | - rot
101 | sk_math.Quaternion
102 |
103 | (optional)
104 |
105 | - scale
106 | sk_math.Scale
107 |
108 | (optional)
109 |
110 |
111 |
112 | Returns:
113 |
114 |
115 | Transform
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 | A 4x4 matrix transform
128 |
129 |
130 | -
131 |
132 | Transform:decompose ()
133 |
134 | -
135 |
136 |
137 |
138 |
139 |
Returns:
140 |
141 | -
142 | vector3.Vector3
143 | position
144 | -
145 | quaternion.Quaternion
146 | rotation
147 | -
148 | vector3.Vector3
149 | scale
150 |
151 |
152 |
153 |
154 |
155 |
156 | -
157 |
158 | Transform:__mul (other)
159 |
160 | -
161 |
162 |
163 |
164 |
Parameters:
165 |
166 | - other
167 | Transform or sk_math.Vector3
168 |
169 |
170 |
171 |
172 | Returns:
173 |
174 |
175 | Transform
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
generated by LDoc 1.4.6
190 |
Last updated 2022-12-30 12:30:52
191 |
192 |
193 |
194 |
195 |
--------------------------------------------------------------------------------
/doc/modules/vector3.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | Reference
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
skeletool64
28 |
29 |
32 |
33 |
Contents
34 |
37 |
38 |
39 |
Modules
40 |
44 |
45 |
46 |
47 |
48 |
49 |
Module vector3
50 |
51 |
52 |
53 |
54 |
55 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | -
70 |
71 | vector3 (x, y, z)
72 |
73 | -
74 | creates a new 3d vector
75 |
76 |
77 |
Parameters:
78 |
79 | - x
80 | the x value for the vector
81 |
82 | - y
83 | the x value for the vector
84 |
85 | - z
86 | the x value for the vector
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
generated by LDoc 1.4.6
102 |
Last updated 2022-10-01 11:25:20
103 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/examples/cube.h:
--------------------------------------------------------------------------------
1 | #ifndef __SKOUT_CUBE_H__
2 | #define __SKOUT_CUBE_H__
3 |
4 | #include
5 |
6 | #define OUTPUT_ATTACHMENT_COUNT 0
7 |
8 | extern Vtx output_Cube__normal[];
9 | extern Gfx output_model_gfx[];
10 |
11 | #endif
12 |
--------------------------------------------------------------------------------
/examples/cube.obj:
--------------------------------------------------------------------------------
1 | # Blender v2.76 (sub 0) OBJ File: ''
2 | # www.blender.org
3 | mtllib cube.mtl
4 | o Cube
5 | v 1.000000 -1.000000 -1.000000
6 | v 1.000000 -1.000000 1.000000
7 | v -1.000000 -1.000000 1.000000
8 | v -1.000000 -1.000000 -1.000000
9 | v 1.000000 1.000000 -0.999999
10 | v 0.999999 1.000000 1.000001
11 | v -1.000000 1.000000 1.000000
12 | v -1.000000 1.000000 -1.000000
13 | vt 1.000000 0.333333
14 | vt 1.000000 0.666667
15 | vt 0.666667 0.666667
16 | vt 0.666667 0.333333
17 | vt 0.666667 0.000000
18 | vt 0.000000 0.333333
19 | vt 0.000000 0.000000
20 | vt 0.333333 0.000000
21 | vt 0.333333 1.000000
22 | vt 0.000000 1.000000
23 | vt 0.000000 0.666667
24 | vt 0.333333 0.333333
25 | vt 0.333333 0.666667
26 | vt 1.000000 0.000000
27 | vn 0.000000 -1.000000 0.000000
28 | vn 0.000000 1.000000 0.000000
29 | vn 1.000000 0.000000 0.000000
30 | vn -0.000000 0.000000 1.000000
31 | vn -1.000000 -0.000000 -0.000000
32 | vn 0.000000 0.000000 -1.000000
33 | usemtl Material
34 | s off
35 | f 2/1/1 3/2/1 4/3/1
36 | f 8/1/2 7/4/2 6/5/2
37 | f 5/6/3 6/7/3 2/8/3
38 | f 6/8/4 7/5/4 3/4/4
39 | f 3/9/5 7/10/5 8/11/5
40 | f 1/12/6 4/13/6 8/11/6
41 | f 1/4/1 2/1/1 4/3/1
42 | f 5/14/2 8/1/2 6/5/2
43 | f 1/12/3 5/6/3 2/8/3
44 | f 2/12/4 6/8/4 3/4/4
45 | f 4/13/5 3/9/5 8/11/5
46 | f 5/6/6 1/12/6 8/11/6
--------------------------------------------------------------------------------
/examples/cube_geo.c:
--------------------------------------------------------------------------------
1 | #include "cube.h"
2 | Vtx output_Cube__normal[] = {
3 | {{{256, -256, 256}, 0, {0, 0}, {0, -128, 0, 255}}},
4 | {{{-256, -256, 256}, 0, {0, 0}, {0, -128, 0, 255}}},
5 | {{{-256, -256, -256}, 0, {0, 0}, {0, -128, 0, 255}}},
6 | {{{-256, 256, -256}, 0, {0, 0}, {0, 127, 0, 255}}},
7 | {{{-256, 256, 256}, 0, {0, 0}, {0, 127, 0, 255}}},
8 | {{{256, 256, 256}, 0, {0, 0}, {0, 127, 0, 255}}},
9 | {{{256, 256, -256}, 0, {0, 0}, {127, 0, 0, 255}}},
10 | {{{256, 256, 256}, 0, {0, 0}, {127, 0, 0, 255}}},
11 | {{{256, -256, 256}, 0, {0, 0}, {127, 0, 0, 255}}},
12 | {{{256, 256, 256}, 0, {0, 0}, {0, 0, 127, 255}}},
13 | {{{-256, 256, 256}, 0, {0, 0}, {0, 0, 127, 255}}},
14 | {{{-256, -256, 256}, 0, {0, 0}, {0, 0, 127, 255}}},
15 | {{{-256, -256, 256}, 0, {0, 0}, {-128, 0, 0, 255}}},
16 | {{{-256, 256, 256}, 0, {0, 0}, {-128, 0, 0, 255}}},
17 | {{{-256, 256, -256}, 0, {0, 0}, {-128, 0, 0, 255}}},
18 | {{{256, -256, -256}, 0, {0, 0}, {0, 0, -128, 255}}},
19 | {{{-256, -256, -256}, 0, {0, 0}, {0, 0, -128, 255}}},
20 | {{{-256, 256, -256}, 0, {0, 0}, {0, 0, -128, 255}}},
21 | {{{256, -256, -256}, 0, {0, 0}, {0, -128, 0, 255}}},
22 | {{{256, 256, -256}, 0, {0, 0}, {0, 127, 0, 255}}},
23 | {{{256, -256, -256}, 0, {0, 0}, {127, 0, 0, 255}}},
24 | {{{256, -256, 256}, 0, {0, 0}, {0, 0, 127, 255}}},
25 | {{{-256, -256, -256}, 0, {0, 0}, {-128, 0, 0, 255}}},
26 | {{{256, 256, -256}, 0, {0, 0}, {0, 0, -128, 255}}},
27 | };
28 |
29 | Gfx output_model_gfx[] = {
30 | /* Material Material */
31 | gsDPPipeSync(),
32 | gsSPGeometryMode(0, G_SHADE | G_LIGHTING),
33 | gsDPSetCombineLERP(0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE),
34 | gsDPSetPrimColor(255, 255, 153, 153, 153, 255),
35 | /* End Material Material */
36 | gsSPVertex(&output_Cube__normal[0], 24, 0),
37 | gsSP2Triangles(0, 1, 2, 0, 3, 4, 5, 0),
38 | gsSP2Triangles(6, 7, 8, 0, 9, 10, 11, 0),
39 | gsSP2Triangles(12, 13, 14, 0, 15, 16, 17, 0),
40 | gsSP2Triangles(18, 0, 2, 0, 19, 3, 5, 0),
41 | gsSP2Triangles(20, 6, 8, 0, 21, 9, 11, 0),
42 | gsSP2Triangles(22, 12, 14, 0, 23, 15, 17, 0),
43 | gsDPPipeSync(),
44 | gsSPEndDisplayList(),
45 | };
46 |
47 |
--------------------------------------------------------------------------------
/examples/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambertjamesd/skelatool64/708cfcae7734dc3d3997286976bbf32f5009da01/examples/image.png
--------------------------------------------------------------------------------
/examples/materials.h:
--------------------------------------------------------------------------------
1 | #ifndef __SKOUT_MATERIALS_H__
2 | #define __SKOUT_MATERIALS_H__
3 |
4 | #include
5 |
6 | #define TEST_MATERIAL_A_INDEX 0
7 | #define DEFAULT_INDEX 1
8 | #define OUTPUT_MATERIAL_COUNT 2
9 | #define OUTPUT_TRANSPARENT_START 3
10 |
11 | extern u64 output_image_i_8b[];
12 | extern Gfx output_Test_Material_A[];
13 | extern Gfx output_Test_Material_A_revert[];
14 | extern Gfx output_default[];
15 | extern Gfx output_default_revert[];
16 | extern Gfx* output_material_list[];
17 | extern Gfx* output_material_revert_list[];
18 |
19 | #endif
20 |
--------------------------------------------------------------------------------
/examples/materials.skm.yaml:
--------------------------------------------------------------------------------
1 |
2 | materials:
3 | default:
4 | gDPSetRenderMode: G_RM_AA_ZB_OPA_SURF
5 | gDPSetCycleType: G_CYC_1CYCLE
6 |
7 | Test Material A:
8 | gDPSetTile:
9 | filename: ./image.png
10 | fmt: G_IM_FMT_I
11 | gDPSetRenderMode: G_RM_AA_ZB_OPA_SURF
12 | gDPSetCombineMode:
13 | color: ["0", "0", "0", "1"]
14 | alpha: ["0", "0", "0", "1"]
15 | gDPSetCycleType: G_CYC_1CYCLE
16 | gDPSetTextureLOD: G_TL_TILE
17 | gDPSetAlphaDither: G_AD_DISABLE
18 | gDPSetPrimColor:
19 | r: 255
20 | g: 0
21 | b: 0
22 | gDPSetEnvColor:
23 | r: 128
24 | g: 128
25 | b: 128
26 | gDPSetFogColor:
27 | r: 200
28 | g: 100
29 | b: 50
30 | gDPSetBlendColor:
31 | r: 180
32 | g: 120
33 | b: 100
--------------------------------------------------------------------------------
/examples/materials_mat.c:
--------------------------------------------------------------------------------
1 | #include "materials.h"
2 | u64 output_image_i_8b[] = {
3 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c,
4 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c,
5 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c,
6 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x9ba49b8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c,
7 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8cbd, 0xe9eed39b8c8c8c8c, 0x8c8c8c8c8c8c8c8c,
8 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8cc4f9, 0xffffffd28c8c8c8c, 0x8c8c8c8c8c8c8c8c,
9 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8cb9f5ff, 0xfffffff8b98c8c8c, 0x8c8c8c8c8c8c8c8c,
10 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8cc1f4ffff, 0xfffffffff0b08c8c, 0x8c8c8c8c8c8c8c8c,
11 | 0x8c8c8c8c8c8c8c8c, 0x8c8c9bd2fbffffff, 0xffffffffffe6a48c, 0x8c8c8c8c8c8c8c8c,
12 | 0x8c8c8c8c8c8c8c8c, 0x8ca4deffffffffff, 0xf5f7ffffffffde9b, 0x8c8c8c8c8c8c8c8c,
13 | 0x8c8c8c8c8c8c8c8c, 0xb0e6fffffffffff0, 0xb9c1fbffffffffd2, 0x8c8c8c8c8c8c8c8c,
14 | 0x8c8c8c8c8c8c8cb9, 0xf0ffffffffffe4b0, 0x8c8cc8fcfffffffc, 0xc88c8c8c8c8c8c8c,
15 | 0x8c8c8c8c8c8cc1f4, 0xfffffffffcd29b8c, 0x8c8c8cd2ffffffff, 0xfbc18c8c8c8c8c8c,
16 | 0x8c8c8c8c8cc8fbff, 0xfffffffbc88c8c8c, 0x8c8c8c9bdeffffff, 0xfffacf8c8c8c8c8c,
17 | 0x8c8c8c8cdbfdffff, 0xfffff4c18c8c8c8c, 0x8c8c8c8ca4e6ffff, 0xffffffc68c8c8c8c,
18 | 0x8c8c8cd0ffffffff, 0xfff0b98c8c8c8c8c, 0x8c8c8c8c8cb0f2ff, 0xffffffe58c8c8c8c,
19 | 0x8c8c8cecffffffff, 0xeeb58c8c8c8c8c8c, 0x8c8c8c8c8c9beaff, 0xffffffd78c8c8c8c,
20 | 0x8c8c8cd0fffffffd, 0xfbeac29b8c8c8c8c, 0x8c8c8c8c8cc8fcff, 0xfffff4a98c8c8c8c,
21 | 0x8c8c8c8cd0f5ffff, 0xfffffceac29b8c8c, 0x8c8c8c8ca9f3ffff, 0xfffcc88c8c8c8c8c,
22 | 0x8c8c8c8c8cc1ffff, 0xfffffffffce4bb9b, 0x8c8c8c8cdbffffff, 0xffe29b8c8c8c8c8c,
23 | 0x8c8c8c8c8c9bd7fc, 0xfffffffffffff8e1, 0xbb9b8cc1fcffffff, 0xf6b08c8c8c8c8c8c,
24 | 0x8c8c8c8c8c8c9bc2, 0xeafcffffffffffff, 0xf8e0bdf2ffffffff, 0xcd8c8c8c8c8c8c8c,
25 | 0x8c8c8c8c8c8c8c8c, 0x9bc2eafdffffffff, 0xfffffbffffffffe4, 0x9b8c8c8c8c8c8c8c,
26 | 0x8c8c8c8c8c8c8c8c, 0x8c8c9bc8f2fdffff, 0xfffffffffffff6b0, 0x8c8c8c8c8c8c8c8c,
27 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8ca9d4f3fd, 0xffffffffffffd78c, 0x8c8c8c8c8c8c8c8c,
28 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8ca9d4, 0xf4fffffffff2a98c, 0x8c8c8c8c8c8c8c8c,
29 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0xa9d7f4f6edb98c8c, 0x8c8c8c8c8c8c8c8c,
30 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8ca9bba98c8c8c, 0x8c8c8c8c8c8c8c8c,
31 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c,
32 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c,
33 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c,
34 | 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c, 0x8c8c8c8c8c8c8c8c,
35 | };
36 |
37 | Gfx output_Test_Material_A[] = {
38 | gsDPPipeSync(),
39 | gsDPSetTextureLOD(G_TL_TILE),
40 | gsDPSetAlphaDither(G_AD_DISABLE),
41 | gsDPSetCombineLERP(0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1),
42 | gsDPSetPrimColor(255, 255, 255, 0, 0, 255),
43 | gsDPSetEnvColor(128, 128, 128, 255),
44 | gsDPSetFogColor(200, 100, 50, 255),
45 | gsDPSetBlendColor(180, 120, 100, 255),
46 | gsSPTexture(65535, 65535, 0, 0, G_ON),
47 | gsDPTileSync(),
48 | gsDPSetTextureImage(G_IM_FMT_I, G_IM_SIZ_8b_LOAD_BLOCK, 1, output_image_i_8b),
49 | gsDPSetTile(G_IM_FMT_I, G_IM_SIZ_8b_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, 0),
50 | gsDPLoadSync(),
51 | gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 511, 512),
52 | gsDPPipeSync(),
53 | gsDPSetTile(G_IM_FMT_I, G_IM_SIZ_8b, 4, 0, 0, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, 0),
54 | gsDPSetTileSize(0, 0, 0, 124, 124),
55 | gsSPEndDisplayList(),
56 | };
57 |
58 | Gfx output_Test_Material_A_revert[] = {gsDPPipeSync(), gsSPEndDisplayList()};
59 |
60 | Gfx output_default[] = {
61 | gsDPPipeSync(),
62 | gsDPSetCycleType(G_CYC_1CYCLE),
63 | gsDPSetRenderMode(G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2),
64 | gsSPEndDisplayList(),
65 | };
66 |
67 | Gfx output_default_revert[] = {gsDPPipeSync(), gsSPEndDisplayList()};
68 |
69 | Gfx* output_material_list[] = {output_Test_Material_A, output_default};
70 |
71 | Gfx* output_material_revert_list[] = {
72 | output_Test_Material_A_revert,
73 | output_default_revert,
74 | };
75 |
76 |
--------------------------------------------------------------------------------
/lua/sk_scene.lua:
--------------------------------------------------------------------------------
1 | --- @module sk_scene
2 |
3 | local node_name_cache = nil
4 |
5 | local exports
6 |
7 | -- Defintions from LuaScene.cpp
8 |
9 | ---A scene node
10 | ---@table Node
11 | ---@tfield string name
12 | ---@tfield sk_transform.Transform transformation
13 | ---@tfield sk_transform.Transform full_transformation
14 | ---@tfield Node parent
15 | ---@tfield {Node,...} children
16 | ---@tfield {sk_mesh.Mesh,...} meshes
17 |
18 | --- Generates mesh and animation data from the current scene
19 | ---@function export_default_mesh
20 | ---@treturn sk_definition_writer.RawType model
21 | ---@treturn sk_definition_writer.RawType material
22 | local function export_default_mesh()
23 | -- implmentation overridden by LuaScene.cpp
24 | end
25 |
26 | -- Defintions from LuaNodeGroups.cpp
27 |
28 | ---A pairing of nodes and pre parsed node arguments
29 | ---@table NodeWithArguments
30 | ---@tfield Node node
31 | ---@tfield {string,...} arguments the list is strings produced by splitting the node name by spaces
32 |
33 | ---Returns a list of nodes with the given string prefix
34 | ---@function nodes_for_type
35 | ---@tparam string prefix the string prefix to search
36 | ---@treturn NodeWithArguments
37 | local function nodes_for_type(prefix)
38 |
39 | end
40 |
41 | ---Finds a named value in a list of arguments
42 | ---@function find_named_argument
43 | ---@tfield {string,...} arg_list
44 | ---@tfield string name
45 | ---@treturn string|nil
46 | local function find_named_argument(arg_list, name)
47 | for i = 1,#arg_list do
48 | if (arg_list[i] == name) then
49 | return arg_list[i + 1]
50 | end
51 | end
52 |
53 | return nil
54 | end
55 |
56 | ---Finds a named value in a list of arguments
57 | ---@function find_flag_argument
58 | ---@tfield {string,...} arg_list
59 | ---@tfield string name
60 | ---@treturn boolean
61 | local function find_flag_argument(arg_list, name)
62 | for i = 1,#arg_list do
63 | if (arg_list[i] == name) then
64 | return true
65 | end
66 | end
67 |
68 | return false
69 | end
70 |
71 | local function build_node_with_name_cache(node)
72 | node_name_cache[node.name] = node
73 |
74 | for _, child in pairs(node.children) do
75 | build_node_with_name_cache(child)
76 | end
77 | end
78 |
79 | --- Returns a node with the given name
80 | ---@function node_with_name
81 | ---@tparam string name
82 | ---@treturn Node result
83 | local function node_with_name(name)
84 | if (not node_name_cache) then
85 | node_name_cache = {}
86 | build_node_with_name_cache(exports.scene.root)
87 | end
88 |
89 | return node_name_cache[name]
90 | end
91 |
92 | local function for_each_node(node, callback)
93 | callback(node)
94 |
95 | for _, child in pairs(node.children) do
96 | for_each_node(child, callback)
97 | end
98 | end
99 |
100 | ---@table Vector3Key
101 | ---@tfield number time
102 | ---@tfield sk_math.Vector3 value
103 |
104 | ---@table QuaternionKey
105 | ---@tfield number time
106 | ---@tfield sk_math.Quaternion value
107 |
108 | ---@table Channel
109 | ---@tfield string node_name
110 | ---@tfield {Vector3Key,...} position_keys
111 | ---@tfield {QuaternionKey,...} rotation_keys
112 | ---@tfield {Vector3Key,...} scaling_keys
113 |
114 | ---@table Animation
115 | ---@tfield string name
116 | ---@tfield number duration
117 | ---@tfield number ticks_per_second
118 | ---@tfield {Channel,...} channels
119 |
120 | exports = {
121 | export_default_mesh = export_default_mesh,
122 | nodes_for_type = nodes_for_type,
123 | find_named_argument = find_named_argument,
124 | find_flag_argument = find_flag_argument,
125 | node_with_name = node_with_name,
126 | for_each_node = for_each_node,
127 | }
128 |
129 | return exports
--------------------------------------------------------------------------------
/makefile:
--------------------------------------------------------------------------------
1 |
2 | GCC_FLAGS = -Wall -Werror -g -rdynamic -I./yaml-cpp/include
3 |
4 | LINKER_FLAGS = -L./yaml-cpp -lassimp -lyaml-cpp -lpng -ltiff -llua5.4 -ldl
5 |
6 | SRC_FILES = main.cpp $(shell find src/ -type f -name '*.cpp')
7 |
8 | OBJ_FILES = $(patsubst %.cpp, build/%.o, $(SRC_FILES))
9 |
10 | LUA_SRC_FILES = $(shell find lua/ -type f -name '*.lua')
11 |
12 | LUA_OBJ_FILES = $(patsubst %.lua, build/%.o, $(LUA_SRC_FILES))
13 |
14 | DEPS = $(patsubst %.cpp, build/%.d, $(SRC_FILES))
15 |
16 | .PHONY: default
17 | default: skeletool64
18 |
19 | -include $(DEPS)
20 |
21 | build/lua/%.o: lua/%.lua
22 | @mkdir -p $(@D)
23 | luac -o $(@:%.o=%.out) $<
24 | ld -r -b binary -o $@ $(@:%.o=%.out)
25 |
26 | build/%.o: %.cpp
27 | @mkdir -p $(@D)
28 | g++ $(GCC_FLAGS) -c $< -o $@
29 | $(CC) $(GCC_FLAGS) -MM $^ -MF "$(@:.o=.d)" -MT"$@"
30 |
31 | skeletool64: $(OBJ_FILES) $(LUA_OBJ_FILES)
32 | g++ -g -o skeletool64 $(OBJ_FILES) $(LUA_OBJ_FILES) $(LINKER_FLAGS)
33 |
34 | clean:
35 | rm -r build/
36 |
37 | init:
38 |
39 |
40 | install: skeletool64
41 | cp skeletool64 ~/.local/bin
42 |
43 | build/skeletool.deb: skeletool64 control
44 | mkdir build/skeletool/usr/local/bin -p
45 | cp skeletool64 build/skeletool/usr/local/bin
46 | mkdir build/skeletool/DEBIAN -p
47 | cp control build/skeletool/DEBIAN
48 | dpkg-deb --build build/skeletool
49 |
50 | docs:
51 | ldoc .
52 |
53 | schema_docs/index.html: schema/material-schema.json
54 | generate-schema-doc schema/ schema_docs/index.html
55 |
--------------------------------------------------------------------------------
/schema_docs/schema_doc.css:
--------------------------------------------------------------------------------
1 | body {
2 | font: 16px/1.5em "Overpass", "Open Sans", Helvetica, sans-serif;
3 | color: #333;
4 | font-weight: 300;
5 | padding: 40px;
6 | }
7 |
8 | .btn.btn-link {
9 | font-size: 18px;
10 | }
11 |
12 | .jsfh-animated-property {
13 | animation: eclair;
14 | animation-iteration-count: 1;
15 | animation-fill-mode: forwards;
16 | animation-duration: .75s;
17 |
18 | }
19 |
20 | @keyframes eclair {
21 | 0%,100% {
22 | transform: scale(1);
23 | }
24 | 50% {
25 | transform: scale(1.03);
26 | }
27 | }
28 |
29 | .btn.btn-primary {
30 | margin: 10px;
31 | }
32 |
33 | .btn.example-show.collapsed:before {
34 | content: "show"
35 | }
36 |
37 | .btn.example-show:before {
38 | content: "hide"
39 | }
40 |
41 | .description.collapse:not(.show) {
42 | max-height: 100px !important;
43 | overflow: hidden;
44 |
45 | display: -webkit-box;
46 | -webkit-line-clamp: 2;
47 | -webkit-box-orient: vertical;
48 | }
49 |
50 | .description.collapsing {
51 | min-height: 100px !important;
52 | }
53 |
54 | .collapse-description-link.collapsed:after {
55 | content: '+ Read More';
56 | }
57 |
58 | .collapse-description-link:not(.collapsed):after {
59 | content: '- Read Less';
60 | }
61 |
62 | .badge {
63 | font-size: 100%;
64 | margin-bottom: 0.5rem;
65 | margin-top: 0.5rem;
66 | }
67 |
68 | .badge.value-type {
69 | font-size: 120%;
70 | margin-right: 5px;
71 | margin-bottom: 10px;
72 | }
73 |
74 |
75 | .badge.default-value {
76 | font-size: 120%;
77 | margin-left: 5px;
78 | margin-bottom: 10px;
79 | }
80 |
81 | .badge.restriction {
82 | display: inline-block;
83 | }
84 |
85 | .badge.required-property,.badge.deprecated-property,.badge.pattern-property,.badge.no-additional {
86 | font-size: 100%;
87 | margin-left: 10px;
88 | }
89 |
90 | .accordion div.card:only-child {
91 | border-bottom: 1px solid rgba(0, 0, 0, 0.125);
92 | }
93 |
94 | .examples {
95 | padding: 1rem !important;
96 | }
97 |
98 | .examples pre {
99 | margin-bottom: 0;
100 | }
101 |
102 | .highlight.jumbotron {
103 | padding: 1rem !important;
104 | }
105 |
106 | .generated-by-footer {
107 | margin-top: 1em;
108 | text-align: right;
109 | }
110 |
111 | /* From https://github.com/richleland/pygments-css/blob/master/friendly.css, see https://github.com/trentm/python-markdown2/wiki/fenced-code-blocks */
112 | .highlight { background: #e9ecef; } /* Changed from #f0f0f0 in the original style to be the same as bootstrap's jumbotron */
113 | .highlight .hll { background-color: #ffffcc }
114 | .highlight .c { color: #60a0b0; font-style: italic } /* Comment */
115 | .highlight .err { border: 1px solid #FF0000 } /* Error */
116 | .highlight .k { color: #007020; font-weight: bold } /* Keyword */
117 | .highlight .o { color: #666666 } /* Operator */
118 | .highlight .ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */
119 | .highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
120 | .highlight .cp { color: #007020 } /* Comment.Preproc */
121 | .highlight .cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */
122 | .highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
123 | .highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
124 | .highlight .gd { color: #A00000 } /* Generic.Deleted */
125 | .highlight .ge { font-style: italic } /* Generic.Emph */
126 | .highlight .gr { color: #FF0000 } /* Generic.Error */
127 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
128 | .highlight .gi { color: #00A000 } /* Generic.Inserted */
129 | .highlight .go { color: #888888 } /* Generic.Output */
130 | .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
131 | .highlight .gs { font-weight: bold } /* Generic.Strong */
132 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
133 | .highlight .gt { color: #0044DD } /* Generic.Traceback */
134 | .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
135 | .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
136 | .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
137 | .highlight .kp { color: #007020 } /* Keyword.Pseudo */
138 | .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
139 | .highlight .kt { color: #902000 } /* Keyword.Type */
140 | .highlight .m { color: #40a070 } /* Literal.Number */
141 | .highlight .s { color: #4070a0 } /* Literal.String */
142 | .highlight .na { color: #4070a0 } /* Name.Attribute */
143 | .highlight .nb { color: #007020 } /* Name.Builtin */
144 | .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
145 | .highlight .no { color: #60add5 } /* Name.Constant */
146 | .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
147 | .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
148 | .highlight .ne { color: #007020 } /* Name.Exception */
149 | .highlight .nf { color: #06287e } /* Name.Function */
150 | .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
151 | .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
152 | .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
153 | .highlight .nv { color: #bb60d5 } /* Name.Variable */
154 | .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
155 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */
156 | .highlight .mb { color: #40a070 } /* Literal.Number.Bin */
157 | .highlight .mf { color: #40a070 } /* Literal.Number.Float */
158 | .highlight .mh { color: #40a070 } /* Literal.Number.Hex */
159 | .highlight .mi { color: #40a070 } /* Literal.Number.Integer */
160 | .highlight .mo { color: #40a070 } /* Literal.Number.Oct */
161 | .highlight .sa { color: #4070a0 } /* Literal.String.Affix */
162 | .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
163 | .highlight .sc { color: #4070a0 } /* Literal.String.Char */
164 | .highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */
165 | .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
166 | .highlight .s2 { color: #4070a0 } /* Literal.String.Double */
167 | .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
168 | .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
169 | .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
170 | .highlight .sx { color: #c65d09 } /* Literal.String.Other */
171 | .highlight .sr { color: #235388 } /* Literal.String.Regex */
172 | .highlight .s1 { color: #4070a0 } /* Literal.String.Single */
173 | .highlight .ss { color: #517918 } /* Literal.String.Symbol */
174 | .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
175 | .highlight .fm { color: #06287e } /* Name.Function.Magic */
176 | .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
177 | .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
178 | .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
179 | .highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */
180 | .highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */
--------------------------------------------------------------------------------
/schema_docs/schema_doc.min.js:
--------------------------------------------------------------------------------
1 | function flashElement(t){myElement=document.getElementById(t),myElement.classList.add("jsfh-animated-property"),setTimeout(function(){myElement.classList.remove("jsfh-animated-property")},1e3)}function setAnchor(t){history.pushState({},"",t)}function anchorOnLoad(){let t=window.location.hash.split("?")[0].split("&")[0];"#"===t[0]&&(t=t.substr(1)),t.length>0&&anchorLink(t)}function anchorLink(t){$("#"+t).parents().addBack().filter(".collapse:not(.show), .tab-pane, [role='tab']").each(function(t){if($(this).hasClass("collapse"))$(this).collapse("show");else if($(this).hasClass("tab-pane")){const t=$("a[href='#"+$(this).attr("id")+"']");t&&t.tab("show")}else"tab"===$(this).attr("role")&&$(this).tab("show")}),setTimeout(function(){let e=document.getElementById(t);e&&(e.scrollIntoView({block:"center",behavior:"smooth"}),setTimeout(function(){flashElement(t)},500))},1e3)}$(document).on("click",'a[href^="#"]',function(t){t.preventDefault(),history.pushState({},"",this.href)});
--------------------------------------------------------------------------------
/setup_dependencies.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/bash
2 |
3 | sudo apt install -y libpng-dev libtiff-dev libassimp-dev g++ liblua5.4-dev cmake
4 |
5 | pushd $(dirname "$0")
6 |
7 | git clone https://github.com/jbeder/yaml-cpp.git
8 |
9 | cmake -S yaml-cpp -B yaml-cpp
10 | make -C yaml-cpp
11 |
12 | wget http://cimg.eu/files/CImg_3.1.3.zip
13 | unzip CImg_3.1.3.zip
14 | mv CImg-3.1.3 cimg
15 |
16 | popd
17 |
--------------------------------------------------------------------------------
/src/BoneHierarchy.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include "BoneHierarchy.h"
4 | #include "CFileDefinition.h"
5 |
6 | Bone::Bone(int index, std::string name, Bone* parent, const aiVector3D& restPosition, const aiQuaternion& restRotation, const aiVector3D& restScale):
7 | mIndex(index),
8 | mName(name),
9 | mParent(parent),
10 | mRestPosition(restPosition),
11 | mRestRotation(restRotation),
12 | mRestScale(restScale) {
13 |
14 | if (mParent) {
15 | mParent->mChildren.push_back(this);
16 | }
17 | }
18 |
19 | int Bone::GetIndex() {
20 | return mIndex;
21 | }
22 |
23 | const std::string& Bone::GetName() {
24 | return mName;
25 | }
26 |
27 | Bone* Bone::GetParent() {
28 | return mParent;
29 | }
30 |
31 | std::unique_ptr Bone::GenerateRestPosiitonData() {
32 | std::unique_ptr result(new StructureDataChunk());
33 |
34 | result->Add(std::unique_ptr(new StructureDataChunk(mRestPosition)));
35 | result->Add(std::unique_ptr(new StructureDataChunk(mRestRotation)));
36 | result->Add(std::unique_ptr(new StructureDataChunk(mRestScale)));
37 |
38 | return std::move(result);
39 | }
40 |
41 | Bone* Bone::FindCommonAncestor(Bone* a, Bone* b) {
42 | std::set hierarchyDifference;
43 |
44 | Bone* curr = a;
45 |
46 | while (curr) {
47 | hierarchyDifference.insert(curr);
48 | curr = curr->mParent;
49 | }
50 |
51 | curr = b;
52 |
53 | while (curr) {
54 | hierarchyDifference.erase(curr);
55 | curr = curr->mParent;
56 | }
57 |
58 | curr = a;
59 |
60 | while (hierarchyDifference.find(curr) != hierarchyDifference.end()) {
61 | curr = curr->mParent;
62 | }
63 |
64 | return curr;
65 | }
66 |
67 | Bone* Bone::StepDownTowards(Bone* ancestor, Bone* decendant) {
68 | Bone* curr = decendant;
69 |
70 | while (curr && curr->mParent != ancestor) {
71 | curr = curr->mParent;
72 | }
73 |
74 | return curr;
75 | }
76 |
77 | bool Bone::CompareBones(Bone* a, Bone* b) {
78 | if (a == nullptr && b == nullptr) {
79 | return false;
80 | } else if (a == nullptr) {
81 | return true;
82 | } else if (b == nullptr) {
83 | return false;
84 | } else {
85 | return a->mIndex < b->mIndex;
86 | }
87 | }
88 |
89 | int Bone::GetBoneIndex(Bone* a) {
90 | if (a == nullptr) {
91 | return -1;
92 | } else {
93 | return a->mIndex;
94 | }
95 | }
96 |
97 | void BoneHierarchy::PopulateWithAnimationNodeInfo(const NodeAnimationInfo& animInfo, float fixedPointScale, aiQuaternion& rotation) {
98 | aiMatrix4x4 rotationMatrix(rotation.GetMatrix());
99 |
100 | for (auto& node : animInfo.nodesWithAnimation) {
101 | Bone* parent = nullptr;
102 |
103 | if (node->parent) {
104 | auto parentFind = mBoneByName.find(node->parent->mName.C_Str());
105 |
106 | if (parentFind != mBoneByName.end()) {
107 | parent = parentFind->second;
108 | }
109 | }
110 |
111 | std::string boneName = node->node->mName.C_Str();
112 |
113 | aiVector3D restPosition;
114 | aiQuaternion restRotation;
115 | aiVector3D restScale;
116 |
117 | aiMatrix4x4 fullRestTransform = node->relativeTransform * node->node->mTransformation;
118 |
119 | if (parent == nullptr) {
120 | fullRestTransform = rotationMatrix * fullRestTransform;
121 | }
122 |
123 | fullRestTransform.Decompose(restScale, restRotation, restPosition);
124 |
125 | mBones.push_back(std::unique_ptr(new Bone(
126 | mBones.size(),
127 | boneName,
128 | parent,
129 | restPosition * fixedPointScale,
130 | restRotation,
131 | restScale
132 | )));
133 |
134 | mBoneByName.insert(std::pair(boneName, mBones.back().get()));
135 | }
136 | }
137 |
138 | void BoneHierarchy::SearchForBones(aiNode* node, Bone* currentBoneParent, std::set& knownBones, bool parentIsBone, float fixedPointScale) {
139 | if (knownBones.find(node->mName.C_Str()) != knownBones.end()) {
140 | aiVector3D restPosition;
141 | aiQuaternion restRotation;
142 | aiVector3D restScale;
143 | node->mTransformation.Decompose(restScale, restRotation, restPosition);
144 |
145 | mBones.push_back(std::unique_ptr(new Bone(
146 | mBones.size(),
147 | node->mName.C_Str(),
148 | currentBoneParent,
149 | restPosition * fixedPointScale,
150 | restRotation,
151 | restScale
152 | )));
153 |
154 | currentBoneParent = mBones[mBones.size() - 1].get();
155 | mBoneByName.insert(std::pair(node->mName.C_Str(), currentBoneParent));
156 |
157 | parentIsBone = true;
158 | }
159 |
160 | for (unsigned int i = 0; i < node->mNumChildren; ++i) {
161 | SearchForBones(node->mChildren[i], currentBoneParent, knownBones, parentIsBone, fixedPointScale);
162 | }
163 | }
164 |
165 | void BoneHierarchy::SearchForBonesInScene(const aiScene* scene, float fixedPointScale) {
166 | std::set knownBones;
167 |
168 | for (unsigned int meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) {
169 | aiMesh* mesh = scene->mMeshes[meshIndex];
170 |
171 | for (unsigned int boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex) {
172 | knownBones.insert(mesh->mBones[boneIndex]->mName.C_Str());
173 | }
174 | }
175 |
176 | SearchForBones(scene->mRootNode, nullptr, knownBones, false, fixedPointScale);
177 | }
178 |
179 | Bone* BoneHierarchy::BoneByIndex(unsigned index) {
180 | return mBones[index].get();
181 | }
182 |
183 | Bone* BoneHierarchy::BoneForName(std::string name) {
184 | auto result = mBoneByName.find(name);
185 |
186 | if (result == mBoneByName.end()) {
187 | return nullptr;
188 | } else {
189 | return result->second;
190 | }
191 | }
192 |
193 | void BoneHierarchy::GenerateRestPosiitonData(CFileDefinition& fileDef, const std::string& variableName) {
194 | if (mBones.size() == 0) return;
195 |
196 | std::unique_ptr transformData(new StructureDataChunk());
197 |
198 | for (unsigned int boneIndex = 0; boneIndex < mBones.size(); ++boneIndex) {
199 | transformData->Add(std::move(mBones[boneIndex]->GenerateRestPosiitonData()));
200 |
201 | std::string boneName = fileDef.GetUniqueName(mBones[boneIndex]->GetName() + "_BONE");
202 | std::transform(boneName.begin(), boneName.end(), boneName.begin(), ::toupper);
203 |
204 | fileDef.AddMacro(boneName, std::to_string(boneIndex));
205 | }
206 |
207 | std::unique_ptr restPosDef(new DataFileDefinition("struct Transform", variableName, true, "_geo", std::move(transformData)));
208 | restPosDef->AddTypeHeader("\"math/transform.h\"");
209 | fileDef.AddDefinition(std::move(restPosDef));
210 | }
211 |
212 | bool BoneHierarchy::HasData() const {
213 | return mBones.size() > 0;
214 | }
215 |
216 | unsigned int BoneHierarchy::GetBoneCount() const {
217 | return mBones.size();
218 | }
--------------------------------------------------------------------------------
/src/BoneHierarchy.h:
--------------------------------------------------------------------------------
1 | #ifndef _BONE_HIERARCHY_H
2 | #define _BONE_HIERARCHY_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include