@ -71,7 +71,7 @@
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / Defines and Macros
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
o">/ / . . .
cp"># define MAX_MESH_VBO 7 / / Maximum number of vbo per mesh
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / Types and Structures Definition
@ -702,7 +702,7 @@ Model LoadModelFromMesh(Mesh mesh)
/ / Unload model from memory ( RAM and / or VRAM )
void UnloadModel ( Model model )
{
for ( int i = 0 ; i < model . meshCount ; i + + ) UnloadMesh ( o">& model . meshes [ i ] ) ;
for ( int i = 0 ; i < model . meshCount ; i + + ) UnloadMesh ( model . meshes [ i ] ) ;
for ( int i = 0 ; i < model . materialCount ; i + + ) UnloadMaterial ( model . materials [ i ] ) ;
RL_FREE ( model . meshes ) ;
@ -729,9 +729,10 @@ Mesh *LoadMeshes(const char *fileName, int *meshCount)
}
/ / Unload mesh from memory ( RAM and / or VRAM )
void UnloadMesh ( Mesh o">* mesh )
void UnloadMesh ( Mesh mesh )
{
rlUnloadMesh ( mesh ) ;
RL_FREE ( mesh . vboId ) ;
}
/ / Export mesh data to file
@ -824,6 +825,7 @@ Material *LoadMaterials(const char *fileName, int *materialCount)
Material LoadMaterialDefault ( void )
{
Material material = { 0 } ;
material . maps = ( MaterialMap * ) RL_CALLOC ( MAX_MATERIAL_MAPS * sizeof ( MaterialMap ) , 1 ) ;
material . shader = GetShaderDefault ( ) ;
material . maps [ MAP_DIFFUSE ] . texture = GetTextureDefault ( ) ; / / White texture ( 1 x1 pixel )
@ -847,6 +849,8 @@ void UnloadMaterial(Material material)
{
if ( material . maps [ i ] . texture . id ! = GetTextureDefault ( ) . id ) rlDeleteTextures ( material . maps [ i ] . texture . id ) ;
}
RL_FREE ( material . maps ) ;
}
/ / Set texture for a material map type ( MAP_DIFFUSE , MAP_SPECULAR . . . )
@ -1173,6 +1177,7 @@ bool IsModelAnimationValid(Model model, ModelAnimation anim)
Mesh GenMeshPoly ( int sides , float radius )
{
Mesh mesh = { 0 } ;
mesh . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) , 1 ) ;
int vertexCount = sides * 3 ;
/ / Vertices definition
@ -1235,6 +1240,7 @@ Mesh GenMeshPoly(int sides, float radius)
Mesh GenMeshPlane ( float width , float length , int resX , int resZ )
{
Mesh mesh = { 0 } ;
mesh . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) , 1 ) ;
# define CUSTOM_MESH_GEN_PLANE
# if defined(CUSTOM_MESH_GEN_PLANE)
@ -1337,6 +1343,7 @@ Mesh GenMeshPlane(float width, float length, int resX, int resZ)
mesh . vertices = ( float * ) RL_MALLOC ( plane - > ntriangles * 3 * 3 * sizeof ( float ) ) ;
mesh . texcoords = ( float * ) RL_MALLOC ( plane - > ntriangles * 3 * 2 * sizeof ( float ) ) ;
mesh . normals = ( float * ) RL_MALLOC ( plane - > ntriangles * 3 * 3 * sizeof ( float ) ) ;
mesh . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) ) ;
mesh . vertexCount = plane - > ntriangles * 3 ;
mesh . triangleCount = plane - > ntriangles ;
@ -1368,6 +1375,7 @@ Mesh GenMeshPlane(float width, float length, int resX, int resZ)
Mesh GenMeshCube ( float width , float height , float length )
{
Mesh mesh = { 0 } ;
mesh . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) , 1 ) ;
# define CUSTOM_MESH_GEN_CUBE
# if defined(CUSTOM_MESH_GEN_CUBE)
@ -1533,6 +1541,7 @@ par_shapes_mesh* par_shapes_create_icosahedron(); // 20 sides polyhedron
RLAPI Mesh GenMeshSphere ( float radius , int rings , int slices )
{
Mesh mesh = { 0 } ;
mesh . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) , 1 ) ;
par_shapes_mesh * sphere = par_shapes_create_parametric_sphere ( slices , rings ) ;
par_shapes_scale ( sphere , radius , radius , radius ) ;
@ -1571,6 +1580,7 @@ RLAPI Mesh GenMeshSphere(float radius, int rings, int slices)
RLAPI Mesh GenMeshHemiSphere ( float radius , int rings , int slices )
{
Mesh mesh = { 0 } ;
mesh . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) , 1 ) ;
par_shapes_mesh * sphere = par_shapes_create_hemisphere ( slices , rings ) ;
par_shapes_scale ( sphere , radius , radius , radius ) ;
@ -1609,6 +1619,7 @@ RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices)
Mesh GenMeshCylinder ( float radius , float height , int slices )
{
Mesh mesh = { 0 } ;
mesh . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) , 1 ) ;
/ / Instance a cylinder that sits on the Z = 0 plane using the given tessellation
/ / levels across the UV domain . Think of " slices " like a number of pizza
@ -1667,6 +1678,7 @@ Mesh GenMeshCylinder(float radius, float height, int slices)
Mesh GenMeshTorus ( float radius , float size , int radSeg , int sides )
{
Mesh mesh = { 0 } ;
mesh . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) , 1 ) ;
if ( radius > 1.0f ) radius = 1.0f ;
else if ( radius < 0.1f ) radius = 0.1f ;
@ -1709,6 +1721,7 @@ Mesh GenMeshTorus(float radius, float size, int radSeg, int sides)
Mesh GenMeshKnot ( float radius , float size , int radSeg , int sides )
{
Mesh mesh = { 0 } ;
mesh . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) , 1 ) ;
if ( radius > 3.0f ) radius = 3.0f ;
else if ( radius < 0.5f ) radius = 0.5f ;
@ -1860,13 +1873,14 @@ Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
Mesh GenMeshCubicmap ( Image cubicmap , Vector3 cubeSize )
{
Mesh mesh = { 0 } ;
mesh . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) , 1 ) ;
Color * cubicmapPixels = GetImageData ( cubicmap ) ;
int mapWidth = cubicmap . width ;
int mapHeight = cubicmap . height ;
/ / NOTE : Max possible number of triangles numCubes * ( 12 triangles by cube )
/ / NOTE : Max possible number of triangles numCubes * ( 12 triangles by cube )
int maxTriangles = cubicmap . width * cubicmap . height * 12 ;
int vCounter = 0 ; / / Used to count vertices
@ -2478,11 +2492,11 @@ bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, floa
/ / Simple way to check for collision , just checking distance between two points
/ / Unfortunately , sqrtf ( ) is a costly operation , so we avoid it with following solution
/*
float dx = centerA . x - centerB . x ; / / X distance between centers
float dy = centerA . y - centerB . y ; / / Y distance between centers
float dz = centerA . z - centerB . z ; / / Z distance between centers
float dx = centerA . x - centerB . x ; / / X distance between centers
float dy = centerA . y - centerB . y ; / / Y distance between centers
float dz = centerA . z - centerB . z ; / / Z distance between centers
float distance = sqrtf ( dx * dx + dy * dy + dz * dz ) ; / / Distance between centers
float distance = sqrtf ( dx * dx + dy * dy + dz * dz ) ; / / Distance between centers
if ( distance < = ( radiusA + radiusB ) ) collision = true ;
*/
@ -2510,35 +2524,35 @@ bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2)
}
/ / Detect collision between box and sphere
bool CheckCollisionBoxSphere ( BoundingBox box , Vector3 centerSphere , float radiusSphere )
bool CheckCollisionBoxSphere ( BoundingBox box , Vector3 center , float radius )
{
bool collision = false ;
float dmin = 0 ;
if ( centerSphere . x < box . min . x ) dmin + = powf ( centerSphere . x - box . min . x , 2 ) ;
else if ( centerSphere . x > box . max . x ) dmin + = powf ( centerSphere . x - box . max . x , 2 ) ;
if ( center . x < box . min . x ) dmin + = powf ( center . x - box . min . x , 2 ) ;
else if ( center . x > box . max . x ) dmin + = powf ( center . x - box . max . x , 2 ) ;
if ( centerSphere . y < box . min . y ) dmin + = powf ( centerSphere . y - box . min . y , 2 ) ;
else if ( centerSphere . y > box . max . y ) dmin + = powf ( centerSphere . y - box . max . y , 2 ) ;
if ( center . y < box . min . y ) dmin + = powf ( center . y - box . min . y , 2 ) ;
else if ( center . y > box . max . y ) dmin + = powf ( center . y - box . max . y , 2 ) ;
if ( centerSphere . z < box . min . z ) dmin + = powf ( centerSphere . z - box . min . z , 2 ) ;
else if ( centerSphere . z > box . max . z ) dmin + = powf ( centerSphere . z - box . max . z , 2 ) ;
if ( center . z < box . min . z ) dmin + = powf ( center . z - box . min . z , 2 ) ;
else if ( center . z > box . max . z ) dmin + = powf ( center . z - box . max . z , 2 ) ;
if ( dmin < = ( radiusSphere * radiusSphere ) ) collision = true ;
if ( dmin < = ( radius * radius ) ) collision = true ;
return collision ;
}
/ / Detect collision between ray and sphere
bool CheckCollisionRaySphere ( Ray ray , Vector3 spherePosition , float sphe reR adius)
bool CheckCollisionRaySphere ( Ray ray , Vector3 center , float radius )
{
bool collision = false ;
Vector3 raySpherePos = Vector3Subtract ( spherePosition , ray . position ) ;
Vector3 raySpherePos = Vector3Subtract ( center , ray . position ) ;
float distance = Vector3Length ( raySpherePos ) ;
float vector = Vector3DotProduct ( raySpherePos , ray . direction ) ;
float d = sphe reR adius* sphe reR adius - ( distance * distance - vector * vector ) ;
float d = radius * radius - ( distance * distance - vector * vector ) ;
if ( d > = 0.0f ) collision = true ;
@ -2546,21 +2560,21 @@ bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius
}
/ / Detect collision between ray and sphere with extended parameters and collision point detection
bool CheckCollisionRaySphereEx ( Ray ray , Vector3 spherePosition , float sphe reR adius, Vector3 * collisionPoint )
bool CheckCollisionRaySphereEx ( Ray ray , Vector3 center , float radius , Vector3 * collisionPoint )
{
bool collision = false ;
Vector3 raySpherePos = Vector3Subtract ( spherePosition , ray . position ) ;
Vector3 raySpherePos = Vector3Subtract ( center , ray . position ) ;
float distance = Vector3Length ( raySpherePos ) ;
float vector = Vector3DotProduct ( raySpherePos , ray . direction ) ;
float d = sphe reR adius* sphe reR adius - ( distance * distance - vector * vector ) ;
float d = radius * radius - ( distance * distance - vector * vector ) ;
if ( d > = 0.0f ) collision = true ;
/ / Check if ray origin is inside the sphere to calculate the correct collision point
float collisionDistance = 0 ;
if ( distance < sphe reR adius) collisionDistance = vector + sqrtf ( d ) ;
if ( distance < radius ) collisionDistance = vector + sqrtf ( d ) ;
else collisionDistance = vector - sqrtf ( d ) ;
/ / Calculate collision point
@ -2594,29 +2608,29 @@ bool CheckCollisionRayBox(Ray ray, BoundingBox box)
}
/ / Get collision info between ray and model
RayHitInfo GetCollisionRayModel ( Ray ray , Model o">* model )
RayHitInfo GetCollisionRayModel ( Ray ray , Model model )
{
RayHitInfo result = { 0 } ;
for ( int m = 0 ; m < model o">- > meshCount ; m + + )
for ( int m = 0 ; m < model p">. meshCount ; m + + )
{
/ / Check if meshhas vertex data on CPU for testing
if ( model o">- > meshes [ m ] . vertices ! = NULL )
if ( model p">. meshes [ m ] . vertices ! = NULL )
{
/ / model - > mesh . triangleCount may not be set , vertexCount is more reliable
int triangleCount = model o">- > meshes [ m ] . vertexCount / 3 ;
int triangleCount = model p">. meshes [ m ] . vertexCount / 3 ;
/ / Test against all triangles in mesh
for ( int i = 0 ; i < triangleCount ; i + + )
{
Vector3 a , b , c ;
Vector3 * vertdata = ( Vector3 * ) model o">- > meshes [ m ] . vertices ;
Vector3 * vertdata = ( Vector3 * ) model p">. meshes [ m ] . vertices ;
if ( model o">- > meshes [ m ] . indices )
if ( model p">. meshes [ m ] . indices )
{
a = vertdata [ model o">- > meshes [ m ] . indices [ i * 3 + 0 ] ] ;
b = vertdata [ model o">- > meshes [ m ] . indices [ i * 3 + 1 ] ] ;
c = vertdata [ model o">- > meshes [ m ] . indices [ i * 3 + 2 ] ] ;
a = vertdata [ model p">. meshes [ m ] . indices [ i * 3 + 0 ] ] ;
b = vertdata [ model p">. meshes [ m ] . indices [ i * 3 + 1 ] ] ;
c = vertdata [ model p">. meshes [ m ] . indices [ i * 3 + 2 ] ] ;
}
else
{
@ -2625,9 +2639,9 @@ RayHitInfo GetCollisionRayModel(Ray ray, Model *model)
c = vertdata [ i * 3 + 2 ] ;
}
a = Vector3Transform ( a , model o">- > transform ) ;
b = Vector3Transform ( b , model o">- > transform ) ;
c = Vector3Transform ( c , model o">- > transform ) ;
a = Vector3Transform ( a , model p">. transform ) ;
b = Vector3Transform ( b , model p">. transform ) ;
c = Vector3Transform ( c , model p">. transform ) ;
RayHitInfo triHitInfo = GetCollisionRayTriangle ( ray , a , b , c ) ;
@ -2800,6 +2814,7 @@ static Model LoadOBJ(const char *fileName)
mesh . vertices = ( float * ) RL_MALLOC ( mesh . vertexCount * 3 * sizeof ( float ) ) ;
mesh . texcoords = ( float * ) RL_MALLOC ( mesh . vertexCount * 2 * sizeof ( float ) ) ;
mesh . normals = ( float * ) RL_MALLOC ( mesh . vertexCount * 3 * sizeof ( float ) ) ;
mesh . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) , 1 ) ;
int vCount = 0 ;
int vtCount = 0 ;
@ -3068,6 +3083,8 @@ static Model LoadIQM(const char *fileName)
/ / NOTE : Animated vertex should be re - uploaded to GPU ( if not using GPU skinning )
model . meshes [ i ] . animVertices = RL_MALLOC ( sizeof ( float ) * model . meshes [ i ] . vertexCount * 3 ) ;
model . meshes [ i ] . animNormals = RL_MALLOC ( sizeof ( float ) * model . meshes [ i ] . vertexCount * 3 ) ;
model . meshes [ i ] . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) , 1 ) ;
}
/ / Triangles data processing
@ -3386,8 +3403,10 @@ static Model LoadGLTF(const char *fileName)
model . meshCount = primitivesCount ;
model . meshes = RL_CALLOC ( model . meshCount , sizeof ( Mesh ) ) ;
model . materialCount = data - > materials_count + 1 ;
model . materials = RL_MALLOC ( model . materialCount * sizeof ( Material ) ) ;
model . meshMaterial = RL_MALLOC ( model . meshCount * sizeof ( int ) ) ;
model . materials = RL_MALLOC ( model . materialCount * sizeof ( Material ) ) ;
model . meshMaterial = RL_MALLOC ( model . meshCount * sizeof ( int ) ) ;
for ( int i = 0 ; i < model . meshCount ; i + + ) model . meshes [ i ] . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO * sizeof ( unsigned int ) , 1 ) ;
for ( int i = 0 ; i < model . materialCount - 1 ; i + + )
{
@ -3397,10 +3416,10 @@ static Model LoadGLTF(const char *fileName)
if ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor )
{
tint . r = ( unsigned char ) ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor [ 0 ] * 255.99f ) ;
tint . g = ( unsigned char ) ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor [ 1 ] * 255.99f ) ;
tint . b = ( unsigned char ) ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor [ 2 ] * 255.99f ) ;
tint . a = ( unsigned char ) ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor [ 3 ] * 255.99f ) ;
tint . r = ( unsigned char ) ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor [ 0 ] * 255.99f ) ;
tint . g = ( unsigned char ) ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor [ 1 ] * 255.99f ) ;
tint . b = ( unsigned char ) ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor [ 2 ] * 255.99f ) ;
tint . a = ( unsigned char ) ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor [ 3 ] * 255.99f ) ;
}
else
{