match J3DUClipper.cpp

This commit is contained in:
SwareJonge 2024-05-30 15:12:25 +02:00
parent aca1942d67
commit fa5fb0c859
9 changed files with 303 additions and 43 deletions

View File

@ -6,6 +6,13 @@ src/kartLocale.cpp:
.sbss: [0x804156e0, 0x804156f0]
.sdata2: [0x804171c0, 0x804171e8]
# having alignment issues, not bothered to fix that(so implement JPABaseShape.cpp)
#libs/JSystem/J3DU/J3DUClipper.cpp:
#.text: [0x80007610, 0x800078fc]
#.rodata: [0x80360990, 0x80360a38]
#.data: [0x80387b88, 0x80387ba0]
#.sdata2: [0x80417200, 0x80417210]
#libs/JSystem/JParticle/JPAFieldBlock.cpp:
#.text: [0x8000e450, 0x80010760]
#.rodata: [0x80360c58, 0x80360ca0]

View File

@ -12,6 +12,12 @@ src/kartLocale.cpp:
#src/buildTimeDat.s:
#.BINARY: [0x8032cbc0, 0x8032cbe0]
libs/JSystem/J3DU/J3DUClipper.cpp:
.text: [0x8000a24c, 0x8000a540]
.rodata: [0x8032cd28, 0x8032cdd0]
.data: [0x80347ab8, 0x80347ac8]
.sdata2: [0x803d6450, 0x803d6460]
libs/JSystem/JKernel/JKRAram.cpp:
.text: [0x8000a540, 0x8000b3b0]
.ctors: [0x802d84ac, 0x802d84b0]

View File

@ -0,0 +1,8 @@
#ifndef JSYSTEM_J3DMATH_H
#define JSYSTEM_J3DMATH_H
#include <dolphin/mtx.h>
inline void J3DVecCrossProduct(Vec *a, Vec *b, Vec *c) { PSVECCrossProduct(a, b, c); }
#endif

View File

@ -1,30 +1,39 @@
#ifndef _JSYSTEM_J3D_J3DUCLIPPER_H
#define _JSYSTEM_J3D_J3DUCLIPPER_H
#include <dolphin/mtx.h>
#include "JSystem/J3D/J3DMath.h"
class J3DModel;
class JUTDbPrint;
struct J3DUClipper
{
J3DUClipper(f32 fovY, f32 aspect, f32 near, f32 far);
J3DUClipper() { init(); }
// NB: vtable is stripped
virtual ~J3DUClipper(); // _08
virtual ~J3DUClipper() {} // _08
void init();
void calcViewFrustum();
int clip(const Mtx, Vec, f32) const;
int clip(const Mtx, Vec *, Vec *) const;
int clip(const Mtx transMtx, Vec point, f32 buffer) const;
int clip(const Mtx transMtx, Vec *minCorner, Vec *maxCorner) const;
void setFovy(f32 fovy) { mFovY = fovy; }
void setAspect(f32 aspect) { mAspect = aspect; }
void setNear(f32 near) { mNear = near; }
void setFar(f32 far) { mFar = far; }
// Inline/Unused
void report() const;
void debugPrint(JUTDbPrint *) const;
void clipBySphere(J3DModel *, f32) const;
void clipByBox(J3DModel *) const;
// _00 = VTBL
Vec _04; // _04
Vec _10; // _10
Vec _1C; // _1C
Vec _28; // _28
Vec mLeftPlane; // _04
Vec mRightPlane; // _10
Vec mTopPlane; // _1C
Vec mBottomPlane; // _28
u8 _34[0x18]; // _34, unknown
f32 mFovY; // _4C
f32 mAspect; // _50

View File

@ -115,6 +115,32 @@ class JASMemChunkPool
};
public:
void free(void *ptr)
{
T::Lock lock(&mMutex); // takes *this
MemoryChunk *chunk = mChunk;
MemoryChunk *prevChunk = NULL;
while (chunk != NULL)
{
if (chunk->checkArea(ptr))
{
chunk->free(ptr);
if ((chunk != mChunk && chunk->isEmpty()) != 0)
{
MemoryChunk *nextChunk = chunk->getNextChunk();
delete chunk;
prevChunk->setNextChunk(nextChunk);
}
return;
}
prevChunk = chunk;
chunk = chunk->getNextChunk();
}
#line 362
JUT_ASSERT_MSG(false, "Cannnot free for JASMemChunkPool");
}
bool createNewChunk()
{
if ((mChunk != NULL && mChunk->isEmpty()) != 0)
@ -160,32 +186,6 @@ public:
return mChunk->alloc(size);
}
void free(void *ptr)
{
T::Lock lock(&mMutex); // takes *this
MemoryChunk *chunk = mChunk;
MemoryChunk *prevChunk = NULL;
while (chunk != NULL)
{
if (chunk->checkArea(ptr))
{
chunk->free(ptr);
if ((chunk != mChunk && chunk->isEmpty()) != 0)
{
MemoryChunk *nextChunk = chunk->getNextChunk();
delete chunk;
prevChunk->setNextChunk(nextChunk);
}
return;
}
prevChunk = chunk;
chunk = chunk->getNextChunk();
}
#line 362
JUT_ASSERT_MSG(false, "Cannnot free for JASMemChunkPool");
}
private:
OSMutex mMutex; // 00
MemoryChunk *mChunk; // 18

View File

@ -0,0 +1,223 @@
#include <stdio.h>
#include <std/math.h>
#include "JSystem/J3DU/J3DUClipper.h"
#include "JSystem/JUtility/JUTDbPrint.h"
J3DUClipper::J3DUClipper(f32 fovY, f32 aspect, f32 near, f32 far)
{
// UNUSED
mFovY = fovY;
mAspect = aspect;
mNear = near;
mFar = far;
}
void J3DUClipper::init()
{
mNear = 1.0f;
mFar = 100000.0f;
}
// NOTE: needs to be just tanf
void J3DUClipper::calcViewFrustum()
{
// Calculate dimensions of the near plane
f32 nearHeight = mNear * std::tanf(MTXDegToRad(0.5f * mFovY)); // Half height of the near plane
f32 nearWidth = mAspect * nearHeight; // Half width of the near plane
Vec unused = {0, 0, 0};
// Define the 4 corners of the near plane
Vec bottomLeft = {-nearWidth, -nearHeight, -mNear};
Vec topLeft = {-nearWidth, nearHeight, -mNear};
Vec topRight = {nearWidth, nearHeight, -mNear};
Vec bottomRight = {nearWidth, -nearHeight, -mNear};
// Calculate the frustum plane normals using cross products
J3DVecCrossProduct(&topLeft, &bottomLeft, &mLeftPlane);
J3DVecCrossProduct(&topRight, &topLeft, &mRightPlane);
J3DVecCrossProduct(&bottomRight, &topRight, &mTopPlane);
J3DVecCrossProduct(&bottomLeft, &bottomRight, &mBottomPlane);
// Normalize the plane normals
PSVECNormalize(&mLeftPlane, &mLeftPlane);
PSVECNormalize(&mRightPlane, &mRightPlane);
PSVECNormalize(&mTopPlane, &mTopPlane);
PSVECNormalize(&mBottomPlane, &mBottomPlane);
}
int J3DUClipper::clip(const Mtx transMtx, Vec point, f32 buffer) const
{
Vec transformedPoint;
PSMTXMultVec(transMtx, &point, &transformedPoint);
// Check against near and far planes
if (-transformedPoint.z < mNear - buffer)
{
return 1;
}
if (-transformedPoint.z > mFar + buffer)
{
return 1;
}
// Check against the four side planes of the frustum
if (transformedPoint.x * mLeftPlane.x + transformedPoint.y * mLeftPlane.y + transformedPoint.z * mLeftPlane.z > buffer)
{
return 1;
}
if (transformedPoint.x * mRightPlane.x + transformedPoint.y * mRightPlane.y + transformedPoint.z * mRightPlane.z > buffer)
{
return 1;
}
if (transformedPoint.x * mTopPlane.x + transformedPoint.y * mTopPlane.y + transformedPoint.z * mTopPlane.z > buffer)
{
return 1;
}
if (transformedPoint.x * mBottomPlane.x + transformedPoint.y * mBottomPlane.y + transformedPoint.z * mBottomPlane.z > buffer)
{
return 1;
}
return 0;
}
int J3DUClipper::clip(const Mtx transMtx, Vec *minCorner, Vec *maxCorner) const
{
// Array to count the number of vertices outside each frustum plane
int outsideCount[6];
for (int i = 0; i < 6; i++)
{
outsideCount[i] = 0;
}
// Array to store the 8 vertices of the bounding box
Vec vertices[8];
vertices[0].x = maxCorner->x;
vertices[0].y = maxCorner->y;
vertices[0].z = minCorner->z;
vertices[1].x = maxCorner->x;
vertices[1].y = maxCorner->y;
vertices[1].z = maxCorner->z;
vertices[2].x = minCorner->x;
vertices[2].y = maxCorner->y;
vertices[2].z = maxCorner->z;
vertices[3].x = minCorner->x;
vertices[3].y = maxCorner->y;
vertices[3].z = minCorner->z;
vertices[4].x = maxCorner->x;
vertices[4].y = minCorner->y;
vertices[4].z = minCorner->z;
vertices[5].x = maxCorner->x;
vertices[5].y = minCorner->y;
vertices[5].z = maxCorner->z;
vertices[6].x = minCorner->x;
vertices[6].y = minCorner->y;
vertices[6].z = maxCorner->z;
vertices[7].x = minCorner->x;
vertices[7].y = minCorner->y;
vertices[7].z = minCorner->z;
// Check each vertex against the frustum planes
for (u32 i = 0; i < 8; i++)
{
Vec transformedVertex;
PSMTXMultVec(transMtx, &vertices[i], &transformedVertex);
int outOfFrustum = 0;
// Check against near plane
if (-transformedVertex.z < mNear)
{
outOfFrustum++;
outsideCount[4]++;
}
// Check against far plane
if (-transformedVertex.z > mFar)
{
outOfFrustum++;
outsideCount[5]++;
}
// Check against left plane
if (transformedVertex.x * mLeftPlane.x + transformedVertex.y * mLeftPlane.y + transformedVertex.z * mLeftPlane.z > 0.0f)
{
outOfFrustum++;
outsideCount[0]++;
}
// Check against right plane
if (transformedVertex.x * mRightPlane.x + transformedVertex.y * mRightPlane.y + transformedVertex.z * mRightPlane.z > 0.0f)
{
outOfFrustum++;
outsideCount[1]++;
}
// Check against top plane
if (transformedVertex.x * mTopPlane.x + transformedVertex.y * mTopPlane.y + transformedVertex.z * mTopPlane.z > 0.0f)
{
outOfFrustum++;
outsideCount[2]++;
}
// Check against bottom plane
if (transformedVertex.x * mBottomPlane.x + transformedVertex.y * mBottomPlane.y + transformedVertex.z * mBottomPlane.z > 0.0f)
{
outOfFrustum++;
outsideCount[3]++;
}
// If any vertex is inside all planes, the box is not completely outside
if (outOfFrustum == 0)
{
return 0;
}
}
// If all vertices are outside any single plane, the box is completely outside the frustum
if (outsideCount[0] == 8)
{
return 1;
}
if (outsideCount[2] == 8)
{
return 1;
}
if (outsideCount[1] == 8)
{
return 1;
}
if (outsideCount[3] == 8)
{
return 1;
}
if (outsideCount[4] == 8)
{
return 1;
}
if (outsideCount[5] == 8)
{
return 1;
}
return 0;
}
void J3DUClipper::report() const {}
void J3DUClipper::debugPrint(JUTDbPrint *print) const // not sure what print function is being used here
{
char buf[256];
sprintf(buf, " J3DUClipper::mFovy = %f", mFovY);
//print->getFont()->drawString(20, 20, buf, true);
sprintf(buf, " J3DUClipper::mAspect = %f", mAspect);
//print->getFont()->drawString(20, 20, buf, true);
sprintf(buf, " J3DUClipper::mNear = %f", mNear);
//print->getFont()->drawString(20, 20, buf, true);
sprintf(buf, " J3DUClipper::mFar = %f", mFar);
//print->getFont()->drawString(20, 20, buf, true);
}

