mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-20 10:37:37 -04:00
work on frustum culling
This commit is contained in:
parent
2eda4a3710
commit
39a9bc4afd
|
@ -14,6 +14,11 @@ struct BoundingSphere {
|
|||
short radius;
|
||||
};
|
||||
|
||||
struct BoundingBoxs16 {
|
||||
short minX, minY, minZ;
|
||||
short maxX, maxY, maxZ;
|
||||
};
|
||||
|
||||
struct LevelDefinition {
|
||||
struct CollisionObject* collisionQuads;
|
||||
struct StaticContentElement *staticContent;
|
||||
|
|
|
@ -29,7 +29,14 @@ void cameraBuildProjectionMatrix(struct Camera* camera, float matrix[4][4], u16*
|
|||
guPerspectiveF(matrix, perspectiveNormalize, camera->fov, aspectRatio, camera->nearPlane * planeScalar, camera->farPlane * planeScalar, 1.0f);
|
||||
}
|
||||
|
||||
Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState, float aspectRatio, u16* perspNorm, Vp* viewport) {
|
||||
void cameraExtractClippingPlane(float viewPersp[4][4], struct Plane* output, int axis, float direction) {
|
||||
output->normal.x = viewPersp[0][axis] * direction + viewPersp[0][3];
|
||||
output->normal.y = viewPersp[1][axis] * direction + viewPersp[1][3];
|
||||
output->normal.z = viewPersp[2][axis] * direction + viewPersp[2][3];
|
||||
output->d = viewPersp[3][axis] * direction + viewPersp[3][3];
|
||||
}
|
||||
|
||||
Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState, float aspectRatio, u16* perspNorm, Vp* viewport, struct FrustrumCullingInformation* clippingInfo) {
|
||||
Mtx* viewProjMatrix = renderStateRequestMatrices(renderState, 2);
|
||||
|
||||
if (!viewProjMatrix) {
|
||||
|
@ -58,6 +65,14 @@ Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState,
|
|||
guMtxCatF(view, persp, combined);
|
||||
guMtxF2L(combined, &viewProjMatrix[1]);
|
||||
|
||||
if (clippingInfo) {
|
||||
cameraExtractClippingPlane(combined, &clippingInfo->clippingPlanes[0], 0, 1.0f);
|
||||
cameraExtractClippingPlane(combined, &clippingInfo->clippingPlanes[1], 0, -1.0f);
|
||||
cameraExtractClippingPlane(combined, &clippingInfo->clippingPlanes[2], 1, 1.0f);
|
||||
cameraExtractClippingPlane(combined, &clippingInfo->clippingPlanes[3], 1, -1.0f);
|
||||
cameraExtractClippingPlane(combined, &clippingInfo->clippingPlanes[4], 2, 1.0f);
|
||||
}
|
||||
|
||||
gSPMatrix(renderState->dl++, osVirtualToPhysical(&viewProjMatrix[1]), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
gSPPerspNormalize(renderState->dl++, perspectiveNormalize);
|
||||
|
||||
|
|
|
@ -6,8 +6,15 @@
|
|||
#include "math/quaternion.h"
|
||||
#include "math/vector3.h"
|
||||
#include "math/transform.h"
|
||||
#include "math/plane.h"
|
||||
#include "graphics/renderstate.h"
|
||||
|
||||
#define CLIPPING_PLANE_COUNT 5
|
||||
|
||||
struct FrustrumCullingInformation {
|
||||
struct Plane clippingPlanes[CLIPPING_PLANE_COUNT];
|
||||
};
|
||||
|
||||
struct Camera {
|
||||
struct Transform transform;
|
||||
float nearPlane;
|
||||
|
@ -18,6 +25,6 @@ struct Camera {
|
|||
void cameraInit(struct Camera* camera, float fov, float near, float far);
|
||||
void cameraBuildViewMatrix(struct Camera* camera, float matrix[4][4]);
|
||||
void cameraBuildProjectionMatrix(struct Camera* camera, float matrix[4][4], u16* perspectiveNorm, float aspectRatio);
|
||||
Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState, float aspectRatio, u16* perspNorm, Vp* viewport);
|
||||
Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState, float aspectRatio, u16* perspNorm, Vp* viewport, struct FrustrumCullingInformation* clippingInfo);
|
||||
|
||||
#endif
|
|
@ -35,7 +35,7 @@ struct Quaternion gVerticalFlip = {0.0f, 1.0f, 0.0f, 0.0f};
|
|||
void renderPropsInit(struct RenderProps* props, struct Camera* camera, float aspectRatio, struct RenderState* renderState) {
|
||||
props->camera = *camera;
|
||||
props->aspectRatio = aspectRatio;
|
||||
props->perspectiveMatrix = cameraSetupMatrices(camera, renderState, aspectRatio, &props->perspectiveCorrect, &fullscreenViewport);
|
||||
props->perspectiveMatrix = cameraSetupMatrices(camera, renderState, aspectRatio, &props->perspectiveCorrect, &fullscreenViewport, &props->cullingInfo);
|
||||
props->viewport = &fullscreenViewport;
|
||||
props->currentDepth = STARTING_RENDER_DEPTH;
|
||||
|
||||
|
@ -85,14 +85,14 @@ void renderPropsNext(struct RenderProps* current, struct RenderProps* next, stru
|
|||
transformConcat(&portalCombined, ¤t->camera.transform, &next->camera.transform);
|
||||
|
||||
// render any objects halfway through portals
|
||||
cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, current->viewport);
|
||||
cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, current->viewport, NULL);
|
||||
dynamicSceneRender(renderState, 1);
|
||||
|
||||
Vp* viewport = renderPropsBuildViewport(next, renderState);
|
||||
|
||||
next->viewport = viewport;
|
||||
|
||||
next->perspectiveMatrix = cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, viewport);
|
||||
next->perspectiveMatrix = cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, viewport, &next->cullingInfo);
|
||||
|
||||
next->currentDepth = current->currentDepth - 1;
|
||||
|
||||
|
|
|
@ -66,8 +66,10 @@ void sceneInit(struct Scene* scene) {
|
|||
void sceneRenderWithProperties(void* data, struct RenderProps* properties, struct RenderState* renderState) {
|
||||
struct Scene* scene = (struct Scene*)data;
|
||||
|
||||
portalRender(&scene->portals[0], &scene->portals[1], properties, sceneRenderWithProperties, data, renderState);
|
||||
portalRender(&scene->portals[1], &scene->portals[0], properties, sceneRenderWithProperties, data, renderState);
|
||||
int closerPortal = vector3DistSqrd(&properties->camera.transform.position, &scene->portals[0].transform.position) > vector3DistSqrd(&properties->camera.transform.position, &scene->portals[1].transform.position) ? 0 : 1;
|
||||
|
||||
portalRender(&scene->portals[closerPortal], &scene->portals[1 - closerPortal], properties, sceneRenderWithProperties, data, renderState);
|
||||
portalRender(&scene->portals[1 - closerPortal], &scene->portals[closerPortal], properties, sceneRenderWithProperties, data, renderState);
|
||||
|
||||
gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);
|
||||
|
||||
|
|
|
@ -1,18 +1,31 @@
|
|||
#include "static_scene.h"
|
||||
|
||||
#include "defs.h"
|
||||
#include "../math/box3d.h"
|
||||
|
||||
int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct BoundingSphere* boundingSphere) {
|
||||
struct Vector3 spherePos;
|
||||
int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct BoundingBoxs16* boundingSphere) {
|
||||
struct Box3D boxAsFloat;
|
||||
|
||||
spherePos.x = boundingSphere->x * (1.0f / SCENE_SCALE);
|
||||
spherePos.y = boundingSphere->y * (1.0f / SCENE_SCALE);
|
||||
spherePos.z = boundingSphere->z * (1.0f / SCENE_SCALE);
|
||||
boxAsFloat.min.x = boundingSphere->minX * (1.0f / SCENE_SCALE);
|
||||
boxAsFloat.min.y = boundingSphere->minY * (1.0f / SCENE_SCALE);
|
||||
boxAsFloat.min.z = boundingSphere->minZ * (1.0f / SCENE_SCALE);
|
||||
|
||||
vector3Sub(&spherePos, &frustrum->cameraPosition, &spherePos);
|
||||
struct Vector3 crossDirection;
|
||||
vector3Cross(&frustrum->frustrumDirection, &spherePos, &crossDirection);
|
||||
boxAsFloat.max.x = boundingSphere->maxX * (1.0f / SCENE_SCALE);
|
||||
boxAsFloat.max.y = boundingSphere->maxY * (1.0f / SCENE_SCALE);
|
||||
boxAsFloat.max.z = boundingSphere->maxZ * (1.0f / SCENE_SCALE);
|
||||
|
||||
float distance = sqrtf(vector3MagSqrd(&crossDirection)) * frustrum->cosFrustumAngle - vector3Dot(&frustrum->frustrumDirection, &crossDirection) * frustrum->sinFrustrumAngle;
|
||||
return distance > boundingSphere->radius * (1.0f / SCENE_SCALE);
|
||||
for (int i = 0; i < CLIPPING_PLANE_COUNT; ++i) {
|
||||
struct Vector3 closestPoint;
|
||||
|
||||
closestPoint.x = frustrum->clippingPlanes[i].normal.x > 0.0f ? boxAsFloat.min.x : boxAsFloat.max.x;
|
||||
closestPoint.y = frustrum->clippingPlanes[i].normal.y > 0.0f ? boxAsFloat.min.y : boxAsFloat.max.y;
|
||||
closestPoint.z = frustrum->clippingPlanes[i].normal.z > 0.0f ? boxAsFloat.min.z : boxAsFloat.max.z;
|
||||
|
||||
if (planePointDistance(&frustrum->clippingPlanes[i], &closestPoint) < 0.0f) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
#include "../math/transform.h"
|
||||
#include "../math/box3d.h"
|
||||
#include "../levels/level_definition.h"
|
||||
#include "../scene/camera.h"
|
||||
|
||||
enum StaticSceneEntryFlags {
|
||||
StaticSceneEntryFlagsHidden,
|
||||
|
@ -31,16 +32,8 @@ struct StaticScene {
|
|||
u16 gridHeight;
|
||||
};
|
||||
|
||||
struct FrustrumCullingInformation {
|
||||
struct Plane nearPlane;
|
||||
struct Vector3 frustrumDirection;
|
||||
struct Vector3 cameraPosition;
|
||||
float cosFrustumAngle;
|
||||
float sinFrustrumAngle;
|
||||
};
|
||||
|
||||
void staticSceneInit();
|
||||
|
||||
int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct BoundingSphere* boundingSphere);
|
||||
int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct BoundingBoxs16* boundingBox);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue