summaryrefslogtreecommitdiff
path: root/kon
diff options
context:
space:
mode:
Diffstat (limited to 'kon')
-rw-r--r--kon/konmodel.h133
1 files changed, 133 insertions, 0 deletions
diff --git a/kon/konmodel.h b/kon/konmodel.h
new file mode 100644
index 0000000..4b4e7e7
--- /dev/null
+++ b/kon/konmodel.h
@@ -0,0 +1,133 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * konmodel.h
+ *
+ * Copyright (c) 2026 KonAki
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef KONMODEL_H
+#define KONMODEL_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "konmath.h"
+#include "konsofren.h"
+#include "konassets.h"
+
+/*** definition ***/
+
+#define KON_MODEL_MAX_BONES 128
+#define KON_MODEL_NAME_SIZE 32
+#define KON_MODEL_TEXTURE_SIZE 64
+
+typedef struct kon_modelMaterial {
+ char texture[KON_MODEL_TEXTURE_SIZE]; /* asset name, empty for none */
+ uint32_t color;
+ kon_filter_t filter;
+ const kon_image *image; /* set by kon_modelBindTextures */
+} kon_modelMaterial_t;
+
+/* joints and weights hold 4 entries per vertex, both are NULL if the mesh isn't skinned */
+typedef struct kon_modelMesh {
+ int material;
+ int vertexCount;
+ int triangleCount;
+ kon_vertex_t *vertices;
+ uint16_t *indices;
+ uint8_t *joints;
+ float *weights;
+} kon_modelMesh_t;
+
+/* bones are sorted so a parent always comes before its children */
+typedef struct kon_modelBone {
+ char name[KON_MODEL_NAME_SIZE];
+ int parent; /* -1 for a root */
+ kon_mat4_t inverseBind;
+ kon_vec3_t position;
+ kon_vec4_t rotation; /* quaternion x y z w */
+ kon_vec3_t scale;
+} kon_modelBone_t;
+
+typedef enum kon_modelPath {
+ KON_MODEL_POSITION = 0,
+ KON_MODEL_ROTATION,
+ KON_MODEL_SCALE
+} kon_modelPath_t;
+
+/* values holds 3 floats per key, 4 for rotation. step holds each key until the next one instead of blending */
+typedef struct kon_modelChannel {
+ int bone;
+ int path;
+ int step;
+ int keyCount;
+ float *times;
+ float *values;
+} kon_modelChannel_t;
+
+typedef struct kon_modelClip {
+ char name[KON_MODEL_NAME_SIZE];
+ float duration;
+ int channelCount;
+ kon_modelChannel_t *channels;
+} kon_modelClip_t;
+
+typedef struct kon_model {
+ int materialCount, meshCount, boneCount, clipCount;
+ kon_modelMaterial_t *materials;
+ kon_modelMesh_t *meshes;
+ kon_modelBone_t *bones;
+ kon_modelClip_t *clips;
+ kon_vertex_t *scratch; /* skinned vertices are built here while drawing */
+ int scratchCount;
+ size_t bytes;
+} kon_model_t;
+
+/*** declarations ***/
+
+/* NULL if the data is not a valid model, nothing is read outside of it */
+kon_model_t *kon_modelLoad(const uint8_t *data, size_t size);
+void kon_modelFree(kon_model_t *model);
+
+/* loads .kmdl files through the asset manager, returns the type id for kon_assetGetAs or -1 */
+int kon_modelRegister(kon_assets_t *assets);
+
+/* gets every texture the materials name and keeps it in use until unbind. missing ones are left untextured */
+void kon_modelBindTextures(kon_model_t *model, kon_assets_t *assets);
+void kon_modelUnbindTextures(kon_model_t *model, kon_assets_t *assets);
+
+int kon_modelFindBone(const kon_model_t *model, const char *name);
+int kon_modelFindClip(const kon_model_t *model, const char *name);
+
+/* fills skin with one matrix per bone to pass to kon_modelDraw. clip -1 gives the rest pose.
+ a looping clip wraps around, otherwise time stops at the end */
+void kon_modelSample(const kon_model_t *model, int clip, float time, int loop, kon_mat4_t *skin);
+
+/* skin can be NULL to draw without animation. light and flags work like in kon_drawMesh.
+ not safe to call for the same model from two threads */
+void kon_modelDraw(kon_framebuffer_t *fb, kon_mat4_t viewProjection, kon_mat4_t world, kon_model_t *model, const kon_mat4_t *skin, const kon_light_t *light, kon_renderFlags_t flags);
+
+#ifdef KONMODEL_WRITER
+/* makes the .kmdl bytes for a model, free them yourself. NULL if it fails. only the converter needs this */
+uint8_t *kon_modelSerialize(const kon_model_t *model, size_t *size);
+#endif
+
+#endif