mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-20 10:37:37 -04:00
Include dynamic objects in sorting and culling logic
This commit is contained in:
parent
6149bad68b
commit
6e00caff73
2
Makefile
2
Makefile
|
@ -144,7 +144,7 @@ MODEL_HEADERS = $(MODEL_LIST:%.blend=build/%.h)
|
||||||
MODEL_OBJECTS = $(MODEL_LIST:%.blend=build/%_geo.o)
|
MODEL_OBJECTS = $(MODEL_LIST:%.blend=build/%_geo.o)
|
||||||
|
|
||||||
build/assets/models/%.h build/assets/models/%_geo.c: build/assets/models/%.fbx assets/materials/objects.skm.yaml $(SKELATOOL64)
|
build/assets/models/%.h build/assets/models/%_geo.c: build/assets/models/%.fbx assets/materials/objects.skm.yaml $(SKELATOOL64)
|
||||||
$(SKELATOOL64) -s 2.56 -n $(<:build/assets/models/%.fbx=%) -m assets/materials/objects.skm.yaml -o $(<:%.fbx=%.h) $<
|
$(SKELATOOL64) -s 2.56 -n $(<:build/assets/models/%.fbx=%) $(shell cat $(<:build/assets/models/%.fbx=assets/models/%.flags)) -o $(<:%.fbx=%.h) $<
|
||||||
|
|
||||||
build/src/models/models.o: $(MODEL_HEADERS)
|
build/src/models/models.o: $(MODEL_HEADERS)
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,4 @@
|
||||||
materials:
|
materials:
|
||||||
cube:
|
|
||||||
gDPSetTile:
|
|
||||||
filename:
|
|
||||||
../images/cube.png
|
|
||||||
siz: G_IM_SIZ_16b
|
|
||||||
fmt: G_IM_FMT_RGBA
|
|
||||||
s:
|
|
||||||
mirror: true
|
|
||||||
t:
|
|
||||||
mirror: true
|
|
||||||
gSPGeometryMode:
|
|
||||||
set: [G_LIGHTING, G_SHADE]
|
|
||||||
gDPSetCombineMode:
|
|
||||||
color: ["SHADE", "0", "TEXEL0", "0"]
|
|
||||||
|
|
||||||
portal_gun_white:
|
portal_gun_white:
|
||||||
gDPSetPrimColor:
|
gDPSetPrimColor:
|
||||||
r: 255
|
r: 255
|
||||||
|
|
|
@ -66,12 +66,22 @@ materials:
|
||||||
gSPGeometryMode:
|
gSPGeometryMode:
|
||||||
clear: [G_CULL_BACK, G_CULL_FRONT]
|
clear: [G_CULL_BACK, G_CULL_FRONT]
|
||||||
|
|
||||||
gDPSetPrimColor:
|
|
||||||
r: 128
|
|
||||||
g: 0
|
|
||||||
b: 0
|
|
||||||
a: 128
|
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
tileSizeS: 0.03125
|
tileSizeS: 0.0625
|
||||||
tileSizeT: 2
|
tileSizeT: 2
|
||||||
|
|
||||||
|
|
||||||
|
cube:
|
||||||
|
gDPSetTile:
|
||||||
|
filename:
|
||||||
|
../images/cube.png
|
||||||
|
siz: G_IM_SIZ_16b
|
||||||
|
fmt: G_IM_FMT_RGBA
|
||||||
|
s:
|
||||||
|
mirror: true
|
||||||
|
t:
|
||||||
|
mirror: true
|
||||||
|
gSPGeometryMode:
|
||||||
|
set: [G_LIGHTING, G_SHADE]
|
||||||
|
gDPSetCombineMode:
|
||||||
|
color: ["SHADE", "0", "TEXEL0", "0"]
|
1
assets/models/cube/cube.flags
Normal file
1
assets/models/cube/cube.flags
Normal file
|
@ -0,0 +1 @@
|
||||||
|
-m assets/materials/static.skm.yaml -D cube
|
1
assets/models/portal_gun/v_portalgun.flags
Normal file
1
assets/models/portal_gun/v_portalgun.flags
Normal file
|
@ -0,0 +1 @@
|
||||||
|
-m assets/materials/objects.skm.yaml
|
|
@ -116,7 +116,7 @@ int main(int argc, char *argv[]) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto defaultMaterial = settings.mMaterials.find("default");
|
auto defaultMaterial = settings.mMaterials.find(args.mDefaultMaterial);
|
||||||
|
|
||||||
if (defaultMaterial != settings.mMaterials.end()) {
|
if (defaultMaterial != settings.mMaterials.end()) {
|
||||||
settings.mDefaultMaterialState = defaultMaterial->second->mState;
|
settings.mDefaultMaterialState = defaultMaterial->second->mState;
|
||||||
|
|
|
@ -20,6 +20,7 @@ bool parseCommandLineArguments(int argc, char *argv[], struct CommandLineArgumen
|
||||||
output.mIsLevel = false;
|
output.mIsLevel = false;
|
||||||
output.mIsLevelDef = false;
|
output.mIsLevelDef = false;
|
||||||
output.mEulerAngles = aiVector3D(0.0f, 0.0f, 0.0f);
|
output.mEulerAngles = aiVector3D(0.0f, 0.0f, 0.0f);
|
||||||
|
output.mDefaultMaterial = "default";
|
||||||
|
|
||||||
char lastParameter = '\0';
|
char lastParameter = '\0';
|
||||||
bool hasError = false;
|
bool hasError = false;
|
||||||
|
@ -55,6 +56,9 @@ bool parseCommandLineArguments(int argc, char *argv[], struct CommandLineArgumen
|
||||||
case 'r':
|
case 'r':
|
||||||
parseEulerAngles(curr, output.mEulerAngles);
|
parseEulerAngles(curr, output.mEulerAngles);
|
||||||
break;
|
break;
|
||||||
|
case 'D':
|
||||||
|
output.mDefaultMaterial = curr;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastParameter = '\0';
|
lastParameter = '\0';
|
||||||
|
@ -100,6 +104,10 @@ bool parseCommandLineArguments(int argc, char *argv[], struct CommandLineArgumen
|
||||||
strcmp(curr, "--level-def") == 0) {
|
strcmp(curr, "--level-def") == 0) {
|
||||||
output.mIsLevelDef = true;
|
output.mIsLevelDef = true;
|
||||||
output.mExportAnimation = false;
|
output.mExportAnimation = false;
|
||||||
|
} else if (
|
||||||
|
strcmp(curr, "-D") == 0 ||
|
||||||
|
strcmp(curr, "--default-material") == 0) {
|
||||||
|
lastParameter = 'D';
|
||||||
} else {
|
} else {
|
||||||
if (curr[0] == '-') {
|
if (curr[0] == '-') {
|
||||||
hasError = true;
|
hasError = true;
|
||||||
|
|
|
@ -13,6 +13,7 @@ struct CommandLineArguments {
|
||||||
std::string mMaterialOutput;
|
std::string mMaterialOutput;
|
||||||
std::string mPrefix;
|
std::string mPrefix;
|
||||||
std::vector<std::string> mMaterialFiles;
|
std::vector<std::string> mMaterialFiles;
|
||||||
|
std::string mDefaultMaterial;
|
||||||
float mGraphicsScale;
|
float mGraphicsScale;
|
||||||
float mCollisionScale;
|
float mCollisionScale;
|
||||||
bool mExportAnimation;
|
bool mExportAnimation;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "../physics/collision_scene.h"
|
#include "../physics/collision_scene.h"
|
||||||
#include "../scene/portal_surface.h"
|
#include "../scene/portal_surface.h"
|
||||||
|
#include "../math/boxs16.h"
|
||||||
|
|
||||||
struct StaticContentElement {
|
struct StaticContentElement {
|
||||||
Gfx* displayList;
|
Gfx* displayList;
|
||||||
|
@ -14,11 +15,6 @@ struct BoundingSphere {
|
||||||
short radius;
|
short radius;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BoundingBoxs16 {
|
|
||||||
short minX, minY, minZ;
|
|
||||||
short maxX, maxY, maxZ;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LevelDefinition {
|
struct LevelDefinition {
|
||||||
struct CollisionObject* collisionQuads;
|
struct CollisionObject* collisionQuads;
|
||||||
struct StaticContentElement *staticContent;
|
struct StaticContentElement *staticContent;
|
||||||
|
|
|
@ -11,7 +11,18 @@ int* gSortKey;
|
||||||
void staticRenderInit() {
|
void staticRenderInit() {
|
||||||
gRenderOrder = malloc(sizeof(u16) * gCurrentLevel->staticContentCount);
|
gRenderOrder = malloc(sizeof(u16) * gCurrentLevel->staticContentCount);
|
||||||
gRenderOrderCopy = malloc(sizeof(u16) * gCurrentLevel->staticContentCount);
|
gRenderOrderCopy = malloc(sizeof(u16) * gCurrentLevel->staticContentCount);
|
||||||
gSortKey = malloc(sizeof(int) * gCurrentLevel->staticContentCount);
|
gSortKey = malloc(sizeof(int) * (gCurrentLevel->staticContentCount + MAX_DYNAMIC_OBJECTS));
|
||||||
|
}
|
||||||
|
|
||||||
|
int staticRenderSorkKeyFromMaterial(int materialIndex, float distanceScaled) {
|
||||||
|
int distance = (int)distanceScaled;
|
||||||
|
|
||||||
|
// sort transparent surfaces from back to front
|
||||||
|
if (materialIndex >= levelMaterialTransparentStart()) {
|
||||||
|
distance = 0x1000000 - distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (materialIndex << 23) | (distance & 0x7FFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
int staticRenderGenerateSortKey(int index, struct FrustrumCullingInformation* cullingInfo) {
|
int staticRenderGenerateSortKey(int index, struct FrustrumCullingInformation* cullingInfo) {
|
||||||
|
@ -23,12 +34,7 @@ int staticRenderGenerateSortKey(int index, struct FrustrumCullingInformation* cu
|
||||||
|
|
||||||
int distance = (int)sqrtf(vector3DistSqrd(&boxCenter, &cullingInfo->cameraPosScaled));
|
int distance = (int)sqrtf(vector3DistSqrd(&boxCenter, &cullingInfo->cameraPosScaled));
|
||||||
|
|
||||||
// sort transparent surfaces from back to front
|
return staticRenderSorkKeyFromMaterial(gCurrentLevel->staticContent[index].materialIndex, distance);
|
||||||
if (gCurrentLevel->staticContent[index].materialIndex >= levelMaterialTransparentStart()) {
|
|
||||||
distance = 0x1000000 - distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((int)gCurrentLevel->staticContent[index].materialIndex << 23) | (distance & 0x7FFFFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void staticRenderSort(int min, int max) {
|
void staticRenderSort(int min, int max) {
|
||||||
|
@ -75,23 +81,6 @@ void staticRenderSort(int min, int max) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct BoundingBoxs16* boundingBox) {
|
|
||||||
for (int i = 0; i < CLIPPING_PLANE_COUNT; ++i) {
|
|
||||||
struct Vector3 closestPoint;
|
|
||||||
|
|
||||||
closestPoint.x = frustrum->clippingPlanes[i].normal.x < 0.0f ? boundingBox->minX : boundingBox->maxX;
|
|
||||||
closestPoint.y = frustrum->clippingPlanes[i].normal.y < 0.0f ? boundingBox->minY : boundingBox->maxY;
|
|
||||||
closestPoint.z = frustrum->clippingPlanes[i].normal.z < 0.0f ? boundingBox->minZ : boundingBox->maxZ;
|
|
||||||
|
|
||||||
if (planePointDistance(&frustrum->clippingPlanes[i], &closestPoint) < 0.0f) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void staticRender(struct FrustrumCullingInformation* cullingInfo, struct RenderState* renderState) {
|
void staticRender(struct FrustrumCullingInformation* cullingInfo, struct RenderState* renderState) {
|
||||||
if (!gCurrentLevel) {
|
if (!gCurrentLevel) {
|
||||||
return;
|
return;
|
||||||
|
@ -109,6 +98,8 @@ void staticRender(struct FrustrumCullingInformation* cullingInfo, struct RenderS
|
||||||
++renderCount;
|
++renderCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderCount = dynamicScenePopulate(cullingInfo, renderCount, gCurrentLevel->staticContentCount, gSortKey, gRenderOrder);
|
||||||
|
|
||||||
staticRenderSort(0, renderCount);
|
staticRenderSort(0, renderCount);
|
||||||
|
|
||||||
int prevMaterial = -1;
|
int prevMaterial = -1;
|
||||||
|
@ -116,19 +107,31 @@ void staticRender(struct FrustrumCullingInformation* cullingInfo, struct RenderS
|
||||||
gSPDisplayList(renderState->dl++, levelMaterialDefault());
|
gSPDisplayList(renderState->dl++, levelMaterialDefault());
|
||||||
|
|
||||||
for (int i = 0; i < renderCount; ++i) {
|
for (int i = 0; i < renderCount; ++i) {
|
||||||
struct StaticContentElement* element = &gCurrentLevel->staticContent[gRenderOrder[i]];
|
int renderIndex = gRenderOrder[i];
|
||||||
|
|
||||||
if (element->materialIndex != prevMaterial) {
|
int materialIndex;
|
||||||
|
|
||||||
|
if (renderIndex < gCurrentLevel->staticContentCount) {
|
||||||
|
materialIndex = gCurrentLevel->staticContent[renderIndex].materialIndex;
|
||||||
|
} else {
|
||||||
|
materialIndex = dynamicSceneObjectMaterialIndex(renderIndex - gCurrentLevel->staticContentCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (materialIndex != prevMaterial && materialIndex != -1) {
|
||||||
if (prevMaterial != -1) {
|
if (prevMaterial != -1) {
|
||||||
gSPDisplayList(renderState->dl++, levelMaterialRevert(prevMaterial));
|
gSPDisplayList(renderState->dl++, levelMaterialRevert(prevMaterial));
|
||||||
}
|
}
|
||||||
|
|
||||||
gSPDisplayList(renderState->dl++, levelMaterial(element->materialIndex));
|
gSPDisplayList(renderState->dl++, levelMaterial(materialIndex));
|
||||||
|
|
||||||
prevMaterial = element->materialIndex;
|
prevMaterial = materialIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
gSPDisplayList(renderState->dl++, element->displayList);
|
if (renderIndex < gCurrentLevel->staticContentCount) {
|
||||||
|
gSPDisplayList(renderState->dl++, gCurrentLevel->staticContent[renderIndex].displayList);
|
||||||
|
} else {
|
||||||
|
dynamicSceneRenderObject(renderIndex - gCurrentLevel->staticContentCount, renderState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevMaterial != -1) {
|
if (prevMaterial != -1) {
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
#include "level_definition.h"
|
#include "level_definition.h"
|
||||||
#include "graphics/renderstate.h"
|
#include "graphics/renderstate.h"
|
||||||
#include "scene/camera.h"
|
#include "scene/camera.h"
|
||||||
|
#include "../scene/dynamic_scene.h"
|
||||||
|
|
||||||
void staticRenderInit();
|
void staticRenderInit();
|
||||||
|
|
||||||
|
int staticRenderSorkKeyFromMaterial(int materialIndex, float distanceScaled);
|
||||||
void staticRender(struct FrustrumCullingInformation* cullingInfo, struct RenderState* renderState);
|
void staticRender(struct FrustrumCullingInformation* cullingInfo, struct RenderState* renderState);
|
||||||
|
|
||||||
int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct BoundingBoxs16* boundingBox);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
0
src/math/boxs16.c
Normal file
0
src/math/boxs16.c
Normal file
9
src/math/boxs16.h
Normal file
9
src/math/boxs16.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef __BOX_S16_H__
|
||||||
|
#define __BOX_S16_H__
|
||||||
|
|
||||||
|
struct BoundingBoxs16 {
|
||||||
|
short minX, minY, minZ;
|
||||||
|
short maxX, maxY, maxZ;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#include "../../build/assets/models/cube/cube.h"
|
#include "../../build/assets/models/cube/cube.h"
|
||||||
#include "../../build/assets/models/portal_gun/v_portalgun.h"
|
#include "../../build/assets/models/portal_gun/v_portalgun.h"
|
||||||
|
#include "../../build/assets/materials/static.h"
|
||||||
|
|
||||||
Gfx* cube_gfx = &cube_cube_model_gfx[0];
|
Gfx* cube_gfx = &cube_cube_model_gfx[0];
|
||||||
|
short cube_material_index = CUBE_INDEX;
|
||||||
Gfx* v_portal_gun_gfx = &portal_gun_v_portalgun_model_gfx[0];
|
Gfx* v_portal_gun_gfx = &portal_gun_v_portalgun_model_gfx[0];
|
|
@ -6,6 +6,7 @@ extern Gfx portal_mask_Circle_mesh_tri_0[];
|
||||||
extern Gfx portal_outline_portal_outline_mesh[];
|
extern Gfx portal_outline_portal_outline_mesh[];
|
||||||
|
|
||||||
extern Gfx* cube_gfx;
|
extern Gfx* cube_gfx;
|
||||||
|
extern short cube_material_index;
|
||||||
extern Gfx* v_portal_gun_gfx;
|
extern Gfx* v_portal_gun_gfx;
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -4,6 +4,33 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "../graphics/graphics.h"
|
#include "../graphics/graphics.h"
|
||||||
|
|
||||||
|
int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct BoundingBoxs16* boundingBox) {
|
||||||
|
for (int i = 0; i < CLIPPING_PLANE_COUNT; ++i) {
|
||||||
|
struct Vector3 closestPoint;
|
||||||
|
|
||||||
|
closestPoint.x = frustrum->clippingPlanes[i].normal.x < 0.0f ? boundingBox->minX : boundingBox->maxX;
|
||||||
|
closestPoint.y = frustrum->clippingPlanes[i].normal.y < 0.0f ? boundingBox->minY : boundingBox->maxY;
|
||||||
|
closestPoint.z = frustrum->clippingPlanes[i].normal.z < 0.0f ? boundingBox->minZ : boundingBox->maxZ;
|
||||||
|
|
||||||
|
if (planePointDistance(&frustrum->clippingPlanes[i], &closestPoint) < 0.0f) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isSphereOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct Vector3* scaledCenter, float scaledRadius) {
|
||||||
|
for (int i = 0; i < CLIPPING_PLANE_COUNT; ++i) {
|
||||||
|
if (planePointDistance(&frustrum->clippingPlanes[i], scaledCenter) < -scaledRadius) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void cameraInit(struct Camera* camera, float fov, float near, float far) {
|
void cameraInit(struct Camera* camera, float fov, float near, float far) {
|
||||||
transformInitIdentity(&camera->transform);
|
transformInitIdentity(&camera->transform);
|
||||||
camera->fov = fov;
|
camera->fov = fov;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "math/transform.h"
|
#include "math/transform.h"
|
||||||
#include "math/plane.h"
|
#include "math/plane.h"
|
||||||
#include "graphics/renderstate.h"
|
#include "graphics/renderstate.h"
|
||||||
|
#include "../math/boxs16.h"
|
||||||
|
|
||||||
#define CLIPPING_PLANE_COUNT 5
|
#define CLIPPING_PLANE_COUNT 5
|
||||||
|
|
||||||
|
@ -24,6 +25,9 @@ struct FrustrumCullingInformation {
|
||||||
struct Vector3 cameraPosScaled;
|
struct Vector3 cameraPosScaled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct BoundingBoxs16* boundingBox);
|
||||||
|
int isSphereOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct Vector3* scaledCenter, float scaledRadius);
|
||||||
|
|
||||||
void cameraInit(struct Camera* camera, float fov, float near, float far);
|
void cameraInit(struct Camera* camera, float fov, float near, float far);
|
||||||
void cameraBuildViewMatrix(struct Camera* camera, float matrix[4][4]);
|
void cameraBuildViewMatrix(struct Camera* camera, float matrix[4][4]);
|
||||||
void cameraBuildProjectionMatrix(struct Camera* camera, float matrix[4][4], u16* perspectiveNorm, float aspectRatio);
|
void cameraBuildProjectionMatrix(struct Camera* camera, float matrix[4][4], u16* perspectiveNorm, float aspectRatio);
|
||||||
|
|
|
@ -74,7 +74,7 @@ void cubeInit(struct Cube* cube) {
|
||||||
|
|
||||||
cube->collisionObject.body->flags |= RigidBodyFlagsGrabbable;
|
cube->collisionObject.body->flags |= RigidBodyFlagsGrabbable;
|
||||||
|
|
||||||
cube->dynamicId = dynamicSceneAdd(cube, cubeRender);
|
cube->dynamicId = dynamicSceneAdd(cube, cubeRender, &cube->rigidBody.transform, sqrtf(vector3MagSqrd(&gCubeCollisionBox.sideLength)), cube_material_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cubeUpdate(struct Cube* cube) {
|
void cubeUpdate(struct Cube* cube) {
|
||||||
|
|
|
@ -1,34 +1,48 @@
|
||||||
#include "dynamic_scene.h"
|
#include "dynamic_scene.h"
|
||||||
|
#include "../levels/static_render.h"
|
||||||
|
#include "defs.h"
|
||||||
|
#include "../levels/levels.h"
|
||||||
|
|
||||||
struct DynamicScene gDynamicScene;
|
struct DynamicScene gDynamicScene;
|
||||||
|
|
||||||
|
#define FLAG_MASK (DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE | DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL)
|
||||||
|
#define FLAG_VALUE_NOT_TOUCHING_PORTAL (DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE)
|
||||||
|
#define FLAG_VALUE_TOUCHING_PORTAL (DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE | DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL)
|
||||||
|
|
||||||
void dynamicSceneInit() {
|
void dynamicSceneInit() {
|
||||||
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
||||||
gDynamicScene.objects[i].flags = 0;
|
gDynamicScene.objects[i].flags = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dynamicSceneRender(struct RenderState* renderState, int touchingPortals) {
|
void dynamicSceneRenderTouchingPortal(struct RenderState* renderState) {
|
||||||
int flagMask = DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE | DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL;
|
|
||||||
int flagValue = DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE;
|
|
||||||
|
|
||||||
if (touchingPortals) {
|
|
||||||
flagValue |= DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
||||||
if ((gDynamicScene.objects[i].flags & flagMask) == flagValue) {
|
struct DynamicSceneObject* object = &gDynamicScene.objects[i];
|
||||||
|
if ((object->flags & FLAG_MASK) == FLAG_VALUE_TOUCHING_PORTAL) {
|
||||||
|
if (object->materialIndex != -1) {
|
||||||
|
gSPDisplayList(renderState->dl++, levelMaterial(object->materialIndex));
|
||||||
|
}
|
||||||
|
|
||||||
gDynamicScene.objects[i].renderCallback(gDynamicScene.objects[i].data, renderState);
|
gDynamicScene.objects[i].renderCallback(gDynamicScene.objects[i].data, renderState);
|
||||||
|
|
||||||
|
if (object->materialIndex != -1) {
|
||||||
|
gSPDisplayList(renderState->dl++, levelMaterialRevert(object->materialIndex));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int dynamicSceneAdd(void* data, DynamicRender renderCallback) {
|
int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Transform* transform, float radius, u16 materialIndex) {
|
||||||
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
||||||
if (!(gDynamicScene.objects[i].flags & DYNAMIC_SCENE_OBJECT_FLAGS_USED)) {
|
struct DynamicSceneObject* object = &gDynamicScene.objects[i];
|
||||||
gDynamicScene.objects[i].flags = DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE;
|
if (!(object->flags & DYNAMIC_SCENE_OBJECT_FLAGS_USED)) {
|
||||||
gDynamicScene.objects[i].data = data;
|
|
||||||
gDynamicScene.objects[i].renderCallback = renderCallback;
|
object->flags = DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE;
|
||||||
|
object->data = data;
|
||||||
|
object->renderCallback = renderCallback;
|
||||||
|
object->transform = transform;
|
||||||
|
object->scaledRadius = radius * SCENE_SCALE;
|
||||||
|
object->materialIndex = materialIndex;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,5 +64,44 @@ void dynamicSceneSetFlags(int id, int flags) {
|
||||||
|
|
||||||
void dynamicSceneClearFlags(int id, int flags) {
|
void dynamicSceneClearFlags(int id, int flags) {
|
||||||
gDynamicScene.objects[id].flags &= ~flags;
|
gDynamicScene.objects[id].flags &= ~flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dynamicScenePopulate(struct FrustrumCullingInformation* cullingInfo, int currentObjectCount, int staticObjectCount, int* sortKey, u16* renderOrder) {
|
||||||
|
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
||||||
|
struct DynamicSceneObject* object = &gDynamicScene.objects[i];
|
||||||
|
if ((object->flags & FLAG_MASK) == FLAG_VALUE_NOT_TOUCHING_PORTAL) {
|
||||||
|
struct Vector3 scaledPos;
|
||||||
|
vector3Scale(&object->transform->position, &scaledPos, SCENE_SCALE);
|
||||||
|
|
||||||
|
if (isSphereOutsideFrustrum(cullingInfo, &scaledPos, object->scaledRadius)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderOrder[currentObjectCount] = staticObjectCount + i;
|
||||||
|
sortKey[staticObjectCount + i] = staticRenderSorkKeyFromMaterial(
|
||||||
|
object->materialIndex,
|
||||||
|
sqrtf(vector3DistSqrd(&scaledPos, &cullingInfo->cameraPosScaled))
|
||||||
|
);
|
||||||
|
++currentObjectCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentObjectCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dynamicSceneRenderObject(int index, struct RenderState* renderState) {
|
||||||
|
if (index < 0 || index >= MAX_DYNAMIC_OBJECTS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DynamicSceneObject* object = &gDynamicScene.objects[index];
|
||||||
|
object->renderCallback(object->data, renderState);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dynamicSceneObjectMaterialIndex(int objectIndex) {
|
||||||
|
if (objectIndex < 0 || objectIndex >= MAX_DYNAMIC_OBJECTS) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gDynamicScene.objects[objectIndex].materialIndex;
|
||||||
}
|
}
|
|
@ -2,6 +2,8 @@
|
||||||
#define __DYNAMIC_SCENE_H__
|
#define __DYNAMIC_SCENE_H__
|
||||||
|
|
||||||
#include "../graphics/renderstate.h"
|
#include "../graphics/renderstate.h"
|
||||||
|
#include "../math/transform.h"
|
||||||
|
#include "../scene/camera.h"
|
||||||
|
|
||||||
typedef void (*DynamicRender)(void* data, struct RenderState* renderState);
|
typedef void (*DynamicRender)(void* data, struct RenderState* renderState);
|
||||||
|
|
||||||
|
@ -16,7 +18,10 @@ typedef void (*DynamicRender)(void* data, struct RenderState* renderState);
|
||||||
struct DynamicSceneObject {
|
struct DynamicSceneObject {
|
||||||
void* data;
|
void* data;
|
||||||
DynamicRender renderCallback;
|
DynamicRender renderCallback;
|
||||||
int flags;
|
struct Transform* transform;
|
||||||
|
float scaledRadius;
|
||||||
|
u16 materialIndex;
|
||||||
|
u16 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DynamicScene {
|
struct DynamicScene {
|
||||||
|
@ -25,11 +30,16 @@ struct DynamicScene {
|
||||||
|
|
||||||
void dynamicSceneInit();
|
void dynamicSceneInit();
|
||||||
|
|
||||||
void dynamicSceneRender(struct RenderState* renderState, int touchingPortals);
|
void dynamicSceneRenderTouchingPortal(struct RenderState* renderState);
|
||||||
|
|
||||||
int dynamicSceneAdd(void* data, DynamicRender renderCallback);
|
int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Transform* transform, float radius, u16 materialIndex);
|
||||||
void dynamicSceneRemove(int id);
|
void dynamicSceneRemove(int id);
|
||||||
void dynamicSceneSetFlags(int id, int flags);
|
void dynamicSceneSetFlags(int id, int flags);
|
||||||
void dynamicSceneClearFlags(int id, int flags);
|
void dynamicSceneClearFlags(int id, int flags);
|
||||||
|
|
||||||
|
int dynamicScenePopulate(struct FrustrumCullingInformation* cullingInfo, int currentObjectCount, int staticObjectCount, int* sortKey, u16* renderOrder);
|
||||||
|
|
||||||
|
void dynamicSceneRenderObject(int index, struct RenderState* renderState);
|
||||||
|
int dynamicSceneObjectMaterialIndex(int objectIndex);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -121,7 +121,7 @@ void renderPropsNext(struct RenderProps* current, struct RenderProps* next, stru
|
||||||
|
|
||||||
// render any objects halfway through portals
|
// render any objects halfway through portals
|
||||||
cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, current->viewport, NULL);
|
cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, current->viewport, NULL);
|
||||||
dynamicSceneRender(renderState, 1);
|
dynamicSceneRenderTouchingPortal(renderState);
|
||||||
|
|
||||||
Vp* viewport = renderPropsBuildViewport(next, renderState);
|
Vp* viewport = renderPropsBuildViewport(next, renderState);
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,6 @@ void sceneRenderWithProperties(void* data, struct RenderProps* properties, struc
|
||||||
gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);
|
gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);
|
||||||
|
|
||||||
staticRender(&properties->cullingInfo, renderState);
|
staticRender(&properties->cullingInfo, renderState);
|
||||||
|
|
||||||
dynamicSceneRender(renderState, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SOLID_COLOR 0, 0, 0, ENVIRONMENT, 0, 0, 0, ENVIRONMENT
|
#define SOLID_COLOR 0, 0, 0, ENVIRONMENT, 0, 0, 0, ENVIRONMENT
|
||||||
|
@ -122,7 +120,7 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr
|
||||||
|
|
||||||
gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);
|
gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);
|
||||||
|
|
||||||
dynamicSceneRender(renderState, 1);
|
dynamicSceneRenderTouchingPortal(renderState);
|
||||||
|
|
||||||
sceneRenderWithProperties(scene, &renderProperties, renderState);
|
sceneRenderWithProperties(scene, &renderProperties, renderState);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue