mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2026-05-31 13:11:07 +00:00
much further draw distance option (#1240)
The existing draw distance options don't actually increase the draw distance. It only impacts whether or not distant objects are rendered. This PR: - Adds another option to the draw distance setting in the display menu, called "Infinite". It is not truly infinite, but it is significantly larger than what current options allow. Due to it not being truly infinite, we could use the name "Max" instead to be more accurate. - Exposes a new function to the Lua API `draw_distance_scalar_is_infinite` which returns whether or not the infinite setting is enabled. - `draw_distance_scalar_is_infinite` is now used in several places in this repo to bypass distance checks for objects if infinite mode is enabled. - Fixes a bug where you couldn't bypass the distance check in `obj_is_in_view`, meaning you could never disable all object distance culling. - The infinite setting now forces the far plane to be at least a minimum of `1,000,000`.
This commit is contained in:
parent
91208e4e06
commit
967d120505
26 changed files with 121 additions and 17 deletions
|
|
@ -2997,6 +2997,12 @@ function position_based_random_float_position()
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @return boolean
|
||||
--- Checks if the draw distance scalar is infinite
|
||||
function draw_distance_scalar_is_infinite()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @return number
|
||||
--- Gets the draw distance scalar
|
||||
function draw_distance_scalar()
|
||||
|
|
|
|||
|
|
@ -139,6 +139,27 @@ Sets the current object's position to random floats between 0.0 and 1.0
|
|||
|
||||
<br />
|
||||
|
||||
## [draw_distance_scalar_is_infinite](#draw_distance_scalar_is_infinite)
|
||||
|
||||
### Description
|
||||
Checks if the draw distance scalar is infinite
|
||||
|
||||
### Lua Example
|
||||
`local booleanValue = draw_distance_scalar_is_infinite()`
|
||||
|
||||
### Parameters
|
||||
- None
|
||||
|
||||
### Returns
|
||||
- `boolean`
|
||||
|
||||
### C Prototype
|
||||
`bool draw_distance_scalar_is_infinite(void);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [draw_distance_scalar](#draw_distance_scalar)
|
||||
|
||||
### Description
|
||||
|
|
|
|||
|
|
@ -623,6 +623,7 @@
|
|||
- [obj_update_gfx_pos_and_angle](functions-3.md#obj_update_gfx_pos_and_angle)
|
||||
- [position_based_random_u16](functions-3.md#position_based_random_u16)
|
||||
- [position_based_random_float_position](functions-3.md#position_based_random_float_position)
|
||||
- [draw_distance_scalar_is_infinite](functions-3.md#draw_distance_scalar_is_infinite)
|
||||
- [draw_distance_scalar](functions-3.md#draw_distance_scalar)
|
||||
|
||||
<br />
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ D1P5X = "1.5x"
|
|||
D3X = "3x"
|
||||
D10X = "10x"
|
||||
D100X = "100x"
|
||||
INFINITE = "Nekonečno"
|
||||
DRAW_DISTANCE = "Vzdálenost vykreslování"
|
||||
DYNOS_PACKS = "DynOS packy"
|
||||
ANTIALIASING = "Anti-aliasing"
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ D1P5X = "1.5x"
|
|||
D3X = "3x"
|
||||
D10X = "10x"
|
||||
D100X = "100x"
|
||||
INFINITE = "Oneindig"
|
||||
DRAW_DISTANCE = "Teken afstand"
|
||||
DYNOS_PACKS = "DynOS Packs"
|
||||
ANTIALIASING = "Anti-aliasing"
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ D1P5X = "1.5x"
|
|||
D3X = "3x"
|
||||
D10X = "10x"
|
||||
D100X = "100x"
|
||||
INFINITE = "Infinite"
|
||||
DRAW_DISTANCE = "Draw Distance"
|
||||
DYNOS_PACKS = "DynOS Packs"
|
||||
ANTIALIASING = "Anti-aliasing"
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ D1P5X = "x1.5"
|
|||
D3X = "x3"
|
||||
D10X = "x10"
|
||||
D100X = "x100"
|
||||
INFINITE = "Infini"
|
||||
DRAW_DISTANCE = "Distance d'affichage"
|
||||
DYNOS_PACKS = "Packs DynOS"
|
||||
ANTIALIASING = "Anti-aliasing"
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ D1P5X = "1.5x"
|
|||
D3X = "3x"
|
||||
D10X = "10x"
|
||||
D100X = "100x"
|
||||
INFINITE = "Unendlich"
|
||||
DRAW_DISTANCE = "Sichtweite"
|
||||
DYNOS_PACKS = "DynOS-Pakete"
|
||||
ANTIALIASING = "Kantenglättung"
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ D1P5X = "1.5x"
|
|||
D3X = "3x"
|
||||
D10X = "10x"
|
||||
D100X = "100x"
|
||||
INFINITE = "Infinito"
|
||||
DRAW_DISTANCE = "Distanza di Simulazione"
|
||||
DYNOS_PACKS = "Pacchetti DynOS"
|
||||
ANTIALIASING = "Anti-aliasing"
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ D1P5X = "1.5x"
|
|||
D3X = "3x"
|
||||
D10X = "10x"
|
||||
D100X = "100x"
|
||||
INFINITE = "無限"
|
||||
DRAW_DISTANCE = "描画距離"
|
||||
DYNOS_PACKS = "DynOSパック"
|
||||
ANTIALIASING = "アンチエイリアス"
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ D1P5X = "1,5x"
|
|||
D3X = "3x"
|
||||
D10X = "10x"
|
||||
D100X = "100x"
|
||||
INFINITE = "Nieskończony"
|
||||
DRAW_DISTANCE = "Odległość Renderowania"
|
||||
DYNOS_PACKS = "Paczki DynOS"
|
||||
ANTIALIASING = "Anti-aliasing"
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ D1P5X = "1.5x"
|
|||
D3X = "3x"
|
||||
D10X = "10x"
|
||||
D100X = "100x"
|
||||
INFINITE = "Infinito"
|
||||
DRAW_DISTANCE = "Distância de renderização"
|
||||
DYNOS_PACKS = "Pacotes DynOS"
|
||||
ANTIALIASING = "Antisserrilhamento"
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ D1P5X = "1.5x"
|
|||
D3X = "3x"
|
||||
D10X = "10x"
|
||||
D100X = "100x"
|
||||
INFINITE = "Бесконечный"
|
||||
DRAW_DISTANCE = "Дальность прорисовки"
|
||||
DYNOS_PACKS = "Пакеты DynOS"
|
||||
ANTIALIASING = "Анизотропная фильтрация"
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ D1P5X = "1.5x"
|
|||
D3X = "3x"
|
||||
D10X = "10x"
|
||||
D100X = "100x"
|
||||
INFINITE = "Infinito"
|
||||
DRAW_DISTANCE = "Distancia de dibujado"
|
||||
DYNOS_PACKS = "Packs DynOS"
|
||||
ANTIALIASING = "Anti-aliasing"
|
||||
|
|
|
|||
|
|
@ -1438,7 +1438,9 @@ cur_obj_update_begin:;
|
|||
} else if ((objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) && gCurrentObject->collisionData == NULL) {
|
||||
if (!(objFlags & OBJ_FLAG_ACTIVE_FROM_AFAR)) {
|
||||
// If the object has a render distance, check if it should be shown.
|
||||
if (distanceFromMario > gCurrentObject->oDrawingDistance * draw_distance_scalar()) {
|
||||
if (!draw_distance_scalar_is_infinite() &&
|
||||
distanceFromMario > gCurrentObject->oDrawingDistance * draw_distance_scalar()
|
||||
) {
|
||||
// Out of render distance, hide the object.
|
||||
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
|
||||
|
||||
|
|
@ -1486,6 +1488,13 @@ f32 position_based_random_float_position(void) {
|
|||
return rnd / (double)0x10000;
|
||||
}
|
||||
|
||||
bool draw_distance_scalar_is_infinite(void) {
|
||||
if (!gBehaviorValues.InfiniteRenderDistance) {
|
||||
return false;
|
||||
}
|
||||
return configDrawDistance == 6; // Expecting this to be "Infinite"
|
||||
}
|
||||
|
||||
f32 draw_distance_scalar(void) {
|
||||
if (!gBehaviorValues.InfiniteRenderDistance) { return 1.0f; }
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ void obj_update_gfx_pos_and_angle(struct Object *obj);
|
|||
u16 position_based_random_u16(void);
|
||||
/* |description|Sets the current object's position to random floats between 0.0 and 1.0|descriptionEnd| */
|
||||
f32 position_based_random_float_position(void);
|
||||
/* |description|Checks if the draw distance scalar is infinite|descriptionEnd| */
|
||||
bool draw_distance_scalar_is_infinite(void);
|
||||
/* |description|Gets the draw distance scalar|descriptionEnd| */
|
||||
f32 draw_distance_scalar(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -1045,7 +1045,9 @@ static void load_object_collision_model_internal(bool isSOC) {
|
|||
|
||||
if (!isSOC) {
|
||||
f32 marioDist = dist_between_objects(gCurrentObject, gMarioStates[0].marioObj);
|
||||
if (marioDist < gCurrentObject->oDrawingDistance * draw_distance_scalar()) {
|
||||
if (draw_distance_scalar_is_infinite() ||
|
||||
marioDist < gCurrentObject->oDrawingDistance * draw_distance_scalar()
|
||||
) {
|
||||
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
|
||||
} else {
|
||||
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ void king_bobomb_act_7(void) {
|
|||
void king_bobomb_act_8(void) {
|
||||
if (!(o->header.gfx.node.flags & GRAPH_RENDER_INVISIBLE)) {
|
||||
struct Object *star = NULL;
|
||||
|
||||
|
||||
create_sound_spawner(SOUND_OBJ_KING_WHOMP_DEATH);
|
||||
cur_obj_hide();
|
||||
cur_obj_become_intangible();
|
||||
|
|
@ -367,6 +367,10 @@ void king_bobomb_move(void) {
|
|||
cur_obj_move_using_fvel_and_gravity();
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sKingBobombActions);
|
||||
exec_anim_sound_state(sKingBobombSoundStates, sizeof(sKingBobombSoundStates) / sizeof(struct SoundState));
|
||||
if (draw_distance_scalar_is_infinite()) {
|
||||
cur_obj_enable_rendering();
|
||||
return;
|
||||
}
|
||||
s32 distanceToPlayer = dist_between_objects(o, gMarioStates[0].marioObj);
|
||||
if (distanceToPlayer < 5000.0f * draw_distance_scalar())
|
||||
cur_obj_enable_rendering();
|
||||
|
|
|
|||
|
|
@ -375,12 +375,16 @@ void bhv_piranha_plant_loop(void) {
|
|||
CUR_OBJ_CALL_ACTION_FUNCTION(TablePiranhaPlantActions);
|
||||
// In WF, hide all Piranha Plants once high enough up.
|
||||
if (gCurrLevelNum == LEVEL_WF) {
|
||||
struct Object* player = gMarioStates[0].marioObj;
|
||||
f32 scalar = max(draw_distance_scalar(), 1.0f);
|
||||
if (player->oPosY > 3400.0f * scalar)
|
||||
cur_obj_hide();
|
||||
else
|
||||
if (draw_distance_scalar_is_infinite()) {
|
||||
cur_obj_unhide();
|
||||
} else {
|
||||
struct Object* player = gMarioStates[0].marioObj;
|
||||
f32 scalar = max(draw_distance_scalar(), 1.0f);
|
||||
if (player->oPosY > 3400.0f * scalar)
|
||||
cur_obj_hide();
|
||||
else
|
||||
cur_obj_unhide();
|
||||
}
|
||||
}
|
||||
o->oInteractStatus = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,11 +44,15 @@ void bhv_whirlpool_loop(void) {
|
|||
o->oWhirlpoolTimeout = 30;
|
||||
}
|
||||
|
||||
f32 marioDist = dist_between_objects(o, gMarioStates[0].marioObj);
|
||||
if (marioDist < 5000.0f * draw_distance_scalar()) {
|
||||
if (draw_distance_scalar_is_infinite()) {
|
||||
o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
} else {
|
||||
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
|
||||
f32 marioDist = dist_between_objects(o, gMarioStates[0].marioObj);
|
||||
if (marioDist < 5000.0f * draw_distance_scalar()) {
|
||||
o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
} else {
|
||||
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
|
||||
}
|
||||
}
|
||||
|
||||
// not sure if actually an array
|
||||
|
|
|
|||
|
|
@ -701,6 +701,10 @@ s8 is_point_close_to_object(struct Object *obj, f32 x, f32 y, f32 z, s32 dist) {
|
|||
/* |description|Sets an object as visible if within a certain distance of Mario's graphical position|descriptionEnd| */
|
||||
void set_object_visibility(struct Object *obj, s32 dist) {
|
||||
if (!obj) { return; }
|
||||
if (draw_distance_scalar_is_infinite()) {
|
||||
obj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
return;
|
||||
}
|
||||
s32 distanceToPlayer = dist_between_objects(obj, gMarioStates[0].marioObj);
|
||||
if (distanceToPlayer < dist * draw_distance_scalar()) {
|
||||
obj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
|
|
|
|||
|
|
@ -3010,7 +3010,9 @@ void cur_obj_if_hit_wall_bounce_away(void) {
|
|||
s32 cur_obj_hide_if_mario_far_away_y(f32 distY) {
|
||||
if (!o) { return 0; }
|
||||
if (!gMarioStates[0].marioObj) { return FALSE; }
|
||||
if (absf(o->oPosY - gMarioStates[0].marioObj->oPosY) < distY * draw_distance_scalar()) {
|
||||
if (draw_distance_scalar_is_infinite() ||
|
||||
absf(o->oPosY - gMarioStates[0].marioObj->oPosY) < distY * draw_distance_scalar()
|
||||
) {
|
||||
cur_obj_unhide();
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@
|
|||
|
||||
#define DISPLAY_LIST_HEAP_SIZE 32000
|
||||
|
||||
#define MAX_FAR_PLANE_DIST 1000000.f
|
||||
|
||||
f32 gProjectionMaxNearValue = 5;
|
||||
s16 gProjectionVanillaNearValue = 100;
|
||||
s16 gProjectionVanillaFarValue = 1000;
|
||||
|
|
@ -310,6 +312,10 @@ void patch_mtx_interpolated(f32 delta) {
|
|||
f32 fovInterpolated = delta_interpolate_f32(sPerspectiveNode->prevFov, sPerspectiveNode->fov, delta);
|
||||
f32 near = get_first_person_enabled() ? 1.f : replace_value_if_not_zero(MIN(sPerspectiveNode->near, gProjectionMaxNearValue), gOverrideNear);
|
||||
f32 far = replace_value_if_not_zero(sPerspectiveNode->far, gOverrideFar);
|
||||
|
||||
// "infinite" draw distance
|
||||
if (gOverrideFar == 0 && configDrawDistance == 6) { far = max(far, MAX_FAR_PLANE_DIST); }
|
||||
|
||||
guPerspective(sPerspectiveMtx, &perspNorm, fovInterpolated, sPerspectiveAspect, near, far, 1.0f);
|
||||
gSPMatrix(sPerspectivePos, VIRTUAL_TO_PHYSICAL(sPerspectiveNode), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
}
|
||||
|
|
@ -650,6 +656,10 @@ static void geo_process_perspective(struct GraphNodePerspective *node) {
|
|||
gProjectionVanillaFarValue = node->far;
|
||||
f32 near = get_first_person_enabled() ? 1.f : replace_value_if_not_zero(MIN(node->near, gProjectionMaxNearValue), gOverrideNear);
|
||||
f32 far = replace_value_if_not_zero(node->far, gOverrideFar);
|
||||
|
||||
// "infinite" draw distance
|
||||
if (gOverrideFar == 0 && configDrawDistance == 6) { far = max(far, MAX_FAR_PLANE_DIST); }
|
||||
|
||||
guPerspective(mtx, &perspNorm, node->prevFov, aspect, near, far, 1.0f);
|
||||
|
||||
sPerspectiveNode = node;
|
||||
|
|
@ -1139,7 +1149,7 @@ static void anim_process(Vec3f translation, Vec3s rotation, Vec3f scale, u8 *ani
|
|||
scale[2] *= ((f32) scaleZ) / 256.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (gCurAnim->flags & ANIM_FLAG_BONE_TRANS) {
|
||||
*animType = ANIM_TYPE_TRANSLATION;
|
||||
}
|
||||
|
|
@ -1459,7 +1469,7 @@ static s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) {
|
|||
// makes PU travel safe when the camera is locked on the main map.
|
||||
// If Mario were rendered with a depth over 65536 it would cause overflow
|
||||
// when converting the transformation matrix to a fixed point matrix.
|
||||
if (matrix[3][2] < -20000.0f - cullingRadius) {
|
||||
if (configDrawDistance != 6 && matrix[3][2] < -20000.0f - cullingRadius) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ bool configShowPing = false;
|
|||
enum RefreshRateMode configFramerateMode = RRM_AUTO;
|
||||
unsigned int configFrameLimit = 60;
|
||||
unsigned int configInterpolationMode = 1;
|
||||
unsigned int configDrawDistance = 4;
|
||||
unsigned int configDrawDistance = 6;
|
||||
// sound settings
|
||||
unsigned int configMasterVolume = 80; // 0 - MAX_VOLUME
|
||||
unsigned int configMusicVolume = MAX_VOLUME;
|
||||
|
|
|
|||
|
|
@ -129,8 +129,16 @@ void djui_panel_display_create(struct DjuiBase* caller) {
|
|||
djui_selectionbox_create(body, DLANG(DISPLAY, ANTIALIASING), msaaChoices, choiceCount, &sMsaaSelection, djui_panel_display_msaa_change);
|
||||
}
|
||||
|
||||
char* drawDistanceChoices[6] = { DLANG(DISPLAY, D0P5X), DLANG(DISPLAY, D1X), DLANG(DISPLAY, D1P5X), DLANG(DISPLAY, D3X), DLANG(DISPLAY, D10X), DLANG(DISPLAY, D100X) };
|
||||
djui_selectionbox_create(body, DLANG(DISPLAY, DRAW_DISTANCE), drawDistanceChoices, 6, &configDrawDistance, NULL);
|
||||
char* drawDistanceChoices[] = {
|
||||
DLANG(DISPLAY, D0P5X),
|
||||
DLANG(DISPLAY, D1X),
|
||||
DLANG(DISPLAY, D1P5X),
|
||||
DLANG(DISPLAY, D3X),
|
||||
DLANG(DISPLAY, D10X),
|
||||
DLANG(DISPLAY, D100X),
|
||||
DLANG(DISPLAY, INFINITE),
|
||||
};
|
||||
djui_selectionbox_create(body, DLANG(DISPLAY, DRAW_DISTANCE), drawDistanceChoices, ARRAY_COUNT(drawDistanceChoices), &configDrawDistance, NULL);
|
||||
|
||||
djui_button_create(body, DLANG(MENU, BACK), DJUI_BUTTON_STYLE_BACK, djui_panel_menu_back);
|
||||
|
||||
|
|
|
|||
|
|
@ -9889,6 +9889,21 @@ int smlua_func_position_based_random_float_position(UNUSED lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_draw_distance_scalar_is_infinite(UNUSED lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 0) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "draw_distance_scalar_is_infinite", 0, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
lua_pushboolean(L, draw_distance_scalar_is_infinite());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_draw_distance_scalar(UNUSED lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
|
|
@ -37695,6 +37710,7 @@ void smlua_bind_functions_autogen(void) {
|
|||
smlua_bind_function(L, "obj_update_gfx_pos_and_angle", smlua_func_obj_update_gfx_pos_and_angle);
|
||||
smlua_bind_function(L, "position_based_random_u16", smlua_func_position_based_random_u16);
|
||||
smlua_bind_function(L, "position_based_random_float_position", smlua_func_position_based_random_float_position);
|
||||
smlua_bind_function(L, "draw_distance_scalar_is_infinite", smlua_func_draw_distance_scalar_is_infinite);
|
||||
smlua_bind_function(L, "draw_distance_scalar", smlua_func_draw_distance_scalar);
|
||||
|
||||
// behavior_table.h
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue