From 39f92391f800190091d581ff8caac98760655758 Mon Sep 17 00:00:00 2001 From: Fazana <52551480+FazanaJ@users.noreply.github.com> Date: Mon, 27 Sep 2021 13:16:04 +0100 Subject: [PATCH] Matrix optimisation Courtesy of Kaze, creator of all existing romhacks --- src/engine/math_util.c | 46 +++++ src/engine/math_util.h | 1 + src/game/rendering_graph_node.c | 279 +++++++++------------------ textures/segment2/custom_text.i4.png | Bin 2646 -> 1870 bytes 4 files changed, 138 insertions(+), 188 deletions(-) diff --git a/src/engine/math_util.c b/src/engine/math_util.c index 9969bf33..0dc5d8f5 100644 --- a/src/engine/math_util.c +++ b/src/engine/math_util.c @@ -148,6 +148,52 @@ void mtxf_translate(Mat4 dest, Vec3f b) { vec3f_copy(dest[3], b); } +void mtxf_rot_trans_mul(Vec3s rot, Vec3f trans, Mat4 dest, Mat4 src) { + register f32 sx = sins(rot[0]); + register f32 cx = coss(rot[0]); + + register f32 sy = sins(rot[1]); + register f32 cy = coss(rot[1]); + + register f32 sz = sins(rot[2]); + register f32 cz = coss(rot[2]); + register f32 entry0; + register f32 entry1; + register f32 entry2; + + entry0 = cy * cz; + entry1 = cy * sz; + entry2 = -sy; + dest[0][0] = entry0 * src[0][0] + entry1 * src[1][0] + entry2 * src[2][0]; + dest[0][1] = entry0 * src[0][1] + entry1 * src[1][1] + entry2 * src[2][1]; + dest[0][2] = entry0 * src[0][2] + entry1 * src[1][2] + entry2 * src[2][2]; + + entry1 = sx * sy; + entry0 = entry1 * cz - cx * sz; + entry1 = entry1 * sz + cx * cz; + entry2 = sx * cy; + dest[1][0] = entry0 * src[0][0] + entry1 * src[1][0] + entry2 * src[2][0]; + dest[1][1] = entry0 * src[0][1] + entry1 * src[1][1] + entry2 * src[2][1]; + dest[1][2] = entry0 * src[0][2] + entry1 * src[1][2] + entry2 * src[2][2]; + + entry1 = cx * sy; + entry0 = entry1 * cz + sx * sz; + entry1 = entry1 * sz - sx * cz; + entry2 = cx * cy; + dest[2][0] = entry0 * src[0][0] + entry1 * src[1][0] + entry2 * src[2][0]; + dest[2][1] = entry0 * src[0][1] + entry1 * src[1][1] + entry2 * src[2][1]; + dest[2][2] = entry0 * src[0][2] + entry1 * src[1][2] + entry2 * src[2][2]; + + entry0 = trans[0]; + entry1 = trans[1]; + entry2 = trans[2]; + dest[3][0] = entry0 * src[0][0] + entry1 * src[1][0] + entry2 * src[2][0] + src[3][0]; + dest[3][1] = entry0 * src[0][1] + entry1 * src[1][1] + entry2 * src[2][1] + src[3][1]; + dest[3][2] = entry0 * src[0][2] + entry1 * src[1][2] + entry2 * src[2][2] + src[3][2]; + dest[0][3] = dest[1][3] = dest[2][3] = 0; + ((u32 *) dest)[15] = 0x3F800000; +} + /** * Set mtx to a look-at matrix for the camera. The resulting transformation * transforms the world as if there exists a camera at position 'from' pointed diff --git a/src/engine/math_util.h b/src/engine/math_util.h index bf572c98..17a605c6 100644 --- a/src/engine/math_util.h +++ b/src/engine/math_util.h @@ -417,5 +417,6 @@ f32 atan2f(f32 a, f32 b); void spline_get_weights(Vec4f result, f32 t, UNUSED s32 c); void anim_spline_init(Vec4s *keyFrames); s32 anim_spline_poll(Vec3f result); +void mtxf_rot_trans_mul(Vec3s rot, Vec3f trans, Mat4 dest, Mat4 src); #endif // MATH_UTIL_H diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 2ed12a49..e7660c44 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -202,7 +202,7 @@ void reset_clipping(void) 3. It does this, because layers 5-7 are non zbuffered, and just doing 0-7 of ZEX, then 0-7 of REJ would make the ZEX 0-4 render on top of Rej's 5-7. */ -static void geo_process_master_list_sub(struct GraphNodeMasterList *node) { +void geo_process_master_list_sub(struct GraphNodeMasterList *node) { struct DisplayListNode *currList; s32 startLayer, endLayer, currLayer = LAYER_FORCE; s32 headsIndex = LIST_HEADS_REJ; @@ -318,7 +318,7 @@ static void geo_process_master_list_sub(struct GraphNodeMasterList *node) { * parameter. Look at the RenderModeContainer struct to see the corresponding * render modes of layers. */ -static void geo_append_display_list(void *displayList, s32 layer) { +void geo_append_display_list(void *displayList, s32 layer) { s32 index = 0; #ifdef F3DEX_GBI_2 gSPLookAt(gDisplayListHead++, &lookAt); @@ -355,10 +355,26 @@ static void geo_append_display_list(void *displayList, s32 layer) { } } +void incrementMatStack() { + Mtx *mtx = alloc_display_list(sizeof(*mtx)); + gMatStackIndex++; + mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); + gMatStackFixed[gMatStackIndex] = mtx; +} +void appendDLandReturn(struct GraphNodeDisplayList *node) { + if (node->displayList != NULL) { + geo_append_display_list(node->displayList, node->node.flags >> 8); + } + if (node->node.children != NULL) { + geo_process_node_and_siblings(node->node.children); + } + gMatStackIndex--; +} + /** * Process the master list node. */ -static void geo_process_master_list(struct GraphNodeMasterList *node) { +void geo_process_master_list(struct GraphNodeMasterList *node) { s32 i; if (gCurGraphNodeMasterList == NULL && node->node.children != NULL) { @@ -376,7 +392,7 @@ static void geo_process_master_list(struct GraphNodeMasterList *node) { /** * Process an orthographic projection node. */ -static void geo_process_ortho_projection(struct GraphNodeOrthoProjection *node) { +void geo_process_ortho_projection(struct GraphNodeOrthoProjection *node) { if (node->node.children != NULL) { Mtx *mtx = alloc_display_list(sizeof(*mtx)); f32 left = (gCurGraphNodeRoot->x - gCurGraphNodeRoot->width ) / 2.0f * node->scale; @@ -395,7 +411,7 @@ static void geo_process_ortho_projection(struct GraphNodeOrthoProjection *node) /** * Process a perspective projection node. */ -static void geo_process_perspective(struct GraphNodePerspective *node) { +void geo_process_perspective(struct GraphNodePerspective *node) { if (node->fnNode.func != NULL) { node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, gMatStack[gMatStackIndex]); } @@ -433,7 +449,7 @@ static void geo_process_perspective(struct GraphNodePerspective *node) { * of this node are only processed if that distance is within the render * range of this node. */ -static void geo_process_level_of_detail(struct GraphNodeLevelOfDetail *node) { +void geo_process_level_of_detail(struct GraphNodeLevelOfDetail *node) { #ifdef AUTO_LOD f32 distanceFromCam = (gIsConsole ? -gMatStack[gMatStackIndex][3][2] : 50); #else @@ -452,7 +468,7 @@ static void geo_process_level_of_detail(struct GraphNodeLevelOfDetail *node) { * if it is 0, and among the node's children, only the selected child is * processed next. */ -static void geo_process_switch(struct GraphNodeSwitchCase *node) { +void geo_process_switch(struct GraphNodeSwitchCase *node) { struct GraphNode *selectedChild = node->fnNode.node.children; s32 i; @@ -467,7 +483,7 @@ static void geo_process_switch(struct GraphNodeSwitchCase *node) { } } -static void make_roll_matrix(Mtx *mtx, s32 angle) { +void make_roll_matrix(Mtx *mtx, s32 angle) { Mat4 temp; mtxf_identity(temp); temp[0][0] = coss(angle); @@ -480,7 +496,7 @@ static void make_roll_matrix(Mtx *mtx, s32 angle) { /** * Process a camera node. */ -static void geo_process_camera(struct GraphNodeCamera *node) { +void geo_process_camera(struct GraphNodeCamera *node) { Mat4 cameraTransform; Mtx *rollMtx = alloc_display_list(sizeof(*rollMtx)); Mtx *mtx = alloc_display_list(sizeof(*mtx)); @@ -494,9 +510,7 @@ static void geo_process_camera(struct GraphNodeCamera *node) { mtxf_lookat(cameraTransform, node->pos, node->focus, node->roll); mtxf_mul(gMatStack[gMatStackIndex + 1], cameraTransform, gMatStack[gMatStackIndex]); - gMatStackIndex++; - mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); - gMatStackFixed[gMatStackIndex] = mtx; + incrementMatStack(); if (node->fnNode.node.children != 0) { gCurGraphNodeCamera = node; node->matrixPtr = &gMatStack[gMatStackIndex]; @@ -512,24 +526,15 @@ static void geo_process_camera(struct GraphNodeCamera *node) { * the float and fixed point matrix stacks. * For the rest it acts as a normal display list node. */ -static void geo_process_translation_rotation(struct GraphNodeTranslationRotation *node) { +void geo_process_translation_rotation(struct GraphNodeTranslationRotation *node) { Mat4 mtxf; Vec3f translation; - Mtx *mtx = alloc_display_list(sizeof(*mtx)); vec3_copy(translation, node->translation); mtxf_rotate_zxy_and_translate(mtxf, translation, node->rotation); mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]); - gMatStackIndex++; - mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); - gMatStackFixed[gMatStackIndex] = mtx; - if (node->displayList != NULL) { - geo_append_display_list(node->displayList, GET_GRAPH_NODE_LAYER(node->node.flags)); - } - if (node->node.children != NULL) { - geo_process_node_and_siblings(node->node.children); - } - gMatStackIndex--; + incrementMatStack(); + appendDLandReturn(((struct GraphNodeDisplayList *)node)); } /** @@ -537,24 +542,15 @@ static void geo_process_translation_rotation(struct GraphNodeTranslationRotation * translation is created and pushed on both the float and fixed point matrix stacks. * For the rest it acts as a normal display list node. */ -static void geo_process_translation(struct GraphNodeTranslation *node) { +void geo_process_translation(struct GraphNodeTranslation *node) { Mat4 mtxf; Vec3f translation; - Mtx *mtx = alloc_display_list(sizeof(*mtx)); vec3_copy(translation, node->translation); mtxf_rotate_zxy_and_translate(mtxf, translation, gVec3sZero); mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]); - gMatStackIndex++; - mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); - gMatStackFixed[gMatStackIndex] = mtx; - if (node->displayList != NULL) { - geo_append_display_list(node->displayList, GET_GRAPH_NODE_LAYER(node->node.flags)); - } - if (node->node.children != NULL) { - geo_process_node_and_siblings(node->node.children); - } - gMatStackIndex--; + incrementMatStack(); + appendDLandReturn(((struct GraphNodeDisplayList *)node)); } /** @@ -562,22 +558,13 @@ static void geo_process_translation(struct GraphNodeTranslation *node) { * rotation is created and pushed on both the float and fixed point matrix stacks. * For the rest it acts as a normal display list node. */ -static void geo_process_rotation(struct GraphNodeRotation *node) { +void geo_process_rotation(struct GraphNodeRotation *node) { Mat4 mtxf; - Mtx *mtx = alloc_display_list(sizeof(*mtx)); mtxf_rotate_zxy_and_translate(mtxf, gVec3fZero, node->rotation); mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]); - gMatStackIndex++; - mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); - gMatStackFixed[gMatStackIndex] = mtx; - if (node->displayList != NULL) { - geo_append_display_list(node->displayList, GET_GRAPH_NODE_LAYER(node->node.flags)); - } - if (node->node.children != NULL) { - geo_process_node_and_siblings(node->node.children); - } - gMatStackIndex--; + incrementMatStack(); + appendDLandReturn(((struct GraphNodeDisplayList *)node)); } /** @@ -585,22 +572,13 @@ static void geo_process_rotation(struct GraphNodeRotation *node) { * scale is created and pushed on both the float and fixed point matrix stacks. * For the rest it acts as a normal display list node. */ -static void geo_process_scale(struct GraphNodeScale *node) { +void geo_process_scale(struct GraphNodeScale *node) { Vec3f scaleVec; - Mtx *mtx = alloc_display_list(sizeof(*mtx)); vec3f_set(scaleVec, node->scale, node->scale, node->scale); mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex], scaleVec); - gMatStackIndex++; - mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); - gMatStackFixed[gMatStackIndex] = mtx; - if (node->displayList != NULL) { - geo_append_display_list(node->displayList, GET_GRAPH_NODE_LAYER(node->node.flags)); - } - if (node->node.children != NULL) { - geo_process_node_and_siblings(node->node.children); - } - gMatStackIndex--; + incrementMatStack(); + appendDLandReturn(((struct GraphNodeDisplayList *)node)); } /** @@ -609,31 +587,20 @@ static void geo_process_scale(struct GraphNodeScale *node) { * point matrix stacks. * For the rest it acts as a normal display list node. */ -static void geo_process_billboard(struct GraphNodeBillboard *node) { +void geo_process_billboard(struct GraphNodeBillboard *node) { Vec3f translation; - Mtx *mtx = alloc_display_list(sizeof(*mtx)); - gMatStackIndex++; vec3_copy(translation, node->translation); - mtxf_billboard(gMatStack[gMatStackIndex], gMatStack[gMatStackIndex - 1], translation, - gCurGraphNodeCamera->roll); + mtxf_billboard(gMatStack[gMatStackIndex+1], gMatStack[gMatStackIndex], translation, gCurGraphNodeCamera->roll); + if (gCurGraphNodeHeldObject != NULL) { - mtxf_scale_vec3f(gMatStack[gMatStackIndex], gMatStack[gMatStackIndex], - gCurGraphNodeHeldObject->objNode->header.gfx.scale); + mtxf_scale_vec3f(gMatStack[gMatStackIndex+1], gMatStack[gMatStackIndex+1], gCurGraphNodeHeldObject->objNode->header.gfx.scale); } else if (gCurGraphNodeObject != NULL) { - mtxf_scale_vec3f(gMatStack[gMatStackIndex], gMatStack[gMatStackIndex], - gCurGraphNodeObject->scale); + mtxf_scale_vec3f(gMatStack[gMatStackIndex+1], gMatStack[gMatStackIndex+1], gCurGraphNodeObject->scale); } - mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); - gMatStackFixed[gMatStackIndex] = mtx; - if (node->displayList != NULL) { - geo_append_display_list(node->displayList, GET_GRAPH_NODE_LAYER(node->node.flags)); - } - if (node->node.children != NULL) { - geo_process_node_and_siblings(node->node.children); - } - gMatStackIndex--; + incrementMatStack(); + appendDLandReturn(((struct GraphNodeDisplayList *)node)); } /** @@ -641,20 +608,16 @@ static void geo_process_billboard(struct GraphNodeBillboard *node) { * a transformation on the stack, so all transformations are inherited from the * parent node. It processes its children if it has them. */ -static void geo_process_display_list(struct GraphNodeDisplayList *node) { - if (node->displayList != NULL) { - geo_append_display_list(node->displayList, GET_GRAPH_NODE_LAYER(node->node.flags)); - } - if (node->node.children != NULL) { - geo_process_node_and_siblings(node->node.children); - } +void geo_process_display_list(struct GraphNodeDisplayList *node) { + appendDLandReturn(((struct GraphNodeDisplayList *)node)); + gMatStackIndex++; } /** * Process a generated list. Instead of storing a pointer to a display list, * the list is generated on the fly by a function. */ -static void geo_process_generated_list(struct GraphNodeGenerated *node) { +void geo_process_generated_list(struct GraphNodeGenerated *node) { if (node->fnNode.func != NULL) { Gfx *list = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, (struct AllocOnlyPool *) gMatStack[gMatStackIndex]); @@ -673,7 +636,7 @@ static void geo_process_generated_list(struct GraphNodeGenerated *node) { * the function of the node. If that function is null or returns null, a black * rectangle is drawn instead. */ -static void geo_process_background(struct GraphNodeBackground *node) { +void geo_process_background(struct GraphNodeBackground *node) { Gfx *list = NULL; if (node->fnNode.func != NULL) { @@ -710,38 +673,26 @@ static void geo_process_background(struct GraphNodeBackground *node) { * Render an animated part. The current animation state is not part of the node * but set in global variables. If an animated part is skipped, everything afterwards desyncs. */ -static void geo_process_animated_part(struct GraphNodeAnimatedPart *node) { - Mat4 matrix; - Vec3s rotation; - Vec3f translation; - Mtx *matrixPtr = alloc_display_list(sizeof(*matrixPtr)); +void geo_process_animated_part(struct GraphNodeAnimatedPart *node) { + Vec3s rotation = {0, 0, 0}; + Vec3f translation = {node->translation[0], node->translation[1], node->translation[2]}; - vec3s_copy(rotation, gVec3sZero); vec3f_set(translation, node->translation[0], node->translation[1], node->translation[2]); if (gCurAnimType == ANIM_TYPE_TRANSLATION) { - translation[0] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] - * gCurAnimTranslationMultiplier; - translation[1] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] - * gCurAnimTranslationMultiplier; - translation[2] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] - * gCurAnimTranslationMultiplier; + translation[0] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier; + translation[1] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier; + translation[2] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier; gCurAnimType = ANIM_TYPE_ROTATION; } else { if (gCurAnimType == ANIM_TYPE_LATERAL_TRANSLATION) { - translation[0] += - gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] - * gCurAnimTranslationMultiplier; + translation[0] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier; gCurrAnimAttribute += 2; - translation[2] += - gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] - * gCurAnimTranslationMultiplier; + translation[2] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier; gCurAnimType = ANIM_TYPE_ROTATION; } else { if (gCurAnimType == ANIM_TYPE_VERTICAL_TRANSLATION) { gCurrAnimAttribute += 2; - translation[1] += - gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] - * gCurAnimTranslationMultiplier; + translation[1] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier; gCurrAnimAttribute += 2; gCurAnimType = ANIM_TYPE_ROTATION; } else if (gCurAnimType == ANIM_TYPE_NO_TRANSLATION) { @@ -750,61 +701,38 @@ static void geo_process_animated_part(struct GraphNodeAnimatedPart *node) { } } } - if (gCurAnimType == ANIM_TYPE_ROTATION) { rotation[0] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]; rotation[1] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]; rotation[2] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]; } - mtxf_rotate_xyz_and_translate(matrix, translation, rotation); - mtxf_mul(gMatStack[gMatStackIndex + 1], matrix, gMatStack[gMatStackIndex]); - gMatStackIndex++; - mtxf_to_mtx(matrixPtr, gMatStack[gMatStackIndex]); - gMatStackFixed[gMatStackIndex] = matrixPtr; - if (node->displayList != NULL) { - geo_append_display_list(node->displayList, GET_GRAPH_NODE_LAYER(node->node.flags)); - } - if (node->node.children != NULL) { - geo_process_node_and_siblings(node->node.children); - } - gMatStackIndex--; + mtxf_rot_trans_mul(rotation, translation, gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex]); + incrementMatStack(); + appendDLandReturn(((struct GraphNodeDisplayList *)node)); } /** * Render an animated part that has an initial rotation value */ -static void geo_process_bone(struct GraphNodeBone *node) { - Mat4 matrix; - Vec3s rotation; - Vec3f translation; - Mtx *matrixPtr = alloc_display_list(sizeof(*matrixPtr)); +void geo_process_bone(struct GraphNodeBone *node) { + Vec3s rotation = {0, 0, 0}; + Vec3f translation = {node->translation[0], node->translation[1], node->translation[2]}; - vec3s_copy(rotation, node->rotation); - vec3f_set(translation, node->translation[0], node->translation[1], node->translation[2]); if (gCurAnimType == ANIM_TYPE_TRANSLATION) { - translation[0] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] - * gCurAnimTranslationMultiplier; - translation[1] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] - * gCurAnimTranslationMultiplier; - translation[2] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] - * gCurAnimTranslationMultiplier; + translation[0] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier; + translation[1] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier; + translation[2] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier; gCurAnimType = ANIM_TYPE_ROTATION; } else { if (gCurAnimType == ANIM_TYPE_LATERAL_TRANSLATION) { - translation[0] += - gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] - * gCurAnimTranslationMultiplier; + translation[0] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier; gCurrAnimAttribute += 2; - translation[2] += - gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] - * gCurAnimTranslationMultiplier; + translation[2] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier; gCurAnimType = ANIM_TYPE_ROTATION; } else { if (gCurAnimType == ANIM_TYPE_VERTICAL_TRANSLATION) { gCurrAnimAttribute += 2; - translation[1] += - gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] - * gCurAnimTranslationMultiplier; + translation[1] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier; gCurrAnimAttribute += 2; gCurAnimType = ANIM_TYPE_ROTATION; } else if (gCurAnimType == ANIM_TYPE_NO_TRANSLATION) { @@ -813,25 +741,14 @@ static void geo_process_bone(struct GraphNodeBone *node) { } } } - if (gCurAnimType == ANIM_TYPE_ROTATION) { - rotation[0] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]; - rotation[1] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]; - rotation[2] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]; + rotation[0] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]; + rotation[1] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]; + rotation[2] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]; } - - mtxf_rotate_xyz_and_translate(matrix, translation, rotation); - mtxf_mul(gMatStack[gMatStackIndex + 1], matrix, gMatStack[gMatStackIndex]); - gMatStackIndex++; - mtxf_to_mtx(matrixPtr, gMatStack[gMatStackIndex]); - gMatStackFixed[gMatStackIndex] = matrixPtr; - if (node->displayList != NULL) { - geo_append_display_list(node->displayList, GET_GRAPH_NODE_LAYER(node->node.flags)); - } - if (node->node.children != NULL) { - geo_process_node_and_siblings(node->node.children); - } - gMatStackIndex--; + mtxf_rot_trans_mul(rotation, translation, gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex]); + incrementMatStack(); + appendDLandReturn(((struct GraphNodeDisplayList *)node)); } /** @@ -872,7 +789,7 @@ void geo_set_animation_globals(struct AnimInfo *node, s32 hasAnimation) { * translation of the first animated component and rotated according to * the floor below it. */ -static void geo_process_shadow(struct GraphNodeShadow *node) { +void geo_process_shadow(struct GraphNodeShadow *node) { Gfx *shadowList; Mat4 mtxf; Vec3f shadowPos; @@ -882,7 +799,6 @@ static void geo_process_shadow(struct GraphNodeShadow *node) { f32 sinAng; f32 cosAng; struct GraphNode *geo; - Mtx *mtx; if (gCurGraphNodeCamera != NULL && gCurGraphNodeObject != NULL) { if (gCurGraphNodeHeldObject != NULL) { @@ -924,12 +840,9 @@ static void geo_process_shadow(struct GraphNodeShadow *node) { shadowList = create_shadow_below_xyz(shadowPos[0], shadowPos[1], shadowPos[2], shadowScale, node->shadowSolidity, node->shadowType); if (shadowList != NULL) { - mtx = alloc_display_list(sizeof(*mtx)); - gMatStackIndex++; mtxf_translate(mtxf, shadowPos); - mtxf_mul(gMatStack[gMatStackIndex], mtxf, *gCurGraphNodeCamera->matrixPtr); - mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); - gMatStackFixed[gMatStackIndex] = mtx; + mtxf_mul(gMatStack[gMatStackIndex+1], mtxf, *gCurGraphNodeCamera->matrixPtr); + incrementMatStack(); geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), ((gShadowAboveWaterOrLava || gShadowAboveCustomWater || gMarioOnIceOrCarpet) ? LAYER_TRANSPARENT : LAYER_TRANSPARENT_DECAL)); gMatStackIndex--; } @@ -970,7 +883,7 @@ static void geo_process_shadow(struct GraphNodeShadow *node) { * * Since (0,0,0) is unaffected by rotation, columns 0, 1 and 2 are ignored. */ -static s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) { +s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) { s32 cullingRadius; s32 halfFov; // half of the fov in in-game angle units instead of degrees struct GraphNode *geo; @@ -1026,17 +939,15 @@ static s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) { /** * Process an object node. */ -static void geo_process_object(struct Object *node) { +void geo_process_object(struct Object *node) { Mat4 mtxf; s32 hasAnimation = (node->header.gfx.node.flags & GRAPH_RENDER_HAS_ANIMATION) != 0; if (node->header.gfx.areaIndex == gCurGraphNodeRoot->areaIndex) { if (node->header.gfx.throwMatrix != NULL) { - mtxf_mul(gMatStack[gMatStackIndex + 1], *node->header.gfx.throwMatrix, - gMatStack[gMatStackIndex]); + mtxf_mul(gMatStack[gMatStackIndex + 1], *node->header.gfx.throwMatrix, gMatStack[gMatStackIndex]); } else if (node->header.gfx.node.flags & GRAPH_RENDER_BILLBOARD) { - mtxf_billboard(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex], - node->header.gfx.pos, gCurGraphNodeCamera->roll); + mtxf_billboard(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex], node->header.gfx.pos, gCurGraphNodeCamera->roll); } else { mtxf_rotate_zxy_and_translate(mtxf, node->header.gfx.pos, node->header.gfx.angle); mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]); @@ -1044,19 +955,16 @@ static void geo_process_object(struct Object *node) { mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex + 1], node->header.gfx.scale); node->header.gfx.throwMatrix = &gMatStack[++gMatStackIndex]; - node->header.gfx.cameraToObject[0] = gMatStack[gMatStackIndex][3][0]; - node->header.gfx.cameraToObject[1] = gMatStack[gMatStackIndex][3][1]; - node->header.gfx.cameraToObject[2] = gMatStack[gMatStackIndex][3][2]; + vec3_copy(node->header.gfx.cameraToObject, gMatStack[gMatStackIndex][3]); // FIXME: correct types if (node->header.gfx.animInfo.curAnim != NULL) { geo_set_animation_globals(&node->header.gfx.animInfo, hasAnimation); } if (obj_is_in_view(&node->header.gfx, gMatStack[gMatStackIndex])) { - Mtx *mtx = alloc_display_list(sizeof(*mtx)); - mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); - gMatStackFixed[gMatStackIndex] = mtx; + gMatStackIndex--; + incrementMatStack(); if (node->header.gfx.sharedChild != NULL) { #ifdef VISUAL_DEBUG if (hitboxView) { @@ -1102,7 +1010,7 @@ static void geo_process_object(struct Object *node) { * the subtree rooted at 'sharedChild' and processes the subtree, after which the * actual children are be processed. (in practice they are null though) */ -static void geo_process_object_parent(struct GraphNodeObjectParent *node) { +void geo_process_object_parent(struct GraphNodeObjectParent *node) { if (node->sharedChild != NULL) { node->sharedChild->parent = (struct GraphNode *) node; geo_process_node_and_siblings(node->sharedChild); @@ -1119,7 +1027,6 @@ static void geo_process_object_parent(struct GraphNodeObjectParent *node) { void geo_process_held_object(struct GraphNodeHeldObject *node) { Mat4 mat; Vec3f translation; - Mtx *mtx = alloc_display_list(sizeof(*mtx)); #ifdef F3DEX_GBI_2 gSPLookAt(gDisplayListHead++, &lookAt); @@ -1141,15 +1048,11 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) { gMatStack[gMatStackIndex + 1][3][1] = gMatStack[gMatStackIndex][3][1]; gMatStack[gMatStackIndex + 1][3][2] = gMatStack[gMatStackIndex][3][2]; mtxf_mul(gMatStack[gMatStackIndex + 1], mat, gMatStack[gMatStackIndex + 1]); - mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex + 1], - node->objNode->header.gfx.scale); + mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex + 1], node->objNode->header.gfx.scale); if (node->fnNode.func != NULL) { - node->fnNode.func(GEO_CONTEXT_HELD_OBJ, &node->fnNode.node, - (struct AllocOnlyPool *) gMatStack[gMatStackIndex + 1]); + node->fnNode.func(GEO_CONTEXT_HELD_OBJ, &node->fnNode.node, (struct AllocOnlyPool *) gMatStack[gMatStackIndex + 1]); } - gMatStackIndex++; - mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); - gMatStackFixed[gMatStackIndex] = mtx; + incrementMatStack(); gGeoTempState.type = gCurAnimType; gGeoTempState.enabled = gCurAnimEnabled; gGeoTempState.frame = gCurrAnimFrame; diff --git a/textures/segment2/custom_text.i4.png b/textures/segment2/custom_text.i4.png index 02dd2d17c379a8fdf962e199cb20fe2e2fc1645a..0227ef1b415075ff334f6ca6624efde5b96313fa 100644 GIT binary patch delta 1856 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