Automatically disable billboards when a DynOS model uses more than 6 vertices

This commit is contained in:
MysterD 2022-04-23 03:05:16 -07:00
parent f2ca0e18fc
commit 9e33ce39e6
7 changed files with 21 additions and 4 deletions

View file

@ -144,7 +144,7 @@ void DynOS_Actor_Override_All(void) {
struct Object *_Head = (struct Object *) &gObjectLists[list]; struct Object *_Head = (struct Object *) &gObjectLists[list];
for (struct Object *_Object = (struct Object *) _Head->header.next; _Object != _Head; _Object = (struct Object *) _Object->header.next) { for (struct Object *_Object = (struct Object *) _Head->header.next; _Object != _Head; _Object = (struct Object *) _Object->header.next) {
if (_Object->header.gfx.sharedChild != NULL && _Object->header.gfx.sharedChild->georef != NULL) { if (_Object->header.gfx.sharedChild != NULL && _Object->header.gfx.sharedChild->georef != NULL) {
GraphNode* georef =(GraphNode*)_Object->header.gfx.sharedChild->georef; GraphNode* georef = (GraphNode*)_Object->header.gfx.sharedChild->georef;
_Object->header.gfx.sharedChild = (GraphNode *) DynOS_Geo_GetGraphNode(georef, true); _Object->header.gfx.sharedChild = (GraphNode *) DynOS_Geo_GetGraphNode(georef, true);
} }
DynOS_Actor_Override((void**)&_Object->header.gfx.sharedChild); DynOS_Actor_Override((void**)&_Object->header.gfx.sharedChild);

View file

@ -1,4 +1,7 @@
#include "dynos.cpp.h" #include "dynos.cpp.h"
extern "C" {
#include "engine/graph_node.h"
}
static Array<PackData>& DynosPacks() { static Array<PackData>& DynosPacks() {
static Array<PackData> sDynosPacks; static Array<PackData> sDynosPacks;
@ -21,6 +24,15 @@ static void DynOS_Pack_ActivateActor(s32 aPackIndex, Pair<const char *, GfxData
.mPackIndex = aPackIndex, .mPackIndex = aPackIndex,
}; };
// Check if we should disable billboards
u32 vertices = 0;
for (auto& vtx : aGfxData->mVertices) {
vertices += vtx->mSize;
}
if (vertices > 6) {
actorGfx.mGraphNode->extraFlags |= GRAPH_EXTRA_FORCE_3D;
}
DynOS_Actor_Valid(georef, actorGfx); DynOS_Actor_Valid(georef, actorGfx);
} }

View file

@ -167,6 +167,7 @@ void *DynOS_Geo_GetGraphNode(const void *aGeoLayout, bool aKeepInMemory) {
if (aKeepInMemory) { if (aKeepInMemory) {
sLoadedGraphNodes.Add({ (void *) aGeoLayout, (void *) _Node }); sLoadedGraphNodes.Add({ (void *) aGeoLayout, (void *) _Node });
} }
free(_Pool); free(_Pool);
return _Node; return _Node;
} }

View file

@ -113,6 +113,7 @@ struct GraphNode
/*0x0C*/ struct GraphNode *parent; /*0x0C*/ struct GraphNode *parent;
/*0x10*/ struct GraphNode *children; /*0x10*/ struct GraphNode *children;
/*0x14*/ const void *georef; /*0x14*/ const void *georef;
/*????*/ u8 extraFlags;
}; };
struct AnimInfo struct AnimInfo

View file

@ -16,6 +16,9 @@
#define GRAPH_RENDER_CYLBOARD (1 << 6) #define GRAPH_RENDER_CYLBOARD (1 << 6)
#define GRAPH_RENDER_PLAYER (1 << 7) #define GRAPH_RENDER_PLAYER (1 << 7)
// Extra, custom, flags
#define GRAPH_EXTRA_FORCE_3D (1 << 0)
// Whether the node type has a function pointer of type GraphNodeFunc // Whether the node type has a function pointer of type GraphNodeFunc
#define GRAPH_NODE_TYPE_FUNCTIONAL 0x100 #define GRAPH_NODE_TYPE_FUNCTIONAL 0x100

View file

@ -225,7 +225,7 @@ void obj_orient_graph(struct Object *obj, f32 normalX, f32 normalY, f32 normalZ)
} }
// Passes on orienting billboard objects, i.e. coins, trees, etc. // Passes on orienting billboard objects, i.e. coins, trees, etc.
if (obj->header.gfx.node.flags & GRAPH_RENDER_BILLBOARD) { if ((obj->header.gfx.node.flags & GRAPH_RENDER_BILLBOARD) && !(obj->header.gfx.sharedChild && obj->header.gfx.sharedChild->extraFlags & GRAPH_EXTRA_FORCE_3D)) {
return; return;
} }

View file

@ -1113,7 +1113,7 @@ static void geo_process_object(struct Object *node) {
} }
mtxf_copy(node->header.gfx.prevThrowMatrix, *node->header.gfx.throwMatrix); mtxf_copy(node->header.gfx.prevThrowMatrix, *node->header.gfx.throwMatrix);
node->header.gfx.prevThrowMatrixTimestamp = gGlobalTimer; node->header.gfx.prevThrowMatrixTimestamp = gGlobalTimer;
} else if (node->header.gfx.node.flags & GRAPH_RENDER_CYLBOARD) { } else if ((node->header.gfx.node.flags & GRAPH_RENDER_CYLBOARD) && !(node->header.gfx.sharedChild && node->header.gfx.sharedChild->extraFlags & GRAPH_EXTRA_FORCE_3D)) {
Vec3f posInterpolated; Vec3f posInterpolated;
if (gGlobalTimer == node->header.gfx.prevTimestamp + 1 && if (gGlobalTimer == node->header.gfx.prevTimestamp + 1 &&
gGlobalTimer != node->header.gfx.skipInterpolationTimestamp && gGlobalTimer != node->header.gfx.skipInterpolationTimestamp &&
@ -1128,7 +1128,7 @@ static void geo_process_object(struct Object *node) {
node->header.gfx.pos, gCurGraphNodeCamera->roll); node->header.gfx.pos, gCurGraphNodeCamera->roll);
mtxf_cylboard(gMatStackInterpolated[gMatStackIndex + 1], gMatStackInterpolated[gMatStackIndex], mtxf_cylboard(gMatStackInterpolated[gMatStackIndex + 1], gMatStackInterpolated[gMatStackIndex],
posInterpolated, gCurGraphNodeCamera->roll); posInterpolated, gCurGraphNodeCamera->roll);
} else if (node->header.gfx.node.flags & GRAPH_RENDER_BILLBOARD) { } else if ((node->header.gfx.node.flags & GRAPH_RENDER_BILLBOARD) && !(node->header.gfx.sharedChild && node->header.gfx.sharedChild->extraFlags & GRAPH_EXTRA_FORCE_3D)) {
Vec3f posInterpolated; Vec3f posInterpolated;
if (gGlobalTimer == node->header.gfx.prevTimestamp + 1 && if (gGlobalTimer == node->header.gfx.prevTimestamp + 1 &&
gGlobalTimer != node->header.gfx.skipInterpolationTimestamp && gGlobalTimer != node->header.gfx.skipInterpolationTimestamp &&