You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Added GEO_BONE geolayout command
This commit is contained in:
@@ -429,4 +429,22 @@
|
||||
#define GEO_CULLING_RADIUS(cullingRadius) \
|
||||
CMD_BBH(0x20, 0x00, cullingRadius)
|
||||
|
||||
#define GEO_BONE_ID 0xFF
|
||||
|
||||
/**
|
||||
* 0x21: Create a scene graph node that is rotated by the object's animation + an initial rotation.
|
||||
* u8 drawingLayer
|
||||
* s16 xTranslation
|
||||
* s16 yTranslation
|
||||
* s16 zTranslation
|
||||
* s16 xRotation
|
||||
* s16 yRotation
|
||||
* s16 zRotation
|
||||
* u32 displayList: dislay list segmented address
|
||||
*/
|
||||
#define GEO_BONE(layer, tx, ty, tz, rx, ry, rz, displayList) \
|
||||
CMD_BBH(GEO_BONE_ID, layer, 0x0000), \
|
||||
CMD_HHHHHH(tx, ty, tz, rx, ry, rz), \
|
||||
CMD_PTR(displayList)
|
||||
|
||||
#endif // GEO_COMMANDS_H
|
||||
|
||||
@@ -767,6 +767,30 @@ void geo_layout_cmd_node_culling_radius(void) {
|
||||
gGeoLayoutCommand += 0x04 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
|
||||
/*
|
||||
Create a scene graph node that is rotated by the object's animation + an initial rotation.
|
||||
*/
|
||||
void geo_layout_cmd_bone(void) {
|
||||
struct GraphNodeBone *graphNode;
|
||||
Vec3s translation;
|
||||
Vec3s rotation;
|
||||
s32 drawingLayer = cur_geo_cmd_u8(0x01);
|
||||
void *displayList;
|
||||
s16 *cmdPos = (s16 *) gGeoLayoutCommand;
|
||||
|
||||
cmdPos = read_vec3s(translation, &cmdPos[2]);
|
||||
cmdPos = read_vec3s(rotation, &cmdPos[0]);
|
||||
displayList = *(void **) &cmdPos[0];
|
||||
cmdPos += 2 << CMD_SIZE_SHIFT;
|
||||
|
||||
graphNode =
|
||||
init_graph_node_bone(gGraphNodePool, NULL, drawingLayer, displayList, translation, rotation);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
gGeoLayoutCommand = (u8 *) cmdPos;
|
||||
}
|
||||
|
||||
struct GraphNode *process_geo_layout(struct AllocOnlyPool *pool, void *segptr) {
|
||||
// set by register_scene_graph_node when gCurGraphNodeIndex is 0
|
||||
// and gCurRootGraphNode is NULL
|
||||
@@ -788,7 +812,14 @@ struct GraphNode *process_geo_layout(struct AllocOnlyPool *pool, void *segptr) {
|
||||
gGeoLayoutStack[1] = 0;
|
||||
|
||||
while (gGeoLayoutCommand != NULL) {
|
||||
GeoLayoutJumpTable[gGeoLayoutCommand[0x00]]();
|
||||
// Custom geo commands can be a part of the switch-case, otherwise use GeoLayoutJumpTable
|
||||
switch (gGeoLayoutCommand[0x00]) {
|
||||
case GEO_BONE_ID:
|
||||
geo_layout_cmd_bone();
|
||||
break;
|
||||
default:
|
||||
GeoLayoutJumpTable[gGeoLayoutCommand[0x00]]();
|
||||
}
|
||||
}
|
||||
|
||||
return gCurRootGraphNode;
|
||||
|
||||
@@ -81,6 +81,7 @@ void geo_layout_cmd_nop(void);
|
||||
void geo_layout_cmd_copy_view(void);
|
||||
void geo_layout_cmd_node_held_obj(void);
|
||||
void geo_layout_cmd_node_culling_radius(void);
|
||||
void geo_layout_cmd_bone(void);
|
||||
|
||||
struct GraphNode *process_geo_layout(struct AllocOnlyPool *a0, void *segptr);
|
||||
|
||||
|
||||
@@ -365,6 +365,28 @@ struct GraphNodeAnimatedPart *init_graph_node_animated_part(struct AllocOnlyPool
|
||||
return graphNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates and returns a newly created bone node with initial rotation/translation
|
||||
*/
|
||||
struct GraphNodeBone *init_graph_node_bone(struct AllocOnlyPool *pool,
|
||||
struct GraphNodeBone *graphNode,
|
||||
s32 drawingLayer, void *displayList,
|
||||
Vec3s translation, Vec3s rotation) {
|
||||
if (pool != NULL) {
|
||||
graphNode = alloc_only_pool_alloc(pool, sizeof(struct GraphNodeBone));
|
||||
}
|
||||
|
||||
if (graphNode != NULL) {
|
||||
init_scene_graph_node_links(&graphNode->node, GRAPH_NODE_TYPE_BONE);
|
||||
vec3s_copy(graphNode->translation, translation);
|
||||
vec3s_copy(graphNode->rotation, rotation);
|
||||
graphNode->node.flags = (drawingLayer << 8) | (graphNode->node.flags & 0xFF);
|
||||
graphNode->displayList = displayList;
|
||||
}
|
||||
|
||||
return graphNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates and returns a newly created billboard node
|
||||
*/
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <PR/gbi.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "geo_commands.h"
|
||||
#include "game/memory.h"
|
||||
|
||||
#define GRAPH_RENDER_ACTIVE (1 << 0)
|
||||
@@ -34,6 +35,7 @@
|
||||
#define GRAPH_NODE_TYPE_ROTATION 0x017
|
||||
#define GRAPH_NODE_TYPE_OBJECT 0x018
|
||||
#define GRAPH_NODE_TYPE_ANIMATED_PART 0x019
|
||||
#define GRAPH_NODE_TYPE_BONE GEO_BONE_ID
|
||||
#define GRAPH_NODE_TYPE_BILLBOARD 0x01A
|
||||
#define GRAPH_NODE_TYPE_DISPLAY_LIST 0x01B
|
||||
#define GRAPH_NODE_TYPE_SCALE 0x01C
|
||||
@@ -242,6 +244,14 @@ struct GraphNodeAnimatedPart
|
||||
/*0x18*/ Vec3s translation;
|
||||
};
|
||||
|
||||
struct GraphNodeBone
|
||||
{
|
||||
struct GraphNode node;
|
||||
void *displayList;
|
||||
Vec3s translation;
|
||||
Vec3s rotation;
|
||||
};
|
||||
|
||||
/** A GraphNode that draws a display list rotated in a way to always face the
|
||||
* camera. Note that if the entire object is a billboard (like a coin or 1-up)
|
||||
* then it simply sets the billboard flag for the entire object, this node is
|
||||
@@ -390,6 +400,8 @@ struct GraphNodeObject *init_graph_node_object(struct AllocOnlyPool *pool, struc
|
||||
struct GraphNodeCullingRadius *init_graph_node_culling_radius(struct AllocOnlyPool *pool, struct GraphNodeCullingRadius *graphNode, s16 radius);
|
||||
struct GraphNodeAnimatedPart *init_graph_node_animated_part(struct AllocOnlyPool *pool, struct GraphNodeAnimatedPart *graphNode,
|
||||
s32 drawingLayer, void *displayList, Vec3s translation);
|
||||
struct GraphNodeBone *init_graph_node_bone(struct AllocOnlyPool *pool, struct GraphNodeBone *graphNode,
|
||||
s32 drawingLayer, void *displayList, Vec3s translation, Vec3s rotation);
|
||||
struct GraphNodeBillboard *init_graph_node_billboard(struct AllocOnlyPool *pool, struct GraphNodeBillboard *graphNode,
|
||||
s32 drawingLayer, void *displayList, Vec3s translation);
|
||||
struct GraphNodeDisplayList *init_graph_node_display_list(struct AllocOnlyPool *pool, struct GraphNodeDisplayList *graphNode,
|
||||
|
||||
@@ -598,6 +598,70 @@ static void geo_process_animated_part(struct GraphNodeAnimatedPart *node) {
|
||||
gMatStackIndex--;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
|
||||
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;
|
||||
gCurAnimType = ANIM_TYPE_ROTATION;
|
||||
} else {
|
||||
if (gCurAnimType == ANIM_TYPE_LATERAL_TRANSLATION) {
|
||||
translation[0] +=
|
||||
gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
gCurrAnimAttribute += 2;
|
||||
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;
|
||||
gCurrAnimAttribute += 2;
|
||||
gCurAnimType = ANIM_TYPE_ROTATION;
|
||||
} else if (gCurAnimType == ANIM_TYPE_NO_TRANSLATION) {
|
||||
gCurrAnimAttribute += 6;
|
||||
gCurAnimType = ANIM_TYPE_ROTATION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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, node->node.flags >> 8);
|
||||
}
|
||||
if (node->node.children != NULL) {
|
||||
geo_process_node_and_siblings(node->node.children);
|
||||
}
|
||||
gMatStackIndex--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the animation-related global variables for the currently drawn
|
||||
* object's animation.
|
||||
@@ -1021,6 +1085,9 @@ void geo_process_node_and_siblings(struct GraphNode *firstNode) {
|
||||
case GRAPH_NODE_TYPE_HELD_OBJ:
|
||||
geo_process_held_object((struct GraphNodeHeldObject *) curGraphNode);
|
||||
break;
|
||||
case GRAPH_NODE_TYPE_BONE:
|
||||
geo_process_bone((struct GraphNodeBone *) curGraphNode);
|
||||
break;
|
||||
default:
|
||||
geo_try_process_children((struct GraphNode *) curGraphNode);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user