View File

@ -72,7 +72,7 @@ inline void enter_(int x, int y, int duration, const char *txt, int n)
void JUTDbPrint::flush() { flush(0, 0, JUTVideo::sManager->getFbWidth(), JUTVideo::sManager->getEfbHeight()); }
void JUTDbPrint::flush(int p1, int p2, int p3, int p4)
void JUTDbPrint::flush(int left, int top, int right, int bottom)
{
// eyebrow raise emoji
JUTDbPrintList *pList = (JUTDbPrintList *)&mList;
@ -82,7 +82,7 @@ void JUTDbPrint::flush(int p1, int p2, int p3, int p4)
{
if (currList)
{
J2DOrthoGraph orthograph(p1, p2, p3, p4, -1.0f, 1.0f);
J2DOrthoGraph orthograph(left, top, right, bottom, -1.0f, 1.0f);
orthograph.setPort();
mFont->setGX();
mFont->setCharColor(mColor);

View File

@ -3,9 +3,16 @@
#include "types.h"
f64 nan(const char*);
#ifdef __cplusplus
extern "C"
{
#endif
f64 nan(const char *);
f32 cosf(f32 __x);
f32 sinf(f32 __x);
f32 tanf(f32 __x);
#ifdef __cplusplus
}
#endif
#endif