Reformat to something more readable for me :3
This commit is contained in:
+165
-115
@@ -6,7 +6,7 @@
|
||||
#include "graph_node.h"
|
||||
#include "../shim.h"
|
||||
|
||||
static Vec3s gVec3sZero = { 0, 0, 0 };
|
||||
static Vec3s gVec3sZero = {0, 0, 0};
|
||||
|
||||
typedef void (*GeoLayoutCommandProc)(void);
|
||||
|
||||
@@ -102,53 +102,60 @@ UNUSED s16 D_8038BD7C;
|
||||
s16 gGeoLayoutReturnIndex; // similar to RA register in MIPS
|
||||
u8 *gGeoLayoutCommand;
|
||||
|
||||
u32 unused_8038B894[3] = { 0 };
|
||||
u32 unused_8038B894[3] = {0};
|
||||
|
||||
/*
|
||||
0x00: Branch and store return address
|
||||
cmd+0x04: void *branchTarget
|
||||
*/
|
||||
void geo_layout_cmd_branch_and_link(void) {
|
||||
gGeoLayoutStack[gGeoLayoutStackIndex++] = (uintptr_t) (gGeoLayoutCommand + CMD_PROCESS_OFFSET(8));
|
||||
void geo_layout_cmd_branch_and_link(void)
|
||||
{
|
||||
gGeoLayoutStack[gGeoLayoutStackIndex++] = (uintptr_t)(gGeoLayoutCommand + CMD_PROCESS_OFFSET(8));
|
||||
gGeoLayoutStack[gGeoLayoutStackIndex++] = (gCurGraphNodeIndex << 16) + gGeoLayoutReturnIndex;
|
||||
gGeoLayoutReturnIndex = gGeoLayoutStackIndex;
|
||||
gGeoLayoutCommand = segmented_to_virtual(cur_geo_cmd_ptr(0x04));
|
||||
}
|
||||
|
||||
// 0x01: Terminate geo layout
|
||||
void geo_layout_cmd_end(void) {
|
||||
void geo_layout_cmd_end(void)
|
||||
{
|
||||
gGeoLayoutStackIndex = gGeoLayoutReturnIndex;
|
||||
gGeoLayoutReturnIndex = gGeoLayoutStack[--gGeoLayoutStackIndex] & 0xFFFF;
|
||||
gCurGraphNodeIndex = gGeoLayoutStack[gGeoLayoutStackIndex] >> 16;
|
||||
gGeoLayoutCommand = (u8 *) gGeoLayoutStack[--gGeoLayoutStackIndex];
|
||||
gGeoLayoutCommand = (u8 *)gGeoLayoutStack[--gGeoLayoutStackIndex];
|
||||
}
|
||||
|
||||
/*
|
||||
0x02: Branch
|
||||
cmd+0x04: void *branchTarget
|
||||
*/
|
||||
void geo_layout_cmd_branch(void) {
|
||||
if (cur_geo_cmd_u8(0x01) == 1) {
|
||||
gGeoLayoutStack[gGeoLayoutStackIndex++] = (uintptr_t) (gGeoLayoutCommand + CMD_PROCESS_OFFSET(8));
|
||||
void geo_layout_cmd_branch(void)
|
||||
{
|
||||
if (cur_geo_cmd_u8(0x01) == 1)
|
||||
{
|
||||
gGeoLayoutStack[gGeoLayoutStackIndex++] = (uintptr_t)(gGeoLayoutCommand + CMD_PROCESS_OFFSET(8));
|
||||
}
|
||||
|
||||
gGeoLayoutCommand = segmented_to_virtual(cur_geo_cmd_ptr(0x04));
|
||||
}
|
||||
|
||||
// 0x03: Return from branch
|
||||
void geo_layout_cmd_return(void) {
|
||||
gGeoLayoutCommand = (u8 *) gGeoLayoutStack[--gGeoLayoutStackIndex];
|
||||
void geo_layout_cmd_return(void)
|
||||
{
|
||||
gGeoLayoutCommand = (u8 *)gGeoLayoutStack[--gGeoLayoutStackIndex];
|
||||
}
|
||||
|
||||
// 0x04: Open node
|
||||
void geo_layout_cmd_open_node(void) {
|
||||
void geo_layout_cmd_open_node(void)
|
||||
{
|
||||
gCurGraphNodeList[gCurGraphNodeIndex + 1] = gCurGraphNodeList[gCurGraphNodeIndex];
|
||||
gCurGraphNodeIndex++;
|
||||
gGeoLayoutCommand += 0x04 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
|
||||
// 0x05: Close node
|
||||
void geo_layout_cmd_close_node(void) {
|
||||
void geo_layout_cmd_close_node(void)
|
||||
{
|
||||
gCurGraphNodeIndex--;
|
||||
gGeoLayoutCommand += 0x04 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
@@ -159,10 +166,12 @@ void geo_layout_cmd_close_node(void) {
|
||||
|
||||
Register the current node in the gGeoViews array at the given index
|
||||
*/
|
||||
void geo_layout_cmd_assign_as_view(void) {
|
||||
void geo_layout_cmd_assign_as_view(void)
|
||||
{
|
||||
u16 index = cur_geo_cmd_s16(0x02);
|
||||
|
||||
if (index < gGeoNumViews) {
|
||||
if (index < gGeoNumViews)
|
||||
{
|
||||
gGeoViews[index] = gCurGraphNodeList[gCurGraphNodeIndex];
|
||||
}
|
||||
|
||||
@@ -174,11 +183,13 @@ void geo_layout_cmd_assign_as_view(void) {
|
||||
cmd+0x01: u8 operation (0 = reset, 1 = set, 2 = clear)
|
||||
cmd+0x02: s16 bits
|
||||
*/
|
||||
void geo_layout_cmd_update_node_flags(void) {
|
||||
void geo_layout_cmd_update_node_flags(void)
|
||||
{
|
||||
u16 operation = cur_geo_cmd_u8(0x01);
|
||||
u16 flagBits = cur_geo_cmd_s16(0x02);
|
||||
|
||||
switch (operation) {
|
||||
switch (operation)
|
||||
{
|
||||
case GEO_CMD_FLAGS_RESET:
|
||||
gCurGraphNodeList[gCurGraphNodeIndex]->flags = flagBits;
|
||||
break;
|
||||
@@ -201,7 +212,8 @@ void geo_layout_cmd_update_node_flags(void) {
|
||||
cmd+0x08: s16 width
|
||||
cmd+0x0A: s16 height
|
||||
*/
|
||||
void geo_layout_cmd_node_root(void) {
|
||||
void geo_layout_cmd_node_root(void)
|
||||
{
|
||||
s32 i;
|
||||
struct GraphNodeRoot *graphNode;
|
||||
|
||||
@@ -215,16 +227,17 @@ void geo_layout_cmd_node_root(void) {
|
||||
// cmd+0x02 = 0x00: Mario face, 0x0A: all other levels
|
||||
gGeoNumViews = cur_geo_cmd_s16(0x02) + 2;
|
||||
|
||||
graphNode = init_graph_node_root(gGraphNodePool, NULL, 0, x, y, width, height);
|
||||
graphNode = init_graph_node_root(gGraphNodePool, nullptr, 0, x, y, width, height);
|
||||
|
||||
// gGeoViews is unused in libsm64
|
||||
gGeoViews = NULL; // alloc_only_pool_alloc(gGraphNodePool, gGeoNumViews * sizeof(struct GraphNode *));
|
||||
gGeoViews = nullptr; // alloc_only_pool_alloc(gGraphNodePool, gGeoNumViews * sizeof(struct GraphNode *));
|
||||
|
||||
graphNode->views = gGeoViews;
|
||||
graphNode->numViews = gGeoNumViews;
|
||||
|
||||
for (i = 0; i < gGeoNumViews; i++) {
|
||||
gGeoViews[i] = NULL;
|
||||
for (i = 0; i < gGeoNumViews; i++)
|
||||
{
|
||||
gGeoViews[i] = nullptr;
|
||||
}
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
@@ -236,11 +249,12 @@ void geo_layout_cmd_node_root(void) {
|
||||
0x09: Create orthographic projection scene graph node
|
||||
cmd+0x02: s16 scale as a percentage (usually it's 100)
|
||||
*/
|
||||
void geo_layout_cmd_node_ortho_projection(void) {
|
||||
void geo_layout_cmd_node_ortho_projection(void)
|
||||
{
|
||||
struct GraphNodeOrthoProjection *graphNode;
|
||||
f32 scale = (f32) cur_geo_cmd_s16(0x02) / 100.0f;
|
||||
f32 scale = (f32)cur_geo_cmd_s16(0x02) / 100.0f;
|
||||
|
||||
graphNode = init_graph_node_ortho_projection(gGraphNodePool, NULL, scale);
|
||||
graphNode = init_graph_node_ortho_projection(gGraphNodePool, nullptr, scale);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
@@ -255,20 +269,22 @@ void geo_layout_cmd_node_ortho_projection(void) {
|
||||
cmd+0x06: s16 far
|
||||
[cmd+0x08: GraphNodeFunc frustumFunc]
|
||||
*/
|
||||
void geo_layout_cmd_node_perspective(void) {
|
||||
void geo_layout_cmd_node_perspective(void)
|
||||
{
|
||||
struct GraphNodePerspective *graphNode;
|
||||
GraphNodeFunc frustumFunc = NULL;
|
||||
GraphNodeFunc frustumFunc = nullptr;
|
||||
s16 fov = cur_geo_cmd_s16(0x02);
|
||||
s16 near = cur_geo_cmd_s16(0x04);
|
||||
s16 far = cur_geo_cmd_s16(0x06);
|
||||
|
||||
if (cur_geo_cmd_u8(0x01) != 0) {
|
||||
if (cur_geo_cmd_u8(0x01) != 0)
|
||||
{
|
||||
// optional asm function
|
||||
frustumFunc = (GraphNodeFunc) cur_geo_cmd_ptr(0x08);
|
||||
frustumFunc = (GraphNodeFunc)cur_geo_cmd_ptr(0x08);
|
||||
gGeoLayoutCommand += 4 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
|
||||
graphNode = init_graph_node_perspective(gGraphNodePool, NULL, (f32) fov, near, far, frustumFunc, 0);
|
||||
graphNode = init_graph_node_perspective(gGraphNodePool, nullptr, (f32)fov, near, far, frustumFunc, 0);
|
||||
|
||||
register_scene_graph_node(&graphNode->fnNode.node);
|
||||
|
||||
@@ -279,10 +295,11 @@ void geo_layout_cmd_node_perspective(void) {
|
||||
0x0B: Create a scene graph node that groups other nodes without any
|
||||
additional functionality
|
||||
*/
|
||||
void geo_layout_cmd_node_start(void) {
|
||||
void geo_layout_cmd_node_start(void)
|
||||
{
|
||||
struct GraphNodeStart *graphNode;
|
||||
|
||||
graphNode = init_graph_node_start(gGraphNodePool, NULL);
|
||||
graphNode = init_graph_node_start(gGraphNodePool, nullptr);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
@@ -290,7 +307,8 @@ void geo_layout_cmd_node_start(void) {
|
||||
}
|
||||
|
||||
// 0x1F: No operation
|
||||
void geo_layout_cmd_nop3(void) {
|
||||
void geo_layout_cmd_nop3(void)
|
||||
{
|
||||
gGeoLayoutCommand += 0x10 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
|
||||
@@ -298,10 +316,11 @@ void geo_layout_cmd_nop3(void) {
|
||||
0x0C: Create zbuffer-toggling scene graph node
|
||||
cmd+0x01: u8 enableZBuffer (1 = on, 0 = off)
|
||||
*/
|
||||
void geo_layout_cmd_node_master_list(void) {
|
||||
void geo_layout_cmd_node_master_list(void)
|
||||
{
|
||||
struct GraphNodeMasterList *graphNode;
|
||||
|
||||
graphNode = init_graph_node_master_list(gGraphNodePool, NULL, cur_geo_cmd_u8(0x01));
|
||||
graphNode = init_graph_node_master_list(gGraphNodePool, nullptr, cur_geo_cmd_u8(0x01));
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
@@ -314,12 +333,13 @@ void geo_layout_cmd_node_master_list(void) {
|
||||
cmd+0x04: s16 minDistance
|
||||
cmd+0x06: s16 maxDistance
|
||||
*/
|
||||
void geo_layout_cmd_node_level_of_detail(void) {
|
||||
void geo_layout_cmd_node_level_of_detail(void)
|
||||
{
|
||||
struct GraphNodeLevelOfDetail *graphNode;
|
||||
s16 minDistance = cur_geo_cmd_s16(0x04);
|
||||
s16 maxDistance = cur_geo_cmd_s16(0x06);
|
||||
|
||||
graphNode = init_graph_node_render_range(gGraphNodePool, NULL, minDistance, maxDistance);
|
||||
graphNode = init_graph_node_render_range(gGraphNodePool, nullptr, minDistance, maxDistance);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
@@ -334,15 +354,16 @@ void geo_layout_cmd_node_level_of_detail(void) {
|
||||
caseSelectorFunc returns an index which is used to select the child node to render.
|
||||
Used for animating coins, blinking, color selection, etc.
|
||||
*/
|
||||
void geo_layout_cmd_node_switch_case(void) {
|
||||
void geo_layout_cmd_node_switch_case(void)
|
||||
{
|
||||
struct GraphNodeSwitchCase *graphNode;
|
||||
|
||||
graphNode =
|
||||
init_graph_node_switch_case(gGraphNodePool, NULL,
|
||||
cur_geo_cmd_s16(0x02), // case which is initially selected
|
||||
0,
|
||||
(GraphNodeFunc) cur_geo_cmd_ptr(0x04), // case update function
|
||||
0);
|
||||
init_graph_node_switch_case(gGraphNodePool, nullptr,
|
||||
cur_geo_cmd_s16(0x02), // case which is initially selected
|
||||
0,
|
||||
(GraphNodeFunc)cur_geo_cmd_ptr(0x04), // case update function
|
||||
0);
|
||||
|
||||
register_scene_graph_node(&graphNode->fnNode.node);
|
||||
|
||||
@@ -360,17 +381,18 @@ void geo_layout_cmd_node_switch_case(void) {
|
||||
cmd+0x0E: s16 focusZ
|
||||
cmd+0x10: GraphNodeFunc func
|
||||
*/
|
||||
void geo_layout_cmd_node_camera(void) {
|
||||
void geo_layout_cmd_node_camera(void)
|
||||
{
|
||||
struct GraphNodeCamera *graphNode;
|
||||
s16 *cmdPos = (s16 *) &gGeoLayoutCommand[4];
|
||||
s16 *cmdPos = (s16 *)&gGeoLayoutCommand[4];
|
||||
|
||||
Vec3f pos, focus;
|
||||
|
||||
cmdPos = read_vec3s_to_vec3f(pos, cmdPos);
|
||||
cmdPos = read_vec3s_to_vec3f(focus, cmdPos);
|
||||
|
||||
graphNode = init_graph_node_camera(gGraphNodePool, NULL, pos, focus,
|
||||
(GraphNodeFunc) cur_geo_cmd_ptr(0x10), cur_geo_cmd_s16(0x02));
|
||||
graphNode = init_graph_node_camera(gGraphNodePool, nullptr, pos, focus,
|
||||
(GraphNodeFunc)cur_geo_cmd_ptr(0x10), cur_geo_cmd_s16(0x02));
|
||||
|
||||
register_scene_graph_node(&graphNode->fnNode.node);
|
||||
|
||||
@@ -413,18 +435,20 @@ void geo_layout_cmd_node_camera(void) {
|
||||
|
||||
[cmd+var: void *displayList]
|
||||
*/
|
||||
void geo_layout_cmd_node_translation_rotation(void) {
|
||||
void geo_layout_cmd_node_translation_rotation(void)
|
||||
{
|
||||
struct GraphNodeTranslationRotation *graphNode;
|
||||
|
||||
Vec3s translation, rotation;
|
||||
|
||||
void *displayList = NULL;
|
||||
void *displayList = nullptr;
|
||||
s16 drawingLayer = 0;
|
||||
|
||||
s16 params = cur_geo_cmd_u8(0x01);
|
||||
s16 *cmdPos = (s16 *) gGeoLayoutCommand;
|
||||
s16 *cmdPos = (s16 *)gGeoLayoutCommand;
|
||||
|
||||
switch ((params & 0x70) >> 4) {
|
||||
switch ((params & 0x70) >> 4)
|
||||
{
|
||||
case 0:
|
||||
cmdPos = read_vec3s(translation, &cmdPos[2]);
|
||||
cmdPos = read_vec3s_angle(rotation, cmdPos);
|
||||
@@ -444,17 +468,18 @@ void geo_layout_cmd_node_translation_rotation(void) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (params & 0x80) {
|
||||
displayList = *(void **) &cmdPos[0];
|
||||
if (params & 0x80)
|
||||
{
|
||||
displayList = *(void **)&cmdPos[0];
|
||||
drawingLayer = params & 0x0F;
|
||||
cmdPos += 2 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
|
||||
graphNode = init_graph_node_translation_rotation(gGraphNodePool, NULL, drawingLayer, displayList,
|
||||
graphNode = init_graph_node_translation_rotation(gGraphNodePool, nullptr, drawingLayer, displayList,
|
||||
translation, rotation);
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
gGeoLayoutCommand = (u8 *) cmdPos;
|
||||
gGeoLayoutCommand = (u8 *)cmdPos;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -467,30 +492,32 @@ void geo_layout_cmd_node_translation_rotation(void) {
|
||||
cmd+0x06: s16 zTranslation
|
||||
[cmd+0x08: void *displayList]
|
||||
*/
|
||||
void geo_layout_cmd_node_translation(void) {
|
||||
void geo_layout_cmd_node_translation(void)
|
||||
{
|
||||
struct GraphNodeTranslation *graphNode;
|
||||
|
||||
Vec3s translation;
|
||||
|
||||
s16 drawingLayer = 0;
|
||||
s16 params = cur_geo_cmd_u8(0x01);
|
||||
s16 *cmdPos = (s16 *) gGeoLayoutCommand;
|
||||
void *displayList = NULL;
|
||||
s16 *cmdPos = (s16 *)gGeoLayoutCommand;
|
||||
void *displayList = nullptr;
|
||||
|
||||
cmdPos = read_vec3s(translation, &cmdPos[1]);
|
||||
|
||||
if (params & 0x80) {
|
||||
displayList = *(void **) &cmdPos[0];
|
||||
if (params & 0x80)
|
||||
{
|
||||
displayList = *(void **)&cmdPos[0];
|
||||
drawingLayer = params & 0x0F;
|
||||
cmdPos += 2 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
|
||||
graphNode =
|
||||
init_graph_node_translation(gGraphNodePool, NULL, drawingLayer, displayList, translation);
|
||||
init_graph_node_translation(gGraphNodePool, nullptr, drawingLayer, displayList, translation);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
gGeoLayoutCommand = (u8 *) cmdPos;
|
||||
gGeoLayoutCommand = (u8 *)cmdPos;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -503,29 +530,31 @@ void geo_layout_cmd_node_translation(void) {
|
||||
cmd+0x06: s16 unkZ
|
||||
[cmd+0x08: void *displayList]
|
||||
*/
|
||||
void geo_layout_cmd_node_rotation(void) {
|
||||
void geo_layout_cmd_node_rotation(void)
|
||||
{
|
||||
struct GraphNodeRotation *graphNode;
|
||||
|
||||
Vec3s sp2c;
|
||||
|
||||
s16 drawingLayer = 0;
|
||||
s16 params = cur_geo_cmd_u8(0x01);
|
||||
s16 *cmdPos = (s16 *) gGeoLayoutCommand;
|
||||
void *displayList = NULL;
|
||||
s16 *cmdPos = (s16 *)gGeoLayoutCommand;
|
||||
void *displayList = nullptr;
|
||||
|
||||
cmdPos = read_vec3s_angle(sp2c, &cmdPos[1]);
|
||||
|
||||
if (params & 0x80) {
|
||||
displayList = *(void **) &cmdPos[0];
|
||||
if (params & 0x80)
|
||||
{
|
||||
displayList = *(void **)&cmdPos[0];
|
||||
drawingLayer = params & 0x0F;
|
||||
cmdPos += 2 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
|
||||
graphNode = init_graph_node_rotation(gGraphNodePool, NULL, drawingLayer, displayList, sp2c);
|
||||
graphNode = init_graph_node_rotation(gGraphNodePool, nullptr, drawingLayer, displayList, sp2c);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
gGeoLayoutCommand = (u8 *) cmdPos;
|
||||
gGeoLayoutCommand = (u8 *)cmdPos;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -536,21 +565,23 @@ void geo_layout_cmd_node_rotation(void) {
|
||||
cmd+0x04: u32 scale (0x10000 = 1.0)
|
||||
[cmd+0x08: void *displayList]
|
||||
*/
|
||||
void geo_layout_cmd_node_scale(void) {
|
||||
void geo_layout_cmd_node_scale(void)
|
||||
{
|
||||
struct GraphNodeScale *graphNode;
|
||||
|
||||
s16 drawingLayer = 0;
|
||||
s16 params = cur_geo_cmd_u8(0x01);
|
||||
f32 scale = cur_geo_cmd_u32(0x04) / 65536.0f;
|
||||
void *displayList = NULL;
|
||||
void *displayList = nullptr;
|
||||
|
||||
if (params & 0x80) {
|
||||
if (params & 0x80)
|
||||
{
|
||||
displayList = cur_geo_cmd_ptr(0x08);
|
||||
drawingLayer = params & 0x0F;
|
||||
gGeoLayoutCommand += 4 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
|
||||
graphNode = init_graph_node_scale(gGraphNodePool, NULL, drawingLayer, displayList, scale);
|
||||
graphNode = init_graph_node_scale(gGraphNodePool, nullptr, drawingLayer, displayList, scale);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
@@ -558,7 +589,8 @@ void geo_layout_cmd_node_scale(void) {
|
||||
}
|
||||
|
||||
// 0x1E: No operation
|
||||
void geo_layout_cmd_nop2(void) {
|
||||
void geo_layout_cmd_nop2(void)
|
||||
{
|
||||
gGeoLayoutCommand += 0x08 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
|
||||
@@ -570,17 +602,18 @@ void geo_layout_cmd_nop2(void) {
|
||||
cmd+0x06: s16 zTranslation
|
||||
cmd+0x08: void *displayList
|
||||
*/
|
||||
void geo_layout_cmd_node_animated_part(void) {
|
||||
void geo_layout_cmd_node_animated_part(void)
|
||||
{
|
||||
struct GraphNodeAnimatedPart *graphNode;
|
||||
Vec3s translation;
|
||||
s32 drawingLayer = cur_geo_cmd_u8(0x01);
|
||||
void *displayList = cur_geo_cmd_ptr(0x08);
|
||||
s16 *cmdPos = (s16 *) gGeoLayoutCommand;
|
||||
s16 *cmdPos = (s16 *)gGeoLayoutCommand;
|
||||
|
||||
read_vec3s(translation, &cmdPos[1]);
|
||||
|
||||
graphNode =
|
||||
init_graph_node_animated_part(gGraphNodePool, NULL, drawingLayer, displayList, translation);
|
||||
init_graph_node_animated_part(gGraphNodePool, nullptr, drawingLayer, displayList, translation);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
@@ -597,27 +630,29 @@ void geo_layout_cmd_node_animated_part(void) {
|
||||
cmd+0x06: s16 zTranslation
|
||||
[cmd+0x08: void *displayList]
|
||||
*/
|
||||
void geo_layout_cmd_node_billboard(void) {
|
||||
void geo_layout_cmd_node_billboard(void)
|
||||
{
|
||||
struct GraphNodeBillboard *graphNode;
|
||||
Vec3s translation;
|
||||
s16 drawingLayer = 0;
|
||||
s16 params = cur_geo_cmd_u8(0x01);
|
||||
s16 *cmdPos = (s16 *) gGeoLayoutCommand;
|
||||
void *displayList = NULL;
|
||||
s16 *cmdPos = (s16 *)gGeoLayoutCommand;
|
||||
void *displayList = nullptr;
|
||||
|
||||
cmdPos = read_vec3s(translation, &cmdPos[1]);
|
||||
|
||||
if (params & 0x80) {
|
||||
displayList = *(void **) &cmdPos[0];
|
||||
if (params & 0x80)
|
||||
{
|
||||
displayList = *(void **)&cmdPos[0];
|
||||
drawingLayer = params & 0x0F;
|
||||
cmdPos += 2 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
|
||||
graphNode = init_graph_node_billboard(gGraphNodePool, NULL, drawingLayer, displayList, translation);
|
||||
graphNode = init_graph_node_billboard(gGraphNodePool, nullptr, drawingLayer, displayList, translation);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
gGeoLayoutCommand = (u8 *) cmdPos;
|
||||
gGeoLayoutCommand = (u8 *)cmdPos;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -625,12 +660,13 @@ void geo_layout_cmd_node_billboard(void) {
|
||||
cmd+0x01: u8 drawingLayer
|
||||
cmd+0x04: void *displayList
|
||||
*/
|
||||
void geo_layout_cmd_node_display_list(void) {
|
||||
void geo_layout_cmd_node_display_list(void)
|
||||
{
|
||||
struct GraphNodeDisplayList *graphNode;
|
||||
s32 drawingLayer = cur_geo_cmd_u8(0x01);
|
||||
void *displayList = cur_geo_cmd_ptr(0x04);
|
||||
|
||||
graphNode = init_graph_node_display_list(gGraphNodePool, NULL, drawingLayer, displayList);
|
||||
graphNode = init_graph_node_display_list(gGraphNodePool, nullptr, drawingLayer, displayList);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
@@ -643,13 +679,14 @@ void geo_layout_cmd_node_display_list(void) {
|
||||
cmd+0x04: s16 shadowSolidity
|
||||
cmd+0x06: s16 shadowScale
|
||||
*/
|
||||
void geo_layout_cmd_node_shadow(void) {
|
||||
void geo_layout_cmd_node_shadow(void)
|
||||
{
|
||||
struct GraphNodeShadow *graphNode;
|
||||
u8 shadowType = cur_geo_cmd_s16(0x02);
|
||||
u8 shadowSolidity = cur_geo_cmd_s16(0x04);
|
||||
s16 shadowScale = cur_geo_cmd_s16(0x06);
|
||||
|
||||
graphNode = init_graph_node_shadow(gGraphNodePool, NULL, shadowScale, shadowSolidity, shadowType);
|
||||
graphNode = init_graph_node_shadow(gGraphNodePool, nullptr, shadowScale, shadowSolidity, shadowType);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
@@ -657,10 +694,11 @@ void geo_layout_cmd_node_shadow(void) {
|
||||
}
|
||||
|
||||
// 0x17: Create scene graph node that manages the group of all object nodes
|
||||
void geo_layout_cmd_node_object_parent(void) {
|
||||
void geo_layout_cmd_node_object_parent(void)
|
||||
{
|
||||
struct GraphNodeObjectParent *graphNode;
|
||||
|
||||
graphNode = init_graph_node_object_parent(gGraphNodePool, NULL, &gObjParentGraphNode);
|
||||
graphNode = init_graph_node_object_parent(gGraphNodePool, nullptr, &gObjParentGraphNode);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
@@ -672,12 +710,13 @@ void geo_layout_cmd_node_object_parent(void) {
|
||||
cmd+0x02: s16 parameter
|
||||
cmd+0x04: GraphNodeFunc func
|
||||
*/
|
||||
void geo_layout_cmd_node_generated(void) {
|
||||
void geo_layout_cmd_node_generated(void)
|
||||
{
|
||||
struct GraphNodeGenerated *graphNode;
|
||||
|
||||
graphNode = init_graph_node_generated(gGraphNodePool, NULL,
|
||||
(GraphNodeFunc) cur_geo_cmd_ptr(0x04), // asm function
|
||||
cur_geo_cmd_s16(0x02)); // parameter
|
||||
graphNode = init_graph_node_generated(gGraphNodePool, nullptr,
|
||||
(GraphNodeFunc)cur_geo_cmd_ptr(0x04), // asm function
|
||||
cur_geo_cmd_s16(0x02)); // parameter
|
||||
|
||||
register_scene_graph_node(&graphNode->fnNode.node);
|
||||
|
||||
@@ -689,13 +728,14 @@ void geo_layout_cmd_node_generated(void) {
|
||||
cmd+0x02: s16 background // background ID, or RGBA5551 color if backgroundFunc is null
|
||||
cmd+0x04: GraphNodeFunc backgroundFunc
|
||||
*/
|
||||
void geo_layout_cmd_node_background(void) {
|
||||
void geo_layout_cmd_node_background(void)
|
||||
{
|
||||
struct GraphNodeBackground *graphNode;
|
||||
|
||||
graphNode = init_graph_node_background(
|
||||
gGraphNodePool, NULL,
|
||||
gGraphNodePool, nullptr,
|
||||
cur_geo_cmd_s16(0x02), // background ID, or RGBA5551 color if asm function is null
|
||||
(GraphNodeFunc) cur_geo_cmd_ptr(0x04), // asm function
|
||||
(GraphNodeFunc)cur_geo_cmd_ptr(0x04), // asm function
|
||||
0);
|
||||
|
||||
register_scene_graph_node(&graphNode->fnNode.node);
|
||||
@@ -704,7 +744,8 @@ void geo_layout_cmd_node_background(void) {
|
||||
}
|
||||
|
||||
// 0x1A: No operation
|
||||
void geo_layout_cmd_nop(void) {
|
||||
void geo_layout_cmd_nop(void)
|
||||
{
|
||||
gGeoLayoutCommand += 0x08 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
|
||||
@@ -713,22 +754,27 @@ void geo_layout_cmd_nop(void) {
|
||||
to a newly created object parent node.
|
||||
cmd+0x02: s16 index (of gGeoViews)
|
||||
*/
|
||||
void geo_layout_cmd_copy_view(void) {
|
||||
void geo_layout_cmd_copy_view(void)
|
||||
{
|
||||
struct GraphNodeObjectParent *graphNode;
|
||||
struct GraphNode *node = NULL;
|
||||
struct GraphNode *node = nullptr;
|
||||
s16 index = cur_geo_cmd_s16(0x02);
|
||||
|
||||
if (index >= 0) {
|
||||
if (index >= 0)
|
||||
{
|
||||
node = gGeoViews[index];
|
||||
|
||||
if (node->type == GRAPH_NODE_TYPE_OBJECT_PARENT) {
|
||||
node = ((struct GraphNodeObjectParent *) node)->sharedChild;
|
||||
} else {
|
||||
node = NULL;
|
||||
if (node->type == GRAPH_NODE_TYPE_OBJECT_PARENT)
|
||||
{
|
||||
node = ((struct GraphNodeObjectParent *)node)->sharedChild;
|
||||
}
|
||||
else
|
||||
{
|
||||
node = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
graphNode = init_graph_node_object_parent(gGraphNodePool, NULL, node);
|
||||
graphNode = init_graph_node_object_parent(gGraphNodePool, nullptr, node);
|
||||
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
|
||||
@@ -743,14 +789,15 @@ void geo_layout_cmd_copy_view(void) {
|
||||
cmd+0x06: s16 offsetZ
|
||||
cmd+0x08: GraphNodeFunc nodeFunc
|
||||
*/
|
||||
void geo_layout_cmd_node_held_obj(void) {
|
||||
void geo_layout_cmd_node_held_obj(void)
|
||||
{
|
||||
struct GraphNodeHeldObject *graphNode;
|
||||
Vec3s offset;
|
||||
|
||||
read_vec3s(offset, (s16 *) &gGeoLayoutCommand[0x02]);
|
||||
read_vec3s(offset, (s16 *)&gGeoLayoutCommand[0x02]);
|
||||
|
||||
graphNode = init_graph_node_held_object(
|
||||
gGraphNodePool, NULL, NULL, offset, (GraphNodeFunc) cur_geo_cmd_ptr(0x08), cur_geo_cmd_u8(0x01));
|
||||
gGraphNodePool, nullptr, nullptr, offset, (GraphNodeFunc)cur_geo_cmd_ptr(0x08), cur_geo_cmd_u8(0x01));
|
||||
|
||||
register_scene_graph_node(&graphNode->fnNode.node);
|
||||
|
||||
@@ -762,17 +809,19 @@ void geo_layout_cmd_node_held_obj(void) {
|
||||
is used for frustum culling.
|
||||
cmd+0x02: s16 cullingRadius
|
||||
*/
|
||||
void geo_layout_cmd_node_culling_radius(void) {
|
||||
void geo_layout_cmd_node_culling_radius(void)
|
||||
{
|
||||
struct GraphNodeCullingRadius *graphNode;
|
||||
graphNode = init_graph_node_culling_radius(gGraphNodePool, NULL, cur_geo_cmd_s16(0x02));
|
||||
graphNode = init_graph_node_culling_radius(gGraphNodePool, nullptr, cur_geo_cmd_s16(0x02));
|
||||
register_scene_graph_node(&graphNode->node);
|
||||
gGeoLayoutCommand += 0x04 << CMD_SIZE_SHIFT;
|
||||
}
|
||||
|
||||
struct GraphNode *process_geo_layout(struct AllocOnlyPool *pool, void *segptr) {
|
||||
struct GraphNode *process_geo_layout(struct AllocOnlyPool *pool, void *segptr)
|
||||
{
|
||||
// set by register_scene_graph_node when gCurGraphNodeIndex is 0
|
||||
// and gCurRootGraphNode is NULL
|
||||
gCurRootGraphNode = NULL;
|
||||
// and gCurRootGraphNode is nullptr
|
||||
gCurRootGraphNode = nullptr;
|
||||
|
||||
gGeoNumViews = 0; // number of entries in gGeoViews
|
||||
|
||||
@@ -789,7 +838,8 @@ struct GraphNode *process_geo_layout(struct AllocOnlyPool *pool, void *segptr) {
|
||||
gGeoLayoutStack[0] = 0;
|
||||
gGeoLayoutStack[1] = 0;
|
||||
|
||||
while (gGeoLayoutCommand != NULL) {
|
||||
while (gGeoLayoutCommand != nullptr)
|
||||
{
|
||||
GeoLayoutJumpTable[gGeoLayoutCommand[0x00]]();
|
||||
}
|
||||
|
||||
|
||||
@@ -49,37 +49,69 @@ extern s16 D_8038BD78;
|
||||
extern struct GraphNode *D_8038BCF8[];
|
||||
|
||||
void geo_layout_cmd_branch_and_link(void);
|
||||
|
||||
void geo_layout_cmd_end(void);
|
||||
|
||||
void geo_layout_cmd_branch(void);
|
||||
|
||||
void geo_layout_cmd_return(void);
|
||||
|
||||
void geo_layout_cmd_open_node(void);
|
||||
|
||||
void geo_layout_cmd_close_node(void);
|
||||
|
||||
void geo_layout_cmd_assign_as_view(void);
|
||||
|
||||
void geo_layout_cmd_update_node_flags(void);
|
||||
|
||||
void geo_layout_cmd_node_root(void);
|
||||
|
||||
void geo_layout_cmd_node_ortho_projection(void);
|
||||
|
||||
void geo_layout_cmd_node_perspective(void);
|
||||
|
||||
void geo_layout_cmd_node_start(void);
|
||||
|
||||
void geo_layout_cmd_nop3(void);
|
||||
|
||||
void geo_layout_cmd_node_master_list(void);
|
||||
|
||||
void geo_layout_cmd_node_level_of_detail(void);
|
||||
|
||||
void geo_layout_cmd_node_switch_case(void);
|
||||
|
||||
void geo_layout_cmd_node_camera(void);
|
||||
|
||||
void geo_layout_cmd_node_translation_rotation(void);
|
||||
|
||||
void geo_layout_cmd_node_translation(void);
|
||||
|
||||
void geo_layout_cmd_node_rotation(void);
|
||||
|
||||
void geo_layout_cmd_node_scale(void);
|
||||
|
||||
void geo_layout_cmd_nop2(void);
|
||||
|
||||
void geo_layout_cmd_node_animated_part(void);
|
||||
|
||||
void geo_layout_cmd_node_billboard(void);
|
||||
|
||||
void geo_layout_cmd_node_display_list(void);
|
||||
|
||||
void geo_layout_cmd_node_shadow(void);
|
||||
|
||||
void geo_layout_cmd_node_object_parent(void);
|
||||
|
||||
void geo_layout_cmd_node_generated(void);
|
||||
|
||||
void geo_layout_cmd_node_background(void);
|
||||
|
||||
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);
|
||||
|
||||
struct GraphNode *process_geo_layout(struct AllocOnlyPool *a0, void *segptr);
|
||||
|
||||
+376
-217
File diff suppressed because it is too large
Load Diff
+241
-113
@@ -18,7 +18,7 @@
|
||||
#define GRAPH_NODE_TYPE_FUNCTIONAL 0x100
|
||||
|
||||
// Type used for Bowser and an unused geo function in obj_behaviors.c
|
||||
#define GRAPH_NODE_TYPE_400 0x400
|
||||
#define GRAPH_NODE_TYPE_400 0x400
|
||||
|
||||
// The discriminant for different types of geo nodes
|
||||
#define GRAPH_NODE_TYPE_ROOT 0x001
|
||||
@@ -70,23 +70,34 @@ typedef Gfx *(*GraphNodeFunc)(s32 callContext, struct GraphNode *node, void *con
|
||||
*/
|
||||
struct FnGraphNode
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ GraphNodeFunc func;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
GraphNodeFunc func;
|
||||
};
|
||||
|
||||
/** The very root of the geo tree. Specifies the viewport.
|
||||
*/
|
||||
struct GraphNodeRoot
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ u8 areaIndex;
|
||||
/*0x15*/ s8 unk15; // ?
|
||||
/*0x16*/ s16 x;
|
||||
/*0x18*/ s16 y;
|
||||
/*0x1A*/ s16 width; // half width, 160
|
||||
/*0x1C*/ s16 height; // half height
|
||||
/*0x1E*/ s16 numViews; // number of entries in mystery array
|
||||
/*0x20*/ struct GraphNode **views;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
u8 areaIndex;
|
||||
/*0x15*/
|
||||
s8 unk15; // ?
|
||||
/*0x16*/
|
||||
s16 x;
|
||||
/*0x18*/
|
||||
s16 y;
|
||||
/*0x1A*/
|
||||
s16 width; // half width, 160
|
||||
/*0x1C*/
|
||||
s16 height; // half height
|
||||
/*0x1E*/
|
||||
s16 numViews; // number of entries in mystery array
|
||||
/*0x20*/
|
||||
struct GraphNode **views;
|
||||
};
|
||||
|
||||
/** A node that sets up an orthographic projection based on the global
|
||||
@@ -94,8 +105,10 @@ struct GraphNodeRoot
|
||||
*/
|
||||
struct GraphNodeOrthoProjection
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ f32 scale;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
f32 scale;
|
||||
};
|
||||
|
||||
/** A node that sets up a perspective projection. Used for drawing the
|
||||
@@ -104,11 +117,16 @@ struct GraphNodeOrthoProjection
|
||||
*/
|
||||
struct GraphNodePerspective
|
||||
{
|
||||
/*0x00*/ struct FnGraphNode fnNode;
|
||||
/*0x18*/ s32 unused;
|
||||
/*0x1C*/ f32 fov; // horizontal field of view in degrees
|
||||
/*0x20*/ s16 near; // near clipping plane
|
||||
/*0x22*/ s16 far; // far clipping plane
|
||||
/*0x00*/
|
||||
struct FnGraphNode fnNode;
|
||||
/*0x18*/
|
||||
s32 unused;
|
||||
/*0x1C*/
|
||||
f32 fov; // horizontal field of view in degrees
|
||||
/*0x20*/
|
||||
s16 near; // near clipping plane
|
||||
/*0x22*/
|
||||
s16 far; // far clipping plane
|
||||
};
|
||||
|
||||
/** An entry in the master list. It is a linked list of display lists
|
||||
@@ -128,9 +146,12 @@ struct DisplayListNode
|
||||
*/
|
||||
struct GraphNodeMasterList
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ struct DisplayListNode *listHeads[GFX_NUM_MASTER_LISTS];
|
||||
/*0x34*/ struct DisplayListNode *listTails[GFX_NUM_MASTER_LISTS];
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
struct DisplayListNode *listHeads[GFX_NUM_MASTER_LISTS];
|
||||
/*0x34*/
|
||||
struct DisplayListNode *listTails[GFX_NUM_MASTER_LISTS];
|
||||
};
|
||||
|
||||
/** Simply used as a parent to group multiple children.
|
||||
@@ -138,7 +159,8 @@ struct GraphNodeMasterList
|
||||
*/
|
||||
struct GraphNodeStart
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
};
|
||||
|
||||
/** GraphNode that only renders its children if the current transformation matrix
|
||||
@@ -149,9 +171,12 @@ struct GraphNodeStart
|
||||
*/
|
||||
struct GraphNodeLevelOfDetail
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ s16 minDistance;
|
||||
/*0x16*/ s16 maxDistance;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
s16 minDistance;
|
||||
/*0x16*/
|
||||
s16 maxDistance;
|
||||
};
|
||||
|
||||
/** GraphNode that renders exactly one of its children.
|
||||
@@ -161,10 +186,14 @@ struct GraphNodeLevelOfDetail
|
||||
*/
|
||||
struct GraphNodeSwitchCase
|
||||
{
|
||||
/*0x00*/ struct FnGraphNode fnNode;
|
||||
/*0x18*/ s32 unused;
|
||||
/*0x1C*/ s16 numCases;
|
||||
/*0x1E*/ s16 selectedCase;
|
||||
/*0x00*/
|
||||
struct FnGraphNode fnNode;
|
||||
/*0x18*/
|
||||
s32 unused;
|
||||
/*0x1C*/
|
||||
s16 numCases;
|
||||
/*0x1E*/
|
||||
s16 selectedCase;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -173,8 +202,12 @@ struct GraphNodeSwitchCase
|
||||
*/
|
||||
struct GraphNodeCamera
|
||||
{
|
||||
/*0x00*/ struct FnGraphNode fnNode;
|
||||
/*0x18*/ union {
|
||||
/*0x00*/
|
||||
struct FnGraphNode fnNode;
|
||||
|
||||
/*0x18*/
|
||||
union
|
||||
{
|
||||
// When the node is created, a mode is assigned to the node.
|
||||
// Later in geo_camera_main a Camera is allocated,
|
||||
// the mode is passed to the struct, and the field is overridden
|
||||
@@ -182,11 +215,17 @@ struct GraphNodeCamera
|
||||
s32 mode;
|
||||
struct Camera *camera;
|
||||
} config;
|
||||
/*0x1C*/ Vec3f pos;
|
||||
/*0x28*/ Vec3f focus;
|
||||
/*0x34*/ Mat4 *matrixPtr; // pointer to look-at matrix of this camera as a Mat4
|
||||
/*0x38*/ s16 roll; // roll in look at matrix. Doesn't account for light direction unlike rollScreen.
|
||||
/*0x3A*/ s16 rollScreen; // rolls screen while keeping the light direction consistent
|
||||
|
||||
/*0x1C*/
|
||||
Vec3f pos;
|
||||
/*0x28*/
|
||||
Vec3f focus;
|
||||
/*0x34*/
|
||||
Mat4 *matrixPtr; // pointer to look-at matrix of this camera as a Mat4
|
||||
/*0x38*/
|
||||
s16 roll; // roll in look at matrix. Doesn't account for light direction unlike rollScreen.
|
||||
/*0x3A*/
|
||||
s16 rollScreen; // rolls screen while keeping the light direction consistent
|
||||
};
|
||||
|
||||
/** GraphNode that translates and rotates its children.
|
||||
@@ -197,10 +236,14 @@ struct GraphNodeCamera
|
||||
*/
|
||||
struct GraphNodeTranslationRotation
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ void *displayList;
|
||||
/*0x18*/ Vec3s translation;
|
||||
/*0x1E*/ Vec3s rotation;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
void *displayList;
|
||||
/*0x18*/
|
||||
Vec3s translation;
|
||||
/*0x1E*/
|
||||
Vec3s rotation;
|
||||
};
|
||||
|
||||
/** GraphNode that translates itself and its children.
|
||||
@@ -209,9 +252,12 @@ struct GraphNodeTranslationRotation
|
||||
*/
|
||||
struct GraphNodeTranslation
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ void *displayList;
|
||||
/*0x18*/ Vec3s translation;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
void *displayList;
|
||||
/*0x18*/
|
||||
Vec3s translation;
|
||||
u8 pad1E[2];
|
||||
};
|
||||
|
||||
@@ -222,9 +268,12 @@ struct GraphNodeTranslation
|
||||
*/
|
||||
struct GraphNodeRotation
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ void *displayList;
|
||||
/*0x18*/ Vec3s rotation;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
void *displayList;
|
||||
/*0x18*/
|
||||
Vec3s rotation;
|
||||
u8 pad1E[2];
|
||||
};
|
||||
|
||||
@@ -237,9 +286,12 @@ struct GraphNodeRotation
|
||||
*/
|
||||
struct GraphNodeAnimatedPart
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ void *displayList;
|
||||
/*0x18*/ Vec3s translation;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
void *displayList;
|
||||
/*0x18*/
|
||||
Vec3s translation;
|
||||
};
|
||||
|
||||
/** A GraphNode that draws a display list rotated in a way to always face the
|
||||
@@ -249,9 +301,12 @@ struct GraphNodeAnimatedPart
|
||||
*/
|
||||
struct GraphNodeBillboard
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ void *displayList;
|
||||
/*0x18*/ Vec3s translation;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
void *displayList;
|
||||
/*0x18*/
|
||||
Vec3s translation;
|
||||
};
|
||||
|
||||
/** A GraphNode that simply draws a display list without doing any
|
||||
@@ -259,8 +314,10 @@ struct GraphNodeBillboard
|
||||
*/
|
||||
struct GraphNodeDisplayList
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ void *displayList;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
void *displayList;
|
||||
};
|
||||
|
||||
/** GraphNode part that scales itself and its children.
|
||||
@@ -273,9 +330,12 @@ struct GraphNodeDisplayList
|
||||
*/
|
||||
struct GraphNodeScale
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ void *displayList;
|
||||
/*0x18*/ f32 scale;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
void *displayList;
|
||||
/*0x18*/
|
||||
f32 scale;
|
||||
};
|
||||
|
||||
/** GraphNode that draws a shadow under an object.
|
||||
@@ -285,10 +345,14 @@ struct GraphNodeScale
|
||||
*/
|
||||
struct GraphNodeShadow
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ s16 shadowScale; // diameter (when a circle) or side (when a square) of shadow
|
||||
/*0x16*/ u8 shadowSolidity; // opacity of shadow, 255 = opaque
|
||||
/*0x17*/ u8 shadowType; // see ShadowType enum in shadow.h
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
s16 shadowScale; // diameter (when a circle) or side (when a square) of shadow
|
||||
/*0x16*/
|
||||
u8 shadowSolidity; // opacity of shadow, 255 = opaque
|
||||
/*0x17*/
|
||||
u8 shadowType; // see ShadowType enum in shadow.h
|
||||
};
|
||||
|
||||
/** GraphNode that contains as its sharedChild a group node containing all
|
||||
@@ -296,8 +360,10 @@ struct GraphNodeShadow
|
||||
*/
|
||||
struct GraphNodeObjectParent
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ struct GraphNode *sharedChild;
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
struct GraphNode *sharedChild;
|
||||
};
|
||||
|
||||
/** GraphNode that draws display lists not directly in memory but generated by
|
||||
@@ -310,8 +376,10 @@ struct GraphNodeObjectParent
|
||||
*/
|
||||
struct GraphNodeGenerated
|
||||
{
|
||||
/*0x00*/ struct FnGraphNode fnNode;
|
||||
/*0x18*/ u32 parameter; // extra context for the function
|
||||
/*0x00*/
|
||||
struct FnGraphNode fnNode;
|
||||
/*0x18*/
|
||||
u32 parameter; // extra context for the function
|
||||
};
|
||||
|
||||
/** GraphNode that draws a background image or a rectangle of a color.
|
||||
@@ -319,19 +387,26 @@ struct GraphNodeGenerated
|
||||
*/
|
||||
struct GraphNodeBackground
|
||||
{
|
||||
/*0x00*/ struct FnGraphNode fnNode;
|
||||
/*0x18*/ s32 unused;
|
||||
/*0x1C*/ s32 background; // background ID, or rgba5551 color if fnNode.func is null
|
||||
/*0x00*/
|
||||
struct FnGraphNode fnNode;
|
||||
/*0x18*/
|
||||
s32 unused;
|
||||
/*0x1C*/
|
||||
s32 background; // background ID, or rgba5551 color if fnNode.func is null
|
||||
};
|
||||
|
||||
/** Renders the object that Mario is holding.
|
||||
*/
|
||||
struct GraphNodeHeldObject
|
||||
{
|
||||
/*0x00*/ struct FnGraphNode fnNode;
|
||||
/*0x18*/ s32 playerIndex;
|
||||
/*0x1C*/ struct Object *objNode;
|
||||
/*0x20*/ Vec3s translation;
|
||||
/*0x00*/
|
||||
struct FnGraphNode fnNode;
|
||||
/*0x18*/
|
||||
s32 playerIndex;
|
||||
/*0x1C*/
|
||||
struct Object *objNode;
|
||||
/*0x20*/
|
||||
Vec3s translation;
|
||||
};
|
||||
|
||||
/** A node that allows an object to specify a different culling radius than the
|
||||
@@ -341,8 +416,10 @@ struct GraphNodeHeldObject
|
||||
*/
|
||||
struct GraphNodeCullingRadius
|
||||
{
|
||||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ s16 cullingRadius; // specifies the 'sphere radius' for purposes of frustum culling
|
||||
/*0x00*/
|
||||
struct GraphNode node;
|
||||
/*0x14*/
|
||||
s16 cullingRadius; // specifies the 'sphere radius' for purposes of frustum culling
|
||||
u8 pad1E[2];
|
||||
};
|
||||
|
||||
@@ -363,71 +440,122 @@ extern s16 gCurGraphNodeIndex;
|
||||
|
||||
void init_scene_graph_node_links(struct GraphNode *graphNode, s32 type);
|
||||
|
||||
struct GraphNodeRoot *init_graph_node_root(struct AllocOnlyPool *pool, struct GraphNodeRoot *graphNode,
|
||||
s16 areaIndex, s16 x, s16 y, s16 width, s16 height);
|
||||
struct GraphNodeRoot *init_graph_node_root(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeRoot *graphNode,
|
||||
s16 areaIndex, s16 x, s16 y, s16 width, s16 height);
|
||||
|
||||
struct GraphNodeOrthoProjection *init_graph_node_ortho_projection(struct AllocOnlyPool *pool, struct GraphNodeOrthoProjection *graphNode, f32 scale);
|
||||
struct GraphNodePerspective *init_graph_node_perspective(struct AllocOnlyPool *pool, struct GraphNodePerspective *graphNode,
|
||||
f32 fov, s16 near, s16 far, GraphNodeFunc nodeFunc, s32 unused);
|
||||
|
||||
struct GraphNodePerspective *init_graph_node_perspective(
|
||||
struct AllocOnlyPool *pool, struct GraphNodePerspective *graphNode,
|
||||
f32 fov, s16 near, s16 far, GraphNodeFunc nodeFunc, s32 unused);
|
||||
|
||||
struct GraphNodeStart *init_graph_node_start(struct AllocOnlyPool *pool, struct GraphNodeStart *graphNode);
|
||||
|
||||
struct GraphNodeMasterList *init_graph_node_master_list(struct AllocOnlyPool *pool, struct GraphNodeMasterList *graphNode, s16 on);
|
||||
struct GraphNodeLevelOfDetail *init_graph_node_render_range(struct AllocOnlyPool *pool, struct GraphNodeLevelOfDetail *graphNode,
|
||||
s16 minDistance, s16 maxDistance);
|
||||
struct GraphNodeSwitchCase *init_graph_node_switch_case(struct AllocOnlyPool *pool, struct GraphNodeSwitchCase *graphNode,
|
||||
s16 numCases, s16 selectedCase, GraphNodeFunc nodeFunc, s32 unused);
|
||||
struct GraphNodeCamera *init_graph_node_camera(struct AllocOnlyPool *pool, struct GraphNodeCamera *graphNode,
|
||||
f32 *pos, f32 *focus, GraphNodeFunc func, s32 mode);
|
||||
struct GraphNodeTranslationRotation *init_graph_node_translation_rotation(struct AllocOnlyPool *pool, struct GraphNodeTranslationRotation *graphNode,
|
||||
s32 drawingLayer, void *displayList, Vec3s translation, Vec3s rotation);
|
||||
struct GraphNodeTranslation *init_graph_node_translation(struct AllocOnlyPool *pool, struct GraphNodeTranslation *graphNode,
|
||||
s32 drawingLayer, void *displayList, Vec3s translation);
|
||||
struct GraphNodeRotation *init_graph_node_rotation(struct AllocOnlyPool *pool, struct GraphNodeRotation *graphNode,
|
||||
s32 drawingLayer, void *displayList, Vec3s rotation);
|
||||
struct GraphNodeScale *init_graph_node_scale(struct AllocOnlyPool *pool, struct GraphNodeScale *graphNode,
|
||||
s32 drawingLayer, void *displayList, f32 scale);
|
||||
struct GraphNodeObject *init_graph_node_object(struct AllocOnlyPool *pool, struct GraphNodeObject *graphNode,
|
||||
struct GraphNode *sharedChild, Vec3f pos, Vec3s angle, Vec3f scale);
|
||||
|
||||
struct GraphNodeLevelOfDetail *init_graph_node_render_range(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeLevelOfDetail *graphNode,
|
||||
s16 minDistance, s16 maxDistance);
|
||||
|
||||
struct GraphNodeSwitchCase *init_graph_node_switch_case(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeSwitchCase *graphNode,
|
||||
s16 numCases, s16 selectedCase, GraphNodeFunc nodeFunc, s32 unused);
|
||||
|
||||
struct GraphNodeCamera *init_graph_node_camera(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeCamera *graphNode,
|
||||
f32 *pos, f32 *focus, GraphNodeFunc func, s32 mode);
|
||||
|
||||
struct GraphNodeTranslationRotation *init_graph_node_translation_rotation(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeTranslationRotation *graphNode,
|
||||
s32 drawingLayer, void *displayList, Vec3s translation, Vec3s rotation);
|
||||
|
||||
struct GraphNodeTranslation *init_graph_node_translation(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeTranslation *graphNode,
|
||||
s32 drawingLayer, void *displayList, Vec3s translation);
|
||||
|
||||
struct GraphNodeRotation *init_graph_node_rotation(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeRotation *graphNode,
|
||||
s32 drawingLayer, void *displayList, Vec3s rotation);
|
||||
|
||||
struct GraphNodeScale *init_graph_node_scale(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeScale *graphNode,
|
||||
s32 drawingLayer, void *displayList, f32 scale);
|
||||
|
||||
struct GraphNodeObject *init_graph_node_object(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeObject *graphNode,
|
||||
struct GraphNode *sharedChild, Vec3f pos, Vec3s angle, Vec3f scale);
|
||||
|
||||
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 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,
|
||||
s32 drawingLayer, void *displayList);
|
||||
struct GraphNodeShadow *init_graph_node_shadow(struct AllocOnlyPool *pool, struct GraphNodeShadow *graphNode,
|
||||
s16 shadowScale, u8 shadowSolidity, u8 shadowType);
|
||||
struct GraphNodeObjectParent *init_graph_node_object_parent(struct AllocOnlyPool *pool, struct GraphNodeObjectParent *sp1c,
|
||||
struct GraphNode *sharedChild);
|
||||
struct GraphNodeGenerated *init_graph_node_generated(struct AllocOnlyPool *pool, struct GraphNodeGenerated *sp1c,
|
||||
GraphNodeFunc gfxFunc, s32 parameter);
|
||||
struct GraphNodeBackground *init_graph_node_background(struct AllocOnlyPool *pool, struct GraphNodeBackground *sp1c,
|
||||
u16 background, GraphNodeFunc backgroundFunc, s32 zero);
|
||||
struct GraphNodeHeldObject *init_graph_node_held_object(struct AllocOnlyPool *pool, struct GraphNodeHeldObject *sp1c,
|
||||
struct Object *objNode, Vec3s translation,
|
||||
GraphNodeFunc nodeFunc, s32 playerIndex);
|
||||
|
||||
struct GraphNodeAnimatedPart *init_graph_node_animated_part(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeAnimatedPart *graphNode,
|
||||
s32 drawingLayer, void *displayList, Vec3s translation);
|
||||
|
||||
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,
|
||||
s32 drawingLayer, void *displayList);
|
||||
|
||||
struct GraphNodeShadow *init_graph_node_shadow(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeShadow *graphNode,
|
||||
s16 shadowScale, u8 shadowSolidity, u8 shadowType);
|
||||
|
||||
struct GraphNodeObjectParent *init_graph_node_object_parent(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeObjectParent *sp1c,
|
||||
struct GraphNode *sharedChild);
|
||||
|
||||
struct GraphNodeGenerated *init_graph_node_generated(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeGenerated *sp1c,
|
||||
GraphNodeFunc gfxFunc, s32 parameter);
|
||||
|
||||
struct GraphNodeBackground *init_graph_node_background(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeBackground *sp1c,
|
||||
u16 background, GraphNodeFunc backgroundFunc, s32 zero);
|
||||
|
||||
struct GraphNodeHeldObject *init_graph_node_held_object(
|
||||
struct AllocOnlyPool *pool, struct GraphNodeHeldObject *sp1c,
|
||||
struct Object *objNode, Vec3s translation,
|
||||
GraphNodeFunc nodeFunc, s32 playerIndex);
|
||||
|
||||
struct GraphNode *geo_add_child(struct GraphNode *parent, struct GraphNode *childNode);
|
||||
|
||||
struct GraphNode *geo_remove_child(struct GraphNode *graphNode);
|
||||
|
||||
struct GraphNode *geo_make_first_child(struct GraphNode *newFirstChild);
|
||||
|
||||
void geo_call_global_function_nodes_helper(struct GraphNode *graphNode, s32 callContext);
|
||||
|
||||
void geo_call_global_function_nodes(struct GraphNode *graphNode, s32 callContext);
|
||||
|
||||
void geo_reset_object_node(struct GraphNodeObject *graphNode);
|
||||
|
||||
void geo_obj_init(struct GraphNodeObject *graphNode, void *sharedChild, Vec3f pos, Vec3s angle);
|
||||
|
||||
void geo_obj_init_spawninfo(struct GraphNodeObject *graphNode, struct SpawnInfo *spawn);
|
||||
|
||||
void geo_obj_init_animation(struct GraphNodeObject *graphNode, struct Animation **animPtrAddr);
|
||||
|
||||
void geo_obj_init_animation_accel(struct GraphNodeObject *graphNode, struct Animation **animPtrAddr, u32 animAccel);
|
||||
|
||||
s32 retrieve_animation_index(s32 frame, u16 **attributes);
|
||||
|
||||
s16 geo_update_animation_frame(struct AnimInfo *obj, s32 *accelAssist);
|
||||
|
||||
void geo_retreive_animation_translation(struct GraphNodeObject *obj, Vec3f position);
|
||||
|
||||
struct GraphNodeRoot *geo_find_root(struct GraphNode *graphNode);
|
||||
|
||||
// graph_node_manager
|
||||
s16 *read_vec3s_to_vec3f(Vec3f, s16 *src);
|
||||
s16 *read_vec3s_to_vec3f(Vec3f, s16 * src);
|
||||
|
||||
s16 *read_vec3s(Vec3s dst, s16 *src);
|
||||
|
||||
s16 *read_vec3s_angle(Vec3s dst, s16 *src);
|
||||
|
||||
void register_scene_graph_node(struct GraphNode *graphNode);
|
||||
|
||||
#endif // GRAPH_NODE_H
|
||||
|
||||
@@ -6,14 +6,17 @@
|
||||
#include "graph_node.h"
|
||||
|
||||
#if IS_64_BIT
|
||||
static s16 next_s16_in_geo_script(s16 **src) {
|
||||
static s16 next_s16_in_geo_script(s16 **src)
|
||||
{
|
||||
s16 ret;
|
||||
if (((uintptr_t)(*src) & 7) == 4) {
|
||||
*src += 2; // skip 32 bits
|
||||
if (((uintptr_t)(*src) & 7) == 4)
|
||||
{
|
||||
*src += 2; // skip 32 bits
|
||||
}
|
||||
ret = *(*src)++;
|
||||
if (((uintptr_t)(*src) & 7) == 4) {
|
||||
*src += 2; // skip 32 bits
|
||||
if (((uintptr_t)(*src) & 7) == 4)
|
||||
{
|
||||
*src += 2; // skip 32 bits
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -25,7 +28,8 @@ static s16 next_s16_in_geo_script(s16 **src) {
|
||||
* Takes a pointer to three shorts (supplied by a geo layout script) and
|
||||
* copies it to the destination float vector.
|
||||
*/
|
||||
s16 *read_vec3s_to_vec3f(Vec3f dst, s16 *src) {
|
||||
s16 *read_vec3s_to_vec3f(Vec3f dst, s16 *src)
|
||||
{
|
||||
dst[0] = next_s16_in_geo_script(&src);
|
||||
dst[1] = next_s16_in_geo_script(&src);
|
||||
dst[2] = next_s16_in_geo_script(&src);
|
||||
@@ -37,7 +41,8 @@ s16 *read_vec3s_to_vec3f(Vec3f dst, s16 *src) {
|
||||
* copies it to the destination vector. It's essentially a memcpy but consistent
|
||||
* with the other two 'geo-script vector to internal vector' functions.
|
||||
*/
|
||||
s16 *read_vec3s(Vec3s dst, s16 *src) {
|
||||
s16 *read_vec3s(Vec3s dst, s16 *src)
|
||||
{
|
||||
dst[0] = next_s16_in_geo_script(&src);
|
||||
dst[1] = next_s16_in_geo_script(&src);
|
||||
dst[2] = next_s16_in_geo_script(&src);
|
||||
@@ -49,7 +54,8 @@ s16 *read_vec3s(Vec3s dst, s16 *src) {
|
||||
* and converts it to a vector of three in-game angle units in [-32768, 32767]
|
||||
* range.
|
||||
*/
|
||||
s16 *read_vec3s_angle(Vec3s dst, s16 *src) {
|
||||
s16 *read_vec3s_angle(Vec3s dst, s16 *src)
|
||||
{
|
||||
dst[0] = (next_s16_in_geo_script(&src) << 15) / 180;
|
||||
dst[1] = (next_s16_in_geo_script(&src) << 15) / 180;
|
||||
dst[2] = (next_s16_in_geo_script(&src) << 15) / 180;
|
||||
@@ -61,19 +67,28 @@ s16 *read_vec3s_angle(Vec3s dst, s16 *src) {
|
||||
* 'gCurGraphNodeList'. This is called from geo_layout commands to add nodes
|
||||
* to the scene graph.
|
||||
*/
|
||||
void register_scene_graph_node(struct GraphNode *graphNode) {
|
||||
if (graphNode != NULL) {
|
||||
void register_scene_graph_node(struct GraphNode *graphNode)
|
||||
{
|
||||
if (graphNode != nullptr)
|
||||
{
|
||||
gCurGraphNodeList[gCurGraphNodeIndex] = graphNode;
|
||||
|
||||
if (gCurGraphNodeIndex == 0) {
|
||||
if (gCurRootGraphNode == NULL) {
|
||||
if (gCurGraphNodeIndex == 0)
|
||||
{
|
||||
if (gCurRootGraphNode == nullptr)
|
||||
{
|
||||
gCurRootGraphNode = graphNode;
|
||||
}
|
||||
} else {
|
||||
if (gCurGraphNodeList[gCurGraphNodeIndex - 1]->type == GRAPH_NODE_TYPE_OBJECT_PARENT) {
|
||||
((struct GraphNodeObjectParent *) gCurGraphNodeList[gCurGraphNodeIndex - 1])
|
||||
->sharedChild = graphNode;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurGraphNodeList[gCurGraphNodeIndex - 1]->type == GRAPH_NODE_TYPE_OBJECT_PARENT)
|
||||
{
|
||||
((struct GraphNodeObjectParent *)gCurGraphNodeList[gCurGraphNodeIndex - 1])
|
||||
->sharedChild = graphNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
geo_add_child(gCurGraphNodeList[gCurGraphNodeIndex - 1], graphNode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,17 @@
|
||||
#endif
|
||||
|
||||
#ifndef GBI_FLOATS
|
||||
void guMtxF2L(float mf[4][4], Mtx *m) {
|
||||
void guMtxF2L(float mf[4][4], Mtx *m)
|
||||
{
|
||||
int r, c;
|
||||
s32 tmp1;
|
||||
s32 tmp2;
|
||||
s32 *m1 = &m->m[0][0];
|
||||
s32 *m2 = &m->m[2][0];
|
||||
for (r = 0; r < 4; r++) {
|
||||
for (c = 0; c < 2; c++) {
|
||||
for (r = 0; r < 4; r++)
|
||||
{
|
||||
for (c = 0; c < 2; c++)
|
||||
{
|
||||
tmp1 = mf[r][2 * c] * 65536.0f;
|
||||
tmp2 = mf[r][2 * c + 1] * 65536.0f;
|
||||
*m1++ = (tmp1 & 0xffff0000) | ((tmp2 >> 0x10) & 0xffff);
|
||||
@@ -20,53 +23,67 @@ void guMtxF2L(float mf[4][4], Mtx *m) {
|
||||
}
|
||||
}
|
||||
}
|
||||
void guMtxL2F(float mf[4][4], Mtx *m) {
|
||||
|
||||
void guMtxL2F(float mf[4][4], Mtx *m)
|
||||
{
|
||||
int r, c;
|
||||
u32 tmp1;
|
||||
u32 tmp2;
|
||||
u32 *m1;
|
||||
u32 *m2;
|
||||
s32 stmp1, stmp2;
|
||||
m1 = (u32 *) &m->m[0][0];
|
||||
m2 = (u32 *) &m->m[2][0];
|
||||
for (r = 0; r < 4; r++) {
|
||||
for (c = 0; c < 2; c++) {
|
||||
m1 = (u32 *)&m->m[0][0];
|
||||
m2 = (u32 *)&m->m[2][0];
|
||||
for (r = 0; r < 4; r++)
|
||||
{
|
||||
for (c = 0; c < 2; c++)
|
||||
{
|
||||
tmp1 = (*m1 & 0xffff0000) | ((*m2 >> 0x10) & 0xffff);
|
||||
tmp2 = ((*m1++ << 0x10) & 0xffff0000) | (*m2++ & 0xffff);
|
||||
stmp1 = *(s32 *) &tmp1;
|
||||
stmp2 = *(s32 *) &tmp2;
|
||||
stmp1 = *(s32 *)&tmp1;
|
||||
stmp2 = *(s32 *)&tmp2;
|
||||
mf[r][c * 2 + 0] = stmp1 / 65536.0f;
|
||||
mf[r][c * 2 + 1] = stmp2 / 65536.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void guMtxF2L(float mf[4][4], Mtx *m) {
|
||||
void guMtxF2L(float mf[4][4], Mtx *m)
|
||||
{
|
||||
memcpy(m, mf, sizeof(Mtx));
|
||||
}
|
||||
void guMtxL2F(float mf[4][4], Mtx *m) {
|
||||
void guMtxL2F(float mf[4][4], Mtx *m)
|
||||
{
|
||||
memcpy(mf, m, sizeof(Mtx));
|
||||
}
|
||||
#endif
|
||||
|
||||
void guMtxIdentF(float mf[4][4]) {
|
||||
void guMtxIdentF(float mf[4][4])
|
||||
{
|
||||
int r, c;
|
||||
for (r = 0; r < 4; r++) {
|
||||
for (c = 0; c < 4; c++) {
|
||||
if (r == c) {
|
||||
for (r = 0; r < 4; r++)
|
||||
{
|
||||
for (c = 0; c < 4; c++)
|
||||
{
|
||||
if (r == c)
|
||||
{
|
||||
mf[r][c] = 1.0f;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mf[r][c] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void guMtxIdent(Mtx *m) {
|
||||
#ifndef GBI_FLOATS
|
||||
|
||||
void guMtxIdent(Mtx *m)
|
||||
{
|
||||
#ifndef GBI_FLOATS
|
||||
float mf[4][4];
|
||||
guMtxIdentF(mf);
|
||||
guMtxF2L(mf, m);
|
||||
#else
|
||||
#else
|
||||
guMtxIdentF(m->m);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../include/PR/gbi.h"
|
||||
|
||||
extern void guMtxF2L(float mf[4][4], Mtx *m);
|
||||
|
||||
extern void guMtxL2F(float mf[4][4], Mtx *m);
|
||||
|
||||
#endif//GUMTXF2L_H
|
||||
+199
-111
@@ -8,13 +8,13 @@
|
||||
#include "graph_node.h"
|
||||
#include "surface_collision.h"
|
||||
|
||||
static Vec3f gVec3fZero = { 0.0f, 0.0f, 0.0f };
|
||||
static Vec3f gVec3fZero = {0.0f, 0.0f, 0.0f};
|
||||
|
||||
// Inlined tables
|
||||
f32 gSineTable[] = {
|
||||
0.000000000f, 0.0015339801f,0.0030679568f,0.004601926f,
|
||||
0.0061358847f,0.007669829f, 0.009203754f, 0.010737659f,
|
||||
0.012271538f, 0.0138053885f,0.015339206f, 0.016872987f,
|
||||
0.000000000f, 0.0015339801f, 0.0030679568f, 0.004601926f,
|
||||
0.0061358847f, 0.007669829f, 0.009203754f, 0.010737659f,
|
||||
0.012271538f, 0.0138053885f, 0.015339206f, 0.016872987f,
|
||||
0.018406730f, 0.019940428f, 0.021474080f, 0.023007682f,
|
||||
0.024541229f, 0.026074719f, 0.027608145f, 0.029141508f,
|
||||
0.030674804f, 0.032208025f, 0.033741172f, 0.035274237f,
|
||||
@@ -268,11 +268,11 @@ f32 gSineTable[] = {
|
||||
0.999830604f, 0.999857664f, 0.999882340f, 0.999904692f,
|
||||
0.999924719f, 0.999942362f, 0.999957621f, 0.999970615f,
|
||||
0.999981165f, 0.999989390f, 0.999995291f, 0.999998808f,
|
||||
#ifndef AVOID_UB
|
||||
#ifndef AVOID_UB
|
||||
};
|
||||
|
||||
f32 gCosineTable[0x1000] = {
|
||||
#endif
|
||||
#endif
|
||||
// cosine
|
||||
1.000000000f, 0.999998808f, 0.999995291f, 0.999989390f,
|
||||
0.999981165f, 0.999970615f, 0.999957621f, 0.999942362f,
|
||||
@@ -529,12 +529,12 @@ f32 gCosineTable[0x1000] = {
|
||||
0.024541229f, 0.023007682f, 0.021474080f, 0.019940428f,
|
||||
0.018406730f, 0.016872987f, 0.015339206f, 0.0138053885f,
|
||||
0.012271538f, 0.010737659f, 0.009203754f, 0.007669829f,
|
||||
0.0061358847f,0.004601926f, 0.0030679568f,0.0015339801f,
|
||||
0.0061358847f, 0.004601926f, 0.0030679568f, 0.0015339801f,
|
||||
|
||||
// negative sine
|
||||
0.000000000f, -0.0015339801f,-0.0030679568f,-0.004601926f,
|
||||
-0.0061358847f,-0.007669829f, -0.009203754f, -0.010737659f,
|
||||
-0.012271538f, -0.0138053885f,-0.015339206f, -0.016872987f,
|
||||
0.000000000f, -0.0015339801f, -0.0030679568f, -0.004601926f,
|
||||
-0.0061358847f, -0.007669829f, -0.009203754f, -0.010737659f,
|
||||
-0.012271538f, -0.0138053885f, -0.015339206f, -0.016872987f,
|
||||
-0.018406730f, -0.019940428f, -0.021474080f, -0.023007682f,
|
||||
-0.024541229f, -0.026074719f, -0.027608145f, -0.029141508f,
|
||||
-0.030674804f, -0.032208025f, -0.033741172f, -0.035274237f,
|
||||
@@ -1045,12 +1045,12 @@ f32 gCosineTable[0x1000] = {
|
||||
-0.024541229f, -0.023007682f, -0.021474080f, -0.019940428f,
|
||||
-0.018406730f, -0.016872987f, -0.015339206f, -0.0138053885f,
|
||||
-0.012271538f, -0.010737659f, -0.009203754f, -0.007669829f,
|
||||
-0.0061358847f,-0.004601926f, -0.0030679568f,-0.0015339801f,
|
||||
-0.0061358847f, -0.004601926f, -0.0030679568f, -0.0015339801f,
|
||||
|
||||
// sine
|
||||
0.000000000f, 0.0015339801f,0.0030679568f,0.004601926f,
|
||||
0.0061358847f,0.007669829f, 0.009203754f, 0.010737659f,
|
||||
0.012271538f, 0.0138053885f,0.015339206f, 0.016872987f,
|
||||
0.000000000f, 0.0015339801f, 0.0030679568f, 0.004601926f,
|
||||
0.0061358847f, 0.007669829f, 0.009203754f, 0.010737659f,
|
||||
0.012271538f, 0.0138053885f, 0.015339206f, 0.016872987f,
|
||||
0.018406730f, 0.019940428f, 0.021474080f, 0.023007682f,
|
||||
0.024541229f, 0.026074719f, 0.027608145f, 0.029141508f,
|
||||
0.030674804f, 0.032208025f, 0.033741172f, 0.035274237f,
|
||||
@@ -1450,7 +1450,8 @@ int gSplineState;
|
||||
#pragma GCC diagnostic ignored "-Wreturn-local-addr"
|
||||
|
||||
/// Copy vector 'src' to 'dest'
|
||||
void *vec3f_copy(Vec3f dest, Vec3f src) {
|
||||
void *vec3f_copy(Vec3f dest, Vec3f src)
|
||||
{
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
@@ -1458,7 +1459,8 @@ void *vec3f_copy(Vec3f dest, Vec3f src) {
|
||||
}
|
||||
|
||||
/// Set vector 'dest' to (x, y, z)
|
||||
void *vec3f_set(Vec3f dest, f32 x, f32 y, f32 z) {
|
||||
void *vec3f_set(Vec3f dest, f32 x, f32 y, f32 z)
|
||||
{
|
||||
dest[0] = x;
|
||||
dest[1] = y;
|
||||
dest[2] = z;
|
||||
@@ -1466,7 +1468,8 @@ void *vec3f_set(Vec3f dest, f32 x, f32 y, f32 z) {
|
||||
}
|
||||
|
||||
/// Add vector 'a' to 'dest'
|
||||
void *vec3f_add(Vec3f dest, Vec3f a) {
|
||||
void *vec3f_add(Vec3f dest, Vec3f a)
|
||||
{
|
||||
dest[0] += a[0];
|
||||
dest[1] += a[1];
|
||||
dest[2] += a[2];
|
||||
@@ -1474,7 +1477,8 @@ void *vec3f_add(Vec3f dest, Vec3f a) {
|
||||
}
|
||||
|
||||
/// Make 'dest' the sum of vectors a and b.
|
||||
void *vec3f_sum(Vec3f dest, Vec3f a, Vec3f b) {
|
||||
void *vec3f_sum(Vec3f dest, Vec3f a, Vec3f b)
|
||||
{
|
||||
dest[0] = a[0] + b[0];
|
||||
dest[1] = a[1] + b[1];
|
||||
dest[2] = a[2] + b[2];
|
||||
@@ -1482,7 +1486,8 @@ void *vec3f_sum(Vec3f dest, Vec3f a, Vec3f b) {
|
||||
}
|
||||
|
||||
/// Copy vector src to dest
|
||||
void *vec3s_copy(Vec3s dest, Vec3s src) {
|
||||
void *vec3s_copy(Vec3s dest, Vec3s src)
|
||||
{
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
@@ -1490,7 +1495,8 @@ void *vec3s_copy(Vec3s dest, Vec3s src) {
|
||||
}
|
||||
|
||||
/// Set vector 'dest' to (x, y, z)
|
||||
void *vec3s_set(Vec3s dest, s16 x, s16 y, s16 z) {
|
||||
void *vec3s_set(Vec3s dest, s16 x, s16 y, s16 z)
|
||||
{
|
||||
dest[0] = x;
|
||||
dest[1] = y;
|
||||
dest[2] = z;
|
||||
@@ -1498,7 +1504,8 @@ void *vec3s_set(Vec3s dest, s16 x, s16 y, s16 z) {
|
||||
}
|
||||
|
||||
/// Add vector a to 'dest'
|
||||
void *vec3s_add(Vec3s dest, Vec3s a) {
|
||||
void *vec3s_add(Vec3s dest, Vec3s a)
|
||||
{
|
||||
dest[0] += a[0];
|
||||
dest[1] += a[1];
|
||||
dest[2] += a[2];
|
||||
@@ -1506,7 +1513,8 @@ void *vec3s_add(Vec3s dest, Vec3s a) {
|
||||
}
|
||||
|
||||
/// Make 'dest' the sum of vectors a and b.
|
||||
void *vec3s_sum(Vec3s dest, Vec3s a, Vec3s b) {
|
||||
void *vec3s_sum(Vec3s dest, Vec3s a, Vec3s b)
|
||||
{
|
||||
dest[0] = a[0] + b[0];
|
||||
dest[1] = a[1] + b[1];
|
||||
dest[2] = a[2] + b[2];
|
||||
@@ -1514,7 +1522,8 @@ void *vec3s_sum(Vec3s dest, Vec3s a, Vec3s b) {
|
||||
}
|
||||
|
||||
/// Subtract vector a from 'dest'
|
||||
void *vec3s_sub(Vec3s dest, Vec3s a) {
|
||||
void *vec3s_sub(Vec3s dest, Vec3s a)
|
||||
{
|
||||
dest[0] -= a[0];
|
||||
dest[1] -= a[1];
|
||||
dest[2] -= a[2];
|
||||
@@ -1522,7 +1531,8 @@ void *vec3s_sub(Vec3s dest, Vec3s a) {
|
||||
}
|
||||
|
||||
/// Convert short vector a to float vector 'dest'
|
||||
void *vec3s_to_vec3f(Vec3f dest, Vec3s a) {
|
||||
void *vec3s_to_vec3f(Vec3f dest, Vec3s a)
|
||||
{
|
||||
dest[0] = a[0];
|
||||
dest[1] = a[1];
|
||||
dest[2] = a[2];
|
||||
@@ -1533,7 +1543,8 @@ void *vec3s_to_vec3f(Vec3f dest, Vec3s a) {
|
||||
* Convert float vector a to a short vector 'dest' by rounding the components
|
||||
* to the nearest integer.
|
||||
*/
|
||||
void *vec3f_to_vec3s(Vec3s dest, Vec3f a) {
|
||||
void *vec3f_to_vec3s(Vec3s dest, Vec3f a)
|
||||
{
|
||||
// add/subtract 0.5 in order to round to the nearest s32 instead of truncating
|
||||
dest[0] = a[0] + ((a[0] > 0) ? 0.5f : -0.5f);
|
||||
dest[1] = a[1] + ((a[1] > 0) ? 0.5f : -0.5f);
|
||||
@@ -1546,7 +1557,8 @@ void *vec3f_to_vec3s(Vec3s dest, Vec3f a) {
|
||||
* It is similar to vec3f_cross, but it calculates the vectors (c-b) and (b-a)
|
||||
* at the same time.
|
||||
*/
|
||||
void *find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c) {
|
||||
void *find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c)
|
||||
{
|
||||
dest[0] = (b[1] - a[1]) * (c[2] - b[2]) - (c[1] - b[1]) * (b[2] - a[2]);
|
||||
dest[1] = (b[2] - a[2]) * (c[0] - b[0]) - (c[2] - b[2]) * (b[0] - a[0]);
|
||||
dest[2] = (b[0] - a[0]) * (c[1] - b[1]) - (c[0] - b[0]) * (b[1] - a[1]);
|
||||
@@ -1554,7 +1566,8 @@ void *find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c)
|
||||
}
|
||||
|
||||
/// Make vector 'dest' the cross product of vectors a and b.
|
||||
void *vec3f_cross(Vec3f dest, Vec3f a, Vec3f b) {
|
||||
void *vec3f_cross(Vec3f dest, Vec3f a, Vec3f b)
|
||||
{
|
||||
dest[0] = a[1] * b[2] - b[1] * a[2];
|
||||
dest[1] = a[2] * b[0] - b[2] * a[0];
|
||||
dest[2] = a[0] * b[1] - b[0] * a[1];
|
||||
@@ -1562,7 +1575,8 @@ void *vec3f_cross(Vec3f dest, Vec3f a, Vec3f b) {
|
||||
}
|
||||
|
||||
/// Scale vector 'dest' so it has length 1
|
||||
void *vec3f_normalize(Vec3f dest) {
|
||||
void *vec3f_normalize(Vec3f dest)
|
||||
{
|
||||
//! Possible division by zero
|
||||
f32 invsqrt = 1.0f / sqrtf(dest[0] * dest[0] + dest[1] * dest[1] + dest[2] * dest[2]);
|
||||
|
||||
@@ -1575,12 +1589,14 @@ void *vec3f_normalize(Vec3f dest) {
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
/// Copy matrix 'src' to 'dest'
|
||||
void mtxf_copy(Mat4 dest, Mat4 src) {
|
||||
void mtxf_copy(Mat4 dest, Mat4 src)
|
||||
{
|
||||
register s32 i;
|
||||
register u32 *d = (u32 *) dest;
|
||||
register u32 *s = (u32 *) src;
|
||||
register u32 *d = (u32 *)dest;
|
||||
register u32 *s = (u32 *)src;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
*d++ = *s++;
|
||||
}
|
||||
}
|
||||
@@ -1588,22 +1604,24 @@ void mtxf_copy(Mat4 dest, Mat4 src) {
|
||||
/**
|
||||
* Set mtx to the identity matrix
|
||||
*/
|
||||
void mtxf_identity(Mat4 mtx) {
|
||||
void mtxf_identity(Mat4 mtx)
|
||||
{
|
||||
register s32 i;
|
||||
register f32 *dest;
|
||||
// These loops must be one line to match on -O2
|
||||
|
||||
// initialize everything except the first and last cells to 0
|
||||
for (dest = (f32 *) mtx + 1, i = 0; i < 14; dest++, i++) *dest = 0;
|
||||
for (dest = (f32 *)mtx + 1, i = 0; i < 14; dest++, i++) *dest = 0;
|
||||
|
||||
// initialize the diagonal cells to 1
|
||||
for (dest = (f32 *) mtx, i = 0; i < 4; dest += 5, i++) *dest = 1;
|
||||
for (dest = (f32 *)mtx, i = 0; i < 4; dest += 5, i++) *dest = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set dest to a translation matrix of vector b
|
||||
*/
|
||||
void mtxf_translate(Mat4 dest, Vec3f b) {
|
||||
void mtxf_translate(Mat4 dest, Vec3f b)
|
||||
{
|
||||
mtxf_identity(dest);
|
||||
dest[3][0] = b[0];
|
||||
dest[3][1] = b[1];
|
||||
@@ -1616,7 +1634,8 @@ void mtxf_translate(Mat4 dest, Vec3f b) {
|
||||
* at the position 'to'. The up-vector is assumed to be (0, 1, 0), but the 'roll'
|
||||
* angle allows a bank rotation of the camera.
|
||||
*/
|
||||
void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) {
|
||||
void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll)
|
||||
{
|
||||
register f32 invLength;
|
||||
f32 dx;
|
||||
f32 dz;
|
||||
@@ -1694,7 +1713,8 @@ void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) {
|
||||
* Build a matrix that rotates around the z axis, then the x axis, then the y
|
||||
* axis, and then translates.
|
||||
*/
|
||||
void mtxf_rotate_zxy_and_translate(Mat4 dest, Vec3f translate, Vec3s rotate) {
|
||||
void mtxf_rotate_zxy_and_translate(Mat4 dest, Vec3f translate, Vec3s rotate)
|
||||
{
|
||||
register f32 sx = sins(rotate[0]);
|
||||
register f32 cx = coss(rotate[0]);
|
||||
|
||||
@@ -1727,7 +1747,8 @@ void mtxf_rotate_zxy_and_translate(Mat4 dest, Vec3f translate, Vec3s rotate) {
|
||||
* Build a matrix that rotates around the x axis, then the y axis, then the z
|
||||
* axis, and then translates.
|
||||
*/
|
||||
void mtxf_rotate_xyz_and_translate(Mat4 dest, Vec3f b, Vec3s c) {
|
||||
void mtxf_rotate_xyz_and_translate(Mat4 dest, Vec3f b, Vec3s c)
|
||||
{
|
||||
register f32 sx = sins(c[0]);
|
||||
register f32 cx = coss(c[0]);
|
||||
|
||||
@@ -1764,7 +1785,8 @@ void mtxf_rotate_xyz_and_translate(Mat4 dest, Vec3f b, Vec3s c) {
|
||||
* 'position' is the position of the object in the world
|
||||
* 'angle' rotates the object while still facing the camera.
|
||||
*/
|
||||
void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) {
|
||||
void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle)
|
||||
{
|
||||
dest[0][0] = coss(angle);
|
||||
dest[0][1] = sins(angle);
|
||||
dest[0][2] = 0;
|
||||
@@ -1781,11 +1803,11 @@ void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) {
|
||||
dest[2][3] = 0;
|
||||
|
||||
dest[3][0] =
|
||||
mtx[0][0] * position[0] + mtx[1][0] * position[1] + mtx[2][0] * position[2] + mtx[3][0];
|
||||
mtx[0][0] * position[0] + mtx[1][0] * position[1] + mtx[2][0] * position[2] + mtx[3][0];
|
||||
dest[3][1] =
|
||||
mtx[0][1] * position[0] + mtx[1][1] * position[1] + mtx[2][1] * position[2] + mtx[3][1];
|
||||
mtx[0][1] * position[0] + mtx[1][1] * position[1] + mtx[2][1] * position[2] + mtx[3][1];
|
||||
dest[3][2] =
|
||||
mtx[0][2] * position[0] + mtx[1][2] * position[1] + mtx[2][2] * position[2] + mtx[3][2];
|
||||
mtx[0][2] * position[0] + mtx[1][2] * position[1] + mtx[2][2] * position[2] + mtx[3][2];
|
||||
dest[3][3] = 1;
|
||||
}
|
||||
|
||||
@@ -1796,7 +1818,8 @@ void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) {
|
||||
* 'yaw' is the angle which it should face
|
||||
* 'pos' is the object's position in the world
|
||||
*/
|
||||
void mtxf_align_terrain_normal(Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw) {
|
||||
void mtxf_align_terrain_normal(Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw)
|
||||
{
|
||||
Vec3f lateralDir;
|
||||
Vec3f leftDir;
|
||||
Vec3f forwardDir;
|
||||
@@ -1839,7 +1862,8 @@ void mtxf_align_terrain_normal(Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw) {
|
||||
* 'pos' is the object's position in the world
|
||||
* 'radius' is the distance from each triangle vertex to the center
|
||||
*/
|
||||
void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s16 yaw, f32 radius) {
|
||||
void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s16 yaw, f32 radius)
|
||||
{
|
||||
struct SM64SurfaceCollisionData *sp74;
|
||||
Vec3f point0;
|
||||
Vec3f point1;
|
||||
@@ -1862,15 +1886,18 @@ void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s16 yaw, f32 radius) {
|
||||
point1[1] = find_floor(point1[0], pos[1] + 150, point1[2], &sp74);
|
||||
point2[1] = find_floor(point2[0], pos[1] + 150, point2[2], &sp74);
|
||||
|
||||
if (point0[1] - pos[1] < minY) {
|
||||
if (point0[1] - pos[1] < minY)
|
||||
{
|
||||
point0[1] = pos[1];
|
||||
}
|
||||
|
||||
if (point1[1] - pos[1] < minY) {
|
||||
if (point1[1] - pos[1] < minY)
|
||||
{
|
||||
point1[1] = pos[1];
|
||||
}
|
||||
|
||||
if (point2[1] - pos[1] < minY) {
|
||||
if (point2[1] - pos[1] < minY)
|
||||
{
|
||||
point2[1] = pos[1];
|
||||
}
|
||||
|
||||
@@ -1913,7 +1940,8 @@ void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s16 yaw, f32 radius) {
|
||||
* The resulting matrix represents first applying transformation b and
|
||||
* then a.
|
||||
*/
|
||||
void mtxf_mul(Mat4 dest, Mat4 a, Mat4 b) {
|
||||
void mtxf_mul(Mat4 dest, Mat4 a, Mat4 b)
|
||||
{
|
||||
Mat4 temp;
|
||||
register f32 entry0;
|
||||
register f32 entry1;
|
||||
@@ -1960,10 +1988,12 @@ void mtxf_mul(Mat4 dest, Mat4 a, Mat4 b) {
|
||||
/**
|
||||
* Set matrix 'dest' to 'mtx' scaled by vector s
|
||||
*/
|
||||
void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, Vec3f s) {
|
||||
void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, Vec3f s)
|
||||
{
|
||||
register s32 i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
dest[0][i] = mtx[0][i] * s[0];
|
||||
dest[1][i] = mtx[1][i] * s[1];
|
||||
dest[2][i] = mtx[2][i] * s[2];
|
||||
@@ -1976,7 +2006,8 @@ void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, Vec3f s) {
|
||||
* to the point. Note that the bottom row is assumed to be [0, 0, 0, 1], which is
|
||||
* true for transformation matrices if the translation has a w component of 1.
|
||||
*/
|
||||
void mtxf_mul_vec3s(Mat4 mtx, Vec3s b) {
|
||||
void mtxf_mul_vec3s(Mat4 mtx, Vec3s b)
|
||||
{
|
||||
register f32 x = b[0];
|
||||
register f32 y = b[1];
|
||||
register f32 z = b[2];
|
||||
@@ -1986,7 +2017,8 @@ void mtxf_mul_vec3s(Mat4 mtx, Vec3s b) {
|
||||
b[2] = x * mtx[0][2] + y * mtx[1][2] + z * mtx[2][2] + mtx[3][2];
|
||||
}
|
||||
|
||||
void mtxf_mul_vec3f(Mat4 mtx, Vec3f b) {
|
||||
void mtxf_mul_vec3f(Mat4 mtx, Vec3f b)
|
||||
{
|
||||
register f32 x = b[0];
|
||||
register f32 y = b[1];
|
||||
register f32 z = b[2];
|
||||
@@ -1994,7 +2026,8 @@ void mtxf_mul_vec3f(Mat4 mtx, Vec3f b) {
|
||||
b[0] = x * mtx[0][0] + y * mtx[1][0] + z * mtx[2][0] + mtx[3][0];
|
||||
b[1] = x * mtx[0][1] + y * mtx[1][1] + z * mtx[2][1] + mtx[3][1];
|
||||
b[2] = x * mtx[0][2] + y * mtx[1][2] + z * mtx[2][2] + mtx[3][2];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert float matrix 'src' to fixed point matrix 'dest'.
|
||||
* The float matrix may not contain entries larger than 65536 or the console
|
||||
@@ -2004,30 +2037,33 @@ void mtxf_mul_vec3f(Mat4 mtx, Vec3f b) {
|
||||
* exception. On Wii and Wii U Virtual Console the value will simply be clamped
|
||||
* and no crashes occur.
|
||||
*/
|
||||
void mtxf_to_mtx(Mtx *dest, Mat4 src) {
|
||||
#ifdef AVOID_UB
|
||||
void mtxf_to_mtx(Mtx *dest, Mat4 src)
|
||||
{
|
||||
#ifdef AVOID_UB
|
||||
// Avoid type-casting which is technically UB by calling the equivalent
|
||||
// guMtxF2L function. This helps little-endian systems, as well.
|
||||
guMtxF2L(src, dest);
|
||||
#else
|
||||
#else
|
||||
s32 asFixedPoint;
|
||||
register s32 i;
|
||||
register s16 *a3 = (s16 *) dest; // all integer parts stored in first 16 bytes
|
||||
register s16 *t0 = (s16 *) dest + 16; // all fraction parts stored in last 16 bytes
|
||||
register f32 *t1 = (f32 *) src;
|
||||
register s16 *a3 = (s16 *)dest; // all integer parts stored in first 16 bytes
|
||||
register s16 *t0 = (s16 *)dest + 16; // all fraction parts stored in last 16 bytes
|
||||
register f32 *t1 = (f32 *)src;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
asFixedPoint = *t1++ * (1 << 16); //! float-to-integer conversion responsible for PU crashes
|
||||
*a3++ = GET_HIGH_S16_OF_32(asFixedPoint); // integer part
|
||||
*t0++ = GET_LOW_S16_OF_32(asFixedPoint); // fraction part
|
||||
*t0++ = GET_LOW_S16_OF_32(asFixedPoint); // fraction part
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Set 'mtx' to a transformation matrix that rotates around the z axis.
|
||||
*/
|
||||
void mtxf_rotate_xy(Mtx *mtx, s16 angle) {
|
||||
void mtxf_rotate_xy(Mtx *mtx, s16 angle)
|
||||
{
|
||||
Mat4 temp;
|
||||
|
||||
mtxf_identity(temp);
|
||||
@@ -2046,17 +2082,18 @@ void mtxf_rotate_xy(Mtx *mtx, s16 angle) {
|
||||
* objMtx back from screen orientation to world orientation, and then subtracting
|
||||
* the camera position.
|
||||
*/
|
||||
void get_pos_from_transform_mtx(Vec3f dest, Mat4 objMtx, Mat4 camMtx) {
|
||||
void get_pos_from_transform_mtx(Vec3f dest, Mat4 objMtx, Mat4 camMtx)
|
||||
{
|
||||
f32 camX = camMtx[3][0] * camMtx[0][0] + camMtx[3][1] * camMtx[0][1] + camMtx[3][2] * camMtx[0][2];
|
||||
f32 camY = camMtx[3][0] * camMtx[1][0] + camMtx[3][1] * camMtx[1][1] + camMtx[3][2] * camMtx[1][2];
|
||||
f32 camZ = camMtx[3][0] * camMtx[2][0] + camMtx[3][1] * camMtx[2][1] + camMtx[3][2] * camMtx[2][2];
|
||||
|
||||
dest[0] =
|
||||
objMtx[3][0] * camMtx[0][0] + objMtx[3][1] * camMtx[0][1] + objMtx[3][2] * camMtx[0][2] - camX;
|
||||
objMtx[3][0] * camMtx[0][0] + objMtx[3][1] * camMtx[0][1] + objMtx[3][2] * camMtx[0][2] - camX;
|
||||
dest[1] =
|
||||
objMtx[3][0] * camMtx[1][0] + objMtx[3][1] * camMtx[1][1] + objMtx[3][2] * camMtx[1][2] - camY;
|
||||
objMtx[3][0] * camMtx[1][0] + objMtx[3][1] * camMtx[1][1] + objMtx[3][2] * camMtx[1][2] - camY;
|
||||
dest[2] =
|
||||
objMtx[3][0] * camMtx[2][0] + objMtx[3][1] * camMtx[2][1] + objMtx[3][2] * camMtx[2][2] - camZ;
|
||||
objMtx[3][0] * camMtx[2][0] + objMtx[3][1] * camMtx[2][1] + objMtx[3][2] * camMtx[2][2] - camZ;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2064,7 +2101,8 @@ void get_pos_from_transform_mtx(Vec3f dest, Mat4 objMtx, Mat4 camMtx) {
|
||||
* of that vector, as well as the yaw and pitch angles.
|
||||
* Basically it converts the direction to spherical coordinates.
|
||||
*/
|
||||
void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw) {
|
||||
void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw)
|
||||
{
|
||||
register f32 x = to[0] - from[0];
|
||||
register f32 y = to[1] - from[1];
|
||||
register f32 z = to[2] - from[2];
|
||||
@@ -2078,7 +2116,8 @@ void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *
|
||||
* Construct the 'to' point which is distance 'dist' away from the 'from' position,
|
||||
* and has the angles pitch and yaw.
|
||||
*/
|
||||
void vec3f_set_dist_and_angle(Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw) {
|
||||
void vec3f_set_dist_and_angle(Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw)
|
||||
{
|
||||
to[0] = from[0] + dist * coss(pitch) * sins(yaw);
|
||||
to[1] = from[1] + dist * sins(pitch);
|
||||
to[2] = from[2] + dist * coss(pitch) * coss(yaw);
|
||||
@@ -2088,18 +2127,24 @@ void vec3f_set_dist_and_angle(Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw
|
||||
* Return the value 'current' after it tries to approach target, going up at
|
||||
* most 'inc' and going down at most 'dec'.
|
||||
*/
|
||||
s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec) {
|
||||
s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec)
|
||||
{
|
||||
//! If target is close to the max or min s32, then it's possible to overflow
|
||||
// past it without stopping.
|
||||
|
||||
if (current < target) {
|
||||
if (current < target)
|
||||
{
|
||||
current += inc;
|
||||
if (current > target) {
|
||||
if (current > target)
|
||||
{
|
||||
current = target;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
current -= dec;
|
||||
if (current < target) {
|
||||
if (current < target)
|
||||
{
|
||||
current = target;
|
||||
}
|
||||
}
|
||||
@@ -2110,15 +2155,21 @@ s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec) {
|
||||
* Return the value 'current' after it tries to approach target, going up at
|
||||
* most 'inc' and going down at most 'dec'.
|
||||
*/
|
||||
f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec) {
|
||||
if (current < target) {
|
||||
f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec)
|
||||
{
|
||||
if (current < target)
|
||||
{
|
||||
current += inc;
|
||||
if (current > target) {
|
||||
if (current > target)
|
||||
{
|
||||
current = target;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
current -= dec;
|
||||
if (current < target) {
|
||||
if (current < target)
|
||||
{
|
||||
current = target;
|
||||
}
|
||||
}
|
||||
@@ -2129,12 +2180,16 @@ f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec) {
|
||||
* Helper function for atan2s. Does a look up of the arctangent of y/x assuming
|
||||
* the resulting angle is in range [0, 0x2000] (1/8 of a circle).
|
||||
*/
|
||||
static u16 atan2_lookup(f32 y, f32 x) {
|
||||
static u16 atan2_lookup(f32 y, f32 x)
|
||||
{
|
||||
u16 ret;
|
||||
|
||||
if (x == 0) {
|
||||
if (x == 0)
|
||||
{
|
||||
ret = gArctanTable[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = gArctanTable[(s32)(y / x * 1024 + 0.5f)];
|
||||
}
|
||||
return ret;
|
||||
@@ -2144,37 +2199,59 @@ static u16 atan2_lookup(f32 y, f32 x) {
|
||||
* Compute the angle from (0, 0) to (x, y) as a s16. Given that terrain is in
|
||||
* the xz-plane, this is commonly called with (z, x) to get a yaw angle.
|
||||
*/
|
||||
s16 atan2s(f32 y, f32 x) {
|
||||
s16 atan2s(f32 y, f32 x)
|
||||
{
|
||||
u16 ret;
|
||||
|
||||
if (x >= 0) {
|
||||
if (y >= 0) {
|
||||
if (y >= x) {
|
||||
if (x >= 0)
|
||||
{
|
||||
if (y >= 0)
|
||||
{
|
||||
if (y >= x)
|
||||
{
|
||||
ret = atan2_lookup(x, y);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0x4000 - atan2_lookup(y, x);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
y = -y;
|
||||
if (y < x) {
|
||||
if (y < x)
|
||||
{
|
||||
ret = 0x4000 + atan2_lookup(y, x);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0x8000 - atan2_lookup(x, y);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
x = -x;
|
||||
if (y < 0) {
|
||||
if (y < 0)
|
||||
{
|
||||
y = -y;
|
||||
if (y >= x) {
|
||||
if (y >= x)
|
||||
{
|
||||
ret = 0x8000 + atan2_lookup(x, y);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0xC000 - atan2_lookup(y, x);
|
||||
}
|
||||
} else {
|
||||
if (y < x) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y < x)
|
||||
{
|
||||
ret = 0xC000 + atan2_lookup(y, x);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -atan2_lookup(x, y);
|
||||
}
|
||||
}
|
||||
@@ -2220,14 +2297,16 @@ s16 atan2s(f32 y, f32 x) {
|
||||
* [0, 0, 0, 0, 1, 2, ... n-1, n, n, n, n]
|
||||
* TODO: verify the classification of the spline / figure out how polynomials were computed
|
||||
*/
|
||||
void spline_get_weights(Vec4f result, f32 t, UNUSED s32 c) {
|
||||
void spline_get_weights(Vec4f result, f32 t, UNUSED s32 c)
|
||||
{
|
||||
f32 tinv = 1 - t;
|
||||
f32 tinv2 = tinv * tinv;
|
||||
f32 tinv3 = tinv2 * tinv;
|
||||
f32 t2 = t * t;
|
||||
f32 t3 = t2 * t;
|
||||
|
||||
switch (gSplineState) {
|
||||
switch (gSplineState)
|
||||
{
|
||||
case CURVE_BEGIN_1:
|
||||
result[0] = tinv3;
|
||||
result[1] = t3 * 1.75f - t2 * 4.5f + t * 3.0f;
|
||||
@@ -2269,7 +2348,8 @@ void spline_get_weights(Vec4f result, f32 t, UNUSED s32 c) {
|
||||
* The array should end with three entries with s=0 (infinite keyframe duration).
|
||||
* That's because the spline has a 3rd degree polynomial, so it looks 3 points ahead.
|
||||
*/
|
||||
void anim_spline_init(Vec4s *keyFrames) {
|
||||
void anim_spline_init(Vec4s *keyFrames)
|
||||
{
|
||||
gSplineKeyframe = keyFrames;
|
||||
gSplineKeyframeFraction = 0;
|
||||
gSplineState = 1;
|
||||
@@ -2280,28 +2360,33 @@ void anim_spline_init(Vec4s *keyFrames) {
|
||||
* anim_spline_init should be called before polling for vectors.
|
||||
* Returns TRUE when the last point is reached, FALSE otherwise.
|
||||
*/
|
||||
s32 anim_spline_poll(Vec3f result) {
|
||||
s32 anim_spline_poll(Vec3f result)
|
||||
{
|
||||
Vec4f weights;
|
||||
s32 i;
|
||||
s32 hasEnded = FALSE;
|
||||
|
||||
vec3f_copy(result, gVec3fZero);
|
||||
spline_get_weights(weights, gSplineKeyframeFraction, gSplineState);
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
result[0] += weights[i] * gSplineKeyframe[i][1];
|
||||
result[1] += weights[i] * gSplineKeyframe[i][2];
|
||||
result[2] += weights[i] * gSplineKeyframe[i][3];
|
||||
}
|
||||
|
||||
if ((gSplineKeyframeFraction += gSplineKeyframe[0][0] / 1000.0f) >= 1) {
|
||||
if ((gSplineKeyframeFraction += gSplineKeyframe[0][0] / 1000.0f) >= 1)
|
||||
{
|
||||
gSplineKeyframe++;
|
||||
gSplineKeyframeFraction--;
|
||||
switch (gSplineState) {
|
||||
switch (gSplineState)
|
||||
{
|
||||
case CURVE_END_2:
|
||||
hasEnded = TRUE;
|
||||
break;
|
||||
case CURVE_MIDDLE:
|
||||
if (gSplineKeyframe[2][0] == 0) {
|
||||
if (gSplineKeyframe[2][0] == 0)
|
||||
{
|
||||
gSplineState = CURVE_END_1;
|
||||
}
|
||||
break;
|
||||
@@ -2315,7 +2400,6 @@ s32 anim_spline_poll(Vec3f result) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// From object_helpers.c
|
||||
|
||||
/**
|
||||
@@ -2326,9 +2410,11 @@ s32 anim_spline_poll(Vec3f result) {
|
||||
* | 0 0 0 1 |
|
||||
* i.e. a matrix representing a linear transformation over 3 space.
|
||||
*/
|
||||
void linear_mtxf_mul_vec3f(Mat4 m, Vec3f dst, Vec3f v) {
|
||||
void linear_mtxf_mul_vec3f(Mat4 m, Vec3f dst, Vec3f v)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
dst[i] = m[0][i] * v[0] + m[1][i] * v[1] + m[2][i] * v[2];
|
||||
}
|
||||
}
|
||||
@@ -2341,9 +2427,11 @@ void linear_mtxf_mul_vec3f(Mat4 m, Vec3f dst, Vec3f v) {
|
||||
* | 0 0 0 1 |
|
||||
* i.e. a matrix representing a linear transformation over 3 space.
|
||||
*/
|
||||
void linear_mtxf_transpose_mul_vec3f(Mat4 m, Vec3f dst, Vec3f v) {
|
||||
void linear_mtxf_transpose_mul_vec3f(Mat4 m, Vec3f dst, Vec3f v)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
dst[i] = m[i][0] * v[0] + m[i][1] * v[1] + m[i][2] * v[2];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,49 +34,87 @@ extern f32 gCosineTable[];
|
||||
#define sqr(x) ((x) * (x))
|
||||
|
||||
void *vec3f_copy(Vec3f dest, Vec3f src);
|
||||
|
||||
void *vec3f_set(Vec3f dest, f32 x, f32 y, f32 z);
|
||||
|
||||
void *vec3f_add(Vec3f dest, Vec3f a);
|
||||
|
||||
void *vec3f_sum(Vec3f dest, Vec3f a, Vec3f b);
|
||||
|
||||
void *vec3s_copy(Vec3s dest, Vec3s src);
|
||||
|
||||
void *vec3s_set(Vec3s dest, s16 x, s16 y, s16 z);
|
||||
|
||||
void *vec3s_add(Vec3s dest, Vec3s a);
|
||||
|
||||
void *vec3s_sum(Vec3s dest, Vec3s a, Vec3s b);
|
||||
|
||||
void *vec3s_sub(Vec3s dest, Vec3s a);
|
||||
|
||||
void *vec3s_to_vec3f(Vec3f dest, Vec3s a);
|
||||
|
||||
void *vec3f_to_vec3s(Vec3s dest, Vec3f a);
|
||||
|
||||
void *find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c);
|
||||
|
||||
void *vec3f_cross(Vec3f dest, Vec3f a, Vec3f b);
|
||||
|
||||
void *vec3f_normalize(Vec3f dest);
|
||||
|
||||
void mtxf_copy(Mat4 dest, Mat4 src);
|
||||
|
||||
void mtxf_identity(Mat4 mtx);
|
||||
|
||||
void mtxf_translate(Mat4 dest, Vec3f b);
|
||||
|
||||
void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll);
|
||||
|
||||
void mtxf_rotate_zxy_and_translate(Mat4 dest, Vec3f translate, Vec3s rotate);
|
||||
|
||||
void mtxf_rotate_xyz_and_translate(Mat4 dest, Vec3f b, Vec3s c);
|
||||
|
||||
void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle);
|
||||
|
||||
void mtxf_align_terrain_normal(Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw);
|
||||
|
||||
void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s16 yaw, f32 radius);
|
||||
|
||||
void mtxf_mul(Mat4 dest, Mat4 a, Mat4 b);
|
||||
|
||||
void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, Vec3f s);
|
||||
|
||||
void mtxf_mul_vec3s(Mat4 mtx, Vec3s b);
|
||||
|
||||
void mtxf_mul_vec3f(Mat4 mtx, Vec3f b);
|
||||
|
||||
void mtxf_to_mtx(Mtx *dest, Mat4 src);
|
||||
|
||||
void mtxf_rotate_xy(Mtx *mtx, s16 angle);
|
||||
|
||||
void get_pos_from_transform_mtx(Vec3f dest, Mat4 objMtx, Mat4 camMtx);
|
||||
|
||||
void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw);
|
||||
void vec3f_set_dist_and_angle(Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw);
|
||||
|
||||
void vec3f_set_dist_and_angle(Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw);
|
||||
|
||||
s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec);
|
||||
|
||||
f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec);
|
||||
|
||||
s16 atan2s(f32 y, f32 x);
|
||||
|
||||
// libsm64: `atan2f()` is not used anywhere and collides with `math.h`'s definition of the function, better to remove it entirely.
|
||||
// f32 atan2f(f32 a, f32 b);
|
||||
void spline_get_weights(Vec4f result, f32 t, UNUSED s32 c);
|
||||
void anim_spline_init(Vec4s *keyFrames);
|
||||
|
||||
void anim_spline_init(Vec4s * keyFrames);
|
||||
|
||||
s32 anim_spline_poll(Vec3f result);
|
||||
|
||||
|
||||
// From object_helpers.c
|
||||
void linear_mtxf_mul_vec3f(Mat4 m, Vec3f dst, Vec3f v);
|
||||
|
||||
void linear_mtxf_transpose_mul_vec3f(Mat4 m, Vec3f dst, Vec3f v);
|
||||
|
||||
|
||||
|
||||
@@ -8,149 +8,168 @@
|
||||
/**
|
||||
* Iterate through the list of ceilings and find the first ceiling over a given point.
|
||||
*/
|
||||
static struct SM64SurfaceCollisionData *find_ceil_from_list( f32 x, f32 y, f32 z, f32 *pheight) {
|
||||
static struct SM64SurfaceCollisionData *find_ceil_from_list(f32 x, f32 y, f32 z, f32 *pheight)
|
||||
{
|
||||
register struct SM64SurfaceCollisionData *surf;
|
||||
register f32 x1, z1, x2, z2, x3, z3;
|
||||
struct SM64SurfaceCollisionData *ceil = NULL;
|
||||
struct SM64SurfaceCollisionData *ceil = nullptr;
|
||||
|
||||
ceil = NULL;
|
||||
ceil = nullptr;
|
||||
|
||||
uint32_t groupCount = loaded_surface_iter_group_count();
|
||||
for( int i = 0; i < groupCount; ++i ) {
|
||||
uint32_t surfCount = loaded_surface_iter_group_size( i );
|
||||
for( int j = 0; j < surfCount; ++j ) {
|
||||
surf = loaded_surface_iter_get_at_index( i, j );
|
||||
|
||||
// libsm64: Weed out surfaces whose triangles are actually line segs. TODO do this at surface load time
|
||||
if( !surf->isValid ) continue;
|
||||
|
||||
// Do the check normally done in add_surface_to_cell
|
||||
if( surf->normal.y >= -0.01f ) continue;
|
||||
|
||||
x1 = surf->vertex1[0];
|
||||
z1 = surf->vertex1[2];
|
||||
z2 = surf->vertex2[2];
|
||||
x2 = surf->vertex2[0];
|
||||
|
||||
// Checking if point is in bounds of the triangle laterally.
|
||||
if ((z1 - z) * (x2 - x1) - (x1 - x) * (z2 - z1) > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Slight optimization by checking these later.
|
||||
x3 = surf->vertex3[0];
|
||||
z3 = surf->vertex3[2];
|
||||
if ((z2 - z) * (x3 - x2) - (x2 - x) * (z3 - z2) > 0) {
|
||||
continue;
|
||||
}
|
||||
if ((z3 - z) * (x1 - x3) - (x3 - x) * (z1 - z3) > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < groupCount; ++i)
|
||||
{
|
||||
uint32_t surfCount = loaded_surface_iter_group_size(i);
|
||||
for (int j = 0; j < surfCount; ++j)
|
||||
{
|
||||
f32 nx = surf->normal.x;
|
||||
f32 ny = surf->normal.y;
|
||||
f32 nz = surf->normal.z;
|
||||
f32 oo = surf->originOffset;
|
||||
f32 height;
|
||||
surf = loaded_surface_iter_get_at_index(i, j);
|
||||
|
||||
// If a wall, ignore it. Likely a remnant, should never occur.
|
||||
if (ny == 0.0f) {
|
||||
continue;
|
||||
}
|
||||
// libsm64: Weed out surfaces whose triangles are actually line segs. TODO do this at surface load time
|
||||
if (!surf->isValid) continue;
|
||||
|
||||
// Find the ceil height at the specific point.
|
||||
height = -(x * nx + nz * z + oo) / ny;
|
||||
// Do the check normally done in add_surface_to_cell
|
||||
if (surf->normal.y >= -0.01f) continue;
|
||||
|
||||
// Checks for ceiling interaction with a 78 unit buffer.
|
||||
//! (Exposed Ceilings) Because any point above a ceiling counts
|
||||
// as interacting with a ceiling, ceilings far below can cause
|
||||
// "invisible walls" that are really just exposed ceilings.
|
||||
if (y - (height - -78.0f) > 0.0f) {
|
||||
continue;
|
||||
}
|
||||
x1 = surf->vertex1[0];
|
||||
z1 = surf->vertex1[2];
|
||||
z2 = surf->vertex2[2];
|
||||
x2 = surf->vertex2[0];
|
||||
|
||||
if( height < *pheight )
|
||||
// Checking if point is in bounds of the triangle laterally.
|
||||
if ((z1 - z) * (x2 - x1) - (x1 - x) * (z2 - z1) > 0)
|
||||
{
|
||||
*pheight = height;
|
||||
ceil = surf;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Slight optimization by checking these later.
|
||||
x3 = surf->vertex3[0];
|
||||
z3 = surf->vertex3[2];
|
||||
if ((z2 - z) * (x3 - x2) - (x2 - x) * (z3 - z2) > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((z3 - z) * (x1 - x3) - (x3 - x) * (z1 - z3) > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
f32 nx = surf->normal.x;
|
||||
f32 ny = surf->normal.y;
|
||||
f32 nz = surf->normal.z;
|
||||
f32 oo = surf->originOffset;
|
||||
f32 height;
|
||||
|
||||
// If a wall, ignore it. Likely a remnant, should never occur.
|
||||
if (ny == 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the ceil height at the specific point.
|
||||
height = -(x * nx + nz * z + oo) / ny;
|
||||
|
||||
// Checks for ceiling interaction with a 78 unit buffer.
|
||||
//! (Exposed Ceilings) Because any point above a ceiling counts
|
||||
// as interacting with a ceiling, ceilings far below can cause
|
||||
// "invisible walls" that are really just exposed ceilings.
|
||||
if (y - (height - -78.0f) > 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (height < *pheight)
|
||||
{
|
||||
*pheight = height;
|
||||
ceil = surf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
}
|
||||
return ceil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate through the list of floors and find the first floor under a given point.
|
||||
*/
|
||||
static struct SM64SurfaceCollisionData *find_floor_from_list( f32 x, f32 y, f32 z, f32 *pheight) {
|
||||
static struct SM64SurfaceCollisionData *find_floor_from_list(f32 x, f32 y, f32 z, f32 *pheight)
|
||||
{
|
||||
register struct SM64SurfaceCollisionData *surf;
|
||||
register f32 x1, z1, x2, z2, x3, z3;
|
||||
f32 nx, ny, nz;
|
||||
f32 oo;
|
||||
f32 height;
|
||||
struct SM64SurfaceCollisionData *floor = NULL;
|
||||
struct SM64SurfaceCollisionData *floor = nullptr;
|
||||
|
||||
uint32_t groupCount = loaded_surface_iter_group_count();
|
||||
for( int i = 0; i < groupCount; ++i ) {
|
||||
uint32_t surfCount = loaded_surface_iter_group_size( i );
|
||||
for( int j = 0; j < surfCount; ++j ) {
|
||||
surf = loaded_surface_iter_get_at_index( i, j );
|
||||
|
||||
// libsm64: Weed out surfaces whose triangles are actually line segs. TODO do this at surface load time
|
||||
if( !surf->isValid ) continue;
|
||||
|
||||
// Do the check normally done in add_surface_to_cell
|
||||
if( surf->normal.y <= 0.01f ) continue;
|
||||
|
||||
x1 = surf->vertex1[0];
|
||||
z1 = surf->vertex1[2];
|
||||
x2 = surf->vertex2[0];
|
||||
z2 = surf->vertex2[2];
|
||||
|
||||
// Check that the point is within the triangle bounds.
|
||||
if ((z1 - z) * (x2 - x1) - (x1 - x) * (z2 - z1) < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// To slightly save on computation time, set this later.
|
||||
x3 = surf->vertex3[0];
|
||||
z3 = surf->vertex3[2];
|
||||
|
||||
if ((z2 - z) * (x3 - x2) - (x2 - x) * (z3 - z2) < 0) {
|
||||
continue;
|
||||
}
|
||||
if ((z3 - z) * (x1 - x3) - (x3 - x) * (z1 - z3) < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nx = surf->normal.x;
|
||||
ny = surf->normal.y;
|
||||
nz = surf->normal.z;
|
||||
oo = surf->originOffset;
|
||||
|
||||
// If a wall, ignore it. Likely a remnant, should never occur.
|
||||
if (ny == 0.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the height of the floor at a given location.
|
||||
height = -(x * nx + nz * z + oo) / ny;
|
||||
// Checks for floor interaction with a 78 unit buffer.
|
||||
if (y - (height + -78.0f) < 0.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( height > *pheight )
|
||||
for (int i = 0; i < groupCount; ++i)
|
||||
{
|
||||
uint32_t surfCount = loaded_surface_iter_group_size(i);
|
||||
for (int j = 0; j < surfCount; ++j)
|
||||
{
|
||||
*pheight = height;
|
||||
floor = surf;
|
||||
surf = loaded_surface_iter_get_at_index(i, j);
|
||||
|
||||
// libsm64: Weed out surfaces whose triangles are actually line segs. TODO do this at surface load time
|
||||
if (!surf->isValid) continue;
|
||||
|
||||
// Do the check normally done in add_surface_to_cell
|
||||
if (surf->normal.y <= 0.01f) continue;
|
||||
|
||||
x1 = surf->vertex1[0];
|
||||
z1 = surf->vertex1[2];
|
||||
x2 = surf->vertex2[0];
|
||||
z2 = surf->vertex2[2];
|
||||
|
||||
// Check that the point is within the triangle bounds.
|
||||
if ((z1 - z) * (x2 - x1) - (x1 - x) * (z2 - z1) < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// To slightly save on computation time, set this later.
|
||||
x3 = surf->vertex3[0];
|
||||
z3 = surf->vertex3[2];
|
||||
|
||||
if ((z2 - z) * (x3 - x2) - (x2 - x) * (z3 - z2) < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((z3 - z) * (x1 - x3) - (x3 - x) * (z1 - z3) < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
nx = surf->normal.x;
|
||||
ny = surf->normal.y;
|
||||
nz = surf->normal.z;
|
||||
oo = surf->originOffset;
|
||||
|
||||
// If a wall, ignore it. Likely a remnant, should never occur.
|
||||
if (ny == 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the height of the floor at a given location.
|
||||
height = -(x * nx + nz * z + oo) / ny;
|
||||
// Checks for floor interaction with a 78 unit buffer.
|
||||
if (y - (height + -78.0f) < 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (height > *pheight)
|
||||
{
|
||||
*pheight = height;
|
||||
floor = surf;
|
||||
}
|
||||
}
|
||||
}}
|
||||
}
|
||||
return floor;
|
||||
}
|
||||
|
||||
static s32 find_wall_collisions_from_list( struct SM64WallCollisionData *data) {
|
||||
static s32 find_wall_collisions_from_list(struct SM64WallCollisionData *data)
|
||||
{
|
||||
register struct SM64SurfaceCollisionData *surf;
|
||||
register f32 offset;
|
||||
register f32 radius = data->radius;
|
||||
@@ -163,129 +182,170 @@ static s32 find_wall_collisions_from_list( struct SM64WallCollisionData *data) {
|
||||
s32 numCols = 0;
|
||||
|
||||
// Max collision radius = 200
|
||||
if (radius > 200.0f) {
|
||||
if (radius > 200.0f)
|
||||
{
|
||||
radius = 200.0f;
|
||||
}
|
||||
|
||||
uint32_t groupCount = loaded_surface_iter_group_count();
|
||||
for( int i = 0; i < groupCount; ++i ) {
|
||||
uint32_t surfCount = loaded_surface_iter_group_size( i );
|
||||
for( int j = 0; j < surfCount; ++j ) {
|
||||
surf = loaded_surface_iter_get_at_index( i, j );
|
||||
for (int i = 0; i < groupCount; ++i)
|
||||
{
|
||||
uint32_t surfCount = loaded_surface_iter_group_size(i);
|
||||
for (int j = 0; j < surfCount; ++j)
|
||||
{
|
||||
surf = loaded_surface_iter_get_at_index(i, j);
|
||||
|
||||
// libsm64: Weed out surfaces whose triangles are actually line segs. TODO do this at surface load time
|
||||
if( !surf->isValid ) continue;
|
||||
// libsm64: Weed out surfaces whose triangles are actually line segs. TODO do this at surface load time
|
||||
if (!surf->isValid) continue;
|
||||
|
||||
// Do the check normally done in add_surface_to_cell
|
||||
if( surf->normal.y < -0.01f || surf->normal.y > 0.01f ) continue;
|
||||
// Do the check normally done in add_surface_to_cell
|
||||
if (surf->normal.y < -0.01f || surf->normal.y > 0.01f) continue;
|
||||
|
||||
if( surf->normal.x < -0.707f || surf->normal.x > 0.707f ) {
|
||||
surf->flags |= SURFACE_FLAG_X_PROJECTION;
|
||||
}
|
||||
if (surf->normal.x < -0.707f || surf->normal.x > 0.707f)
|
||||
{
|
||||
surf->flags |= SURFACE_FLAG_X_PROJECTION;
|
||||
}
|
||||
|
||||
// Exclude a large number of walls immediately to optimize.
|
||||
if (y < surf->lowerY || y > surf->upperY) {
|
||||
continue;
|
||||
}
|
||||
// Exclude a large number of walls immediately to optimize.
|
||||
if (y < surf->lowerY || y > surf->upperY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
offset = surf->normal.x * x + surf->normal.y * y + surf->normal.z * z + surf->originOffset;
|
||||
offset = surf->normal.x * x + surf->normal.y * y + surf->normal.z * z + surf->originOffset;
|
||||
|
||||
if (offset < -radius || offset > radius) {
|
||||
continue;
|
||||
}
|
||||
if (offset < -radius || offset > radius)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
px = x;
|
||||
pz = z;
|
||||
px = x;
|
||||
pz = z;
|
||||
|
||||
//! (Quantum Tunneling) Due to issues with the vertices walls choose and
|
||||
// the fact they are floating point, certain floating point positions
|
||||
// along the seam of two walls may collide with neither wall or both walls.
|
||||
if (surf->flags & SURFACE_FLAG_X_PROJECTION) {
|
||||
w1 = -surf->vertex1[2]; w2 = -surf->vertex2[2]; w3 = -surf->vertex3[2];
|
||||
y1 = surf->vertex1[1]; y2 = surf->vertex2[1]; y3 = surf->vertex3[1];
|
||||
//! (Quantum Tunneling) Due to issues with the vertices walls choose and
|
||||
// the fact they are floating point, certain floating point positions
|
||||
// along the seam of two walls may collide with neither wall or both walls.
|
||||
if (surf->flags & SURFACE_FLAG_X_PROJECTION)
|
||||
{
|
||||
w1 = -surf->vertex1[2];
|
||||
w2 = -surf->vertex2[2];
|
||||
w3 = -surf->vertex3[2];
|
||||
y1 = surf->vertex1[1];
|
||||
y2 = surf->vertex2[1];
|
||||
y3 = surf->vertex3[1];
|
||||
|
||||
if (surf->normal.x > 0.0f) {
|
||||
if ((y1 - y) * (w2 - w1) - (w1 - -pz) * (y2 - y1) > 0.0f) {
|
||||
continue;
|
||||
if (surf->normal.x > 0.0f)
|
||||
{
|
||||
if ((y1 - y) * (w2 - w1) - (w1 - -pz) * (y2 - y1) > 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((y2 - y) * (w3 - w2) - (w2 - -pz) * (y3 - y2) > 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((y3 - y) * (w1 - w3) - (w3 - -pz) * (y1 - y3) > 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((y2 - y) * (w3 - w2) - (w2 - -pz) * (y3 - y2) > 0.0f) {
|
||||
continue;
|
||||
}
|
||||
if ((y3 - y) * (w1 - w3) - (w3 - -pz) * (y1 - y3) > 0.0f) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ((y1 - y) * (w2 - w1) - (w1 - -pz) * (y2 - y1) < 0.0f) {
|
||||
continue;
|
||||
}
|
||||
if ((y2 - y) * (w3 - w2) - (w2 - -pz) * (y3 - y2) < 0.0f) {
|
||||
continue;
|
||||
}
|
||||
if ((y3 - y) * (w1 - w3) - (w3 - -pz) * (y1 - y3) < 0.0f) {
|
||||
continue;
|
||||
else
|
||||
{
|
||||
if ((y1 - y) * (w2 - w1) - (w1 - -pz) * (y2 - y1) < 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((y2 - y) * (w3 - w2) - (w2 - -pz) * (y3 - y2) < 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((y3 - y) * (w1 - w3) - (w3 - -pz) * (y1 - y3) < 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
w1 = surf->vertex1[0]; w2 = surf->vertex2[0]; w3 = surf->vertex3[0];
|
||||
y1 = surf->vertex1[1]; y2 = surf->vertex2[1]; y3 = surf->vertex3[1];
|
||||
else
|
||||
{
|
||||
w1 = surf->vertex1[0];
|
||||
w2 = surf->vertex2[0];
|
||||
w3 = surf->vertex3[0];
|
||||
y1 = surf->vertex1[1];
|
||||
y2 = surf->vertex2[1];
|
||||
y3 = surf->vertex3[1];
|
||||
|
||||
if (surf->normal.z > 0.0f) {
|
||||
if ((y1 - y) * (w2 - w1) - (w1 - px) * (y2 - y1) > 0.0f) {
|
||||
continue;
|
||||
if (surf->normal.z > 0.0f)
|
||||
{
|
||||
if ((y1 - y) * (w2 - w1) - (w1 - px) * (y2 - y1) > 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((y2 - y) * (w3 - w2) - (w2 - px) * (y3 - y2) > 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((y3 - y) * (w1 - w3) - (w3 - px) * (y1 - y3) > 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((y2 - y) * (w3 - w2) - (w2 - px) * (y3 - y2) > 0.0f) {
|
||||
continue;
|
||||
}
|
||||
if ((y3 - y) * (w1 - w3) - (w3 - px) * (y1 - y3) > 0.0f) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ((y1 - y) * (w2 - w1) - (w1 - px) * (y2 - y1) < 0.0f) {
|
||||
continue;
|
||||
}
|
||||
if ((y2 - y) * (w3 - w2) - (w2 - px) * (y3 - y2) < 0.0f) {
|
||||
continue;
|
||||
}
|
||||
if ((y3 - y) * (w1 - w3) - (w3 - px) * (y1 - y3) < 0.0f) {
|
||||
continue;
|
||||
else
|
||||
{
|
||||
if ((y1 - y) * (w2 - w1) - (w1 - px) * (y2 - y1) < 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((y2 - y) * (w3 - w2) - (w2 - px) * (y3 - y2) < 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((y3 - y) * (w1 - w3) - (w3 - px) * (y1 - y3) < 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore camera only surfaces.
|
||||
if (surf->type == SURFACE_CAMERA_BOUNDARY) {
|
||||
continue;
|
||||
}
|
||||
// Ignore camera only surfaces.
|
||||
if (surf->type == SURFACE_CAMERA_BOUNDARY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// If an object can pass through a vanish cap wall, pass through.
|
||||
if (surf->type == SURFACE_VANISH_CAP_WALLS) {
|
||||
// If an object can pass through a vanish cap wall, pass through.
|
||||
if (gCurrentObject != NULL
|
||||
&& (gCurrentObject->activeFlags & ACTIVE_FLAG_MOVE_THROUGH_GRATE)) {
|
||||
continue;
|
||||
if (surf->type == SURFACE_VANISH_CAP_WALLS)
|
||||
{
|
||||
// If an object can pass through a vanish cap wall, pass through.
|
||||
if (gCurrentObject != nullptr
|
||||
&& (gCurrentObject->activeFlags & ACTIVE_FLAG_MOVE_THROUGH_GRATE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// If Mario has a vanish cap, pass through the vanish cap wall.
|
||||
if (gCurrentObject != nullptr && gCurrentObject == gMarioObject
|
||||
&& (gMarioState->flags & MARIO_VANISH_CAP))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If Mario has a vanish cap, pass through the vanish cap wall.
|
||||
if (gCurrentObject != NULL && gCurrentObject == gMarioObject
|
||||
&& (gMarioState->flags & MARIO_VANISH_CAP)) {
|
||||
continue;
|
||||
//! (Wall Overlaps) Because this doesn't update the x and z local variables,
|
||||
// multiple walls can push mario more than is required.
|
||||
data->x += surf->normal.x * (radius - offset);
|
||||
data->z += surf->normal.z * (radius - offset);
|
||||
|
||||
//! (Unreferenced Walls) Since this only returns the first four walls,
|
||||
// this can lead to wall interaction being missed. Typically unreferenced walls
|
||||
// come from only using one wall, however.
|
||||
if (data->numWalls < 4)
|
||||
{
|
||||
data->walls[data->numWalls++] = surf;
|
||||
}
|
||||
|
||||
numCols++;
|
||||
}
|
||||
|
||||
//! (Wall Overlaps) Because this doesn't update the x and z local variables,
|
||||
// multiple walls can push mario more than is required.
|
||||
data->x += surf->normal.x * (radius - offset);
|
||||
data->z += surf->normal.z * (radius - offset);
|
||||
|
||||
//! (Unreferenced Walls) Since this only returns the first four walls,
|
||||
// this can lead to wall interaction being missed. Typically unreferenced walls
|
||||
// come from only using one wall, however.
|
||||
if (data->numWalls < 4) {
|
||||
data->walls[data->numWalls++] = surf;
|
||||
}
|
||||
|
||||
numCols++;
|
||||
}}
|
||||
}
|
||||
|
||||
return numCols;
|
||||
}
|
||||
@@ -335,8 +395,8 @@ s32 find_wall_collisions(struct SM64WallCollisionData *colData)
|
||||
f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct SM64SurfaceCollisionData **pceil)
|
||||
{
|
||||
f32 height = CELL_HEIGHT_LIMIT;
|
||||
*pceil = find_ceil_from_list( posX, posY, posZ, &height );
|
||||
return height;
|
||||
*pceil = find_ceil_from_list(posX, posY, posZ, &height);
|
||||
return height;
|
||||
}
|
||||
|
||||
struct SM64FloorCollisionData sFloorGeo;
|
||||
@@ -346,9 +406,10 @@ f32 find_floor_height_and_data(f32 xPos, f32 yPos, f32 zPos, struct SM64FloorCol
|
||||
struct SM64SurfaceCollisionData *floor;
|
||||
f32 floorHeight = find_floor(xPos, yPos, zPos, &floor);
|
||||
|
||||
*floorGeo = NULL;
|
||||
*floorGeo = nullptr;
|
||||
|
||||
if (floor != NULL) {
|
||||
if (floor != nullptr)
|
||||
{
|
||||
sFloorGeo.normalX = floor->normal.x;
|
||||
sFloorGeo.normalY = floor->normal.y;
|
||||
sFloorGeo.normalZ = floor->normal.z;
|
||||
@@ -362,23 +423,23 @@ f32 find_floor_height_and_data(f32 xPos, f32 yPos, f32 zPos, struct SM64FloorCol
|
||||
f32 find_floor_height(f32 x, f32 y, f32 z)
|
||||
{
|
||||
f32 height = FLOOR_LOWER_LIMIT;
|
||||
find_floor_from_list( x, y, z, &height );
|
||||
return height;
|
||||
find_floor_from_list(x, y, z, &height);
|
||||
return height;
|
||||
}
|
||||
|
||||
f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct SM64SurfaceCollisionData **pfloor)
|
||||
{
|
||||
f32 height = FLOOR_LOWER_LIMIT;
|
||||
*pfloor = find_floor_from_list( xPos, yPos, zPos, &height );
|
||||
return height;
|
||||
*pfloor = find_floor_from_list(xPos, yPos, zPos, &height);
|
||||
return height;
|
||||
}
|
||||
|
||||
f32 find_water_level(f32 x, f32 z)
|
||||
{
|
||||
return -10000.0f;
|
||||
return -10000.0f;
|
||||
}
|
||||
|
||||
f32 find_poison_gas_level(f32 x, f32 z)
|
||||
{
|
||||
return -10000.0f;
|
||||
return -10000.0f;
|
||||
}
|
||||
|
||||
@@ -7,18 +7,25 @@
|
||||
#include "../include/types.h"
|
||||
|
||||
#define LEVEL_BOUNDARY_MAX 0x2000
|
||||
#define CELL_SIZE 0x400
|
||||
#define CELL_SIZE 0x400
|
||||
|
||||
#define CELL_HEIGHT_LIMIT 100000.f
|
||||
#define FLOOR_LOWER_LIMIT -110000.f
|
||||
|
||||
s32 f32_find_wall_collision(f32 *xPtr, f32 *yPtr, f32 *zPtr, f32 offsetY, f32 radius);
|
||||
|
||||
s32 find_wall_collisions(struct SM64WallCollisionData *colData);
|
||||
|
||||
f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct SM64SurfaceCollisionData **pceil);
|
||||
|
||||
f32 find_floor_height_and_data(f32 xPos, f32 yPos, f32 zPos, struct SM64FloorCollisionData **floorGeo);
|
||||
|
||||
f32 find_floor_height(f32 x, f32 y, f32 z);
|
||||
|
||||
f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct SM64SurfaceCollisionData **pfloor);
|
||||
|
||||
f32 find_water_level(f32 x, f32 z);
|
||||
|
||||
f32 find_poison_gas_level(f32 x, f32 z);
|
||||
|
||||
#endif // SURFACE_COLLISION_H
|
||||
|
||||
Reference in New Issue
Block a user