2448 lines
65 KiB
C
2448 lines
65 KiB
C
#include "main.h"
|
|
#include "state.h"
|
|
#include "models.h"
|
|
#include "lua_core.h"
|
|
#include "rmath.h"
|
|
#include "textures.h"
|
|
#include "core.h"
|
|
|
|
static void checkMeshRealloc( int i ) {
|
|
if ( i == state->meshCount ) {
|
|
state->meshCount++;
|
|
}
|
|
|
|
if ( state->meshCount == state->meshAlloc ) {
|
|
state->meshAlloc += ALLOC_PAGE_SIZE;
|
|
state->meshes = realloc( state->meshes, state->meshAlloc * sizeof( Mesh* ) );
|
|
|
|
for ( i = state->meshCount; i < state->meshAlloc; i++ ) {
|
|
state->meshes[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void checkMaterialRealloc( int i ) {
|
|
if ( i == state->materialCount ) {
|
|
state->materialCount++;
|
|
}
|
|
|
|
if ( state->materialCount == state->materialAlloc ) {
|
|
state->materialAlloc += ALLOC_PAGE_SIZE;
|
|
state->materials = realloc( state->materials, state->materialAlloc * sizeof( Material* ) );
|
|
|
|
for ( i = state->materialCount; i < state->materialAlloc; i++ ) {
|
|
state->materials[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void checkModelRealloc( int i ) {
|
|
if ( i == state->modelCount ) {
|
|
state->modelCount++;
|
|
}
|
|
|
|
if ( state->modelCount == state->modelAlloc ) {
|
|
state->modelAlloc += ALLOC_PAGE_SIZE;
|
|
state->models = realloc( state->models, state->modelAlloc * sizeof( Model* ) );
|
|
|
|
for ( i = state->modelCount; i < state->modelAlloc; i++ ) {
|
|
state->models[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void checkAnimationRealloc( int i ) {
|
|
if ( i == state->animationCount ) {
|
|
state->animationCount++;
|
|
}
|
|
|
|
if ( state->animationCount == state->animationAlloc ) {
|
|
state->animationAlloc += ALLOC_PAGE_SIZE;
|
|
state->animations = realloc( state->animations, state->animationAlloc * sizeof( ModelAnimations* ) );
|
|
|
|
for ( i = state->animationCount; i < state->animationAlloc; i++ ) {
|
|
state->animations[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool validMesh( size_t id ) {
|
|
if ( id < 0 || state->meshCount < id || state->meshes[ id ] == NULL ) {
|
|
TraceLog( LOG_WARNING, "%s %d", "Invalid mesh", id );
|
|
return false;
|
|
}
|
|
else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
static bool validMaterial( size_t id ) {
|
|
if ( id < 0 || state->materialCount < id || state->materials[ id ] == NULL ) {
|
|
TraceLog( LOG_WARNING, "%s %d", "Invalid material", id );
|
|
return false;
|
|
}
|
|
else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
static bool validModel( size_t id ) {
|
|
if ( id < 0 || state->modelCount < id || state->models[ id ] == NULL ) {
|
|
TraceLog( LOG_WARNING, "%s %d", "Invalid model", id );
|
|
return false;
|
|
}
|
|
else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
static bool validAnimation( size_t id ) {
|
|
if ( id < 0 || state->animationCount < id || state->animations[ id ] == NULL ) {
|
|
TraceLog( LOG_WARNING, "%s %d", "Invalid animation", id );
|
|
return false;
|
|
}
|
|
else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
static int newMesh() {
|
|
int i = 0;
|
|
|
|
for ( i = 0; i < state->meshCount; i++ ) {
|
|
if ( state->meshes[i] == NULL ) {
|
|
break;
|
|
}
|
|
}
|
|
state->meshes[i] = malloc( sizeof( Mesh ) );
|
|
checkMeshRealloc( i );
|
|
|
|
return i;
|
|
}
|
|
|
|
/*
|
|
## Models - Basic
|
|
*/
|
|
|
|
/*
|
|
> success = RL_DrawLine3D( Vector3 startPos, Vector3 endPos, Color color )
|
|
|
|
Draw a line in 3D world space
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawLine3D( lua_State *L ) {
|
|
if ( !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawLine3D( Vector3 startPos, Vector3 endPos, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 endPos = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 startPos = uluaGetVector3( L );
|
|
|
|
DrawLine3D( startPos, endPos, color);
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawPoint3D( Vector3 position, Color color )
|
|
|
|
Draw a point in 3D space, actually a small line
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawPoint3D( lua_State *L ) {
|
|
if ( !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawPoint3D( Vector3 position, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 position = uluaGetVector3( L );
|
|
|
|
DrawPoint3D( position, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawCircle3D( Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color )
|
|
|
|
Draw a circle in 3D world space
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawCircle3D( lua_State *L ) {
|
|
if ( !lua_istable( L, -5 ) || !lua_isnumber( L, -4 ) || !lua_istable( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawCircle3D( Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
float rotationAngle = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 rotationAxis = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
float radius = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 center = uluaGetVector3( L );
|
|
|
|
DrawCircle3D( center, radius, rotationAxis, rotationAngle, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawTriangle3D( Vector3 v1, Vector3 v2, Vector3 v3, Color color )
|
|
|
|
Draw a color-filled triangle ( Vertex in counter-clockwise order! )
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawTriangle3D( lua_State *L ) {
|
|
if ( !lua_istable( L, -4 ) || !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawTriangle3D( Vector3 v1, Vector3 v2, Vector3 v3, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 v3 = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 v2 = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 v1 = uluaGetVector3( L );
|
|
|
|
DrawTriangle3D( v1, v2, v3, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawCube( Vector3 position, Vector3 size, Color color )
|
|
|
|
Draw cube
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawCube( lua_State *L ) {
|
|
if ( !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawCube( Vector3 position, Vector3 size, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 size = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 pos = uluaGetVector3( L );
|
|
|
|
DrawCubeV( pos, size, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawCubeWires( Vector3 position, Vector3 size, Color color )
|
|
|
|
Draw cube wires
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawCubeWires( lua_State *L ) {
|
|
if ( !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawCubeWires( Vector3 position, Vector3 size, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 size = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 pos = uluaGetVector3( L );
|
|
|
|
DrawCubeWiresV( pos, size, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawCubeTexture( Texture2D texture, Vector3 position, Vector3 size, Color color )
|
|
|
|
Draw cube textured
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawCubeTexture( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -4 ) || !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawCubeTexture( Texture2D texture, Vector3 position, Vector3 size, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 size = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 pos = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
size_t texId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validSourceTexture( texId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
|
|
DrawCubeTexture( *texturesGetSourceTexture( texId ), pos, size.x, size.y, size.z, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawSphere( Vector3 centerPos, float radius, Color color )
|
|
|
|
Draw sphere
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawSphere( lua_State *L ) {
|
|
if ( !lua_istable( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawSphere( Vector3 centerPos, float radius, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
float radius = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 centerPos = uluaGetVector3( L );
|
|
|
|
DrawSphere( centerPos, radius, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawSphereEx( Vector3 centerPos, float radius, int rings, int slices, Color color )
|
|
|
|
Draw sphere with extended parameters
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawSphereEx( lua_State *L ) {
|
|
if ( !lua_istable( L, -5 ) || !lua_isnumber( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawSphereEx( Vector3 centerPos, float radius, int rings, int slices, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
int slices = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
int rings = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
float radius = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 centerPos = uluaGetVector3( L );
|
|
|
|
DrawSphereEx( centerPos, radius, rings, slices, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawSphereWires( Vector3 centerPos, float radius, int rings, int slices, Color color )
|
|
|
|
Draw sphere wires
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawSphereWires( lua_State *L ) {
|
|
if ( !lua_istable( L, -5 ) || !lua_isnumber( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawSphereWires( Vector3 centerPos, float radius, int rings, int slices, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
int slices = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
int rings = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
float radius = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 centerPos = uluaGetVector3( L );
|
|
|
|
DrawSphereWires( centerPos, radius, rings, slices, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawCylinder( Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color )
|
|
|
|
Draw a cylinder/cone
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawCylinder( lua_State *L ) {
|
|
if ( !lua_istable( L, -6 ) || !lua_isnumber( L, -5 ) || !lua_isnumber( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawCylinder( Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
int slices = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
float height = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
float radiusBottom = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
float radiusTop = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 position = uluaGetVector3( L );
|
|
|
|
DrawCylinder( position, radiusTop, radiusBottom, height, slices, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawCylinderEx( Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color )
|
|
|
|
Draw a cylinder with base at startPos and top at endPos
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawCylinderEx( lua_State *L ) {
|
|
if ( !lua_istable( L, -6 ) || !lua_istable( L, -5 ) || !lua_isnumber( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawCylinderEx( Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
int sides = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
float endRadius = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
float startRadius = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 endPos = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 startPos = uluaGetVector3( L );
|
|
|
|
DrawCylinderEx( startPos, endPos, startRadius, endRadius, sides, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawCylinderWires( Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color )
|
|
|
|
Draw a cylinder/cone wires
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawCylinderWires( lua_State *L ) {
|
|
if ( !lua_istable( L, -6 ) || !lua_isnumber( L, -5 ) || !lua_isnumber( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawCylinderWires( Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
int slices = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
float height = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
float radiusBottom = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
float radiusTop = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 position = uluaGetVector3( L );
|
|
|
|
DrawCylinderWires( position, radiusTop, radiusBottom, height, slices, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawCylinderWiresEx( Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color )
|
|
|
|
Draw a cylinder wires with base at startPos and top at endPos
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawCylinderWiresEx( lua_State *L ) {
|
|
if ( !lua_istable( L, -6 ) || !lua_istable( L, -5 ) || !lua_isnumber( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawCylinderWiresEx( Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
int sides = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
float endRadius = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
float startRadius = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 endPos = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 startPos = uluaGetVector3( L );
|
|
|
|
DrawCylinderWiresEx( startPos, endPos, startRadius, endRadius, sides, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawPlane( Vector3 centerPos, Vector2 size, Color color )
|
|
|
|
Draw a plane XZ
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawPlane( lua_State *L ) {
|
|
if ( !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawPlane( Vector3 centerPos, Vector2 size, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
Vector2 size = uluaGetVector2( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 centerPos = uluaGetVector3( L );
|
|
|
|
DrawPlane( centerPos, size, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawQuad3DTexture( texture, Vector3{} vertices, Vector2{} texCoords, Color color )
|
|
|
|
Draw 3D quad texture using vertices and texture coordinates. Texture coordinates opengl style 0.0 - 1.0.
|
|
Note! Could be replaced something like "DrawPlaneTextureRec"
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelDrawQuad3DTexture( lua_State *L ) {
|
|
if ( !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawQuad3DTexture( texture, Vector3{} vertices, Vector2{} texCoords, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
|
|
/* TexCoords. */
|
|
Vector2 texcoords[4] = { 0 };
|
|
|
|
int t = lua_gettop( L ), i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t ) != 0 ) {
|
|
if ( lua_istable( L, -1 ) && i < 4 ) {
|
|
texcoords[i] = uluaGetVector2( L );
|
|
}
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
lua_pop( L, 1 );
|
|
|
|
/* Vertices. */
|
|
Vector3 vertices[4] = { 0 };
|
|
|
|
t = lua_gettop( L );
|
|
i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t ) != 0 ) {
|
|
if ( lua_istable( L, -1 ) && i < 4 ) {
|
|
vertices[i] = uluaGetVector3( L );
|
|
}
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
lua_pop( L, 1 );
|
|
size_t texId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validSourceTexture( texId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
|
|
// Draw.
|
|
rlCheckRenderBatchLimit( 4 );
|
|
rlSetTexture( texturesGetSourceTexture( texId )->id );
|
|
|
|
//TODO Normals. maybe something like Vector3Normalize(Vector3CrossProduct(Vector3Subtract(vB, vA), Vector3Subtract(vC, vA)));
|
|
|
|
rlBegin( RL_QUADS );
|
|
rlColor4ub( color.r, color.g, color.b, color.a );
|
|
|
|
for ( i = 0; i < 4; ++i ) {
|
|
rlTexCoord2f( texcoords[i].x, texcoords[i].y );
|
|
rlVertex3f( vertices[i].x, vertices[i].y, vertices[i].z );
|
|
}
|
|
rlEnd();
|
|
rlSetTexture( 0 );
|
|
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawRay( Ray ray, Color color )
|
|
|
|
Draw a ray line
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawRay( lua_State *L ) {
|
|
if ( !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawRay( Ray ray, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
Ray ray = uluaGetRay( L );
|
|
|
|
DrawRay( ray, color );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawGrid( int slices, float spacing )
|
|
|
|
Draw a grid ( Centered at ( 0, 0, 0 ) )
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawGrid( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawGrid( int slices, float spacing )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
DrawGrid( lua_tointeger( L, -2 ), lua_tonumber( L, -1 ) );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
## Models - Mesh
|
|
*/
|
|
|
|
/*
|
|
> mesh = RL_GenMeshPoly( int sides, float radius )
|
|
|
|
Generate polygonal mesh
|
|
|
|
- Failure return -1
|
|
- Success return int
|
|
*/
|
|
int lmodelsGenMeshPoly( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshPoly( int sides, float radius )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
float radius = lua_tonumber( L, -1 );
|
|
int sides = lua_tointeger( L, -2 );
|
|
int i = newMesh();
|
|
|
|
*state->meshes[i] = GenMeshPoly( sides, radius );
|
|
lua_pushinteger( L, i );
|
|
checkMeshRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> mesh = RL_GenMeshPlane( float width, float length, int resX, int resZ )
|
|
|
|
Generate plane mesh ( With subdivisions )
|
|
|
|
- Failure return -1
|
|
- Success return int
|
|
*/
|
|
int lmodelsGenMeshPlane( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshPlane( float width, float length, int resX, int resZ )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
int resZ = lua_tointeger( L, -1 );
|
|
int resX = lua_tointeger( L, -2 );
|
|
float length = lua_tonumber( L, -3 );
|
|
float width = lua_tonumber( L, -4 );
|
|
int i = newMesh();
|
|
|
|
*state->meshes[i] = GenMeshPlane( width, length, resX, resZ );
|
|
lua_pushinteger( L, i );
|
|
checkMeshRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> mesh = RL_GenMeshCube( Vector3 size )
|
|
|
|
Generate cuboid mesh
|
|
|
|
- Failure return -1
|
|
- Success return int
|
|
*/
|
|
int lmodelsGenMeshCube( lua_State *L ) {
|
|
if ( !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshCube( Vector3 size )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
Vector3 size = uluaGetVector3( L );
|
|
int i = newMesh();
|
|
|
|
*state->meshes[i] = GenMeshCube( size.x, size.y, size.z );
|
|
lua_pushinteger( L, i );
|
|
checkMeshRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> mesh = RL_GenMeshSphere( float radius, int rings, int slices )
|
|
|
|
Generate sphere mesh ( Standard sphere )
|
|
|
|
- Failure return -1
|
|
- Success return int
|
|
*/
|
|
int lmodelsGenMeshSphere( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshSphere( float radius, int rings, int slices )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
int slices = lua_tointeger( L, -1 );
|
|
int rings = lua_tointeger( L, -2 );
|
|
float radius = lua_tonumber( L, -3 );
|
|
int i = newMesh();
|
|
|
|
*state->meshes[i] = GenMeshSphere( radius, rings, slices );
|
|
lua_pushinteger( L, i );
|
|
checkMeshRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> mesh = RL_GenMeshCylinder( float radius, float height, int slices )
|
|
|
|
Generate cylinder mesh
|
|
|
|
- Failure return -1
|
|
- Success return int
|
|
*/
|
|
int lmodelsGenMeshCylinder( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshCylinder( float radius, float height, int slices )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
int slices = lua_tointeger( L, -1 );
|
|
float height = lua_tonumber( L, -2 );
|
|
float radius = lua_tonumber( L, -3 );
|
|
int i = newMesh();
|
|
|
|
*state->meshes[i] = GenMeshCylinder( radius, height, slices);
|
|
lua_pushinteger( L, i );
|
|
checkMeshRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> mesh = RL_GenMeshCone( float radius, float height, int slices )
|
|
|
|
Generate cone/pyramid mesh
|
|
|
|
- Failure return -1
|
|
- Success return int
|
|
*/
|
|
int lmodelsGenMeshCone( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshCone( float radius, float height, int slices )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
int slices = lua_tointeger( L, -1 );
|
|
float height = lua_tonumber( L, -2 );
|
|
float radius = lua_tonumber( L, -3 );
|
|
int i = newMesh();
|
|
|
|
*state->meshes[i] = GenMeshCone( radius, height, slices);
|
|
lua_pushinteger( L, i );
|
|
checkMeshRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> mesh = RL_GenMeshTorus( float radius, float size, int radSeg, int sides )
|
|
|
|
Generate torus mesh
|
|
|
|
- Failure return -1
|
|
- Success return int
|
|
*/
|
|
int lmodelsGenMeshTorus( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshTorus( float radius, float size, int radSeg, int sides )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
int sides = lua_tointeger( L, -1 );
|
|
int radSeg = lua_tointeger( L, -2 );
|
|
float size = lua_tonumber( L, -3 );
|
|
float radius = lua_tonumber( L, -4 );
|
|
int i = newMesh();
|
|
|
|
*state->meshes[i] = GenMeshTorus( radius, size, radSeg, sides );
|
|
lua_pushinteger( L, i );
|
|
checkMeshRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> mesh = RL_GenMeshKnot( float radius, float size, int radSeg, int sides )
|
|
|
|
Generate torus mesh
|
|
|
|
- Failure return -1
|
|
- Success return int
|
|
*/
|
|
int lmodelsGenMeshKnot( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshKnot( float radius, float size, int radSeg, int sides )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
int sides = lua_tointeger( L, -1 );
|
|
int radSeg = lua_tointeger( L, -2 );
|
|
float size = lua_tonumber( L, -3 );
|
|
float radius = lua_tonumber( L, -4 );
|
|
int i = newMesh();
|
|
|
|
*state->meshes[i] = GenMeshKnot( radius, size, radSeg, sides );
|
|
lua_pushinteger( L, i );
|
|
checkMeshRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> mesh = RL_GenMeshHeightmap( Image heightmap, Vector3 size )
|
|
|
|
Generate heightmap mesh from image data
|
|
|
|
- Failure return -1
|
|
- Success return int
|
|
*/
|
|
int lmodelsGenMeshHeightmap( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshHeightmap( Image heightmap, Vector3 size )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
Vector3 size = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
size_t imageId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validImage( imageId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Image *heightmap = state->images[ imageId ];
|
|
int i = newMesh();
|
|
|
|
*state->meshes[i] = GenMeshHeightmap( *heightmap, size );
|
|
lua_pushinteger( L, i );
|
|
checkMeshRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> mesh = RL_GenMeshCustom( Mesh{}, bool dynamic )
|
|
|
|
Generate custom mesh from vertex attribute data and uploads it into a VAO ( if supported ) and VBO
|
|
|
|
- Failure return -1
|
|
- Success return int
|
|
*/
|
|
int lmodelsGenMeshCustom( lua_State *L ) {
|
|
if ( !lua_istable( L, -2 ) || !lua_isboolean( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshCustom( Mesh{}, bool dynamic )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
Mesh mesh = { 0 };
|
|
|
|
bool dynamic = lua_toboolean( L, -1 );
|
|
lua_pop( L, 1 );
|
|
|
|
int t = lua_gettop( L );
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t ) != 0 ) {
|
|
if ( strcmp( "vertices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
|
|
mesh.vertexCount = len;
|
|
mesh.triangleCount = len / 3;
|
|
mesh.vertices = (float*)MemAlloc( len * 3 * sizeof(float) );
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
Vector3 vec = uluaGetVector3( L );
|
|
|
|
mesh.vertices[(i*3)+0] = vec.x;
|
|
mesh.vertices[(i*3)+1] = vec.y;
|
|
mesh.vertices[(i*3)+2] = vec.z;
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
}
|
|
else if ( strcmp( "texcoords", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
|
|
mesh.texcoords = (float*)MemAlloc( len * 2 * sizeof(float) );
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
Vector2 vec = uluaGetVector2( L );
|
|
|
|
mesh.texcoords[(i*2)+0] = vec.x;
|
|
mesh.texcoords[(i*2)+1] = vec.y;
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
}
|
|
else if ( strcmp( "texcoords2", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
|
|
mesh.texcoords2 = (float*)MemAlloc( len * 2 * sizeof(float) );
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
Vector2 vec = uluaGetVector2( L );
|
|
|
|
mesh.texcoords2[(i*2)+0] = vec.x;
|
|
mesh.texcoords2[(i*2)+1] = vec.y;
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
}
|
|
else if ( strcmp( "normals", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
|
|
mesh.normals = (float*)MemAlloc( len * 3 * sizeof(float) );
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
Vector3 vec = uluaGetVector3( L );
|
|
|
|
mesh.normals[(i*3)+0] = vec.x;
|
|
mesh.normals[(i*3)+1] = vec.y;
|
|
mesh.normals[(i*3)+2] = vec.z;
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
}
|
|
else if ( strcmp( "tangents", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
|
|
mesh.tangents = (float*)MemAlloc( len * 4 * sizeof(float) );
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
Vector4 vec = uluaGetVector4( L );
|
|
|
|
mesh.tangents[(i*4)+0] = vec.x;
|
|
mesh.tangents[(i*4)+1] = vec.y;
|
|
mesh.tangents[(i*4)+2] = vec.z;
|
|
mesh.tangents[(i*4)+3] = vec.w;
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
}
|
|
else if ( strcmp( "colors", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
|
|
mesh.colors = (unsigned char*)MemAlloc( len * 4 * sizeof(unsigned char) );
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
Color color = uluaGetColor( L );
|
|
|
|
mesh.colors[(i*4)+0] = color.r;
|
|
mesh.colors[(i*4)+1] = color.g;
|
|
mesh.colors[(i*4)+2] = color.b;
|
|
mesh.colors[(i*4)+3] = color.a;
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
}
|
|
else if ( strcmp( "indices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
|
|
mesh.indices = (unsigned short*)MemAlloc( len * sizeof(unsigned short) );
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
mesh.indices[i] = (unsigned short)lua_tointeger( L, -1 );
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
}
|
|
lua_pop( L, 1 );
|
|
}
|
|
UploadMesh( &mesh, dynamic );
|
|
|
|
int i = newMesh();
|
|
|
|
*state->meshes[i] = mesh;
|
|
lua_pushinteger( L, i );
|
|
checkMeshRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_UpdateMesh( Mesh{} )
|
|
|
|
Update mesh vertex data in GPU. ( Mainly intented to be used with custom meshes )
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsUpdateMesh( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_UpdateMesh( Mesh{} )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t meshId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validMesh( meshId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Mesh *mesh = state->meshes[ meshId ];
|
|
|
|
int t = lua_gettop( L );
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t ) != 0 ) {
|
|
if ( strcmp( "vertices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
Vector3 data[ len ];
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 && i < mesh->vertexCount ) {
|
|
data[i] = uluaGetVector3( L );
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
UpdateMeshBuffer( *mesh, 0, (void*)data, len * 3 * sizeof( float ), 0 );
|
|
}
|
|
else if ( strcmp( "texcoords", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
Vector2 data[ len ];
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
data[i] = uluaGetVector2( L );
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
UpdateMeshBuffer( *mesh, 1, (void*)data, len * 2 * sizeof( float ), 0 );
|
|
}
|
|
else if ( strcmp( "texcoords2", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
Vector2 data[ len ];
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
data[i] = uluaGetVector2( L );
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
UpdateMeshBuffer( *mesh, 5, (void*)data, len * 2 * sizeof( float ), 0 );
|
|
}
|
|
else if ( strcmp( "normals", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
Vector3 data[ len ];
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
data[i] = uluaGetVector3( L );
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
UpdateMeshBuffer( *mesh, 2, (void*)data, len * 3 * sizeof( float ), 0 );
|
|
}
|
|
else if ( strcmp( "tangents", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
Vector4 data[ len ];
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
data[i] = uluaGetVector4( L );
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
UpdateMeshBuffer( *mesh, 4, (void*)data, len * 4 * sizeof( float ), 0 );
|
|
}
|
|
else if ( strcmp( "colors", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
Color data[ len ];
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
data[i] = uluaGetColor( L );
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
UpdateMeshBuffer( *mesh, 3, (void*)data, len * 4 * sizeof( unsigned char ), 0 );
|
|
}
|
|
else if ( strcmp( "indices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
size_t len = uluaGetTableLen( L );
|
|
unsigned short data[ len ];
|
|
|
|
int t2 = lua_gettop( L );
|
|
int i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
data[i] = (unsigned short)lua_tointeger( L, -1 );
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
UpdateMeshBuffer( *mesh, 6, (void*)data, len * sizeof( unsigned short ), 0 );
|
|
}
|
|
lua_pop( L, 1 );
|
|
}
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_UnloadMesh( Mesh mesh )
|
|
|
|
Unload mesh data from CPU and GPU
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsUnloadMesh( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_UnloadMesh( Mesh mesh )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t id = lua_tointeger( L, -1 );
|
|
|
|
if ( !validMesh( id ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
UnloadMesh( *state->meshes[ id ] );
|
|
state->meshes[ id ] = NULL;
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawMesh( Mesh mesh, Material material, Matrix transform )
|
|
|
|
Draw a 3d mesh with material and transform
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawMesh( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawMesh( Mesh mesh, Material material, Matrix transform )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Matrix matrix = uluaGetMatrix( L );
|
|
lua_pop( L, 1 );
|
|
size_t materialId = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
size_t meshId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validMesh( meshId ) || !validMaterial( materialId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
|
|
DrawMesh( *state->meshes[ meshId ], *state->materials[ materialId ], matrix );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* TODO Untested. */
|
|
/*
|
|
> success = RL_DrawMeshInstanced( Mesh mesh, Material material, Matrix{} transforms, int instances )
|
|
|
|
Draw multiple mesh instances with material and different transforms
|
|
Note! Untested.
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawMeshInstanced( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_istable( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawMeshInstanced( Mesh mesh, Material material, Matrix{} transforms, int instances )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
int instances = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Matrix matrises[ instances ];
|
|
|
|
int t = lua_gettop( L ), i = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t ) != 0 ) {
|
|
if ( lua_istable( L, -1 ) ) {
|
|
matrises[i] = uluaGetMatrix( L );
|
|
}
|
|
i++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
lua_pop( L, 1 );
|
|
size_t materialId = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
size_t meshId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validMesh( meshId ) || !validMaterial( materialId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
DrawMeshInstanced( *state->meshes[ meshId ], *state->materials[ materialId ], matrises, instances );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_SetMeshColor( Mesh mesh, Color color )
|
|
|
|
Updades mesh color vertex attribute buffer
|
|
NOTE: Currently only works on custom mesh
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsSetMeshColor( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_SetMeshColor( Mesh mesh, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
size_t meshId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validMesh( meshId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
|
|
Mesh *mesh = state->meshes[ meshId ];
|
|
|
|
if ( mesh->colors == NULL ) {
|
|
TraceLog( LOG_WARNING, "Mesh %d %s", meshId, "Mesh doesn't have vertex colors allocated" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
|
|
for ( int i = 0; i < mesh->vertexCount; ++i ) {
|
|
mesh->colors[(i*4)+0] = (unsigned char)color.r;
|
|
mesh->colors[(i*4)+1] = (unsigned char)color.g;
|
|
mesh->colors[(i*4)+2] = (unsigned char)color.b;
|
|
mesh->colors[(i*4)+3] = (unsigned char)color.a;
|
|
}
|
|
/* Update vertex attribute: color */
|
|
rlUpdateVertexBuffer( mesh->vboId[3], mesh->colors, mesh->vertexCount * 4 * sizeof( unsigned char ), 0 );
|
|
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_ExportMesh( Mesh mesh, string fileName )
|
|
|
|
Export mesh data to file, returns true on success
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsExportMesh( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -2 ) || !lua_isstring( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_ExportMesh( Mesh mesh, string fileName )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t meshId = lua_tointeger( L, -2 );
|
|
|
|
if ( !validMesh( meshId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
lua_pushboolean( L, ExportMesh( *state->meshes[ meshId ], lua_tostring( L, -1 ) ) );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> boundingBox = RL_GetMeshBoundingBox( Mesh mesh )
|
|
|
|
Compute mesh bounding box limits
|
|
|
|
- Failure return false
|
|
- Success return BoundingBox
|
|
*/
|
|
int lmodelsGetMeshBoundingBox( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GetMeshBoundingBox( Mesh mesh )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t meshId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validMesh( meshId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
uluaPushBoundingBox( L, GetMeshBoundingBox( *state->meshes[ meshId ] ) );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_GenMeshTangents( Mesh mesh )
|
|
|
|
Compute mesh tangents
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsGenMeshTangents( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshTangents( Mesh mesh )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t meshId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validMesh( meshId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
GenMeshTangents( state->meshes[ meshId ] );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
## Models - Material
|
|
*/
|
|
|
|
/*
|
|
> material = RL_LoadMaterialDefault()
|
|
|
|
Load default material
|
|
|
|
- Success return int
|
|
*/
|
|
int lmodelsLoadMaterialDefault( lua_State *L ) {
|
|
int i = 0;
|
|
|
|
for ( i = 0; i < state->materialCount; i++ ) {
|
|
if ( state->materials[i] == NULL ) {
|
|
break;
|
|
}
|
|
}
|
|
state->materials[i] = malloc( sizeof( Material ) );
|
|
*state->materials[i] = LoadMaterialDefault();
|
|
lua_pushinteger( L, i );
|
|
checkMaterialRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> material = RL_CreateMaterial( material{} )
|
|
|
|
Load material from table. See material table definition
|
|
|
|
- Failure return false
|
|
- Success return int
|
|
*/
|
|
int lmodelsCreateMaterial( lua_State *L ) {
|
|
if ( !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_CreateMaterial( material{} )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
int i = 0;
|
|
|
|
for ( i = 0; i < state->materialCount; i++ ) {
|
|
if ( state->materials[i] == NULL ) {
|
|
break;
|
|
}
|
|
}
|
|
state->materials[i] = malloc( sizeof( Material ) );
|
|
*state->materials[i] = LoadMaterialDefault();
|
|
|
|
int t = lua_gettop( L );
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t ) != 0 ) {
|
|
if ( strcmp( "maps", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
int t2 = lua_gettop( L );
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
/* Loop maps. Array where we don't care about the index value. */
|
|
if ( lua_istable( L, -1 ) ) {
|
|
int t3 = lua_gettop( L ), j = 0, map = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t3 ) != 0 ) {
|
|
switch ( j ) {
|
|
case 0: /* Map */
|
|
map = lua_tointeger( L, -1 );
|
|
break;
|
|
case 1: /* Parameters */
|
|
{
|
|
int t4 = lua_gettop( L );
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t4 ) != 0 ) {
|
|
if ( strcmp( "texture", (char*)lua_tostring( L, -2 ) ) == 0 && lua_isnumber( L, -1 ) ) {
|
|
size_t texId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validSourceTexture( texId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
state->materials[i]->maps[map].texture = *texturesGetSourceTexture( texId );
|
|
}
|
|
else if ( strcmp( "color", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
state->materials[i]->maps[map].color = uluaGetColor( L );
|
|
}
|
|
else if ( strcmp( "value", (char*)lua_tostring( L, -2 ) ) == 0 && lua_isnumber( L, -1 ) ) {
|
|
state->materials[i]->maps[map].value = lua_tonumber( L, -1 );
|
|
}
|
|
lua_pop( L, 1 );
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
j++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
}
|
|
lua_pop( L, 1 );
|
|
}
|
|
}
|
|
else if ( strcmp( "params", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) {
|
|
int t2 = lua_gettop( L ), j = 0;
|
|
lua_pushnil( L );
|
|
|
|
while ( lua_next( L, t2 ) != 0 ) {
|
|
if ( j <= 3 ) {
|
|
state->materials[i]->params[j] = lua_tonumber( L, -1 );
|
|
}
|
|
j++;
|
|
lua_pop( L, 1 );
|
|
}
|
|
}
|
|
else if ( strcmp( "shader", (char*)lua_tostring( L, -2 ) ) == 0 && lua_isnumber( L, -1 ) ) {
|
|
state->materials[i]->shader = *state->shaders[ lua_tointeger( L, -1 ) ];
|
|
}
|
|
lua_pop( L, 1 );
|
|
}
|
|
lua_pushinteger( L, i );
|
|
checkMaterialRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_UnloadMaterial( Material material )
|
|
|
|
Unload material from GPU memory ( VRAM )
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsUnloadMaterial( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_UnloadMaterial( Material material )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t id = lua_tointeger( L, -1 );
|
|
|
|
if ( !validMaterial( id ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
UnloadMaterial( *state->materials[ id ] );
|
|
state->materials[ id ] = NULL;
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_SetMaterialTexture( Material material, int mapType, Texture2D texture )
|
|
|
|
Set texture for a material map type ( MATERIAL_MAP_ALBEDO, MATERIAL_MAP_METALNESS... )
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsSetMaterialTexture( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_SetMaterialTexture( Material material, int mapType, Texture2D texture )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t texId = lua_tointeger( L, -1 );
|
|
size_t materialId = lua_tointeger( L, -3 );
|
|
|
|
if ( !validMaterial( materialId ) || !validSourceTexture( texId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
|
|
SetMaterialTexture( state->materials[ materialId ], lua_tointeger( L, -2 ), *texturesGetSourceTexture( texId ) );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_SetMaterialColor( Material material, int mapType, Color color )
|
|
|
|
Set color for a material map type
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsSetMaterialColor( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_SetMaterialColor( Material material, int mapType, Color color )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color color = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
size_t mapType = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
size_t materialId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validMaterial( materialId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
|
|
state->materials[ materialId ]->maps[ mapType ].color = color;
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_SetMaterialValue( Material material, int mapType, float value )
|
|
|
|
Set value for a material map type
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsSetMaterialValue( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_SetMaterialValue( Material material, int mapType, float value )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
float value = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
size_t mapType = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
size_t materialId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validMaterial( materialId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
|
|
state->materials[ materialId ]->maps[ mapType ].value = value;
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
## Models - Model
|
|
*/
|
|
|
|
/*
|
|
> model = RL_LoadModel( string fileName )
|
|
|
|
Load model from files ( Meshes and materials )
|
|
|
|
- Failure return -1
|
|
- Success return int
|
|
*/
|
|
int lmodelsLoadModel( lua_State *L ) {
|
|
if ( !lua_isstring( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_LoadModel( string fileName )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
int i = 0;
|
|
|
|
for ( i = 0; i < state->modelCount; i++ ) {
|
|
if ( state->models[i] == NULL ) {
|
|
break;
|
|
}
|
|
}
|
|
state->models[i] = malloc( sizeof( Model ) );
|
|
*state->models[i] = LoadModel( lua_tostring( L, -1 ) );
|
|
lua_pushinteger( L, i );
|
|
checkModelRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> model = RL_LoadModelFromMesh( Mesh mesh )
|
|
|
|
Load model from generated mesh ( Default material )
|
|
|
|
- Failure return -1
|
|
- Success return int
|
|
*/
|
|
int lmodelsLoadModelFromMesh( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_LoadModelFromMesh( Mesh mesh )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
size_t meshId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validMesh( meshId ) ) {
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
int i = 0;
|
|
|
|
for ( i = 0; i < state->modelCount; i++ ) {
|
|
if ( state->models[i] == NULL ) {
|
|
break;
|
|
}
|
|
}
|
|
state->models[i] = malloc( sizeof( Model ) );
|
|
*state->models[i] = LoadModelFromMesh( *state->meshes[ meshId ] );
|
|
lua_pushinteger( L, i );
|
|
checkModelRealloc( i );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_UnloadModel( Model model )
|
|
|
|
Unload model ( Including meshes ) from memory ( RAM and/or VRAM )
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsUnloadModel( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_UnloadModel( Model model )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t modelId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validModel( modelId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
UnloadModel( *state->models[ modelId ] );
|
|
state->models[ modelId ] = NULL;
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawModel( Model model, Vector3 position, float scale, Color tint )
|
|
|
|
Draw a model ( With texture if set )
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawModel( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -4 ) || !lua_istable( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawModel( Model model, Vector3 position, float scale, Color tint )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color tint = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
float scale = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 position = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
size_t modelId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validModel( modelId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
|
|
DrawModel( *state->models[ modelId ], position, scale, tint );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawModelEx( Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint )
|
|
|
|
Draw a model with extended parameters
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawModelEx( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -6 ) || !lua_istable( L, -5 ) || !lua_istable( L, -4 )
|
|
|| !lua_isnumber( L, -3 ) || !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawModelEx( Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color tint = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 scale = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
float rotationAngle = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 rotationAxis = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 position = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
size_t modelId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validModel( modelId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
|
|
DrawModelEx( *state->models[ modelId ], position, rotationAxis, rotationAngle, scale, tint );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_SetModelMaterial( Model model, Material modelMaterial, Material material )
|
|
|
|
Copies material to model material. ( Model material is the material id in models. Material can be deleted if not used elsewhere )
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsSetModelMaterial( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_SetModelMaterial( Model model, Material modelMaterial, Material material )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t materialId = lua_tointeger( L, -1 );
|
|
size_t modelId = lua_tointeger( L, -3 );
|
|
|
|
if ( !validModel( modelId ) || !validMaterial( materialId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
|
|
Model *model = state->models[ modelId ];
|
|
int modelMaterialId = lua_tointeger( L, -2 );
|
|
Material *material = state->materials[ materialId ];
|
|
|
|
/* Copy material data instead of using pointer. Pointer would result in double free error. */
|
|
model->materials[ modelMaterialId ].shader = material->shader;
|
|
model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_ALBEDO ] = material->maps[ MATERIAL_MAP_ALBEDO ];
|
|
model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_METALNESS ] = material->maps[ MATERIAL_MAP_METALNESS ];
|
|
model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_NORMAL ] = material->maps[ MATERIAL_MAP_NORMAL ];
|
|
model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_ROUGHNESS ] = material->maps[ MATERIAL_MAP_ROUGHNESS ];
|
|
model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_OCCLUSION ] = material->maps[ MATERIAL_MAP_OCCLUSION ];
|
|
model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_EMISSION ] = material->maps[ MATERIAL_MAP_EMISSION ];
|
|
model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_HEIGHT ] = material->maps[ MATERIAL_MAP_HEIGHT ];
|
|
model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_CUBEMAP ] = material->maps[ MATERIAL_MAP_CUBEMAP ];
|
|
model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_IRRADIANCE ] = material->maps[ MATERIAL_MAP_IRRADIANCE ];
|
|
model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_PREFILTER ] = material->maps[ MATERIAL_MAP_PREFILTER ];
|
|
model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_BRDF ] = material->maps[ MATERIAL_MAP_BRDF ];
|
|
|
|
for ( int i = 0; i < 4; i++ ) {
|
|
model->materials[ modelMaterialId ].params[i] = material->params[i];
|
|
}
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_SetModelMeshMaterial( Model model, int meshId, int materialId )
|
|
|
|
Set material for a mesh ( Mesh and material on this model )
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsSetModelMeshMaterial( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_SetModelMeshMaterial( Model model, int meshId, int materialId )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
int materialId = lua_tointeger( L, -1 );
|
|
int meshId = lua_tointeger( L, -2 );
|
|
size_t modelId = lua_tointeger( L, -3 );
|
|
|
|
if ( !validModel( modelId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
|
|
SetModelMeshMaterial( state->models[ modelId ], meshId, materialId );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawBillboard( Camera camera, Texture2D texture, Vector3 position, float size, Color tint )
|
|
|
|
Draw a billboard texture
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawBillboard( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -5 ) || !lua_isnumber( L, -4 ) || !lua_istable( L, -3 )
|
|
|| !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawBillboard( Camera camera, Texture2D texture, Vector3 position, float size, Color tint )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color tint = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
float size = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 position = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
size_t texId = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
size_t cameraId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validSourceTexture( texId ) || !validCamera3D( cameraId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
DrawBillboard( *state->camera3Ds[ cameraId ], *texturesGetSourceTexture( texId ), position, size, tint );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_DrawBillboardRec( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint )
|
|
|
|
Draw a billboard texture defined by source
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsDrawBillboardRec( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -6 ) || !lua_isnumber( L, -5 ) || !lua_istable( L, -4 )
|
|
|| !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawBillboardRec( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Color tint = uluaGetColor( L );
|
|
lua_pop( L, 1 );
|
|
Vector2 size = uluaGetVector2( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 position = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Rectangle source = uluaGetRectangle( L );
|
|
lua_pop( L, 1 );
|
|
size_t texId = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
size_t cameraId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validSourceTexture( texId ) || !validCamera3D( cameraId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
DrawBillboardRec( *state->camera3Ds[ cameraId ], *texturesGetSourceTexture( texId ), source, position, size, tint );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_SetModelTransform( Model model, Matrix transform )
|
|
|
|
Set model transform matrix
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsSetModelTransform( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_SetModelTransform( Model model, Matrix transform )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
Matrix transform = uluaGetMatrix( L );
|
|
lua_pop( L, 1 );
|
|
size_t modelId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validModel( modelId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
state->models[ modelId ]->transform = transform;
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> transform = RL_GetModelTransform( Model model )
|
|
|
|
Get model transform matrix
|
|
|
|
- Failure return false
|
|
- Success return Matrix
|
|
*/
|
|
int lmodelsGetModelTransform( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GetModelTransform( Model model )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t modelId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validModel( modelId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
uluaPushMatrix( L, state->models[ modelId ]->transform );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
## Model - Animations
|
|
*/
|
|
|
|
/*
|
|
> animations, animationCount = RL_LoadModelAnimations( string fileName )
|
|
|
|
Load model animations from file
|
|
|
|
- Failure return -1
|
|
- Success return int, int
|
|
*/
|
|
int lmodelsLoadModelAnimations( lua_State *L ) {
|
|
if ( !lua_isstring( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_LoadModelAnimations( string fileName )" );
|
|
lua_pushinteger( L, -1 );
|
|
return 1;
|
|
}
|
|
int i = 0;
|
|
|
|
for ( i = 0; i < state->animationCount; i++ ) {
|
|
if ( state->animations[i] == NULL ) {
|
|
break;
|
|
}
|
|
}
|
|
state->animations[i] = malloc( sizeof( ModelAnimations ) );
|
|
state->animations[i]->animations = LoadModelAnimations( lua_tostring( L, -1 ), &state->animations[i]->animCount );
|
|
checkAnimationRealloc( i );
|
|
|
|
lua_pushinteger( L, i );
|
|
lua_pushinteger( L, state->animations[i]->animCount );
|
|
|
|
return 2;
|
|
}
|
|
|
|
/*
|
|
> success = RL_UpdateModelAnimation( Model model, ModelAnimations animations, int animation, int frame )
|
|
|
|
Update model animation pose
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsUpdateModelAnimation( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_UpdateModelAnimation( Model model, ModelAnimations animations, int animation, int frame )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
int frame = imax( 0, lua_tointeger( L, -1 ) );
|
|
size_t animId = lua_tointeger( L, -3 );
|
|
size_t modelId = lua_tointeger( L, -4 );
|
|
|
|
if ( !validModel( modelId ) || !validAnimation( animId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
UpdateModelAnimation( *state->models[ modelId ], state->animations[ animId ]->animations[ lua_tointeger( L, -2 ) ], frame );
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> success = RL_UnloadModelAnimations( ModelAnimations animations )
|
|
|
|
Unload animation data
|
|
|
|
- Failure return false
|
|
- Success return true
|
|
*/
|
|
int lmodelsUnloadModelAnimations( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_UnloadModelAnimations( ModelAnimations animations )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t animId = lua_tointeger( L, -1 );
|
|
|
|
if ( !validAnimation( animId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
UnloadModelAnimation( *state->animations[ animId ]->animations );
|
|
state->animations[ animId ]->animCount = 0;
|
|
state->animations[ animId ] = NULL;
|
|
|
|
lua_pushboolean( L, true );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> valid = RL_IsModelAnimationValid( Model model, ModelAnimations animations )
|
|
|
|
Check model animation skeleton match
|
|
|
|
- Failure return nil
|
|
- Success return bool
|
|
*/
|
|
int lmodelsIsModelAnimationValid( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_IsModelAnimationValid( Model model, ModelAnimations animations )" );
|
|
lua_pushnil( L );
|
|
return 1;
|
|
}
|
|
size_t animId = lua_tointeger( L, -1 );
|
|
size_t modelId = lua_tointeger( L, -2 );
|
|
|
|
if ( !validModel( modelId ) || !validAnimation( animId ) ) {
|
|
lua_pushnil( L );
|
|
return 1;
|
|
}
|
|
lua_pushboolean( L, IsModelAnimationValid( *state->models[ modelId ], *state->animations[ animId ]->animations ) );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> boneCount = RL_GetModelAnimationBoneCount( ModelAnimations animations, int animation )
|
|
|
|
Return modelAnimation bone count
|
|
|
|
- Failure return false
|
|
- Success return int
|
|
*/
|
|
int lmodelsGetModelAnimationBoneCount( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GetModelAnimationBoneCount( ModelAnimations animations, int animation )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t animId = lua_tointeger( L, -2 );
|
|
|
|
if ( !validAnimation( animId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
lua_pushinteger( L, state->animations[ animId ]->animations[ lua_tointeger( L, -1 ) ].boneCount );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> frameCount = RL_GetModelAnimationFrameCount( ModelAnimations animations, int animation )
|
|
|
|
Return modelAnimation frame count
|
|
|
|
- Failure return false
|
|
- Success return int
|
|
*/
|
|
int lmodelsGetModelAnimationFrameCount( lua_State *L ) {
|
|
if ( !lua_isnumber( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GetModelAnimationFrameCount( ModelAnimations animations, int animation )" );
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
size_t animId = lua_tointeger( L, -2 );
|
|
|
|
if ( !validAnimation( animId ) ) {
|
|
lua_pushboolean( L, false );
|
|
return 1;
|
|
}
|
|
lua_pushinteger( L, state->animations[ animId ]->animations[ lua_tointeger( L, -1 ) ].frameCount );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
## Model - Collision
|
|
*/
|
|
|
|
/*
|
|
> collision = RL_CheckCollisionSpheres( Vector3 center1, float radius1, Vector3 center2, float radius2 )
|
|
|
|
Check collision between two spheres
|
|
|
|
- Failure return nil
|
|
- Success return bool
|
|
*/
|
|
int lmodelsCheckCollisionSpheres( lua_State *L ) {
|
|
if ( !lua_istable( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_istable( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_CheckCollisionSpheres( Vector3 center1, float radius1, Vector3 center2, float radius2 )" );
|
|
lua_pushnil( L );
|
|
return 1;
|
|
}
|
|
float radius2 = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 center2 = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
float radius1 = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 center1 = uluaGetVector3( L );
|
|
|
|
lua_pushboolean( L, CheckCollisionSpheres( center1, radius1, center2, radius2 ) );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> collision = RL_CheckCollisionBoxes( BoundingBox box1, BoundingBox box2 )
|
|
|
|
Check collision between two bounding boxes
|
|
|
|
- Failure return nil
|
|
- Success return bool
|
|
*/
|
|
int lmodelsCheckCollisionBoxes( lua_State *L ) {
|
|
if ( !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_CheckCollisionBoxes( BoundingBox box1, BoundingBox box2 )" );
|
|
lua_pushnil( L );
|
|
return 1;
|
|
}
|
|
BoundingBox box2 = uluaGetBoundingBox( L );
|
|
lua_pop( L, 1 );
|
|
BoundingBox box1 = uluaGetBoundingBox( L );
|
|
|
|
lua_pushboolean( L, CheckCollisionBoxes( box1, box2 ) );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> collision = RL_CheckCollisionBoxSphere( BoundingBox box, Vector3 center, float radius )
|
|
|
|
Check collision between box and sphere
|
|
|
|
- Failure return nil
|
|
- Success return bool
|
|
*/
|
|
int lmodelsCheckCollisionBoxSphere( lua_State *L ) {
|
|
if ( !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_CheckCollisionBoxSphere( BoundingBox box, Vector3 center, float radius )" );
|
|
lua_pushnil( L );
|
|
return 1;
|
|
}
|
|
float radius = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 center = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
BoundingBox box = uluaGetBoundingBox( L );
|
|
|
|
lua_pushboolean( L, CheckCollisionBoxSphere( box, center, radius ) );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> rayCollision = RL_GetRayCollisionSphere( Ray ray, Vector3 center, float radius )
|
|
|
|
Get collision info between ray and sphere. ( RayCollision is Lua table of { hit, distance, point, normal } )
|
|
|
|
- Failure return nil
|
|
- Success return RayCollision
|
|
*/
|
|
int lmodelsGetRayCollisionSphere( lua_State *L ) {
|
|
if ( !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_isnumber( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GetRayCollisionSphere( Ray ray, Vector3 center, float radius )" );
|
|
lua_pushnil( L );
|
|
return 1;
|
|
}
|
|
float radius = lua_tonumber( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Vector3 center = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Ray ray = uluaGetRay( L );
|
|
|
|
uluaPushRayCollision( L, GetRayCollisionSphere( ray, center, radius ) );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> rayCollision = RL_GetRayCollisionBox( Ray ray, BoundingBox box )
|
|
|
|
Get collision info between ray and box
|
|
|
|
- Failure return nil
|
|
- Success return RayCollision
|
|
*/
|
|
int lmodelsGetRayCollisionBox( lua_State *L ) {
|
|
if ( !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GetRayCollisionBox( Ray ray, BoundingBox box )" );
|
|
lua_pushnil( L );
|
|
return 1;
|
|
}
|
|
BoundingBox box = uluaGetBoundingBox( L );
|
|
lua_pop( L, 1 );
|
|
Ray ray = uluaGetRay( L );
|
|
|
|
uluaPushRayCollision( L, GetRayCollisionBox( ray, box ) );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> rayCollision = RL_GetRayCollisionMesh( Ray ray, Mesh mesh, Matrix transform )
|
|
|
|
Get collision info between ray and mesh
|
|
|
|
- Failure return nil
|
|
- Success return RayCollision
|
|
*/
|
|
int lmodelsGetRayCollisionMesh( lua_State *L ) {
|
|
if ( !lua_istable( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GetRayCollisionMesh( Ray ray, Mesh mesh, Matrix transform )" );
|
|
lua_pushnil( L );
|
|
return 1;
|
|
}
|
|
Matrix transform = uluaGetMatrix( L );
|
|
lua_pop( L, 1 );
|
|
size_t meshId = lua_tointeger( L, -1 );
|
|
lua_pop( L, 1 );
|
|
Ray ray = uluaGetRay( L );
|
|
|
|
if ( !validMesh( meshId ) ) {
|
|
lua_pushnil( L );
|
|
return 1;
|
|
}
|
|
uluaPushRayCollision( L, GetRayCollisionMesh( ray, *state->meshes[ meshId ], transform ) );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> rayCollision = RL_GetRayCollisionTriangle( Ray ray, Vector3 p1, Vector3 p2, Vector3 p3 )
|
|
|
|
Get collision info between ray and triangle
|
|
|
|
- Failure return nil
|
|
- Success return RayCollision
|
|
*/
|
|
int lmodelsGetRayCollisionTriangle( lua_State *L ) {
|
|
if ( !lua_istable( L, -4 ) || !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GetRayCollisionTriangle( Ray ray, Vector3 p1, Vector3 p2, Vector3 p3 )" );
|
|
lua_pushnil( L );
|
|
return 1;
|
|
}
|
|
Vector3 p3 = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 p2 = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 p1 = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Ray ray = uluaGetRay( L );
|
|
|
|
uluaPushRayCollision( L, GetRayCollisionTriangle( ray, p1, p2, p3 ) );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
> rayCollision = RL_GetRayCollisionQuad( Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4 )
|
|
|
|
Get collision info between ray and quad
|
|
|
|
- Failure return nil
|
|
- Success return RayCollision
|
|
*/
|
|
int lmodelsGetRayCollisionQuad( lua_State *L ) {
|
|
if ( !lua_istable( L, -5 ) || !lua_istable( L, -4 ) || !lua_istable( L, -3 )
|
|
|| !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) {
|
|
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GetRayCollisionQuad( Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4 )" );
|
|
lua_pushnil( L );
|
|
return 1;
|
|
}
|
|
Vector3 p4 = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 p3 = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 p2 = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Vector3 p1 = uluaGetVector3( L );
|
|
lua_pop( L, 1 );
|
|
Ray ray = uluaGetRay( L );
|
|
|
|
uluaPushRayCollision( L, GetRayCollisionQuad( ray, p1, p2, p3, p4 ) );
|
|
|
|
return 1;
|
|
}
|
|
|