Skip to content

Commit 6fabc6b

Browse files
committed
chore(release): release v1.1.1
1 parent 87235e1 commit 6fabc6b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1929
-1723
lines changed

.clang-format

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,4 @@ SpacesBeforeTrailingComments: 1
5252
TabWidth: 4
5353
UseTab: ForIndentation
5454
AccessModifierOffset: -4
55+
IndentPPDirectives: BeforeHash

.gitmodules

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
[submodule "vendor/mio"]
55
path = vendor/mio
66
url = https://github.com/mandreyel/mio.git
7-
[submodule "vendor/lexy"]
8-
path = vendor/lexy
9-
url = https://github.com/foonathan/lexy.git
107
[submodule "vendor/libsquish"]
118
path = vendor/libsquish
129
url = https://github.com/lmichaelis/phoenix-libsquish.git

CMakeLists.txt

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
cmake_minimum_required(VERSION 3.10)
22
include(CheckIncludeFiles)
3-
project(phoenix VERSION 1.0.1)
3+
project(phoenix VERSION 1.1.1)
44

55
set(CMAKE_CXX_STANDARD 17)
66
set(PHOENIX_LOG_LEVEL 3 CACHE STRING "The logging level to use for phoenix. Set to 4, 3, 2, or 1 for DEBUG, INFO, WARN or ERROR respectively")
77

88
option(PHOENIX_BUILD_EXAMPLES "Build example code" OFF)
99
option(PHOENIX_BUILD_TESTS "Build tests" ON)
10+
option(PHOENIX_BUILD_SHARED "Build phoenix as a shared library" OFF)
1011
option(PHOENIX_DISABLE_SANITIZERS "Build without sanitizers in debug mode" OFF)
1112
option(PHOENIX_INSTALL "Configure phoenix for cmake install" ON)
1213

@@ -57,12 +58,14 @@ set(PHOENIX_SOURCES
5758
source/buffer.cc
5859
source/font.cc
5960
source/material.cc
61+
source/math.cc
6062
source/mesh.cc
6163
source/messages.cc
6264
source/model.cc
6365
source/model_hierarchy.cc
6466
source/model_mesh.cc
6567
source/model_script.cc
68+
source/model_script_dsl.cc
6669
source/morph_mesh.cc
6770
source/phoenix.cc
6871
source/proto_mesh.cc
@@ -112,32 +115,42 @@ set(PHOENIX_TESTS
112115
tests/test_world.cc)
113116

114117
# add the phoenix library definition
115-
add_library(phoenix ${PHOENIX_SOURCES} ${PHOENIX_EXTENSIONS} ${PHOENIX_HEADERS})
118+
if (BUILD_SHARED_LIBS AND PHOENIX_BUILD_SHARED)
119+
add_library(phoenix SHARED)
120+
set_target_properties(phoenix PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1)
121+
else ()
122+
add_library(phoenix STATIC)
123+
set(PHOENIX_DEFINES ${PHOENIX_DEFINES} PHOENIX_STATIC=1)
124+
set_target_properties(phoenix PROPERTIES COMPILE_FLAGS "-DPHOENIX_STATIC=1")
125+
endif ()
126+
127+
target_sources(phoenix PRIVATE ${PHOENIX_SOURCES} ${PHOENIX_EXTENSIONS} ${PHOENIX_HEADERS})
116128
target_include_directories(phoenix PUBLIC include)
117129

118130
# Apps using phoenix will also need to link to glm, fmt and squish to avoid missing symbols
119131
target_link_libraries(phoenix
120132
PUBLIC glm::glm_static squish
121-
PRIVATE mio lexy)
133+
PRIVATE mio)
122134

123-
target_compile_definitions(phoenix PUBLIC ${PHOENIX_DEFINES})
135+
target_compile_definitions(phoenix PUBLIC ${PHOENIX_DEFINES} PRIVATE PHOENIX_EXPORTS=1)
124136
target_compile_options(phoenix PRIVATE ${PHOENIX_CXX_FLAGS})
125137

126138
if (NOT MSVC)
127139
target_link_options(phoenix PUBLIC ${PHOENIX_CXX_FLAGS})
128140
endif ()
129141

130142
set_target_properties(phoenix PROPERTIES
131-
DEBUG_POSTFIX "${PHOENIX_DEBUG_POSTFIX}")
143+
DEBUG_POSTFIX "${PHOENIX_DEBUG_POSTFIX}"
144+
VERSION ${PROJECT_VERSION})
132145

