mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
Lighting engine improvements (#870)
* Lighting engine improvements
Now objects will be affected by the lighting engine. This is
accomplished by passing the renderer the object's model matrix
(uncombined with the view or projection). You can now setup the
lighting engine mode to affect all shaded surfaces, lighting can
be affected by surface normals, and you can control what type of
tone mapping is applied.
added le_set_mode(mode)
By default we retain the previous behavior.
When set to LE_MODE_AFFECT_ALL_SHADED the lighting engine will
affect every shaded material.
This way we don't have to recompile every object and level that
we want shaded with special coop-specific commands
added le_get_mode()
added le_set_tone_mapping(toneMapping)
Tone mapping is what happens when a color value exceeds its 0-255
range.
By default we retain the current tone mapping (called
LE_TONE_MAPPING_TOTAL_WEIGHTED).
LE_TONE_MAPPING_WEIGHTED is now accessible, it was the tone
mapping that was previously left out of the compile through ifdefs.
LE_TONE_MAPPING_CLAMP is just simple additive with a clamp at a
color value of 255.
LE_TONE_MAPPING_REINHARD is reinhard tone mapping
(vout = (vin + 1) / vin).
added le_set_light_use_surface_normals(id, useSurfaceNormals)
By default lights retain their previous behavior (of ignoring
surface normals).
When enabled lights cast on one side of the object will not
appear on the other side of the object.
It is kind of like backface culling, but for lights.
added le_calculate_lighting_color_with_normal(pos, normal, outColor, lightIntensityScalar)
It's just like le_calculate_lighting_color(), but you can pass
in normals now.
* Removed normal calculation from vertex colored surfaces - they don't have normals
* Use packed normals correctly
* made LE_MODE_AFFECT_ALL_SHADED the default
* made useSurfaceNormals the default for lights
* Set ambient color, performed le_is_enabled() checks
The ambient color was black, which is why everything was dark by default.
If we set ambient to white then people will never see the effects of their
lights unless they set ambient to a lower value. So I added checks for
if a light has ever been added. The alternative would be to have something
like le_set_enabled()
* Rewrite how we obtain the model matrix - invert the camera
* run autogen
* Change default tonemapper to weighted, make setting ambient enable LE, fix null deref
* Address Peachy's comments
---------
Co-authored-by: MysterD <myster@d>
This commit is contained in:
parent
afb1c7f0e8
commit
82ca45eeb6
17 changed files with 750 additions and 77 deletions
|
|
@ -51,6 +51,7 @@ in_files = [
|
||||||
"src/game/player_palette.h",
|
"src/game/player_palette.h",
|
||||||
"src/pc/network/lag_compensation.h",
|
"src/pc/network/lag_compensation.h",
|
||||||
"src/pc/djui/djui_panel_menu.h",
|
"src/pc/djui/djui_panel_menu.h",
|
||||||
|
"src/engine/lighting_engine.h",
|
||||||
"include/PR/gbi.h"
|
"include/PR/gbi.h"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3608,6 +3608,24 @@ HUD_DISPLAY_DEFAULT = HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_CO
|
||||||
--- | `HUD_DISPLAY_NONE`
|
--- | `HUD_DISPLAY_NONE`
|
||||||
--- | `HUD_DISPLAY_DEFAULT`
|
--- | `HUD_DISPLAY_DEFAULT`
|
||||||
|
|
||||||
|
LE_MODE_AFFECT_ALL_SHADED = 0 --- @type LEMode
|
||||||
|
LE_MODE_AFFECT_ONLY_GEOMETRY_MODE = 1 --- @type LEMode
|
||||||
|
|
||||||
|
--- @alias LEMode
|
||||||
|
--- | `LE_MODE_AFFECT_ALL_SHADED`
|
||||||
|
--- | `LE_MODE_AFFECT_ONLY_GEOMETRY_MODE`
|
||||||
|
|
||||||
|
LE_TONE_MAPPING_TOTAL_WEIGHTED = 0 --- @type LEToneMapping
|
||||||
|
LE_TONE_MAPPING_WEIGHTED = 1 --- @type LEToneMapping
|
||||||
|
LE_TONE_MAPPING_CLAMP = 2 --- @type LEToneMapping
|
||||||
|
LE_TONE_MAPPING_REINHARD = 3 --- @type LEToneMapping
|
||||||
|
|
||||||
|
--- @alias LEToneMapping
|
||||||
|
--- | `LE_TONE_MAPPING_TOTAL_WEIGHTED`
|
||||||
|
--- | `LE_TONE_MAPPING_WEIGHTED`
|
||||||
|
--- | `LE_TONE_MAPPING_CLAMP`
|
||||||
|
--- | `LE_TONE_MAPPING_REINHARD`
|
||||||
|
|
||||||
MARIO_ANIM_SLOW_LEDGE_GRAB = 0 --- @type MarioAnimID
|
MARIO_ANIM_SLOW_LEDGE_GRAB = 0 --- @type MarioAnimID
|
||||||
MARIO_ANIM_FALL_OVER_BACKWARDS = 1 --- @type MarioAnimID
|
MARIO_ANIM_FALL_OVER_BACKWARDS = 1 --- @type MarioAnimID
|
||||||
MARIO_ANIM_BACKWARD_AIR_KB = 2 --- @type MarioAnimID
|
MARIO_ANIM_BACKWARD_AIR_KB = 2 --- @type MarioAnimID
|
||||||
|
|
|
||||||
|
|
@ -5022,6 +5022,30 @@ function lvl_set_current_level(param, levelNum)
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param mode LEMode
|
||||||
|
--- Sets the lighting engine mode to `mode`
|
||||||
|
function le_set_mode(mode)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @return LEMode
|
||||||
|
--- Gets the lighting engine mode
|
||||||
|
function le_get_mode()
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param toneMapping LEToneMapping
|
||||||
|
--- Sets the lighting engine's tone mapping mode to `toneMapping`
|
||||||
|
function le_set_tone_mapping(toneMapping)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @return boolean
|
||||||
|
--- Gets whether the lighting engine has been enabled or not. It becomes enabled once a light is added.
|
||||||
|
function le_is_enabled()
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param pos Vec3f
|
--- @param pos Vec3f
|
||||||
--- @param out Color
|
--- @param out Color
|
||||||
--- @param lightIntensityScalar number
|
--- @param lightIntensityScalar number
|
||||||
|
|
@ -5030,6 +5054,15 @@ function le_calculate_lighting_color(pos, out, lightIntensityScalar)
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param pos Vec3f
|
||||||
|
--- @param normal Vec3f
|
||||||
|
--- @param out Color
|
||||||
|
--- @param lightIntensityScalar number
|
||||||
|
--- Calculates the lighting with `lightIntensityScalar` at a position and with a normal and outputs the color in `out`
|
||||||
|
function le_calculate_lighting_color_with_normal(pos, normal, out, lightIntensityScalar)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param pos Vec3f
|
--- @param pos Vec3f
|
||||||
--- @param out Vec3f
|
--- @param out Vec3f
|
||||||
--- Calculates the lighting direction from a position and outputs the result in `out`
|
--- Calculates the lighting direction from a position and outputs the result in `out`
|
||||||
|
|
@ -5103,6 +5136,13 @@ function le_set_light_intensity(id, intensity)
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param id integer
|
||||||
|
--- @param useSurfaceNormals boolean
|
||||||
|
--- Sets whether a lighting engine point light will use a surface's normals to determine its brightness with `useSurfaceNormals`
|
||||||
|
function le_set_light_use_surface_normals(id, useSurfaceNormals)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param m MarioState
|
--- @param m MarioState
|
||||||
--- @return integer
|
--- @return integer
|
||||||
--- Checks if Mario's current animation has reached its final frame (i.e., the last valid frame in the animation). Useful for deciding when to transition out of an animation-driven action
|
--- Checks if Mario's current animation has reached its final frame (i.e., the last valid frame in the animation). Useful for deciding when to transition out of an animation-driven action
|
||||||
|
|
@ -6589,11 +6629,19 @@ end
|
||||||
|
|
||||||
--- @param dest Mat4
|
--- @param dest Mat4
|
||||||
--- @param src Mat4
|
--- @param src Mat4
|
||||||
--- Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space
|
--- Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space. The `src` matrix *must* be affine!
|
||||||
function mtxf_inverse(dest, src)
|
function mtxf_inverse(dest, src)
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param dest Mat4
|
||||||
|
--- @param src Mat4
|
||||||
|
--- @return boolean
|
||||||
|
--- Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space. Returns `false` if the inversion failed.
|
||||||
|
function mtxf_inverse_non_affine(dest, src)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param dest Vec3f
|
--- @param dest Vec3f
|
||||||
--- @param objMtx Mat4
|
--- @param objMtx Mat4
|
||||||
--- @param camMtx Mat4
|
--- @param camMtx Mat4
|
||||||
|
|
|
||||||
|
|
@ -13,4 +13,4 @@ if [ ! -f "$FILE" ]; then
|
||||||
FILE=./build/us_pc/sm64coopdx
|
FILE=./build/us_pc/sm64coopdx
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$FILE &
|
$FILE --console --server 7777 &
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,9 @@
|
||||||
- [level_update.h](#level_updateh)
|
- [level_update.h](#level_updateh)
|
||||||
- [enum MarioSpawnType](#enum-MarioSpawnType)
|
- [enum MarioSpawnType](#enum-MarioSpawnType)
|
||||||
- [enum HUDDisplayFlag](#enum-HUDDisplayFlag)
|
- [enum HUDDisplayFlag](#enum-HUDDisplayFlag)
|
||||||
|
- [lighting_engine.h](#lighting_engineh)
|
||||||
|
- [enum LEMode](#enum-LEMode)
|
||||||
|
- [enum LEToneMapping](#enum-LEToneMapping)
|
||||||
- [mario_animation_ids.h](#mario_animation_idsh)
|
- [mario_animation_ids.h](#mario_animation_idsh)
|
||||||
- [enum MarioAnimID](#enum-MarioAnimID)
|
- [enum MarioAnimID](#enum-MarioAnimID)
|
||||||
- [enum CharacterAnimID](#enum-CharacterAnimID)
|
- [enum CharacterAnimID](#enum-CharacterAnimID)
|
||||||
|
|
@ -1619,6 +1622,26 @@
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
## [lighting_engine.h](#lighting_engine.h)
|
||||||
|
|
||||||
|
### [enum LEMode](#LEMode)
|
||||||
|
| Identifier | Value |
|
||||||
|
| :--------- | :---- |
|
||||||
|
| LE_MODE_AFFECT_ALL_SHADED | 0 |
|
||||||
|
| LE_MODE_AFFECT_ONLY_GEOMETRY_MODE | 1 |
|
||||||
|
|
||||||
|
### [enum LEToneMapping](#LEToneMapping)
|
||||||
|
| Identifier | Value |
|
||||||
|
| :--------- | :---- |
|
||||||
|
| LE_TONE_MAPPING_TOTAL_WEIGHTED | 0 |
|
||||||
|
| LE_TONE_MAPPING_WEIGHTED | 1 |
|
||||||
|
| LE_TONE_MAPPING_CLAMP | 2 |
|
||||||
|
| LE_TONE_MAPPING_REINHARD | 3 |
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [mario_animation_ids.h](#mario_animation_ids.h)
|
## [mario_animation_ids.h](#mario_animation_ids.h)
|
||||||
|
|
||||||
### [enum MarioAnimID](#MarioAnimID)
|
### [enum MarioAnimID](#MarioAnimID)
|
||||||
|
|
|
||||||
|
|
@ -6633,6 +6633,94 @@ Sets the level number and handles the act select screen. `param` is used for ove
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
|
||||||
|
## [le_set_mode](#le_set_mode)
|
||||||
|
|
||||||
|
### Description
|
||||||
|
Sets the lighting engine mode to `mode`
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`le_set_mode(mode)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| mode | [enum LEMode](constants.md#enum-LEMode) |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- None
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`void le_set_mode(enum LEMode mode);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [le_get_mode](#le_get_mode)
|
||||||
|
|
||||||
|
### Description
|
||||||
|
Gets the lighting engine mode
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local enumValue = le_get_mode()`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
- None
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
[enum LEMode](constants.md#enum-LEMode)
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`enum LEMode le_get_mode(void);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [le_set_tone_mapping](#le_set_tone_mapping)
|
||||||
|
|
||||||
|
### Description
|
||||||
|
Sets the lighting engine's tone mapping mode to `toneMapping`
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`le_set_tone_mapping(toneMapping)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| toneMapping | [enum LEToneMapping](constants.md#enum-LEToneMapping) |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- None
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`void le_set_tone_mapping(enum LEToneMapping toneMapping);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [le_is_enabled](#le_is_enabled)
|
||||||
|
|
||||||
|
### Description
|
||||||
|
Gets whether the lighting engine has been enabled or not. It becomes enabled once a light is added.
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local booleanValue = le_is_enabled()`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
- None
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- `boolean`
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`bool le_is_enabled(void);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [le_calculate_lighting_color](#le_calculate_lighting_color)
|
## [le_calculate_lighting_color](#le_calculate_lighting_color)
|
||||||
|
|
||||||
### Description
|
### Description
|
||||||
|
|
@ -6658,6 +6746,32 @@ Calculates the lighting with `lightIntensityScalar` at a position and outputs th
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
## [le_calculate_lighting_color_with_normal](#le_calculate_lighting_color_with_normal)
|
||||||
|
|
||||||
|
### Description
|
||||||
|
Calculates the lighting with `lightIntensityScalar` at a position and with a normal and outputs the color in `out`
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`le_calculate_lighting_color_with_normal(pos, normal, out, lightIntensityScalar)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| pos | [Vec3f](structs.md#Vec3f) |
|
||||||
|
| normal | [Vec3f](structs.md#Vec3f) |
|
||||||
|
| out | [Color](structs.md#Color) |
|
||||||
|
| lightIntensityScalar | `number` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- None
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, OUT Color out, f32 lightIntensityScalar);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [le_calculate_lighting_dir](#le_calculate_lighting_dir)
|
## [le_calculate_lighting_dir](#le_calculate_lighting_dir)
|
||||||
|
|
||||||
### Description
|
### Description
|
||||||
|
|
@ -6879,6 +6993,30 @@ Sets a lighting engine point light's `intensity`
|
||||||
|
|
||||||
[:arrow_up_small:](#)
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [le_set_light_use_surface_normals](#le_set_light_use_surface_normals)
|
||||||
|
|
||||||
|
### Description
|
||||||
|
Sets whether a lighting engine point light will use a surface's normals to determine its brightness with `useSurfaceNormals`
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`le_set_light_use_surface_normals(id, useSurfaceNormals)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| id | `integer` |
|
||||||
|
| useSurfaceNormals | `boolean` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- None
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`void le_set_light_use_surface_normals(s32 id, bool useSurfaceNormals);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4803,7 +4803,7 @@ Rotates the matrix `mtx` in the XY plane by the given `angle`. Rotating in the X
|
||||||
## [mtxf_inverse](#mtxf_inverse)
|
## [mtxf_inverse](#mtxf_inverse)
|
||||||
|
|
||||||
### Description
|
### Description
|
||||||
Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space
|
Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space. The `src` matrix *must* be affine!
|
||||||
|
|
||||||
### Lua Example
|
### Lua Example
|
||||||
`mtxf_inverse(dest, src)`
|
`mtxf_inverse(dest, src)`
|
||||||
|
|
@ -4824,6 +4824,30 @@ Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Ap
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
## [mtxf_inverse_non_affine](#mtxf_inverse_non_affine)
|
||||||
|
|
||||||
|
### Description
|
||||||
|
Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space. Returns `false` if the inversion failed.
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local booleanValue = mtxf_inverse_non_affine(dest, src)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| dest | [Mat4](structs.md#Mat4) |
|
||||||
|
| src | [Mat4](structs.md#Mat4) |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- `boolean`
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`bool mtxf_inverse_non_affine(OUT Mat4 dest, Mat4 src);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [get_pos_from_transform_mtx](#get_pos_from_transform_mtx)
|
## [get_pos_from_transform_mtx](#get_pos_from_transform_mtx)
|
||||||
|
|
||||||
### Description
|
### Description
|
||||||
|
|
|
||||||
|
|
@ -964,7 +964,12 @@
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
- lighting_engine.h
|
- lighting_engine.h
|
||||||
|
- [le_set_mode](functions-3.md#le_set_mode)
|
||||||
|
- [le_get_mode](functions-3.md#le_get_mode)
|
||||||
|
- [le_set_tone_mapping](functions-3.md#le_set_tone_mapping)
|
||||||
|
- [le_is_enabled](functions-3.md#le_is_enabled)
|
||||||
- [le_calculate_lighting_color](functions-3.md#le_calculate_lighting_color)
|
- [le_calculate_lighting_color](functions-3.md#le_calculate_lighting_color)
|
||||||
|
- [le_calculate_lighting_color_with_normal](functions-3.md#le_calculate_lighting_color_with_normal)
|
||||||
- [le_calculate_lighting_dir](functions-3.md#le_calculate_lighting_dir)
|
- [le_calculate_lighting_dir](functions-3.md#le_calculate_lighting_dir)
|
||||||
- [le_add_light](functions-3.md#le_add_light)
|
- [le_add_light](functions-3.md#le_add_light)
|
||||||
- [le_remove_light](functions-3.md#le_remove_light)
|
- [le_remove_light](functions-3.md#le_remove_light)
|
||||||
|
|
@ -974,6 +979,7 @@
|
||||||
- [le_set_light_color](functions-3.md#le_set_light_color)
|
- [le_set_light_color](functions-3.md#le_set_light_color)
|
||||||
- [le_set_light_radius](functions-3.md#le_set_light_radius)
|
- [le_set_light_radius](functions-3.md#le_set_light_radius)
|
||||||
- [le_set_light_intensity](functions-3.md#le_set_light_intensity)
|
- [le_set_light_intensity](functions-3.md#le_set_light_intensity)
|
||||||
|
- [le_set_light_use_surface_normals](functions-3.md#le_set_light_use_surface_normals)
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
|
@ -1217,6 +1223,7 @@
|
||||||
- [mtxf_mul_vec3s](functions-4.md#mtxf_mul_vec3s)
|
- [mtxf_mul_vec3s](functions-4.md#mtxf_mul_vec3s)
|
||||||
- [mtxf_rotate_xy](functions-4.md#mtxf_rotate_xy)
|
- [mtxf_rotate_xy](functions-4.md#mtxf_rotate_xy)
|
||||||
- [mtxf_inverse](functions-4.md#mtxf_inverse)
|
- [mtxf_inverse](functions-4.md#mtxf_inverse)
|
||||||
|
- [mtxf_inverse_non_affine](functions-4.md#mtxf_inverse_non_affine)
|
||||||
- [get_pos_from_transform_mtx](functions-4.md#get_pos_from_transform_mtx)
|
- [get_pos_from_transform_mtx](functions-4.md#get_pos_from_transform_mtx)
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
#define G_TEXADDR_DJUI 0x13
|
#define G_TEXADDR_DJUI 0x13
|
||||||
#define G_EXECUTE_DJUI 0xdd
|
#define G_EXECUTE_DJUI 0xdd
|
||||||
|
|
||||||
|
#define G_MTX_INVERSE_CAMERA_EXT 0x08
|
||||||
|
|
||||||
#define gsSPTextureAddrDjui(c) \
|
#define gsSPTextureAddrDjui(c) \
|
||||||
{{ \
|
{{ \
|
||||||
(_SHIFTL(G_TEXADDR_DJUI,24,8)|_SHIFTL(~(u32)(c),0,24)),(u32)(0) \
|
(_SHIFTL(G_TEXADDR_DJUI,24,8)|_SHIFTL(~(u32)(c),0,24)),(u32)(0) \
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,13 @@
|
||||||
#include "data/dynos_cmap.cpp.h"
|
#include "data/dynos_cmap.cpp.h"
|
||||||
|
|
||||||
#define LE_MAX_LIGHTS 256
|
#define LE_MAX_LIGHTS 256
|
||||||
#define LE_TOTAL_WEIGHTED_LIGHTING
|
|
||||||
|
|
||||||
static Color sAmbientColor;
|
static Color sAmbientColor = { 127, 127, 127 };
|
||||||
static void* sLights = NULL;
|
static void* sLights = NULL;
|
||||||
static s32 sLightID = 0;
|
static s32 sLightID = 0;
|
||||||
|
static enum LEMode sMode = LE_MODE_AFFECT_ALL_SHADED;
|
||||||
|
static enum LEToneMapping sToneMapping = LE_TONE_MAPPING_WEIGHTED;
|
||||||
|
static bool sEnabled = false;
|
||||||
|
|
||||||
static inline void color_set(Color color, u8 r, u8 g, u8 b) {
|
static inline void color_set(Color color, u8 r, u8 g, u8 b) {
|
||||||
color[0] = r;
|
color[0] = r;
|
||||||
|
|
@ -17,82 +19,156 @@ static inline void color_set(Color color, u8 r, u8 g, u8 b) {
|
||||||
color[2] = b;
|
color[2] = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void le_calculate_vertex_lighting(Vtx_t* v, OUT Color out) {
|
bool le_is_enabled(void) {
|
||||||
if (sLights == NULL) { return; }
|
// this is needed because we don't want to make vanilla darker,
|
||||||
|
// and we don't want to set the ambient color to { 255, 255, 255 }
|
||||||
|
// because then no one could see the effect of their lights
|
||||||
|
return sEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef LE_TOTAL_WEIGHTED_LIGHTING
|
void le_set_mode(enum LEMode mode) {
|
||||||
f32 r = v->cn[0] * (sAmbientColor[0] / 255.0f);
|
sMode = mode;
|
||||||
f32 g = v->cn[1] * (sAmbientColor[1] / 255.0f);
|
}
|
||||||
f32 b = v->cn[2] * (sAmbientColor[2] / 255.0f);
|
|
||||||
#else
|
|
||||||
f32 r = 0;
|
|
||||||
f32 g = 0;
|
|
||||||
f32 b = 0;
|
|
||||||
#endif
|
|
||||||
f32 weight = 1.0f;
|
|
||||||
for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) {
|
|
||||||
f32 diffX = light->posX - v->ob[0];
|
|
||||||
f32 diffY = light->posY - v->ob[1];
|
|
||||||
f32 diffZ = light->posZ - v->ob[2];
|
|
||||||
f32 dist = (diffX * diffX) + (diffY * diffY) + (diffZ * diffZ);
|
|
||||||
f32 radius = light->radius * light->radius;
|
|
||||||
if (dist > radius) { continue; }
|
|
||||||
|
|
||||||
f32 brightness = (1 - (dist / radius)) * light->intensity;
|
enum LEMode le_get_mode(void) {
|
||||||
r += light->colorR * brightness;
|
return sMode;
|
||||||
g += light->colorG * brightness;
|
}
|
||||||
b += light->colorB * brightness;
|
|
||||||
weight += brightness;
|
void le_set_tone_mapping(enum LEToneMapping toneMapping) {
|
||||||
|
sToneMapping = toneMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void le_tone_map_total_weighted(OUT Color out, Color in_ambient, Vec3f in_color, float weight) {
|
||||||
|
out[0] = clamp((in_ambient[0] + in_color[0]) / weight, 0, 255);
|
||||||
|
out[1] = clamp((in_ambient[1] + in_color[1]) / weight, 0, 255);
|
||||||
|
out[2] = clamp((in_ambient[2] + in_color[2]) / weight, 0, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void le_tone_map_weighted(OUT Color out, Color in_ambient, Vec3f in_color, float weight) {
|
||||||
|
out[0] = clamp(in_ambient[0] + (in_color[0] / weight), 0, 255);
|
||||||
|
out[1] = clamp(in_ambient[1] + (in_color[1] / weight), 0, 255);
|
||||||
|
out[2] = clamp(in_ambient[2] + (in_color[2] / weight), 0, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void le_tone_map_clamp(OUT Color out, Color in_ambient, Vec3f in_color) {
|
||||||
|
out[0] = clamp(in_ambient[0] + in_color[0], 0, 255);
|
||||||
|
out[1] = clamp(in_ambient[1] + in_color[1], 0, 255);
|
||||||
|
out[2] = clamp(in_ambient[2] + in_color[2], 0, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void le_tone_map_reinhard(OUT Color out, Color in_ambient, Vec3f in_color) {
|
||||||
|
in_color[0] += in_ambient[0];
|
||||||
|
in_color[1] += in_ambient[1];
|
||||||
|
in_color[2] += in_ambient[2];
|
||||||
|
|
||||||
|
out[0] = clamp((in_color[0] / (in_color[0] + 255.0f)) * 255.0f, 0, 255);
|
||||||
|
out[1] = clamp((in_color[1] / (in_color[1] + 255.0f)) * 255.0f, 0, 255);
|
||||||
|
out[2] = clamp((in_color[2] / (in_color[2] + 255.0f)) * 255.0f, 0, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void le_tone_map(OUT Color out, Color in_ambient, Vec3f in_color, float weight) {
|
||||||
|
switch (sToneMapping) {
|
||||||
|
case LE_TONE_MAPPING_TOTAL_WEIGHTED: le_tone_map_total_weighted(out, in_ambient, in_color, weight); break;
|
||||||
|
case LE_TONE_MAPPING_WEIGHTED: le_tone_map_weighted(out, in_ambient, in_color, weight); break;
|
||||||
|
case LE_TONE_MAPPING_CLAMP: le_tone_map_clamp(out, in_ambient, in_color); break;
|
||||||
|
case LE_TONE_MAPPING_REINHARD: le_tone_map_reinhard(out, in_ambient, in_color); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void le_calculate_light_contribution(struct LELight* light, Vec3f pos, Vec3f normal, f32 lightIntensityScalar, OUT Vec3f out_color, OUT f32* weight) {
|
||||||
|
// skip 'inactive' lights
|
||||||
|
if (light->intensity <= 0 || light->radius <= 0) { return; }
|
||||||
|
|
||||||
|
// vector to light
|
||||||
|
f32 diffX = light->posX - pos[0];
|
||||||
|
f32 diffY = light->posY - pos[1];
|
||||||
|
f32 diffZ = light->posZ - pos[2];
|
||||||
|
|
||||||
|
// squared distance check
|
||||||
|
f32 dist2 = (diffX * diffX) + (diffY * diffY) + (diffZ * diffZ);
|
||||||
|
f32 radius2 = light->radius * light->radius;
|
||||||
|
if (dist2 > radius2 || dist2 <= 0) { return; }
|
||||||
|
|
||||||
|
// attenuation & intensity
|
||||||
|
f32 att = 1.0f - (dist2 / radius2);
|
||||||
|
f32 brightness = att * light->intensity * lightIntensityScalar;
|
||||||
|
|
||||||
|
// normalize diff
|
||||||
|
f32 invLen = 1.0f / sqrtf(dist2);
|
||||||
|
diffX *= invLen;
|
||||||
|
diffY *= invLen;
|
||||||
|
diffZ *= invLen;
|
||||||
|
|
||||||
|
if (light->useSurfaceNormals && normal) {
|
||||||
|
// lambert term
|
||||||
|
f32 nl = (normal[0] * diffX) + (normal[1] * diffY) + (normal[2] * diffZ);
|
||||||
|
if (nl <= 0.0f) { return; }
|
||||||
|
|
||||||
|
// modulate by normal
|
||||||
|
brightness *= nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LE_TOTAL_WEIGHTED_LIGHTING
|
// accumulate
|
||||||
out[0] = min(r / weight, 255);
|
out_color[0] += light->colorR * brightness;
|
||||||
out[1] = min(g / weight, 255);
|
out_color[1] += light->colorG * brightness;
|
||||||
out[2] = min(b / weight, 255);
|
out_color[2] += light->colorB * brightness;
|
||||||
#else
|
*weight += brightness;
|
||||||
out[0] = min((v->cn[0] * (sAmbientColor[0] / 255.0f)) + (r / weight), 255);
|
}
|
||||||
out[1] = min((v->cn[1] * (sAmbientColor[1] / 255.0f)) + (g / weight), 255);
|
|
||||||
out[2] = min((v->cn[2] * (sAmbientColor[2] / 255.0f)) + (b / weight), 255);
|
void le_calculate_vertex_lighting(Vtx_t* v, Vec3f pos, OUT Color out) {
|
||||||
#endif
|
if (sLights == NULL) { return; }
|
||||||
|
|
||||||
|
// clear color
|
||||||
|
Vec3f color = { 0 };
|
||||||
|
|
||||||
|
// accumulate lighting
|
||||||
|
f32 weight = 1.0f;
|
||||||
|
for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) {
|
||||||
|
le_calculate_light_contribution(light, pos, NULL, 1, color, &weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// tone map and output
|
||||||
|
Color vtxAmbient = {
|
||||||
|
v->cn[0] * (sAmbientColor[0] / 255.0f),
|
||||||
|
v->cn[1] * (sAmbientColor[1] / 255.0f),
|
||||||
|
v->cn[2] * (sAmbientColor[2] / 255.0f),
|
||||||
|
};
|
||||||
|
le_tone_map(out, vtxAmbient, color, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void le_calculate_lighting_color(Vec3f pos, OUT Color out, f32 lightIntensityScalar) {
|
void le_calculate_lighting_color(Vec3f pos, OUT Color out, f32 lightIntensityScalar) {
|
||||||
if (sLights == NULL) { return; }
|
if (sLights == NULL) { return; }
|
||||||
|
|
||||||
#ifdef LE_TOTAL_WEIGHTED_LIGHTING
|
// clear color
|
||||||
f32 r = sAmbientColor[0];
|
Vec3f color = { 0 };
|
||||||
f32 g = sAmbientColor[1];
|
|
||||||
f32 b = sAmbientColor[2];
|
// accumulate lighting
|
||||||
#else
|
|
||||||
f32 r = 0;
|
|
||||||
f32 g = 0;
|
|
||||||
f32 b = 0;
|
|
||||||
#endif
|
|
||||||
f32 weight = 1.0f;
|
f32 weight = 1.0f;
|
||||||
for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) {
|
for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) {
|
||||||
f32 diffX = light->posX - pos[0];
|
le_calculate_light_contribution(light, pos, NULL, lightIntensityScalar, color, &weight);
|
||||||
f32 diffY = light->posY - pos[1];
|
|
||||||
f32 diffZ = light->posZ - pos[2];
|
|
||||||
f32 dist = (diffX * diffX) + (diffY * diffY) + (diffZ * diffZ);
|
|
||||||
f32 radius = light->radius * light->radius;
|
|
||||||
if (dist > radius) { continue; }
|
|
||||||
|
|
||||||
f32 brightness = (1 - (dist / radius)) * light->intensity * lightIntensityScalar;
|
|
||||||
r += light->colorR * brightness;
|
|
||||||
g += light->colorG * brightness;
|
|
||||||
b += light->colorB * brightness;
|
|
||||||
weight += brightness;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LE_TOTAL_WEIGHTED_LIGHTING
|
// tone map and output
|
||||||
out[0] = min(r / weight, 255);
|
le_tone_map(out, sAmbientColor, color, weight);
|
||||||
out[1] = min(g / weight, 255);
|
}
|
||||||
out[2] = min(b / weight, 255);
|
|
||||||
#else
|
void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, OUT Color out, f32 lightIntensityScalar) {
|
||||||
out[0] = min(sAmbientColor[0] + (r / weight), 255);
|
if (sLights == NULL) { return; }
|
||||||
out[1] = min(sAmbientColor[1] + (g / weight), 255);
|
|
||||||
out[2] = min(sAmbientColor[2] + (b / weight), 255);
|
// normalize normal
|
||||||
#endif
|
if (normal) { vec3f_normalize(normal); }
|
||||||
|
|
||||||
|
// clear color
|
||||||
|
Vec3f color = { 0 };
|
||||||
|
|
||||||
|
// accumulate lighting
|
||||||
|
f32 weight = 1.0f;
|
||||||
|
for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) {
|
||||||
|
le_calculate_light_contribution(light, pos, normal, lightIntensityScalar, color, &weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// tone map and output
|
||||||
|
le_tone_map(out, sAmbientColor, color, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void le_calculate_lighting_dir(Vec3f pos, OUT Vec3f out) {
|
void le_calculate_lighting_dir(Vec3f pos, OUT Vec3f out) {
|
||||||
|
|
@ -145,7 +221,10 @@ s32 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensit
|
||||||
light->colorB = b;
|
light->colorB = b;
|
||||||
light->radius = radius;
|
light->radius = radius;
|
||||||
light->intensity = intensity;
|
light->intensity = intensity;
|
||||||
|
light->useSurfaceNormals = true;
|
||||||
hmap_put(sLights, ++sLightID, light);
|
hmap_put(sLights, ++sLightID, light);
|
||||||
|
|
||||||
|
sEnabled = true;
|
||||||
return sLightID;
|
return sLightID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,6 +242,7 @@ s32 le_get_light_count(void) {
|
||||||
|
|
||||||
void le_set_ambient_color(u8 r, u8 g, u8 b) {
|
void le_set_ambient_color(u8 r, u8 g, u8 b) {
|
||||||
color_set(sAmbientColor, r, g, b);
|
color_set(sAmbientColor, r, g, b);
|
||||||
|
sEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void le_set_light_pos(s32 id, f32 x, f32 y, f32 z) {
|
void le_set_light_pos(s32 id, f32 x, f32 y, f32 z) {
|
||||||
|
|
@ -201,6 +281,14 @@ void le_set_light_intensity(s32 id, f32 intensity) {
|
||||||
light->intensity = intensity;
|
light->intensity = intensity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void le_set_light_use_surface_normals(s32 id, bool useSurfaceNormals) {
|
||||||
|
if (sLights == NULL || id <= 0) { return; }
|
||||||
|
|
||||||
|
struct LELight* light = hmap_get(sLights, id);
|
||||||
|
if (light == NULL) { return; }
|
||||||
|
light->useSurfaceNormals = useSurfaceNormals;
|
||||||
|
}
|
||||||
|
|
||||||
void le_clear(void) {
|
void le_clear(void) {
|
||||||
if (sLights == NULL) { return; }
|
if (sLights == NULL) { return; }
|
||||||
|
|
||||||
|
|
@ -209,14 +297,17 @@ void le_clear(void) {
|
||||||
}
|
}
|
||||||
hmap_clear(sLights);
|
hmap_clear(sLights);
|
||||||
sLightID = 0;
|
sLightID = 0;
|
||||||
sAmbientColor[0] = 0;
|
sAmbientColor[0] = 127;
|
||||||
sAmbientColor[1] = 0;
|
sAmbientColor[1] = 127;
|
||||||
sAmbientColor[2] = 0;
|
sAmbientColor[2] = 127;
|
||||||
}
|
}
|
||||||
|
|
||||||
void le_shutdown(void) {
|
void le_shutdown(void) {
|
||||||
if (sLights == NULL) { return; }
|
if (sLights == NULL) { return; }
|
||||||
|
|
||||||
|
sEnabled = false;
|
||||||
|
sMode = LE_MODE_AFFECT_ALL_SHADED;
|
||||||
|
sToneMapping = LE_TONE_MAPPING_WEIGHTED;
|
||||||
le_clear();
|
le_clear();
|
||||||
hmap_destroy(sLights);
|
hmap_destroy(sLights);
|
||||||
sLights = NULL;
|
sLights = NULL;
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,35 @@ struct LELight
|
||||||
u8 colorB;
|
u8 colorB;
|
||||||
f32 radius;
|
f32 radius;
|
||||||
f32 intensity;
|
f32 intensity;
|
||||||
|
bool useSurfaceNormals;
|
||||||
};
|
};
|
||||||
|
|
||||||
void le_calculate_vertex_lighting(Vtx_t* v, OUT Color out);
|
enum LEMode {
|
||||||
|
LE_MODE_AFFECT_ALL_SHADED,
|
||||||
|
LE_MODE_AFFECT_ONLY_GEOMETRY_MODE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LEToneMapping {
|
||||||
|
LE_TONE_MAPPING_TOTAL_WEIGHTED,
|
||||||
|
LE_TONE_MAPPING_WEIGHTED,
|
||||||
|
LE_TONE_MAPPING_CLAMP,
|
||||||
|
LE_TONE_MAPPING_REINHARD,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* |description|Sets the lighting engine mode to `mode`|descriptionEnd|*/
|
||||||
|
void le_set_mode(enum LEMode mode);
|
||||||
|
/* |description|Gets the lighting engine mode|descriptionEnd|*/
|
||||||
|
enum LEMode le_get_mode(void);
|
||||||
|
/* |description|Sets the lighting engine's tone mapping mode to `toneMapping`|descriptionEnd|*/
|
||||||
|
void le_set_tone_mapping(enum LEToneMapping toneMapping);
|
||||||
|
/* |description|Gets whether the lighting engine has been enabled or not. It becomes enabled once a light is added.|descriptionEnd|*/
|
||||||
|
bool le_is_enabled(void);
|
||||||
|
|
||||||
|
void le_calculate_vertex_lighting(Vtx_t* v, Vec3f pos, OUT Color out);
|
||||||
/* |description|Calculates the lighting with `lightIntensityScalar` at a position and outputs the color in `out`|descriptionEnd|*/
|
/* |description|Calculates the lighting with `lightIntensityScalar` at a position and outputs the color in `out`|descriptionEnd|*/
|
||||||
void le_calculate_lighting_color(Vec3f pos, OUT Color out, f32 lightIntensityScalar);
|
void le_calculate_lighting_color(Vec3f pos, OUT Color out, f32 lightIntensityScalar);
|
||||||
|
/* |description|Calculates the lighting with `lightIntensityScalar` at a position and with a normal and outputs the color in `out`|descriptionEnd|*/
|
||||||
|
void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, OUT Color out, f32 lightIntensityScalar);
|
||||||
/* |description|Calculates the lighting direction from a position and outputs the result in `out`|descriptionEnd| */
|
/* |description|Calculates the lighting direction from a position and outputs the result in `out`|descriptionEnd| */
|
||||||
void le_calculate_lighting_dir(Vec3f pos, OUT Vec3f out);
|
void le_calculate_lighting_dir(Vec3f pos, OUT Vec3f out);
|
||||||
/* |description|Adds a lighting engine point light at `x`, `y`, `z` with color `r`, `g`, `b` and `radius` with `intensity`|descriptionEnd| */
|
/* |description|Adds a lighting engine point light at `x`, `y`, `z` with color `r`, `g`, `b` and `radius` with `intensity`|descriptionEnd| */
|
||||||
|
|
@ -36,6 +60,8 @@ void le_set_light_color(s32 id, u8 r, u8 g, u8 b);
|
||||||
void le_set_light_radius(s32 id, f32 radius);
|
void le_set_light_radius(s32 id, f32 radius);
|
||||||
/* |description|Sets a lighting engine point light's `intensity`|descriptionEnd| */
|
/* |description|Sets a lighting engine point light's `intensity`|descriptionEnd| */
|
||||||
void le_set_light_intensity(s32 id, f32 intensity);
|
void le_set_light_intensity(s32 id, f32 intensity);
|
||||||
|
/* |description|Sets whether a lighting engine point light will use a surface's normals to determine its brightness with `useSurfaceNormals`|descriptionEnd| */
|
||||||
|
void le_set_light_use_surface_normals(s32 id, bool useSurfaceNormals);
|
||||||
void le_clear(void);
|
void le_clear(void);
|
||||||
void le_shutdown(void);
|
void le_shutdown(void);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -781,6 +781,64 @@ OPTIMIZE_O3 void mtxf_inverse(OUT Mat4 dest, Mat4 src) {
|
||||||
mtxf_copy(dest, buf);
|
mtxf_copy(dest, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the inverse of 'src' and put it into 'dest' but it can be a non-affine matrix.
|
||||||
|
* Obtains the inverse via Gauss-Jordan elimination.
|
||||||
|
*/
|
||||||
|
OPTIMIZE_O3 bool mtxf_inverse_non_affine(OUT Mat4 dest, Mat4 src) {
|
||||||
|
// augmented matrix [ src | I ]
|
||||||
|
f32 aug[4][8];
|
||||||
|
for (s32 i = 0; i < 4; i++) {
|
||||||
|
for (s32 j = 0; j < 4; j++) {
|
||||||
|
aug[i][j] = src[i][j];
|
||||||
|
aug[i][j + 4] = (i == j) ? 1.0f : 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// forward elimination
|
||||||
|
for (s32 k = 0; k < 4; k++) {
|
||||||
|
// find pivot row
|
||||||
|
s32 piv = k;
|
||||||
|
for (s32 i = k + 1; i < 4; i++) {
|
||||||
|
if (fabsf(aug[i][k]) > fabsf(aug[piv][k])) { piv = i; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fabsf(aug[piv][k]) < FLT_EPSILON) { return false; }
|
||||||
|
|
||||||
|
// swap pivot row into place
|
||||||
|
if (piv != k) {
|
||||||
|
for (s32 j = 0; j < 8; j++) {
|
||||||
|
f32 tmp = aug[k][j];
|
||||||
|
aug[k][j] = aug[piv][j];
|
||||||
|
aug[piv][j] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// scale pivot row to make pivot = 1
|
||||||
|
f32 inv_p = 1.0f / aug[k][k];
|
||||||
|
for (s32 j = k; j < 8; j++) { aug[k][j] *= inv_p; }
|
||||||
|
|
||||||
|
// eliminate below
|
||||||
|
for (s32 i = k+1; i < 4; i++) {
|
||||||
|
f32 f = aug[i][k];
|
||||||
|
for (s32 j = k; j < 8; j++) { aug[i][j] -= f * aug[k][j]; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// backward substitution
|
||||||
|
for (s32 k = 3; k >= 0; k--) {
|
||||||
|
for (s32 i = 0; i < k; i++) {
|
||||||
|
f32 f = aug[i][k];
|
||||||
|
for (s32 j = k; j < 8; j++) { aug[i][j] -= f * aug[k][j]; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy right half (the inverse) into dest
|
||||||
|
for (s32 i = 0; i < 4; i++) { memcpy(dest[i], &aug[i][4], 4 * sizeof(f32)); }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract a position given an object's transformation matrix and a camera matrix.
|
* Extract a position given an object's transformation matrix and a camera matrix.
|
||||||
* This is used for determining the world position of the held object: since objMtx
|
* This is used for determining the world position of the held object: since objMtx
|
||||||
|
|
@ -800,3 +858,4 @@ OPTIMIZE_O3 Vec3fp get_pos_from_transform_mtx(OUT Vec3f dest, Mat4 objMtx, Mat4
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -253,10 +253,15 @@ Rotates the matrix `mtx` in the XY plane by the given `angle`. Rotating in the X
|
||||||
OPTIMIZE_O3 void mtxf_rotate_xy(OUT Mat4 mtx, s16 angle);
|
OPTIMIZE_O3 void mtxf_rotate_xy(OUT Mat4 mtx, s16 angle);
|
||||||
|
|
||||||
/* |description|
|
/* |description|
|
||||||
Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space
|
Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space. The `src` matrix *must* be affine!
|
||||||
|descriptionEnd| */
|
|descriptionEnd| */
|
||||||
OPTIMIZE_O3 void mtxf_inverse(OUT Mat4 dest, Mat4 src);
|
OPTIMIZE_O3 void mtxf_inverse(OUT Mat4 dest, Mat4 src);
|
||||||
|
|
||||||
|
/* |description|
|
||||||
|
Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space. Returns `false` if the inversion failed.
|
||||||
|
|descriptionEnd| */
|
||||||
|
OPTIMIZE_O3 bool mtxf_inverse_non_affine(OUT Mat4 dest, Mat4 src);
|
||||||
|
|
||||||
/* |description|
|
/* |description|
|
||||||
Extracts the position (translation component) from the transformation matrix `objMtx` relative to the coordinate system defined by `camMtx` and stores that 3D position in `dest`. This can be used to get the object's coordinates in camera space
|
Extracts the position (translation component) from the transformation matrix `objMtx` relative to the coordinate system defined by `camMtx` and stores that 3D position in `dest`. This can be used to get the object's coordinates in camera space
|
||||||
|descriptionEnd| */
|
|descriptionEnd| */
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "area.h"
|
#include "area.h"
|
||||||
#include "engine/math_util.h"
|
#include "engine/math_util.h"
|
||||||
|
#include "engine/lighting_engine.h"
|
||||||
#include "game_init.h"
|
#include "game_init.h"
|
||||||
#include "gfx_dimensions.h"
|
#include "gfx_dimensions.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
@ -403,9 +404,12 @@ static void geo_process_master_list_sub(struct GraphNodeMasterList *node) {
|
||||||
gMtxTbl[gMtxTblSize].displayList = currList->displayList;
|
gMtxTbl[gMtxTblSize].displayList = currList->displayList;
|
||||||
gMtxTbl[gMtxTblSize++].usingCamSpace = currList->usingCamSpace;
|
gMtxTbl[gMtxTblSize++].usingCamSpace = currList->usingCamSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(currList->transformPrev),
|
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(currList->transformPrev),
|
||||||
G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
|
G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||||
|
|
||||||
gSPDisplayList(gDisplayListHead++, currList->displayList);
|
gSPDisplayList(gDisplayListHead++, currList->displayList);
|
||||||
|
|
||||||
currList = currList->next;
|
currList = currList->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -609,6 +613,16 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
|
||||||
mtxf_copy(gCamera->mtx, gMatStack[gMatStackIndex]);
|
mtxf_copy(gCamera->mtx, gMatStack[gMatStackIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute inverse matrix for lighting engine
|
||||||
|
if (le_is_enabled()) {
|
||||||
|
Mat4 invCameraMatrix;
|
||||||
|
if (mtxf_inverse_non_affine(invCameraMatrix, gCamera->mtx)) {
|
||||||
|
Mtx *invMtx = alloc_display_list(sizeof(Mtx));
|
||||||
|
mtxf_to_mtx(invMtx, invCameraMatrix);
|
||||||
|
gSPMatrix(gDisplayListHead++, invMtx, G_MTX_INVERSE_CAMERA_EXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (node->fnNode.node.children != 0) {
|
if (node->fnNode.node.children != 0) {
|
||||||
gCurGraphNodeCamera = node;
|
gCurGraphNodeCamera = node;
|
||||||
sUsingCamSpace = TRUE;
|
sUsingCamSpace = TRUE;
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,10 @@ Color gVertexColor = { 0xFF, 0xFF, 0xFF };
|
||||||
Color gFogColor = { 0xFF, 0xFF, 0xFF };
|
Color gFogColor = { 0xFF, 0xFF, 0xFF };
|
||||||
f32 gFogIntensity = 1;
|
f32 gFogIntensity = 1;
|
||||||
|
|
||||||
|
// need inverse camera matrix to compute world space for lighting engine
|
||||||
|
static Mat4 sInverseCameraMatrix;
|
||||||
|
static bool sHasInverseCameraMatrix = false;
|
||||||
|
|
||||||
// 4x4 pink-black checkerboard texture to indicate missing textures
|
// 4x4 pink-black checkerboard texture to indicate missing textures
|
||||||
#define MISSING_W 4
|
#define MISSING_W 4
|
||||||
#define MISSING_H 4
|
#define MISSING_H 4
|
||||||
|
|
@ -627,7 +631,18 @@ static void calculate_normal_dir(const Light_t *light, Vec3f coeffs, bool applyL
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OPTIMIZE_O3 gfx_sp_matrix(uint8_t parameters, const int32_t *addr) {
|
static void OPTIMIZE_O3 gfx_sp_matrix(uint8_t parameters, const int32_t *addr) {
|
||||||
|
|
||||||
Mat4 matrix;
|
Mat4 matrix;
|
||||||
|
|
||||||
|
// remember inverse camera matrix to use for the lighting engine
|
||||||
|
if (parameters == G_MTX_INVERSE_CAMERA_EXT) {
|
||||||
|
if (addr) {
|
||||||
|
memcpy(sInverseCameraMatrix, addr, sizeof(sInverseCameraMatrix));
|
||||||
|
sHasInverseCameraMatrix = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Original code when fixed point matrices were used
|
// Original code when fixed point matrices were used
|
||||||
for (int32_t i = 0; i < 4; i++) {
|
for (int32_t i = 0; i < 4; i++) {
|
||||||
|
|
@ -642,6 +657,7 @@ static void OPTIMIZE_O3 gfx_sp_matrix(uint8_t parameters, const int32_t *addr) {
|
||||||
memcpy(matrix, addr, sizeof(matrix));
|
memcpy(matrix, addr, sizeof(matrix));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (parameters & G_MTX_PROJECTION) {
|
if (parameters & G_MTX_PROJECTION) {
|
||||||
if (parameters & G_MTX_LOAD) {
|
if (parameters & G_MTX_LOAD) {
|
||||||
mtxf_copy(rsp.P_matrix, matrix);
|
mtxf_copy(rsp.P_matrix, matrix);
|
||||||
|
|
@ -678,6 +694,37 @@ static float gfx_adjust_x_for_aspect_ratio(float x) {
|
||||||
return x * gfx_current_dimensions.x_adjust_ratio;
|
return x * gfx_current_dimensions.x_adjust_ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static OPTIMIZE_O3 void gfx_local_to_world_space(OUT Vec3f pos, OUT Vec3f normal) {
|
||||||
|
if (!sHasInverseCameraMatrix) { return; }
|
||||||
|
|
||||||
|
// strip view matrix off of the model-view matrix
|
||||||
|
Mat4 model;
|
||||||
|
mtxf_mul(model, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size-1], sInverseCameraMatrix);
|
||||||
|
|
||||||
|
// transform position to world
|
||||||
|
Vec3f worldPos;
|
||||||
|
worldPos[0] = pos[0] * model[0][0] + pos[1] * model[1][0] + pos[2] * model[2][0] + model[3][0];
|
||||||
|
worldPos[1] = pos[0] * model[0][1] + pos[1] * model[1][1] + pos[2] * model[2][1] + model[3][1];
|
||||||
|
worldPos[2] = pos[0] * model[0][2] + pos[1] * model[1][2] + pos[2] * model[2][2] + model[3][2];
|
||||||
|
|
||||||
|
pos[0] = worldPos[0];
|
||||||
|
pos[1] = worldPos[1];
|
||||||
|
pos[2] = worldPos[2];
|
||||||
|
|
||||||
|
// transform normal to world
|
||||||
|
if (normal) {
|
||||||
|
Vec3f worldNormal;
|
||||||
|
worldNormal[0] = normal[0] * model[0][0] + normal[1] * model[1][0] + normal[2] * model[2][0];
|
||||||
|
worldNormal[1] = normal[0] * model[0][1] + normal[1] * model[1][1] + normal[2] * model[2][1];
|
||||||
|
worldNormal[2] = normal[0] * model[0][2] + normal[1] * model[1][2] + normal[2] * model[2][2];
|
||||||
|
|
||||||
|
normal[0] = worldNormal[0];
|
||||||
|
normal[1] = worldNormal[1];
|
||||||
|
normal[2] = worldNormal[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *vertices, bool luaVertexColor) {
|
static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *vertices, bool luaVertexColor) {
|
||||||
if (!vertices) { return; }
|
if (!vertices) { return; }
|
||||||
|
|
||||||
|
|
@ -814,21 +861,37 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
|
||||||
V = (int32_t)((doty / 127.0f + 1.0f) / 4.0f * rsp.texture_scaling_factor.t);
|
V = (int32_t)((doty / 127.0f + 1.0f) / 4.0f * rsp.texture_scaling_factor.t);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rsp.geometry_mode & G_LIGHTING_ENGINE_EXT) {
|
if (le_is_enabled() && ((le_get_mode() == LE_MODE_AFFECT_ALL_SHADED) || (rsp.geometry_mode & G_LIGHTING_ENGINE_EXT))) {
|
||||||
Color color;
|
Color color;
|
||||||
CTX_BEGIN(CTX_LIGHTING);
|
CTX_BEGIN(CTX_LIGHTING);
|
||||||
le_calculate_lighting_color(((Vtx_t*)v)->ob, color, 1.0f);
|
|
||||||
|
Vec3f vpos = { v->ob[0], v->ob[1], v->ob[2] };
|
||||||
|
Vec3f vnormal = { nx, ny, nz };
|
||||||
|
|
||||||
|
// transform vpos and vnormal to world space
|
||||||
|
gfx_local_to_world_space(vpos, vnormal);
|
||||||
|
|
||||||
|
le_calculate_lighting_color_with_normal(vpos, vnormal, color, 1.0f);
|
||||||
|
|
||||||
CTX_END(CTX_LIGHTING);
|
CTX_END(CTX_LIGHTING);
|
||||||
|
|
||||||
d->color.r *= color[0] / 255.0f;
|
d->color.r *= color[0] / 255.0f;
|
||||||
d->color.g *= color[1] / 255.0f;
|
d->color.g *= color[1] / 255.0f;
|
||||||
d->color.b *= color[2] / 255.0f;
|
d->color.b *= color[2] / 255.0f;
|
||||||
}
|
}
|
||||||
} else if (rsp.geometry_mode & G_LIGHTING_ENGINE_EXT) {
|
} else if (le_is_enabled() && (rsp.geometry_mode & G_LIGHTING_ENGINE_EXT)) {
|
||||||
Color color;
|
Color color;
|
||||||
CTX_BEGIN(CTX_LIGHTING);
|
CTX_BEGIN(CTX_LIGHTING);
|
||||||
le_calculate_vertex_lighting((Vtx_t*)v, color);
|
|
||||||
|
Vec3f vpos = { v->ob[0], v->ob[1], v->ob[2] };
|
||||||
|
|
||||||
|
// transform vpos to world space
|
||||||
|
gfx_local_to_world_space(vpos, NULL);
|
||||||
|
|
||||||
|
le_calculate_vertex_lighting((Vtx_t*)v, vpos, color);
|
||||||
|
|
||||||
CTX_END(CTX_LIGHTING);
|
CTX_END(CTX_LIGHTING);
|
||||||
|
|
||||||
if (luaVertexColor) {
|
if (luaVertexColor) {
|
||||||
d->color.r = color[0] * vertexColorCached[0];
|
d->color.r = color[0] * vertexColorCached[0];
|
||||||
d->color.g = color[1] * vertexColorCached[1];
|
d->color.g = color[1] * vertexColorCached[1];
|
||||||
|
|
@ -1875,6 +1938,8 @@ void gfx_start_frame(void) {
|
||||||
void gfx_run(Gfx *commands) {
|
void gfx_run(Gfx *commands) {
|
||||||
gfx_sp_reset();
|
gfx_sp_reset();
|
||||||
|
|
||||||
|
sHasInverseCameraMatrix = false;
|
||||||
|
|
||||||
//puts("New frame");
|
//puts("New frame");
|
||||||
|
|
||||||
if (!gfx_wapi->start_frame()) {
|
if (!gfx_wapi->start_frame()) {
|
||||||
|
|
|
||||||
|
|
@ -1777,6 +1777,12 @@ char gSmluaConstants[] = ""
|
||||||
"HUD_DISPLAY_FLAG_EMPHASIZE_POWER=0x8000\n"
|
"HUD_DISPLAY_FLAG_EMPHASIZE_POWER=0x8000\n"
|
||||||
"HUD_DISPLAY_NONE=0x0000\n"
|
"HUD_DISPLAY_NONE=0x0000\n"
|
||||||
"HUD_DISPLAY_DEFAULT=HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_COIN_COUNT | HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA_AND_POWER | HUD_DISPLAY_FLAG_CAMERA | HUD_DISPLAY_FLAG_POWER | HUD_DISPLAY_FLAG_KEYS | HUD_DISPLAY_FLAG_UNKNOWN_0020\n"
|
"HUD_DISPLAY_DEFAULT=HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_COIN_COUNT | HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA_AND_POWER | HUD_DISPLAY_FLAG_CAMERA | HUD_DISPLAY_FLAG_POWER | HUD_DISPLAY_FLAG_KEYS | HUD_DISPLAY_FLAG_UNKNOWN_0020\n"
|
||||||
|
"LE_MODE_AFFECT_ALL_SHADED=0\n"
|
||||||
|
"LE_MODE_AFFECT_ONLY_GEOMETRY_MODE=1\n"
|
||||||
|
"LE_TONE_MAPPING_TOTAL_WEIGHTED=0\n"
|
||||||
|
"LE_TONE_MAPPING_WEIGHTED=1\n"
|
||||||
|
"LE_TONE_MAPPING_CLAMP=2\n"
|
||||||
|
"LE_TONE_MAPPING_REINHARD=3\n"
|
||||||
"MARIO_ANIM_SLOW_LEDGE_GRAB=0\n"
|
"MARIO_ANIM_SLOW_LEDGE_GRAB=0\n"
|
||||||
"MARIO_ANIM_FALL_OVER_BACKWARDS=1\n"
|
"MARIO_ANIM_FALL_OVER_BACKWARDS=1\n"
|
||||||
"MARIO_ANIM_BACKWARD_AIR_KB=2\n"
|
"MARIO_ANIM_BACKWARD_AIR_KB=2\n"
|
||||||
|
|
|
||||||
|
|
@ -15515,6 +15515,70 @@ int smlua_func_lvl_set_current_level(lua_State* L) {
|
||||||
// lighting_engine.h //
|
// lighting_engine.h //
|
||||||
///////////////////////
|
///////////////////////
|
||||||
|
|
||||||
|
int smlua_func_le_set_mode(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 1) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "le_set_mode", 1, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mode = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_set_mode"); return 0; }
|
||||||
|
|
||||||
|
le_set_mode(mode);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smlua_func_le_get_mode(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", "le_get_mode", 0, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lua_pushinteger(L, le_get_mode());
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smlua_func_le_set_tone_mapping(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 1) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "le_set_tone_mapping", 1, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int toneMapping = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_set_tone_mapping"); return 0; }
|
||||||
|
|
||||||
|
le_set_tone_mapping(toneMapping);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smlua_func_le_is_enabled(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", "le_is_enabled", 0, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lua_pushboolean(L, le_is_enabled());
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int smlua_func_le_calculate_lighting_color(lua_State* L) {
|
int smlua_func_le_calculate_lighting_color(lua_State* L) {
|
||||||
if (L == NULL) { return 0; }
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
|
@ -15542,6 +15606,37 @@ int smlua_func_le_calculate_lighting_color(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smlua_func_le_calculate_lighting_color_with_normal(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 4) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "le_calculate_lighting_color_with_normal", 4, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vec3f pos;
|
||||||
|
smlua_get_vec3f(pos, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_calculate_lighting_color_with_normal"); return 0; }
|
||||||
|
|
||||||
|
Vec3f normal;
|
||||||
|
smlua_get_vec3f(normal, 2);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "le_calculate_lighting_color_with_normal"); return 0; }
|
||||||
|
|
||||||
|
Color out;
|
||||||
|
smlua_get_color(out, 3);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "le_calculate_lighting_color_with_normal"); return 0; }
|
||||||
|
f32 lightIntensityScalar = smlua_to_number(L, 4);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "le_calculate_lighting_color_with_normal"); return 0; }
|
||||||
|
|
||||||
|
le_calculate_lighting_color_with_normal(pos, normal, out, lightIntensityScalar);
|
||||||
|
|
||||||
|
smlua_push_color(out, 3);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int smlua_func_le_calculate_lighting_dir(lua_State* L) {
|
int smlua_func_le_calculate_lighting_dir(lua_State* L) {
|
||||||
if (L == NULL) { return 0; }
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
|
@ -15735,6 +15830,25 @@ int smlua_func_le_set_light_intensity(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smlua_func_le_set_light_use_surface_normals(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 2) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "le_set_light_use_surface_normals", 2, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 id = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_set_light_use_surface_normals"); return 0; }
|
||||||
|
bool useSurfaceNormals = smlua_to_boolean(L, 2);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "le_set_light_use_surface_normals"); return 0; }
|
||||||
|
|
||||||
|
le_set_light_use_surface_normals(id, useSurfaceNormals);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
// mario.h //
|
// mario.h //
|
||||||
/////////////
|
/////////////
|
||||||
|
|
@ -19890,6 +20004,31 @@ int smlua_func_mtxf_inverse(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smlua_func_mtxf_inverse_non_affine(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 2) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mtxf_inverse_non_affine", 2, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Mat4 dest;
|
||||||
|
smlua_get_mat4(dest, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mtxf_inverse_non_affine"); return 0; }
|
||||||
|
|
||||||
|
Mat4 src;
|
||||||
|
smlua_get_mat4(src, 2);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "mtxf_inverse_non_affine"); return 0; }
|
||||||
|
|
||||||
|
lua_pushboolean(L, mtxf_inverse_non_affine(dest, src));
|
||||||
|
|
||||||
|
smlua_push_mat4(dest, 1);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int smlua_func_get_pos_from_transform_mtx(lua_State* L) {
|
int smlua_func_get_pos_from_transform_mtx(lua_State* L) {
|
||||||
if (L == NULL) { return 0; }
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
|
@ -36380,7 +36519,12 @@ void smlua_bind_functions_autogen(void) {
|
||||||
smlua_bind_function(L, "lvl_set_current_level", smlua_func_lvl_set_current_level);
|
smlua_bind_function(L, "lvl_set_current_level", smlua_func_lvl_set_current_level);
|
||||||
|
|
||||||
// lighting_engine.h
|
// lighting_engine.h
|
||||||
|
smlua_bind_function(L, "le_set_mode", smlua_func_le_set_mode);
|
||||||
|
smlua_bind_function(L, "le_get_mode", smlua_func_le_get_mode);
|
||||||
|
smlua_bind_function(L, "le_set_tone_mapping", smlua_func_le_set_tone_mapping);
|
||||||
|
smlua_bind_function(L, "le_is_enabled", smlua_func_le_is_enabled);
|
||||||
smlua_bind_function(L, "le_calculate_lighting_color", smlua_func_le_calculate_lighting_color);
|
smlua_bind_function(L, "le_calculate_lighting_color", smlua_func_le_calculate_lighting_color);
|
||||||
|
smlua_bind_function(L, "le_calculate_lighting_color_with_normal", smlua_func_le_calculate_lighting_color_with_normal);
|
||||||
smlua_bind_function(L, "le_calculate_lighting_dir", smlua_func_le_calculate_lighting_dir);
|
smlua_bind_function(L, "le_calculate_lighting_dir", smlua_func_le_calculate_lighting_dir);
|
||||||
smlua_bind_function(L, "le_add_light", smlua_func_le_add_light);
|
smlua_bind_function(L, "le_add_light", smlua_func_le_add_light);
|
||||||
smlua_bind_function(L, "le_remove_light", smlua_func_le_remove_light);
|
smlua_bind_function(L, "le_remove_light", smlua_func_le_remove_light);
|
||||||
|
|
@ -36390,6 +36534,7 @@ void smlua_bind_functions_autogen(void) {
|
||||||
smlua_bind_function(L, "le_set_light_color", smlua_func_le_set_light_color);
|
smlua_bind_function(L, "le_set_light_color", smlua_func_le_set_light_color);
|
||||||
smlua_bind_function(L, "le_set_light_radius", smlua_func_le_set_light_radius);
|
smlua_bind_function(L, "le_set_light_radius", smlua_func_le_set_light_radius);
|
||||||
smlua_bind_function(L, "le_set_light_intensity", smlua_func_le_set_light_intensity);
|
smlua_bind_function(L, "le_set_light_intensity", smlua_func_le_set_light_intensity);
|
||||||
|
smlua_bind_function(L, "le_set_light_use_surface_normals", smlua_func_le_set_light_use_surface_normals);
|
||||||
|
|
||||||
// mario.h
|
// mario.h
|
||||||
smlua_bind_function(L, "is_anim_at_end", smlua_func_is_anim_at_end);
|
smlua_bind_function(L, "is_anim_at_end", smlua_func_is_anim_at_end);
|
||||||
|
|
@ -36616,6 +36761,7 @@ void smlua_bind_functions_autogen(void) {
|
||||||
smlua_bind_function(L, "mtxf_mul_vec3s", smlua_func_mtxf_mul_vec3s);
|
smlua_bind_function(L, "mtxf_mul_vec3s", smlua_func_mtxf_mul_vec3s);
|
||||||
smlua_bind_function(L, "mtxf_rotate_xy", smlua_func_mtxf_rotate_xy);
|
smlua_bind_function(L, "mtxf_rotate_xy", smlua_func_mtxf_rotate_xy);
|
||||||
smlua_bind_function(L, "mtxf_inverse", smlua_func_mtxf_inverse);
|
smlua_bind_function(L, "mtxf_inverse", smlua_func_mtxf_inverse);
|
||||||
|
smlua_bind_function(L, "mtxf_inverse_non_affine", smlua_func_mtxf_inverse_non_affine);
|
||||||
smlua_bind_function(L, "get_pos_from_transform_mtx", smlua_func_get_pos_from_transform_mtx);
|
smlua_bind_function(L, "get_pos_from_transform_mtx", smlua_func_get_pos_from_transform_mtx);
|
||||||
|
|
||||||
// math_util.inl
|
// math_util.inl
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue