This commit is contained in:
2026-04-10 18:47:46 -05:00
parent efa583c154
commit bb7c41c754
3 changed files with 253 additions and 10 deletions
+14 -8
View File
@@ -23,14 +23,16 @@
engine_t ENGINE;
texture_t TEXTURE;
#pragma pack(push, 1)
color_t TEXTURE_COLORS[] = {
COLOR_RED, COLOR_GREEN, COLOR_MAGENTA, COLOR_CYAN,
COLOR_BLUE, COLOR_WHITE, COLOR_YELLOW, COLOR_BLACK,
COLOR_CYAN, COLOR_MAGENTA, COLOR_GREEN, COLOR_RED,
COLOR_WHITE, COLOR_BLUE, COLOR_BLACK, COLOR_YELLOW
};
#pragma pack(pop)
entityid_t ent1;
componentid_t ent1Pos;
componentid_t ent1Mesh;
componentid_t ent1Mat;
errorret_t engineInit(const int32_t argc, const char_t **argv) {
memoryZero(&ENGINE, sizeof(engine_t));
@@ -62,10 +64,10 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
);
componentid_t camCam = entityAddComponent(cam, COMPONENT_TYPE_CAMERA);
entityid_t ent1 = entityManagerAdd();
componentid_t ent1Pos = entityAddComponent(ent1, COMPONENT_TYPE_POSITION);
componentid_t ent1Mesh = entityAddComponent(ent1, COMPONENT_TYPE_MESH);
componentid_t ent1Mat = entityAddComponent(ent1, COMPONENT_TYPE_MATERIAL);
ent1 = entityManagerAdd();
ent1Pos = entityAddComponent(ent1, COMPONENT_TYPE_POSITION);
ent1Mesh = entityAddComponent(ent1, COMPONENT_TYPE_MESH);
ent1Mat = entityAddComponent(ent1, COMPONENT_TYPE_MATERIAL);
textureInit(&TEXTURE, 4, 4, TEXTURE_FORMAT_RGBA, (texturedata_t){
.rgbaColors = TEXTURE_COLORS
@@ -80,8 +82,7 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
));
shadermaterial_t *mat = entityMaterialGetShaderMaterial(ent1, ent1Mat);
// mat->unlit.color = COLOR_WHITE;
mat->unlit.color = COLOR_RED;
mat->unlit.color = COLOR_WHITE;
mat->unlit.texture = &TEXTURE;
// EOF
@@ -99,6 +100,11 @@ errorret_t engineUpdate(void) {
timeUpdate();
inputUpdate();
vec3 rotation;
entityPositionGetRotation(ent1, ent1Pos, rotation);
rotation[1] += 0.01f;
entityPositionSetRotation(ent1, ent1Pos, rotation);
uiUpdate();
errorChain(sceneUpdate());
errorChain(gameUpdate());
@@ -15,6 +15,9 @@ void entityPositionInit(
entityId, componentId, COMPONENT_TYPE_POSITION
);
glm_vec3_zero(pos->position);
glm_vec3_zero(pos->rotation);
glm_vec3_one(pos->scale);
glm_mat4_identity(pos->transform);
}
@@ -29,6 +32,7 @@ void entityPositionLookAt(
entityId, componentId, COMPONENT_TYPE_POSITION
);
glm_lookat(eye, target, up, pos->transform);
entityPositionDecompose(pos);
}
void entityPositionGetTransform(
@@ -40,4 +44,141 @@ void entityPositionGetTransform(
entityId, componentId, COMPONENT_TYPE_POSITION
);
glm_mat4_copy(pos->transform, dest);
}
void entityPositionGetPosition(
const entityid_t entityId,
const componentid_t componentId,
vec3 dest
) {
entityposition_t *pos = componentGetData(
entityId, componentId, COMPONENT_TYPE_POSITION
);
glm_vec3_copy(pos->position, dest);
}
void entityPositionSetPosition(
const entityid_t entityId,
const componentid_t componentId,
vec3 position
) {
entityposition_t *pos = componentGetData(
entityId, componentId, COMPONENT_TYPE_POSITION
);
glm_vec3_copy(position, pos->position);
entityPositionRebuild(pos);
}
void entityPositionGetRotation(
const entityid_t entityId,
const componentid_t componentId,
vec3 dest
) {
entityposition_t *pos = componentGetData(
entityId, componentId, COMPONENT_TYPE_POSITION
);
glm_vec3_copy(pos->rotation, dest);
}
void entityPositionSetRotation(
const entityid_t entityId,
const componentid_t componentId,
vec3 rotation
) {
entityposition_t *pos = componentGetData(
entityId, componentId, COMPONENT_TYPE_POSITION
);
glm_vec3_copy(rotation, pos->rotation);
entityPositionRebuild(pos);
}
void entityPositionGetScale(
const entityid_t entityId,
const componentid_t componentId,
vec3 dest
) {
entityposition_t *pos = componentGetData(
entityId, componentId, COMPONENT_TYPE_POSITION
);
glm_vec3_copy(pos->scale, dest);
}
void entityPositionSetScale(
const entityid_t entityId,
const componentid_t componentId,
vec3 scale
) {
entityposition_t *pos = componentGetData(
entityId, componentId, COMPONENT_TYPE_POSITION
);
glm_vec3_copy(scale, pos->scale);
entityPositionRebuild(pos);
}
void entityPositionRebuild(entityposition_t *pos) {
glm_mat4_identity(pos->transform);
glm_translate(pos->transform, pos->position);
glm_rotate_x(pos->transform, pos->rotation[0], pos->transform);
glm_rotate_y(pos->transform, pos->rotation[1], pos->transform);
glm_rotate_z(pos->transform, pos->rotation[2], pos->transform);
glm_scale(pos->transform, pos->scale);
}
void entityPositionDecompose(entityposition_t *pos) {
// Translation: column 3
pos->position[0] = pos->transform[3][0];
pos->position[1] = pos->transform[3][1];
pos->position[2] = pos->transform[3][2];
// Scale: length of each basis column (xyz only)
pos->scale[0] = sqrtf(
pos->transform[0][0] * pos->transform[0][0] +
pos->transform[0][1] * pos->transform[0][1] +
pos->transform[0][2] * pos->transform[0][2]
);
pos->scale[1] = sqrtf(
pos->transform[1][0] * pos->transform[1][0] +
pos->transform[1][1] * pos->transform[1][1] +
pos->transform[1][2] * pos->transform[1][2]
);
pos->scale[2] = sqrtf(
pos->transform[2][0] * pos->transform[2][0] +
pos->transform[2][1] * pos->transform[2][1] +
pos->transform[2][2] * pos->transform[2][2]
);
// Normalize columns to isolate the rotation matrix
float invS0 = pos->scale[0] > 0.0f ? 1.0f / pos->scale[0] : 0.0f;
float invS1 = pos->scale[1] > 0.0f ? 1.0f / pos->scale[1] : 0.0f;
float invS2 = pos->scale[2] > 0.0f ? 1.0f / pos->scale[2] : 0.0f;
mat4 r;
glm_mat4_identity(r);
r[0][0] = pos->transform[0][0] * invS0;
r[0][1] = pos->transform[0][1] * invS0;
r[0][2] = pos->transform[0][2] * invS0;
r[1][0] = pos->transform[1][0] * invS1;
r[1][1] = pos->transform[1][1] * invS1;
r[1][2] = pos->transform[1][2] * invS1;
r[2][0] = pos->transform[2][0] * invS2;
r[2][1] = pos->transform[2][1] * invS2;
r[2][2] = pos->transform[2][2] * invS2;
// Extract XYZ euler angles (R = Rx * Ry * Rz, column-major)
// r[2][0] = sin(Y), r[2][1] = -sin(X)*cos(Y), r[2][2] = cos(X)*cos(Y)
// r[0][0] = cos(Y)*cos(Z), r[1][0] = -cos(Y)*sin(Z)
float sinBeta = glm_clamp(r[2][0], -1.0f, 1.0f);
pos->rotation[1] = asinf(sinBeta);
float cosBeta = cosf(pos->rotation[1]);
if (fabsf(cosBeta) > 1e-6f) {
pos->rotation[0] = atan2f(-r[2][1], r[2][2]);
pos->rotation[2] = atan2f(-r[1][0], r[0][0]);
} else {
// Gimbal lock: pin Z to 0, recover X from the remaining degree of freedom
pos->rotation[2] = 0.0f;
pos->rotation[0] = (sinBeta > 0.0f)
? atan2f(r[0][1], r[1][1])
: -atan2f(r[0][1], r[1][1]);
}
}
@@ -10,6 +10,9 @@
typedef struct {
mat4 transform;
vec3 position;
vec3 rotation;
vec3 scale;
} entityposition_t;
/**
@@ -42,7 +45,7 @@ void entityPositionLookAt(
/**
* Gets the transform matrix of the entity position component.
*
*
* @param entityId The entity ID.
* @param componentId The component ID.
* @param dest The destination matrix to write the transform to.
@@ -51,4 +54,97 @@ void entityPositionGetTransform(
const entityid_t entityId,
const componentid_t componentId,
mat4 dest
);
);
/**
* Gets the cached position of the entity.
*
* @param entityId The entity ID.
* @param componentId The component ID.
* @param dest The destination vec3 to write the position to.
*/
void entityPositionGetPosition(
const entityid_t entityId,
const componentid_t componentId,
vec3 dest
);
/**
* Sets the position of the entity and rebuilds the transform matrix.
*
* @param entityId The entity ID.
* @param componentId The component ID.
* @param position The new position.
*/
void entityPositionSetPosition(
const entityid_t entityId,
const componentid_t componentId,
vec3 position
);
/**
* Gets the cached euler rotation (XYZ, radians) of the entity.
*
* @param entityId The entity ID.
* @param componentId The component ID.
* @param dest The destination vec3 to write the rotation to.
*/
void entityPositionGetRotation(
const entityid_t entityId,
const componentid_t componentId,
vec3 dest
);
/**
* Sets the euler rotation (XYZ, radians) of the entity and rebuilds the
* transform matrix.
*
* @param entityId The entity ID.
* @param componentId The component ID.
* @param rotation The new euler rotation in radians.
*/
void entityPositionSetRotation(
const entityid_t entityId,
const componentid_t componentId,
vec3 rotation
);
/**
* Gets the cached scale of the entity.
*
* @param entityId The entity ID.
* @param componentId The component ID.
* @param dest The destination vec3 to write the scale to.
*/
void entityPositionGetScale(
const entityid_t entityId,
const componentid_t componentId,
vec3 dest
);
/**
* Sets the scale of the entity and rebuilds the transform matrix.
*
* @param entityId The entity ID.
* @param componentId The component ID.
* @param scale The new scale.
*/
void entityPositionSetScale(
const entityid_t entityId,
const componentid_t componentId,
vec3 scale
);
/**
* Internal function to rebuild the transform matrix of the entity position
* component based on the current position, rotation, and scale.
*/
void entityPositionRebuild(entityposition_t *pos);
/**
* Decomposes the transform matrix back into the position, rotation (XYZ euler,
* radians), and scale cache fields. Call after any direct matrix modification.
*
* @param pos Pointer to the entity position component data.
*/
void entityPositionDecompose(entityposition_t *pos);