133146
if (PHOENIX_INSTALL)
134147
install(TARGETS phoenix ARCHIVE LIBRARY RUNTIME)
135-
136148
install(DIRECTORY "include/phoenix" TYPE INCLUDE)
137-
install(DIRECTORY "${glm_SOURCE_DIR}/glm" TYPE INCLUDE FILES_MATCHING PATTERN "*.hpp" PATTERN "*.inl" PATTERN "*.h")
138149

139-
if (NOT BUILD_SHARED_LIBS)
150+
if (NOT PHOENIX_BUILD_SHARED)
140151
# For static linking we'll need to provide the dependency static libraries
152+
install(DIRECTORY "${glm_SOURCE_DIR}/glm" TYPE INCLUDE FILES_MATCHING PATTERN "*.hpp" PATTERN "*.inl" PATTERN "*.h")
153+
141154
foreach (lib glm::glm_static squish)
142155
install(FILES "$<TARGET_LINKER_FILE:${lib}>" TYPE LIB)
143156
endforeach ()

changelog.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,33 @@ found in [readme.md](readme.md#versioning).
66

77
---
88

9+
## v1.1.1
10+
11+
This update again brings many bugfixes and smaller improvements in addition to updates to the documentation.
12+
_phoenix_ can now also be built as a shared library which should be considered an experimental feature. This update
13+
also finally replaces the old [lexy](https://github.com/foonathan/lexy) parser for model scripts with a self-rolled
14+
implementation.
15+
16+
### Bugfixes
17+
* [03cb97bd] Fixed a stack corruption issue in the VM which could be triggered if the `movvf` or `movf` was called
18+
with a member but no current instance was present
19+
* [c6cb69de] Fixed broken VM execution flag `allow_null_instance_access` for instructions `addmovi`, `submovi`,
20+
`mulmovi` and `divmovi`.
21+
* [cae1c118, f0d6751f] Fixed a VM/script bug which could occur when using higher-order functions.
22+
* [2cd3da6f] Added checks for division by zero errors in the VM.
23+
* [3693450b] Prevent null-pointer de-reference in `vm::initialize_instance` if the instance's parent symbol can
24+
not be found.
25+
* [1bf25106] VDF entries with a size larger than the VDF file itself are now no longer loaded.
26+
* [5d78aa49, 4e7b8630] Fix an issues with ignoring whitespace in binary archives.
27+
* [c7d4115f] Catch numeric conversion errors in archives and re-throw them as `parser_error`s.
28+
29+
### Misc
30+
31+
* [4e9ae25e] Move the const-ness check for script symbols into the VM.
32+
* [c7c6b94a] (experimental) Allow for building phoenix as a shared library.
33+
* [15cd5893] Save the checksums for animations, model meshes and skeletons.
34+
* [16679249] Switch to a custom model script parser, dropping the dependency on [lexy](https://github.com/foonathan/lexy)
35+
936
## v1.1.0
1037

1138
Oh boy, this is a big one! There are a lot of additions, some changes and also some deprecations here. Also, the

docs/assets/javascript/mathjax.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
window.MathJax = {
2+
tex: {
3+
inlineMath: [["\\(", "\\)"]],
4+
displayMath: [["\\[", "\\]"]],
5+
processEscapes: true,
6+
processEnvironments: true
7+
},
8+
options: {
9+
ignoreHtmlClass: ".*|",
10+
processHtmlClass: "arithmatex"
11+
}
12+
};
13+
14+
document$.subscribe(() => {
15+
MathJax.typesetPromise()
16+
})

docs/engine/formats/animation.md

Lines changed: 185 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ chunks. Also refer to the [Datatype Reference](../datatypes.md) for general info
5353
float fps;
5454
float fpsSource;
5555

56-
float samplePositionRangeMin;
57-
float samplePositionScalar;
56+
float samplePositionMin;
57+
float samplePositionScale;
5858
5959
zTBBox3D bounds;
6060
string next;
@@ -85,7 +85,188 @@ chunks. Also refer to the [Datatype Reference](../datatypes.md) for general info
8585
struct zCModelAni_Samples {
8686
uint checksum;
8787
uint nodeIndices[/* zCModelAni_Header.numNodes */];
88-
ushort rotation[3];
89-
ushort position[3];
88+
89+
struct zTMdl_AniSample {
90+
ushort rotation[3];
91+
ushort position[3];
92+
} samples[/* zCModelAni_Header.numNodes * zCModelAni_Header.numFrames */];
9093
};
9194
```
95+
96+
The `zCModelAni.checksum` field is used to match compatible the animation to a specific model. It is the same for
97+
assets belonging to the same model. Linked assets are `zCModelAni.checksum`, `zCModelMeshLib.checksum` and
98+
`zCModelHierarchy.checksum`.
99+
100+
It is important to understand that the animation samples do not contain the actual values for the rotation and
101+
position. To save on memory and disk space consumption, the values are packed into shorts which are converted
102+
back to floats on demand. See [Sample Positions](#sample-positions) and [Sample Rotations](#sample-rotations) for
103+
more information.
104+
105+
---
106+
107+
### Sample Positions
108+
109+
The positions are represented as multiples of `zCModelAni_Header.samplePositionScale`. The formula for packing a
110+
given `zVEC3` position into the stored format can be summarized like this:
111+
112+
$$
113+
\begin{bmatrix}
114+
x_{p} \\
115+
y_{p} \\
116+
z_{p}
117+
\end{bmatrix}
118+
=
119+
\Bigg(-v_{min} +
120+
\begin{bmatrix}
121+
x \\
122+
y \\
123+
z
124+
\end{bmatrix}
125+
\Bigg) \cdot \frac{65535}{v_{max} - v_{min}}
126+
$$
127+
128+
where $v_{min}$ is the smallest value across all components of all sample positions of the animation and $v_{max}$
129+
is the maximum value. The output vector $\begin{smallmatrix}x_{p} \\ y_{p} \\ z_{p} \end{smallmatrix}$ then contains a
130+
scaled representation of the input vector $\begin{smallmatrix}x \\ y \\ z\end{smallmatrix}$ as three 16-bit unsigned
131+
integers. This operation is performed by `zCModelAni::AddTrafoMatrix` and `zTMdl_AniSample::PackTrans`.
132+
133+
Alongside these packed positions, both $v_{min}$ and the constant $s = (\frac{65535}{v_{max} - v_{min}})^{-1}$ are saved
134+
as `zCModelAni_Header.samplePositionMin` and `zCModelAni_Header.samplePositionScale` respectively. Thus, to convert
135+
the stored position back to its floating point representation, the following calculation may be applied:
136+
137+
$$
138+
\begin{bmatrix}
139+
x \\
140+
y \\
141+
z
142+
\end{bmatrix}
143+
=
144+
\begin{bmatrix}
145+
x_{p} \\
146+
y_{p} \\
147+
z_{p}
148+
\end{bmatrix}
149+
\cdot s + v_{min}
150+
$$
151+
152+
where $x_{p}$ , $y_{p}$ and $z_{p}$ are `zTMdl_AniSample.position[0]`, `zTMdl_AniSample.position[1]` and
153+
`zTMdl_AniSample.position[2]` respectively. This operation is performed by `zTMdl_AniSample::UnpackTrans` .
154+
155+
### Sample Rotations
156+
157+
The rotations are represented as a packed quaternion which is calculated in the following way:
158+
159+
$$
160+
\begin{bmatrix}
161+
x_{p} \\
162+
y_{p} \\
163+
z_{p}
164+
\end{bmatrix}
165+
=
166+
\begin{cases}
167+
\begin{bmatrix}
168+
x \\
169+
y \\
170+
z
171+
\end{bmatrix}
172+
\div s + h & \quad \text{if } w \geq 0 \\
173+
-\Bigg(
174+
\begin{bmatrix}
175+
x \\
176+
y \\
177+
z
178+
\end{bmatrix}
179+
\div s + h\Bigg) - 2 & \quad \text{if } w < 0 \\
180+
\end{cases}
181+
$$
182+
183+
where
184+
185+
$$
186+
s = \frac{1}{2^{16} - 1} * 2.1 = \frac{1}{65535} * 2.1
187+
$$
188+
189+
and
190+
191+
$$
192+
h = 2^{15} - 1 = 32767
193+
$$
194+
195+
This operation packs a quaternion of the form $r = \begin{smallmatrix}x \\ y \\ z \\ w\end{smallmatrix}$ into a set of
196+
three 16-bit unsigned integers $x_{p}$ , $y_{p}$ and $z_{p}$ which are stored into the sample. **The input quaternion
197+
$r$ is required to be a unit vector**. This operation was performed by `zCModelAni::AddTrafoMatrix` and
198+
`zTMdl_AniSample::PackQuat`.
199+
200+
They can be unpacked using some quaternion wizardry as described below.
201+
202+
$$
203+
\begin{bmatrix}
204+
x \\
205+
y \\
206+
z \\
207+
w
208+
\end{bmatrix}
209+
=
210+
\begin{cases}
211+
\begin{bmatrix}
212+
x_{t} \\
213+
y_{t} \\
214+
z_{t} \\
215+
\sqrt{1 - l}
216+
\end{bmatrix} & \quad \text{if } l \leq 1 \\
217+
\begin{bmatrix}
218+
x_{t} \\
219+
y_{t} \\
220+
z_{t} \\
221+
0
222+
\end{bmatrix}
223+
\cdot \frac{1}{\sqrt{l}} & \quad \text{if } l > 1
224+
\end{cases}
225+
$$
226+
227+
where
228+
229+
$$
230+
\begin{bmatrix}
231+
x_{t} \\
232+
y_{t} \\
233+
z_{t} \\
234+
\end{bmatrix}
235+
=
236+
\Bigg(\begin{bmatrix}
237+
x_{p} \\
238+
y_{p} \\
239+
z_{p} \\
240+
\end{bmatrix} - h\Bigg) \cdot s
241+
$$
242+
243+
and
244+
245+
$$
246+
l = (x_{t})^2 + (y_{t})^2 + (z_{t})^2
247+
$$
248+
249+
The values $x_{p}$ , $y_{p}$ and $z_{p}$ for this computation are stored in `zTMdl_AniSample.rotation[0]`,
250+
`zTMdl_AniSample.rotation[1]` and `zTMdl_AniSample.rotation[2]` respectively. This is possible since the quaternion
251+
$r$ used to calculate the packed rotation is guaranteed to be a unit-quaternion, thus, if we have three components
252+
(like we do), it is possible to calculate the third component. This operation is performed by
253+
`zTMdl_AniSample::UnpackQuat`.
254+
255+
---
256+
257+
### (todo) How animated models are loaded
258+
259+
Animated models are loaded by using their associated model script file. While parsing the model script, the parser
260+
will encounter a `meshAndTree` directive (in MSB files a chunk of type `0xf300`) which points to a model hierarchy.
261+
262+
This model hierarchy is then loaded and acts as the ground truth of the model. If a hierarchy can't be loaded for any
263+
reason, the engine tries to load a model mesh instead.
264+
265+
The model script parser continues and eventually hits the `aniEnum` section. While loading it, it will come across
266+
`ani` sections. Those sections contain a model and animation name which are then loaded as animations and model meshes
267+
respectively.
268+
269+
Linking these parts together is a checksum calculates from the list of hierarchy nodes. It is just the CRC32 checksum
270+
of all node names appended after each other in the order they are saved in. I.e. a model hierarchy with two nodes
271+
`"BIP01"` and `"BIP01 LEVER STICK"` (in that order) will have a checksum of `ea809bf7` (which
272+
is `crc32("BIP01BIP01 LEVER STICK")`.

docs/library/formats/animation.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
3+
Animations (also called _Model Animations_) form part of the animations system of the _ZenGin_ they contain only
4+
animation samples, i.e. the position and orientation of each bone of the skeleton they're applied to. While there is
5+
space for additional data within animation files, it is mostly empty.
6+
7+
## Overview
8+
9+
*phoenix'* implementation of animations lives in `include/phoenix/animation.hh` and `source/animation.cc`. The most
10+
important part of an animation are its samples. They are stored in `animation::samples` after it has been parsed.
11+
Animation files themselves don't contain information about when to run animation or any other effects which should be
12+
applied during it. Those parts of the animation system are defined in [Model Script](formats/model-script.md) files
13+
which should be loaded before animations. The `animation::events` field will always be empty for that reason.
14+
15+
16+
### Loading a Font
17+
18+
Like most data structures in *phoenix*, animations can be loaded using the `#!cpp phoenix::animation::parse()` function.
19+
It takes a `phoenix::buffer` as a parameter and loads the animation from it.
20+
21+
```cpp title="Example"
22+
#include <phoenix/animation.hh>
23+
24+
int main(int, const char** argv) {
25+
auto anim_buffer = phoenix::buffer::mmap("A.man");
26+
[[maybe_unused]] auto anim = phoenix::animation::parse(anim_buffer);
27+
return 0;
28+
}
29+
```

docs/library/reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The following is a list of file types and formats used by ZenGin.
1515

1616
| Format | Extension | Description | _phoenix_ Class Name |
1717
|-----------------------------------------------------------|:------------------------------:|----------------------------------------------------------------------------------------------------------------------------|----------------------|
18-
| [Model Animation](formats/model-animation.md) | `.MAN` | Contains animations for a model | `animation` |
18+
| [Model Animation](formats/animation.md) | `.MAN` | Contains animations for a model | `animation` |
1919
| [Model Hierarchy](formats/model-hierarchy.md) | `.MDH` | Contains skeletal information for a model | `model_hierarchy` |
2020
| [Model Mesh](formats/model-mesh.md) | `.MDM` | Contains the mesh of a model | `model_mesh` |
2121
| [Model](formats/model.md) | `.MDL` | Contains a mesh and a hierarchy which make up a model | `model` |

0 commit comments

Comments
 (0)