summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjussi2025-06-02 20:49:51 +0300
committerjussi2025-06-02 20:49:51 +0300
commit5b8af05e96b33f2d032cc31a329b89e1231d5502 (patch)
tree9ea0f70bae6c77cfc0edeb3f4b0b11fa9fb6be94
parente26bb8603c5a4053f2790fc7d6ce02b3179f5289 (diff)
downloadreilua-enhanced-5b8af05e96b33f2d032cc31a329b89e1231d5502.tar.gz
reilua-enhanced-5b8af05e96b33f2d032cc31a329b89e1231d5502.tar.bz2
reilua-enhanced-5b8af05e96b33f2d032cc31a329b89e1231d5502.zip
Frustum math from raylib extras.
-rw-r--r--API.md38
-rw-r--r--ReiLua_API.lua33
-rw-r--r--changelog1
-rw-r--r--examples/basic_lighting/main.lua7
-rw-r--r--include/frustum.h62
-rw-r--r--include/rmath.h5
-rw-r--r--src/frustum.c212
-rw-r--r--src/lua_core.c5
-rw-r--r--src/rmath.c101
9 files changed, 462 insertions, 2 deletions
diff --git a/API.md b/API.md
index 4786403..a2ef74a 100644
--- a/API.md
+++ b/API.md
@@ -3682,7 +3682,7 @@ Default projection matrix near cull distance
---
-> RL_CULL_DISTANCE_FAR = 1000
+> RL_CULL_DISTANCE_FAR = 1000.0
Default projection matrix far cull distance
@@ -10746,6 +10746,42 @@ Check whether two given quaternions are almost equal
---
+## Math - Frustum
+
+---
+
+> frustum = RL.ExtractFrustum( Matrix projection, Matrix modelview )
+
+Extract frustum from projection and modelView matrices.
+
+- Success return Vector4{}
+
+---
+
+> inFrustum = RL.PointInFrustum( Vector4{} frustum, Vector3 position )
+
+Check if point inside frustum
+
+- Success return bool
+
+---
+
+> inFrustum = RL.SphereInFrustum( Vector4{} frustum, Vector3 position )
+
+Check if sphere inside frustum
+
+- Success return bool
+
+---
+
+> inFrustum = RL.AABBInFrustum( Vector4{} frustum, Vector3 min, Vector3 max )
+
+Check if AABB inside frustum
+
+- Success return bool
+
+---
+
## Gui - Global gui state control functions
---
diff --git a/ReiLua_API.lua b/ReiLua_API.lua
index 406c038..dec0d17 100644
--- a/ReiLua_API.lua
+++ b/ReiLua_API.lua
@@ -1167,7 +1167,7 @@ RL.RL_MAX_SHADER_LOCATIONS=32
---Default projection matrix near cull distance
RL.RL_CULL_DISTANCE_NEAR=0.01
---Default projection matrix far cull distance
-RL.RL_CULL_DISTANCE_FAR=1000
+RL.RL_CULL_DISTANCE_FAR=1000.0
-- Defines - RLGL Texture parameters
@@ -6985,6 +6985,37 @@ function RL.QuaternionTransform( q, mat ) end
---@return any result
function RL.QuaternionEquals( q1, q2 ) end
+-- Math - Frustum
+
+---Extract frustum from projection and modelView matrices.
+---- Success return Vector4{}
+---@param projection table
+---@param modelview table
+---@return any frustum
+function RL.ExtractFrustum( projection, modelview ) end
+
+---Check if point inside frustum
+---- Success return bool
+---@param frustum table
+---@param position table
+---@return any inFrustum
+function RL.PointInFrustum( frustum, position ) end
+
+---Check if sphere inside frustum
+---- Success return bool
+---@param frustum table
+---@param position table
+---@return any inFrustum
+function RL.SphereInFrustum( frustum, position ) end
+
+---Check if AABB inside frustum
+---- Success return bool
+---@param frustum table
+---@param min table
+---@param max table
+---@return any inFrustum
+function RL.AABBInFrustum( frustum, min, max ) end
+
-- Gui - Global gui state control functions
---Enable gui controls (global state)
diff --git a/changelog b/changelog
index 8780974..7689b94 100644
--- a/changelog
+++ b/changelog
@@ -51,6 +51,7 @@ DETAILED CHANGES:
- ADDED: DrawTextBoxed Color change escape sequence.
- ADDED: RL.load and RL.unload functions for memory leak debugging.
- ADDED: SoundAlias garbage collection.
+ - ADDED: Frustum math from raylib extras.
------------------------------------------------------------------------
Release: ReiLua version 0.8.0 Using Raylib 5.0 and Forked Raygui 4.0
diff --git a/examples/basic_lighting/main.lua b/examples/basic_lighting/main.lua
index 52552c3..8c5aed0 100644
--- a/examples/basic_lighting/main.lua
+++ b/examples/basic_lighting/main.lua
@@ -22,6 +22,7 @@ function RL.init()
local mSize = Vec2:newT( RL.GetMonitorSize( monitor ) )
local winSize = Vec2:new( 1028, 720 )
+ RL.SetGCUnload( false )
RL.SetWindowTitle( "Simple Lighting" )
RL.SetWindowState( RL.FLAG_WINDOW_RESIZABLE )
RL.SetWindowState( RL.FLAG_VSYNC_HINT )
@@ -138,3 +139,9 @@ function RL.draw()
RL.DrawText( "Use keys [Y][R][G][B] to toggle lights", { 10, 10 }, 20, RL.DARKGRAY )
end
+
+function RL.exit()
+ RL.UnloadMaterial( material, true )
+ RL.UnloadMesh( plane )
+ RL.UnloadMesh( cube )
+end
diff --git a/include/frustum.h b/include/frustum.h
new file mode 100644
index 0000000..370074c
--- /dev/null
+++ b/include/frustum.h
@@ -0,0 +1,62 @@
+/**********************************************************************************************
+*
+* raylibExtras * Utilities and Shared Components for Raylib
+*
+* RLSprite * Simple Sprite Managment System for Raylib
+*
+* LICENSE: MIT
+*
+* Copyright (c) 2020 Jeffery Myers
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all
+* copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+**********************************************************************************************/
+
+#pragma once
+#ifndef FRUSTUM_H
+#define FRUSTUM_H
+
+#include "raylib.h"
+#include "raymath.h"
+#include "frustum.h"
+
+typedef enum
+{
+ Back = 0,
+ Front = 1,
+ Bottom = 2,
+ Top = 3,
+ Right = 4,
+ Left = 5,
+ MAX = 6
+}FrustumPlanes;
+
+typedef struct
+{
+ Vector4 Planes[6];
+}Frustum;
+
+// RLAPI void ExtractFrustum(Frustum* frustrum);
+RLAPI void ExtractFrustum(Frustum* frustum, Matrix projection, Matrix modelview);
+RLAPI bool PointInFrustumV(Frustum* frustrum, Vector3 position);
+RLAPI bool SphereInFrustumV(Frustum* frustrum, Vector3 position, float radius);
+
+RLAPI bool AABBoxInFrustum(Frustum* frustrum, Vector3 min, Vector3 max);
+
+#endif //FRUSTUM_H
diff --git a/include/rmath.h b/include/rmath.h
index 20c4049..7b96f14 100644
--- a/include/rmath.h
+++ b/include/rmath.h
@@ -152,3 +152,8 @@ int lmathQuaternionFromEuler( lua_State* L );
int lmathQuaternionToEuler( lua_State* L );
int lmathQuaternionTransform( lua_State* L );
int lmathQuaternionEquals( lua_State* L );
+/* Frustum */
+int lmathExtractFrustum( lua_State* L );
+int lmathPointInFrustum( lua_State* L );
+int lmathSphereInFrustum( lua_State* L );
+int lmathAABBInFrustum( lua_State* L );
diff --git a/src/frustum.c b/src/frustum.c
new file mode 100644
index 0000000..4c63e38
--- /dev/null
+++ b/src/frustum.c
@@ -0,0 +1,212 @@
+/**********************************************************************************************
+*
+* raylibExtras * Utilities and Shared Components for Raylib
+*
+* RLAssets * Simple Asset Managment System for Raylib
+*
+* LICENSE: MIT
+*
+* Copyright (c) 2020 Jeffery Myers
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all
+* copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+**********************************************************************************************/
+
+
+#include "frustum.h"
+#include "rlgl.h"
+#include "raymath.h"
+
+#include <math.h>
+#include <stddef.h>
+
+void NormalizePlane(Vector4* plane)
+{
+ if (plane == NULL)
+ return;
+
+ float magnitude = sqrtf(plane->x * plane->x + plane->y * plane->y + plane->z * plane->z);
+
+ plane->x /= magnitude;
+ plane->y /= magnitude;
+ plane->z /= magnitude;
+ plane->w /= magnitude;
+}
+
+// void ExtractFrustum(Frustum* frustum)
+void ExtractFrustum(Frustum* frustum, Matrix projection, Matrix modelview)
+{
+ if (frustum == NULL)
+ return;
+
+ // Matrix projection = rlGetMatrixProjection();
+ // Matrix modelview = rlGetMatrixModelview();
+
+ Matrix planes = { 0 };
+
+ planes.m0 = modelview.m0 * projection.m0 + modelview.m1 * projection.m4 + modelview.m2 * projection.m8 + modelview.m3 * projection.m12;
+ planes.m1 = modelview.m0 * projection.m1 + modelview.m1 * projection.m5 + modelview.m2 * projection.m9 + modelview.m3 * projection.m13;
+ planes.m2 = modelview.m0 * projection.m2 + modelview.m1 * projection.m6 + modelview.m2 * projection.m10 + modelview.m3 * projection.m14;
+ planes.m3 = modelview.m0 * projection.m3 + modelview.m1 * projection.m7 + modelview.m2 * projection.m11 + modelview.m3 * projection.m15;
+ planes.m4 = modelview.m4 * projection.m0 + modelview.m5 * projection.m4 + modelview.m6 * projection.m8 + modelview.m7 * projection.m12;
+ planes.m5 = modelview.m4 * projection.m1 + modelview.m5 * projection.m5 + modelview.m6 * projection.m9 + modelview.m7 * projection.m13;
+ planes.m6 = modelview.m4 * projection.m2 + modelview.m5 * projection.m6 + modelview.m6 * projection.m10 + modelview.m7 * projection.m14;
+ planes.m7 = modelview.m4 * projection.m3 + modelview.m5 * projection.m7 + modelview.m6 * projection.m11 + modelview.m7 * projection.m15;
+ planes.m8 = modelview.m8 * projection.m0 + modelview.m9 * projection.m4 + modelview.m10 * projection.m8 + modelview.m11 * projection.m12;
+ planes.m9 = modelview.m8 * projection.m1 + modelview.m9 * projection.m5 + modelview.m10 * projection.m9 + modelview.m11 * projection.m13;
+ planes.m10 = modelview.m8 * projection.m2 + modelview.m9 * projection.m6 + modelview.m10 * projection.m10 + modelview.m11 * projection.m14;
+ planes.m11 = modelview.m8 * projection.m3 + modelview.m9 * projection.m7 + modelview.m10 * projection.m11 + modelview.m11 * projection.m15;
+ planes.m12 = modelview.m12 * projection.m0 + modelview.m13 * projection.m4 + modelview.m14 * projection.m8 + modelview.m15 * projection.m12;
+ planes.m13 = modelview.m12 * projection.m1 + modelview.m13 * projection.m5 + modelview.m14 * projection.m9 + modelview.m15 * projection.m13;
+ planes.m14 = modelview.m12 * projection.m2 + modelview.m13 * projection.m6 + modelview.m14 * projection.m10 + modelview.m15 * projection.m14;
+ planes.m15 = modelview.m12 * projection.m3 + modelview.m13 * projection.m7 + modelview.m14 * projection.m11 + modelview.m15 * projection.m15;
+
+ frustum->Planes[Right] = (Vector4){ planes.m3 - planes.m0, planes.m7 - planes.m4, planes.m11 - planes.m8, planes.m15 - planes.m12 };
+ NormalizePlane(&frustum->Planes[Right]);
+
+ frustum->Planes[Left] = (Vector4){ planes.m3 + planes.m0, planes.m7 + planes.m4, planes.m11 + planes.m8, planes.m15 + planes.m12 };
+ NormalizePlane(&frustum->Planes[Left]);
+
+ frustum->Planes[Top] = (Vector4){ planes.m3 - planes.m1, planes.m7 - planes.m5, planes.m11 - planes.m9, planes.m15 - planes.m13 };
+ NormalizePlane(&frustum->Planes[Top]);
+
+ frustum->Planes[Bottom] = (Vector4){ planes.m3 + planes.m1, planes.m7 + planes.m5, planes.m11 + planes.m9, planes.m15 + planes.m13 };
+ NormalizePlane(&frustum->Planes[Bottom]);
+
+ frustum->Planes[Back] = (Vector4){ planes.m3 - planes.m2, planes.m7 - planes.m6, planes.m11 - planes.m10, planes.m15 - planes.m14 };
+ NormalizePlane(&frustum->Planes[Back]);
+
+ frustum->Planes[Front] = (Vector4){ planes.m3 + planes.m2, planes.m7 + planes.m6, planes.m11 + planes.m10, planes.m15 + planes.m14 };
+ NormalizePlane(&frustum->Planes[Front]);
+}
+
+float DistanceToPlaneV(const Vector4* plane, const Vector3* position)
+{
+ return (plane->x * position->x + plane->y * position->y + plane->z * position->z + plane->w);
+}
+
+float DistanceToPlane(const Vector4* plane, float x, float y, float z)
+{
+ return (plane->x * x + plane->y * y + plane->z * z + plane->w);
+}
+
+bool PointInFrustumV(Frustum* frustum, Vector3 position)
+{
+ if (frustum == NULL)
+ return false;
+
+ for (int i = 0; i < 6; i++)
+ {
+ if (DistanceToPlaneV(&frustum->Planes[i], &position) <= 0) // point is behind plane
+ return false;
+ }
+
+ return true;
+}
+
+bool PointInFrustum(Frustum* frustum, float x, float y, float z)
+{
+ if (frustum == NULL)
+ return false;
+
+ for (int i = 0; i < 6; i++)
+ {
+ if (DistanceToPlane(&frustum->Planes[i], x, y, z) <= 0) // point is behind plane
+ return false;
+ }
+
+ return true;
+}
+
+bool SphereInFrustumV(Frustum* frustum, Vector3 position, float radius)
+{
+ if (frustum == NULL)
+ return false;
+
+ for (int i = 0; i < 6; i++)
+ {
+ if (DistanceToPlaneV(&frustum->Planes[i], &position) < -radius) // center is behind plane by more than the radius
+ return false;
+ }
+
+ return true;
+}
+bool AABBoxInFrustum(Frustum* frustum, Vector3 min, Vector3 max)
+{
+ // if any point is in and we are good
+ if (PointInFrustum(frustum, min.x, min.y, min.z))
+ return true;
+
+ if (PointInFrustum(frustum, min.x, max.y, min.z))
+ return true;
+
+ if (PointInFrustum(frustum, max.x, max.y, min.z))
+ return true;
+
+ if (PointInFrustum(frustum, max.x, min.y, min.z))
+ return true;
+
+ if (PointInFrustum(frustum, min.x, min.y, max.z))
+ return true;
+
+ if (PointInFrustum(frustum, min.x, max.y, max.z))
+ return true;
+
+ if (PointInFrustum(frustum, max.x, max.y, max.z))
+ return true;
+
+ if (PointInFrustum(frustum, max.x, min.y, max.z))
+ return true;
+
+ // check to see if all points are outside of any one plane, if so the entire box is outside
+ for (int i = 0; i < 6; i++)
+ {
+ bool oneInside = false;
+
+ if (DistanceToPlane(&frustum->Planes[i], min.x, min.y, min.z) >= 0)
+ oneInside = true;
+
+ if (DistanceToPlane(&frustum->Planes[i], max.x, min.y, min.z) >= 0)
+ oneInside = true;
+
+ if (DistanceToPlane(&frustum->Planes[i], max.x, max.y, min.z) >= 0)
+ oneInside = true;
+
+ if (DistanceToPlane(&frustum->Planes[i], min.x, max.y, min.z) >= 0)
+ oneInside = true;
+
+ if (DistanceToPlane(&frustum->Planes[i], min.x, min.y, max.z) >= 0)
+ oneInside = true;
+
+ if (DistanceToPlane(&frustum->Planes[i], max.x, min.y, max.z) >= 0)
+ oneInside = true;
+
+ if (DistanceToPlane(&frustum->Planes[i], max.x, max.y, max.z) >= 0)
+ oneInside = true;
+
+ if (DistanceToPlane(&frustum->Planes[i], min.x, max.y, max.z) >= 0)
+ oneInside = true;
+
+ if (!oneInside)
+ return false;
+ }
+
+ // the box extends outside the frustum but crosses it
+ return true;
+}
diff --git a/src/lua_core.c b/src/lua_core.c
index 035685d..253d9e5 100644
--- a/src/lua_core.c
+++ b/src/lua_core.c
@@ -2470,6 +2470,11 @@ void luaRegister() {
assingGlobalFunction( "QuaternionToEuler", lmathQuaternionToEuler );
assingGlobalFunction( "QuaternionTransform", lmathQuaternionTransform );
assingGlobalFunction( "QuaternionEquals", lmathQuaternionEquals );
+ /* Frustum. */
+ assingGlobalFunction( "ExtractFrustum", lmathExtractFrustum );
+ assingGlobalFunction( "PointInFrustum", lmathPointInFrustum );
+ assingGlobalFunction( "SphereInFrustum", lmathSphereInFrustum );
+ assingGlobalFunction( "AABBInFrustum", lmathAABBInFrustum );
/* Gui. */
/* Global gui state control functions. */
diff --git a/src/rmath.c b/src/rmath.c
index 40e8cb8..d1e14f0 100644
--- a/src/rmath.c
+++ b/src/rmath.c
@@ -2,6 +2,7 @@
#include "state.h"
#include "rmath.h"
#include "lua_core.h"
+#include "frustum.h"
int imin( int a, int b ) {
return a < b ? a : b;
@@ -2343,3 +2344,103 @@ int lmathQuaternionEquals( lua_State* L ) {
return 1;
}
+
+/*
+## Math - Frustum
+*/
+
+static Frustum getFrustum( lua_State* L, int index ) {
+ luaL_checktype( L, index, LUA_TTABLE );
+ Frustum frustum = { 0 };
+
+ int t = index, i = 0;
+ lua_pushnil( L );
+
+ while ( lua_next( L, t ) != 0 && i < 6 ) {
+ frustum.Planes[i] = uluaGetVector4( L, lua_gettop( L ) );
+ i++;
+ lua_pop( L, 1 );
+ }
+
+ return frustum;
+}
+
+static int pushFrustum( lua_State* L, Frustum* frustum ) {
+ lua_createtable( L, 6, 0 );
+
+ for ( int i = 0; i < 6; i++ ) {
+ uluaPushVector4( L, frustum->Planes[i] );
+ lua_rawseti( L, -2, 1 + i );
+ }
+
+ return 1;
+}
+
+/*
+> frustum = RL.ExtractFrustum( Matrix projection, Matrix modelview )
+
+Extract frustum from projection and modelView matrices.
+
+- Success return Vector4{}
+*/
+int lmathExtractFrustum( lua_State* L ) {
+ Matrix projection = uluaGetMatrix( L, 1 );
+ Matrix modelview = uluaGetMatrix( L, 2 );
+
+ Frustum frustum = { 0 };
+ ExtractFrustum( &frustum, projection, modelview );
+
+ pushFrustum( L, &frustum );
+
+ return 1;
+}
+
+/*
+> inFrustum = RL.PointInFrustum( Vector4{} frustum, Vector3 position )
+
+Check if point inside frustum
+
+- Success return bool
+*/
+int lmathPointInFrustum( lua_State* L ) {
+ Frustum frustum = getFrustum( L, 1 );
+ Vector3 position = uluaGetVector3( L, 2 );
+
+ lua_pushboolean( L, PointInFrustumV( &frustum, position ) );
+
+ return 1;
+}
+
+/*
+> inFrustum = RL.SphereInFrustum( Vector4{} frustum, Vector3 position )
+
+Check if sphere inside frustum
+
+- Success return bool
+*/
+int lmathSphereInFrustum( lua_State* L ) {
+ Frustum frustum = getFrustum( L, 1 );
+ Vector3 position = uluaGetVector3( L, 2 );
+ float radius = luaL_checknumber( L, 3 );
+
+ lua_pushboolean( L, SphereInFrustumV( &frustum, position, radius ) );
+
+ return 1;
+}
+
+/*
+> inFrustum = RL.AABBInFrustum( Vector4{} frustum, Vector3 min, Vector3 max )
+
+Check if AABB inside frustum
+
+- Success return bool
+*/
+int lmathAABBInFrustum( lua_State* L ) {
+ Frustum frustum = getFrustum( L, 1 );
+ Vector3 min = uluaGetVector3( L, 2 );
+ Vector3 max = uluaGetVector3( L, 3 );
+
+ lua_pushboolean( L, AABBoxInFrustum( &frustum, min, max ) );
+
+ return 1;
+}