This commit is contained in:
Jeffery Myers 2026-06-27 15:27:33 -04:00 committed by GitHub
commit b89b4e7c32
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 278 additions and 150 deletions

View File

@ -43,7 +43,7 @@
// Module Functions Declaration
//------------------------------------------------------------------------------------
static bool IsUpperBodyBone(const char *boneName);
static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim1, int frame1,
static void UpdateModelAnimationBoneCustom(Model *model, ModelAnimation *anim1, int frame1,
ModelAnimation *anim2, int frame2, float blend, bool upperBodyBlend);
//------------------------------------------------------------------------------------
@ -117,7 +117,7 @@ int main(void)
// When upperBodyBlend is ON: upper body = attack (1.0), lower body = walk (0.0)
// When upperBodyBlend is OFF: uniform blend at 0.5 (50% walk, 50% attack)
float blendFactor = (upperBodyBlend? 1.0f : 0.5f);
UpdateModelAnimationBones(&model, &anim0, animCurrentFrame0,
UpdateModelAnimationBoneCustom(&model, &anim0, animCurrentFrame0,
&anim1, animCurrentFrame1, blendFactor, upperBodyBlend);
// raylib provided animation blending function
@ -194,7 +194,7 @@ static bool IsUpperBodyBone(const char *boneName)
}
// Blend two animations per-bone with selective upper/lower body blending
static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim0, int frame0,
static void UpdateModelAnimationBoneCustom(Model *model, ModelAnimation *anim0, int frame0,
ModelAnimation *anim1, int frame1, float blend, bool upperBodyBlend)
{
// Validate inputs

View File

@ -322,7 +322,7 @@
#endif
#ifndef SUPPORT_GPU_SKINNING
// GPU skinning disabled by default, some GPUs do not support more than 8 VBOs
#define SUPPORT_GPU_SKINNING 0
#define SUPPORT_GPU_SKINNING 1
#endif
//------------------------------------------------------------------------------------

View File

@ -1649,6 +1649,8 @@ RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId);
RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file
RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, float frame); // Update model animation pose (vertex buffers and bone matrices)
RLAPI void UpdateModelAnimationEx(Model model, ModelAnimation animA, float frameA, ModelAnimation animB, float frameB, float blend); // Update model animation pose, blending two animations
RLAPI void UpdateModelAnimationBones(Model model, ModelAnimation anim, float frame); // Update model animation pose (bones only)
RLAPI void UpdateModelAnimationBonesEx(Model model, ModelAnimation animA, float frameA, ModelAnimation animB, float frameB, float blend); // Update model animation bones to pose, blending two animations
RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data
RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match

View File

@ -182,6 +182,21 @@ static void ProcessMaterialsOBJ(Material *rayMaterials, tinyobj_material_t *mate
// Update model vertex data (positions and normals)
static void UpdateModelAnimationVertexBuffers(Model model);
// Lazy allocation of CPU animation buffers for vertex positions and normals, used for software skinning
static void AllocateMeshCPUAnimBuffers(Mesh* mesh)
{
if (mesh == NULL || mesh->animVertices != NULL || mesh->animNormals != NULL) return; // Buffers already allocated
mesh->animVertices = (float*)RL_CALLOC(mesh->vertexCount * 3, sizeof(float));
memcpy(mesh->animVertices, mesh->vertices, mesh->vertexCount * 3 * sizeof(float));
if (mesh->normals != NULL)
{
mesh->animNormals = (float*)RL_CALLOC(mesh->vertexCount * 3, sizeof(float));
memcpy(mesh->animNormals, mesh->normals, mesh->vertexCount * 3 * sizeof(float));
}
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
@ -2295,11 +2310,9 @@ ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount)
return animations;
}
// Update model animation data (vertex buffers / bone matrices) for a specific pose
// Update model animation data (bone matrices) for a specific pose
// NOTE 1: Request frame could be fractional, using a lerp interpolation between two frames
// NOTE 2: Updated vertex animation data is uploaded to GPU in case of CPU skinning,
// for GPU skinning, bone matrices are uploaded to shader on DrawModelEx()
void UpdateModelAnimation(Model model, ModelAnimation anim, float frame)
void UpdateModelAnimationBones(Model model, ModelAnimation anim, float frame)
{
if (model.boneMatrices == NULL) return;
@ -2313,8 +2326,8 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, float frame)
int nextFrame = currentFrame + 1;
float blend = frame - currentFrame;
blend = Clamp(blend, 0.0f, 1.0f);
if (currentFrame >= anim.keyframeCount) currentFrame = currentFrame%anim.keyframeCount;
if (nextFrame >= anim.keyframeCount) nextFrame = nextFrame%anim.keyframeCount;
if (currentFrame >= anim.keyframeCount) currentFrame = currentFrame % anim.keyframeCount;
if (nextFrame >= anim.keyframeCount) nextFrame = nextFrame % anim.keyframeCount;
Matrix bindPoseMatrix = { 0 };
Matrix currentPoseMatrix = { 0 };
@ -2336,13 +2349,13 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, float frame)
// Compute runtime bone matrix from model current pose
//-----------------------------------------------------------------------------------
Transform *bindPoseTransform = &model.skeleton.bindPose[boneIndex];
Transform* bindPoseTransform = &model.skeleton.bindPose[boneIndex];
bindPoseMatrix = MatrixMultiply(
MatrixMultiply(MatrixScale(bindPoseTransform->scale.x, bindPoseTransform->scale.y, bindPoseTransform->scale.z),
QuaternionToMatrix(bindPoseTransform->rotation)),
MatrixTranslate(bindPoseTransform->translation.x, bindPoseTransform->translation.y, bindPoseTransform->translation.z));
Transform *currentPoseTransform = &model.currentPose[boneIndex];
Transform* currentPoseTransform = &model.currentPose[boneIndex];
currentPoseMatrix = MatrixMultiply(
MatrixMultiply(MatrixScale(currentPoseTransform->scale.x, currentPoseTransform->scale.y, currentPoseTransform->scale.z),
QuaternionToMatrix(currentPoseTransform->rotation)),
@ -2351,6 +2364,18 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, float frame)
model.boneMatrices[boneIndex] = MatrixMultiply(MatrixInvert(bindPoseMatrix), currentPoseMatrix);
//-----------------------------------------------------------------------------------
}
}
}
// Update model animation data (vertex buffers / bone matrices) for a specific pose
// NOTE 1: Request frame could be fractional, using a lerp interpolation between two frames
// NOTE 2: Updated vertex animation data is uploaded to GPU in case of CPU skinning,
// for GPU skinning, bone matrices are uploaded to shader on DrawModelEx()
void UpdateModelAnimation(Model model, ModelAnimation anim, float frame)
{
if ((anim.keyframeCount > 0) && (model.skeleton.bones != NULL) && (anim.keyframePoses != NULL))
{
UpdateModelAnimationBones(model, anim, frame);
// CPU skinning, updates CPU buffers and uploads them to GPU
// NOTE: On GPU skinning not supported, use CPU skinning
@ -2358,12 +2383,10 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, float frame)
}
}
// Update model animation data (vertex buffers / bone matrices) for a specific pose,
// Update model animation data (bone matrices) for a specific pose,
// defined by two different animations at specific frames blended together
// NOTE 1: Request frames could be fractional, using a lerp interpolation between two frames
// NOTE 2: Updated vertex animation data is uploaded to GPU in case of CPU skinning,
// for GPU skinning, bone matrices are uploaded to shader on DrawModelEx()
void UpdateModelAnimationEx(Model model, ModelAnimation animA, float frameA, ModelAnimation animB, float frameB, float blend)
void UpdateModelAnimationBonesEx(Model model, ModelAnimation animA, float frameA, ModelAnimation animB, float frameB, float blend)
{
if (model.boneMatrices == NULL) return;
@ -2372,20 +2395,20 @@ void UpdateModelAnimationEx(Model model, ModelAnimation animA, float frameA, Mod
(blend >= 0.0f) && (blend <= 1.0f))
{
// Inter-frame interpolation values for first animation
int currentFrameA = (int)frameA%animA.keyframeCount;
int currentFrameA = (int)frameA % animA.keyframeCount;
int nextFrameA = currentFrameA + 1;
float blendA = frameA - currentFrameA;
blendA = Clamp(blendA, 0.0f, 1.0f);
if (currentFrameA >= animA.keyframeCount) currentFrameA = currentFrameA%animA.keyframeCount;
if (nextFrameA >= animA.keyframeCount) nextFrameA = nextFrameA%animA.keyframeCount;
if (currentFrameA >= animA.keyframeCount) currentFrameA = currentFrameA % animA.keyframeCount;
if (nextFrameA >= animA.keyframeCount) nextFrameA = nextFrameA % animA.keyframeCount;
// Inter-frame interpolation values for second animation
int currentFrameB = (int)frameB%animB.keyframeCount;
int currentFrameB = (int)frameB % animB.keyframeCount;
int nextFrameB = currentFrameB + 1;
float blendB = frameB - currentFrameB;
blendB = Clamp(blendB, 0.0f, 1.0f);
if (currentFrameB >= animB.keyframeCount) currentFrameB = currentFrameB%animB.keyframeCount;
if (nextFrameB >= animB.keyframeCount) nextFrameB = nextFrameB%animB.keyframeCount;
if (currentFrameB >= animB.keyframeCount) currentFrameB = currentFrameB % animB.keyframeCount;
if (nextFrameB >= animB.keyframeCount) nextFrameB = nextFrameB % animB.keyframeCount;
Matrix bindPoseMatrix = { 0 };
Matrix currentPoseMatrix = { 0 };
@ -2422,13 +2445,13 @@ void UpdateModelAnimationEx(Model model, ModelAnimation animA, float frameA, Mod
// Compute runtime bone matrix from model current pose
//-----------------------------------------------------------------------------------
Transform *bindPoseTransform = &model.skeleton.bindPose[boneIndex];
Transform* bindPoseTransform = &model.skeleton.bindPose[boneIndex];
bindPoseMatrix = MatrixMultiply(
MatrixMultiply(MatrixScale(bindPoseTransform->scale.x, bindPoseTransform->scale.y, bindPoseTransform->scale.z),
QuaternionToMatrix(bindPoseTransform->rotation)),
MatrixTranslate(bindPoseTransform->translation.x, bindPoseTransform->translation.y, bindPoseTransform->translation.z));
Transform *currentPoseTransform = &model.currentPose[boneIndex];
Transform* currentPoseTransform = &model.currentPose[boneIndex];
currentPoseMatrix = MatrixMultiply(
MatrixMultiply(MatrixScale(currentPoseTransform->scale.x, currentPoseTransform->scale.y, currentPoseTransform->scale.z),
QuaternionToMatrix(currentPoseTransform->rotation)),
@ -2466,6 +2489,23 @@ void UpdateModelAnimationEx(Model model, ModelAnimation animA, float frameA, Mod
MatrixScale(boneScale.x, boneScale.y, boneScale.z));
*/
}
}
}
// Update model animation data (vertex buffers / bone matrices) for a specific pose,
// defined by two different animations at specific frames blended together
// NOTE 1: Request frames could be fractional, using a lerp interpolation between two frames
// NOTE 2: Updated vertex animation data is uploaded to GPU in case of CPU skinning,
// for GPU skinning, bone matrices are uploaded to shader on DrawModelEx()
void UpdateModelAnimationEx(Model model, ModelAnimation animA, float frameA, ModelAnimation animB, float frameB, float blend)
{
if (model.boneMatrices == NULL) return;
if ((animA.keyframeCount > 0) && (animA.keyframePoses != NULL) &&
(animB.keyframeCount > 0) && (animB.keyframePoses != NULL) &&
(blend >= 0.0f) && (blend <= 1.0f))
{
UpdateModelAnimationBonesEx(model, animA, frameA, animB, frameB, blend);
// CPU skinning, updates CPU buffers and uploads them to GPU (if available)
// NOTE: Fallback in case GPU skinning is not supported or enabled
@ -2479,10 +2519,10 @@ static void UpdateModelAnimationVertexBuffers(Model model)
{
for (int m = 0; m < model.meshCount; m++)
{
Mesh mesh = model.meshes[m];
Mesh* mesh = model.meshes + m; // don't copy the mesh, we may need to allocate buffers
Vector3 animVertex = { 0 };
Vector3 animNormal = { 0 };
const int vertexValuesCount = mesh.vertexCount*3;
const int vertexValuesCount = mesh->vertexCount*3;
int boneIndex = 0;
int boneCounter = 0;
@ -2490,45 +2530,52 @@ static void UpdateModelAnimationVertexBuffers(Model model)
bool bufferUpdateRequired = false; // Flag to check when anim vertex information is updated
// Skip if missing bone data or missing anim buffers initialization
if ((mesh.boneWeights == NULL) || (mesh.boneIndices == NULL) ||
(mesh.animVertices == NULL) || (mesh.animNormals == NULL)) continue;
if ((mesh->boneWeights == NULL) || (mesh->boneIndices == NULL)) continue;
// Skip if the shader is using the bones directly
#if defined (SUPPORT_GPU_SKINNING)
Material material = model.materials[model.meshMaterial[m]];
if ((material.shader.locs[SHADER_LOC_VERTEX_BONEIDS] != -1) ) continue;
#endif
if (mesh->animVertices == NULL) AllocateMeshCPUAnimBuffers(mesh);
for (int vCounter = 0; vCounter < vertexValuesCount; vCounter += 3)
{
mesh.animVertices[vCounter] = 0;
mesh.animVertices[vCounter + 1] = 0;
mesh.animVertices[vCounter + 2] = 0;
if (mesh.animNormals != NULL)
mesh->animVertices[vCounter] = 0;
mesh->animVertices[vCounter + 1] = 0;
mesh->animVertices[vCounter + 2] = 0;
if (mesh->animNormals != NULL)
{
mesh.animNormals[vCounter] = 0;
mesh.animNormals[vCounter + 1] = 0;
mesh.animNormals[vCounter + 2] = 0;
mesh->animNormals[vCounter] = 0;
mesh->animNormals[vCounter + 1] = 0;
mesh->animNormals[vCounter + 2] = 0;
}
// Iterates over 4 bones per vertex
for (int j = 0; j < 4; j++, boneCounter++)
{
boneWeight = mesh.boneWeights[boneCounter];
boneIndex = mesh.boneIndices[boneCounter];
boneWeight = mesh->boneWeights[boneCounter];
boneIndex = mesh->boneIndices[boneCounter];
// Early stop when no transformation will be applied
if (boneWeight == 0.0f) continue;
animVertex = (Vector3){ mesh.vertices[vCounter], mesh.vertices[vCounter + 1], mesh.vertices[vCounter + 2] };
animVertex = (Vector3){ mesh->vertices[vCounter], mesh->vertices[vCounter + 1], mesh->vertices[vCounter + 2] };
animVertex = Vector3Transform(animVertex, model.boneMatrices[boneIndex]);
mesh.animVertices[vCounter] += animVertex.x*boneWeight;
mesh.animVertices[vCounter + 1] += animVertex.y*boneWeight;
mesh.animVertices[vCounter + 2] += animVertex.z*boneWeight;
mesh->animVertices[vCounter] += animVertex.x*boneWeight;
mesh->animVertices[vCounter + 1] += animVertex.y*boneWeight;
mesh->animVertices[vCounter + 2] += animVertex.z*boneWeight;
bufferUpdateRequired = true;
// Normals processing
// NOTE: Using meshes.baseNormals (default normal) to calculate meshes.normals (animated normals)
if ((mesh.normals != NULL) && (mesh.animNormals != NULL ))
if ((mesh->normals != NULL) && (mesh->animNormals != NULL ))
{
animNormal = (Vector3){ mesh.normals[vCounter], mesh.normals[vCounter + 1], mesh.normals[vCounter + 2] };
animNormal = (Vector3){ mesh->normals[vCounter], mesh->normals[vCounter + 1], mesh->normals[vCounter + 2] };
animNormal = Vector3Transform(animNormal, MatrixTranspose(MatrixInvert(model.boneMatrices[boneIndex])));
mesh.animNormals[vCounter] += animNormal.x*boneWeight;
mesh.animNormals[vCounter + 1] += animNormal.y*boneWeight;
mesh.animNormals[vCounter + 2] += animNormal.z*boneWeight;
mesh->animNormals[vCounter] += animNormal.x*boneWeight;
mesh->animNormals[vCounter + 1] += animNormal.y*boneWeight;
mesh->animNormals[vCounter + 2] += animNormal.z*boneWeight;
}
}
}
@ -2536,8 +2583,8 @@ static void UpdateModelAnimationVertexBuffers(Model model)
if (bufferUpdateRequired)
{
// Update GPU vertex buffers with updated data (position + normals)
rlUpdateVertexBuffer(mesh.vboId[SHADER_LOC_VERTEX_POSITION], mesh.animVertices, mesh.vertexCount*3*sizeof(float), 0);
if (mesh.normals != NULL) rlUpdateVertexBuffer(mesh.vboId[SHADER_LOC_VERTEX_NORMAL], mesh.animNormals, mesh.vertexCount*3*sizeof(float), 0);
rlUpdateVertexBuffer(mesh->vboId[SHADER_LOC_VERTEX_POSITION], mesh->animVertices, mesh->vertexCount*3*sizeof(float), 0);
if (mesh->normals != NULL) rlUpdateVertexBuffer(mesh->vboId[SHADER_LOC_VERTEX_NORMAL], mesh->animNormals, mesh->vertexCount*3*sizeof(float), 0);
}
}
}
@ -4825,13 +4872,6 @@ static Model LoadIQM(const char *fileName)
model.meshes[i].triangleCount = imesh[i].num_triangles;
model.meshes[i].indices = (unsigned short *)RL_CALLOC(model.meshes[i].triangleCount*3, sizeof(unsigned short));
#if !SUPPORT_GPU_SKINNING
// Animated vertex data, processed for rendering
// NOTE: Animated vertex should be re-uploaded to GPU (if not using GPU skinning)
model.meshes[i].animVertices = (float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float));
model.meshes[i].animNormals = (float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float));
#endif
}
// Triangles data processing
@ -6331,13 +6371,6 @@ static Model LoadGLTF(const char *fileName)
}
}
#if !SUPPORT_GPU_SKINNING
// Animated vertex data (CPU skinning)
model.meshes[meshIndex].animVertices = (float *)RL_CALLOC(model.meshes[meshIndex].vertexCount*3, sizeof(float));
memcpy(model.meshes[meshIndex].animVertices, model.meshes[meshIndex].vertices, model.meshes[meshIndex].vertexCount*3*sizeof(float));
model.meshes[meshIndex].animNormals = (float *)RL_CALLOC(model.meshes[meshIndex].vertexCount*3, sizeof(float));
if (model.meshes[meshIndex].normals != NULL) memcpy(model.meshes[meshIndex].animNormals, model.meshes[meshIndex].normals, model.meshes[meshIndex].vertexCount*3*sizeof(float));
#endif
model.meshes[meshIndex].boneCount = model.skeleton.boneCount;
meshIndex++; // Move to next mesh
@ -6987,10 +7020,6 @@ static Model LoadM3D(const char *fileName)
{
model.meshes[k].boneIndices = (unsigned char *)RL_CALLOC(model.meshes[k].vertexCount*4, sizeof(unsigned char));
model.meshes[k].boneWeights = (float *)RL_CALLOC(model.meshes[k].vertexCount*4, sizeof(float));
#if !SUPPORT_GPU_SKINNING
model.meshes[k].animVertices = (float *)RL_CALLOC(model.meshes[k].vertexCount*3, sizeof(float));
model.meshes[k].animNormals = (float *)RL_CALLOC(model.meshes[k].vertexCount*3, sizeof(float));
#endif
}
model.meshMaterial[k] = mi + 1;
@ -7193,12 +7222,6 @@ static Model LoadM3D(const char *fileName)
for (i = 0; i < model.meshCount; i++)
{
model.meshes[i].boneCount = model.skeleton.boneCount;
#if !SUPPORT_GPU_SKINNING
// Initialize vertex buffers for CPU skinning
memcpy(model.meshes[i].animVertices, model.meshes[i].vertices, model.meshes[i].vertexCount*3*sizeof(float));
memcpy(model.meshes[i].animNormals, model.meshes[i].normals, model.meshes[i].vertexCount*3*sizeof(float));
#endif
}
// Initialize runtime animation data: current pose and bone matrices

View File

@ -11685,6 +11685,56 @@
}
]
},
{
"name": "UpdateModelAnimationBones",
"description": "Update model animation pose (bones only)",
"returnType": "void",
"params": [
{
"type": "Model",
"name": "model"
},
{
"type": "ModelAnimation",
"name": "anim"
},
{
"type": "float",
"name": "frame"
}
]
},
{
"name": "UpdateModelAnimationBonesEx",
"description": "Update model animation bones to pose, blending two animations",
"returnType": "void",
"params": [
{
"type": "Model",
"name": "model"
},
{
"type": "ModelAnimation",
"name": "animA"
},
{
"type": "float",
"name": "frameA"
},
{
"type": "ModelAnimation",
"name": "animB"
},
{
"type": "float",
"name": "frameB"
},
{
"type": "float",
"name": "blend"
}
]
},
{
"name": "UnloadModelAnimations",
"description": "Unload animation array data",

View File

@ -7929,6 +7929,29 @@ return {
{type = "float", name = "blend"}
}
},
{
name = "UpdateModelAnimationBones",
description = "Update model animation pose (bones only)",
returnType = "void",
params = {
{type = "Model", name = "model"},
{type = "ModelAnimation", name = "anim"},
{type = "float", name = "frame"}
}
},
{
name = "UpdateModelAnimationBonesEx",
description = "Update model animation bones to pose, blending two animations",
returnType = "void",
params = {
{type = "Model", name = "model"},
{type = "ModelAnimation", name = "animA"},
{type = "float", name = "frameA"},
{type = "ModelAnimation", name = "animB"},
{type = "float", name = "frameB"},
{type = "float", name = "blend"}
}
},
{
name = "UnloadModelAnimations",
description = "Unload animation array data",

View File

@ -995,7 +995,7 @@ Callback 006: AudioCallback() (2 input parameters)
Param[1]: bufferData (type: void *)
Param[2]: frames (type: unsigned int)
Functions found: 607
Functions found: 609
Function 001: InitWindow() (3 input parameters)
Name: InitWindow
@ -4437,19 +4437,36 @@ Function 531: UpdateModelAnimationEx() (6 input parameters)
Param[4]: animB (type: ModelAnimation)
Param[5]: frameB (type: float)
Param[6]: blend (type: float)
Function 532: UnloadModelAnimations() (2 input parameters)
Function 532: UpdateModelAnimationBones() (3 input parameters)
Name: UpdateModelAnimationBones
Return type: void
Description: Update model animation pose (bones only)
Param[1]: model (type: Model)
Param[2]: anim (type: ModelAnimation)
Param[3]: frame (type: float)
Function 533: UpdateModelAnimationBonesEx() (6 input parameters)
Name: UpdateModelAnimationBonesEx
Return type: void
Description: Update model animation bones to pose, blending two animations
Param[1]: model (type: Model)
Param[2]: animA (type: ModelAnimation)
Param[3]: frameA (type: float)
Param[4]: animB (type: ModelAnimation)
Param[5]: frameB (type: float)
Param[6]: blend (type: float)
Function 534: UnloadModelAnimations() (2 input parameters)
Name: UnloadModelAnimations
Return type: void
Description: Unload animation array data
Param[1]: animations (type: ModelAnimation *)
Param[2]: animCount (type: int)
Function 533: IsModelAnimationValid() (2 input parameters)
Function 535: IsModelAnimationValid() (2 input parameters)
Name: IsModelAnimationValid
Return type: bool
Description: Check model animation skeleton match
Param[1]: model (type: Model)
Param[2]: anim (type: ModelAnimation)
Function 534: CheckCollisionSpheres() (4 input parameters)
Function 536: CheckCollisionSpheres() (4 input parameters)
Name: CheckCollisionSpheres
Return type: bool
Description: Check collision between two spheres
@ -4457,40 +4474,40 @@ Function 534: CheckCollisionSpheres() (4 input parameters)
Param[2]: radius1 (type: float)
Param[3]: center2 (type: Vector3)
Param[4]: radius2 (type: float)
Function 535: CheckCollisionBoxes() (2 input parameters)
Function 537: CheckCollisionBoxes() (2 input parameters)
Name: CheckCollisionBoxes
Return type: bool
Description: Check collision between two bounding boxes
Param[1]: box1 (type: BoundingBox)
Param[2]: box2 (type: BoundingBox)
Function 536: CheckCollisionBoxSphere() (3 input parameters)
Function 538: CheckCollisionBoxSphere() (3 input parameters)
Name: CheckCollisionBoxSphere
Return type: bool
Description: Check collision between box and sphere
Param[1]: box (type: BoundingBox)
Param[2]: center (type: Vector3)
Param[3]: radius (type: float)
Function 537: GetRayCollisionSphere() (3 input parameters)
Function 539: GetRayCollisionSphere() (3 input parameters)
Name: GetRayCollisionSphere
Return type: RayCollision
Description: Get collision info between ray and sphere
Param[1]: ray (type: Ray)
Param[2]: center (type: Vector3)
Param[3]: radius (type: float)
Function 538: GetRayCollisionBox() (2 input parameters)
Function 540: GetRayCollisionBox() (2 input parameters)
Name: GetRayCollisionBox
Return type: RayCollision
Description: Get collision info between ray and box
Param[1]: ray (type: Ray)
Param[2]: box (type: BoundingBox)
Function 539: GetRayCollisionMesh() (3 input parameters)
Function 541: GetRayCollisionMesh() (3 input parameters)
Name: GetRayCollisionMesh
Return type: RayCollision
Description: Get collision info between ray and mesh
Param[1]: ray (type: Ray)
Param[2]: mesh (type: Mesh)
Param[3]: transform (type: Matrix)
Function 540: GetRayCollisionTriangle() (4 input parameters)
Function 542: GetRayCollisionTriangle() (4 input parameters)
Name: GetRayCollisionTriangle
Return type: RayCollision
Description: Get collision info between ray and triangle
@ -4498,7 +4515,7 @@ Function 540: GetRayCollisionTriangle() (4 input parameters)
Param[2]: p1 (type: Vector3)
Param[3]: p2 (type: Vector3)
Param[4]: p3 (type: Vector3)
Function 541: GetRayCollisionQuad() (5 input parameters)
Function 543: GetRayCollisionQuad() (5 input parameters)
Name: GetRayCollisionQuad
Return type: RayCollision
Description: Get collision info between ray and quad
@ -4507,158 +4524,158 @@ Function 541: GetRayCollisionQuad() (5 input parameters)
Param[3]: p2 (type: Vector3)
Param[4]: p3 (type: Vector3)
Param[5]: p4 (type: Vector3)
Function 542: InitAudioDevice() (0 input parameters)
Function 544: InitAudioDevice() (0 input parameters)
Name: InitAudioDevice
Return type: void
Description: Initialize audio device and context
No input parameters
Function 543: CloseAudioDevice() (0 input parameters)
Function 545: CloseAudioDevice() (0 input parameters)
Name: CloseAudioDevice
Return type: void
Description: Close the audio device and context
No input parameters
Function 544: IsAudioDeviceReady() (0 input parameters)
Function 546: IsAudioDeviceReady() (0 input parameters)
Name: IsAudioDeviceReady
Return type: bool
Description: Check if audio device has been initialized successfully
No input parameters
Function 545: SetMasterVolume() (1 input parameters)
Function 547: SetMasterVolume() (1 input parameters)
Name: SetMasterVolume
Return type: void
Description: Set master volume (listener)
Param[1]: volume (type: float)
Function 546: GetMasterVolume() (0 input parameters)
Function 548: GetMasterVolume() (0 input parameters)
Name: GetMasterVolume
Return type: float
Description: Get master volume (listener)
No input parameters
Function 547: LoadWave() (1 input parameters)
Function 549: LoadWave() (1 input parameters)
Name: LoadWave
Return type: Wave
Description: Load wave data from file
Param[1]: fileName (type: const char *)
Function 548: LoadWaveFromMemory() (3 input parameters)
Function 550: LoadWaveFromMemory() (3 input parameters)
Name: LoadWaveFromMemory
Return type: Wave
Description: Load wave from memory buffer, fileType refers to extension: i.e. '.wav'
Param[1]: fileType (type: const char *)
Param[2]: fileData (type: const unsigned char *)
Param[3]: dataSize (type: int)
Function 549: IsWaveValid() (1 input parameters)
Function 551: IsWaveValid() (1 input parameters)
Name: IsWaveValid
Return type: bool
Description: Check if wave data is valid (data loaded and parameters)
Param[1]: wave (type: Wave)
Function 550: LoadSound() (1 input parameters)
Function 552: LoadSound() (1 input parameters)
Name: LoadSound
Return type: Sound
Description: Load sound from file
Param[1]: fileName (type: const char *)
Function 551: LoadSoundFromWave() (1 input parameters)
Function 553: LoadSoundFromWave() (1 input parameters)
Name: LoadSoundFromWave
Return type: Sound
Description: Load sound from wave data
Param[1]: wave (type: Wave)
Function 552: LoadSoundAlias() (1 input parameters)
Function 554: LoadSoundAlias() (1 input parameters)
Name: LoadSoundAlias
Return type: Sound
Description: Load sound alias, new sound that shares the same sample data as the source sound, does not own the sound data
Param[1]: source (type: Sound)
Function 553: IsSoundValid() (1 input parameters)
Function 555: IsSoundValid() (1 input parameters)
Name: IsSoundValid
Return type: bool
Description: Check if sound is valid (data loaded and buffers initialized)
Param[1]: sound (type: Sound)
Function 554: UpdateSound() (3 input parameters)
Function 556: UpdateSound() (3 input parameters)
Name: UpdateSound
Return type: void
Description: Update sound buffer with new data (default data format: 32 bit float, stereo)
Param[1]: sound (type: Sound)
Param[2]: data (type: const void *)
Param[3]: frameCount (type: int)
Function 555: UnloadWave() (1 input parameters)
Function 557: UnloadWave() (1 input parameters)
Name: UnloadWave
Return type: void
Description: Unload wave data
Param[1]: wave (type: Wave)
Function 556: UnloadSound() (1 input parameters)
Function 558: UnloadSound() (1 input parameters)
Name: UnloadSound
Return type: void
Description: Unload sound
Param[1]: sound (type: Sound)
Function 557: UnloadSoundAlias() (1 input parameters)
Function 559: UnloadSoundAlias() (1 input parameters)
Name: UnloadSoundAlias
Return type: void
Description: Unload sound alias (does not deallocate sample data)
Param[1]: alias (type: Sound)
Function 558: ExportWave() (2 input parameters)
Function 560: ExportWave() (2 input parameters)
Name: ExportWave
Return type: bool
Description: Export wave data to file, returns true on success
Param[1]: wave (type: Wave)
Param[2]: fileName (type: const char *)
Function 559: ExportWaveAsCode() (2 input parameters)
Function 561: ExportWaveAsCode() (2 input parameters)
Name: ExportWaveAsCode
Return type: bool
Description: Export wave sample data to code (.h), returns true on success
Param[1]: wave (type: Wave)
Param[2]: fileName (type: const char *)
Function 560: PlaySound() (1 input parameters)
Function 562: PlaySound() (1 input parameters)
Name: PlaySound
Return type: void
Description: Play a sound
Param[1]: sound (type: Sound)
Function 561: StopSound() (1 input parameters)
Function 563: StopSound() (1 input parameters)
Name: StopSound
Return type: void
Description: Stop playing a sound
Param[1]: sound (type: Sound)
Function 562: PauseSound() (1 input parameters)
Function 564: PauseSound() (1 input parameters)
Name: PauseSound
Return type: void
Description: Pause a sound
Param[1]: sound (type: Sound)
Function 563: ResumeSound() (1 input parameters)
Function 565: ResumeSound() (1 input parameters)
Name: ResumeSound
Return type: void
Description: Resume a paused sound
Param[1]: sound (type: Sound)
Function 564: IsSoundPlaying() (1 input parameters)
Function 566: IsSoundPlaying() (1 input parameters)
Name: IsSoundPlaying
Return type: bool
Description: Check if sound is currently playing
Param[1]: sound (type: Sound)
Function 565: SetSoundVolume() (2 input parameters)
Function 567: SetSoundVolume() (2 input parameters)
Name: SetSoundVolume
Return type: void
Description: Set volume for a sound (1.0 is max level)
Param[1]: sound (type: Sound)
Param[2]: volume (type: float)
Function 566: SetSoundPitch() (2 input parameters)
Function 568: SetSoundPitch() (2 input parameters)
Name: SetSoundPitch
Return type: void
Description: Set pitch for a sound (1.0 is base level)
Param[1]: sound (type: Sound)
Param[2]: pitch (type: float)
Function 567: SetSoundPan() (2 input parameters)
Function 569: SetSoundPan() (2 input parameters)
Name: SetSoundPan
Return type: void
Description: Set pan for a sound (-1.0 left, 0.0 center, 1.0 right)
Param[1]: sound (type: Sound)
Param[2]: pan (type: float)
Function 568: WaveCopy() (1 input parameters)
Function 570: WaveCopy() (1 input parameters)
Name: WaveCopy
Return type: Wave
Description: Copy a wave to a new wave
Param[1]: wave (type: Wave)
Function 569: WaveCrop() (3 input parameters)
Function 571: WaveCrop() (3 input parameters)
Name: WaveCrop
Return type: void
Description: Crop a wave to defined frames range
Param[1]: wave (type: Wave *)
Param[2]: initFrame (type: int)
Param[3]: finalFrame (type: int)
Function 570: WaveFormat() (4 input parameters)
Function 572: WaveFormat() (4 input parameters)
Name: WaveFormat
Return type: void
Description: Convert wave data to desired format
@ -4666,203 +4683,203 @@ Function 570: WaveFormat() (4 input parameters)
Param[2]: sampleRate (type: int)
Param[3]: sampleSize (type: int)
Param[4]: channels (type: int)
Function 571: LoadWaveSamples() (1 input parameters)
Function 573: LoadWaveSamples() (1 input parameters)
Name: LoadWaveSamples
Return type: float *
Description: Load samples data from wave as a 32bit float data array
Param[1]: wave (type: Wave)
Function 572: UnloadWaveSamples() (1 input parameters)
Function 574: UnloadWaveSamples() (1 input parameters)
Name: UnloadWaveSamples
Return type: void
Description: Unload samples data loaded with LoadWaveSamples()
Param[1]: samples (type: float *)
Function 573: LoadMusicStream() (1 input parameters)
Function 575: LoadMusicStream() (1 input parameters)
Name: LoadMusicStream
Return type: Music
Description: Load music stream from file
Param[1]: fileName (type: const char *)
Function 574: LoadMusicStreamFromMemory() (3 input parameters)
Function 576: LoadMusicStreamFromMemory() (3 input parameters)
Name: LoadMusicStreamFromMemory
Return type: Music
Description: Load music stream from data
Param[1]: fileType (type: const char *)
Param[2]: data (type: const unsigned char *)
Param[3]: dataSize (type: int)
Function 575: IsMusicValid() (1 input parameters)
Function 577: IsMusicValid() (1 input parameters)
Name: IsMusicValid
Return type: bool
Description: Check if music stream is valid (context and buffers initialized)
Param[1]: music (type: Music)
Function 576: UnloadMusicStream() (1 input parameters)
Function 578: UnloadMusicStream() (1 input parameters)
Name: UnloadMusicStream
Return type: void
Description: Unload music stream
Param[1]: music (type: Music)
Function 577: PlayMusicStream() (1 input parameters)
Function 579: PlayMusicStream() (1 input parameters)
Name: PlayMusicStream
Return type: void
Description: Start music playing
Param[1]: music (type: Music)
Function 578: IsMusicStreamPlaying() (1 input parameters)
Function 580: IsMusicStreamPlaying() (1 input parameters)
Name: IsMusicStreamPlaying
Return type: bool
Description: Check if music is playing
Param[1]: music (type: Music)
Function 579: UpdateMusicStream() (1 input parameters)
Function 581: UpdateMusicStream() (1 input parameters)
Name: UpdateMusicStream
Return type: void
Description: Update buffers for music streaming
Param[1]: music (type: Music)
Function 580: StopMusicStream() (1 input parameters)
Function 582: StopMusicStream() (1 input parameters)
Name: StopMusicStream
Return type: void
Description: Stop music playing
Param[1]: music (type: Music)
Function 581: PauseMusicStream() (1 input parameters)
Function 583: PauseMusicStream() (1 input parameters)
Name: PauseMusicStream
Return type: void
Description: Pause music playing
Param[1]: music (type: Music)
Function 582: ResumeMusicStream() (1 input parameters)
Function 584: ResumeMusicStream() (1 input parameters)
Name: ResumeMusicStream
Return type: void
Description: Resume playing paused music
Param[1]: music (type: Music)
Function 583: SeekMusicStream() (2 input parameters)
Function 585: SeekMusicStream() (2 input parameters)
Name: SeekMusicStream
Return type: void
Description: Seek music to a position (in seconds)
Param[1]: music (type: Music)
Param[2]: position (type: float)
Function 584: SetMusicVolume() (2 input parameters)
Function 586: SetMusicVolume() (2 input parameters)
Name: SetMusicVolume
Return type: void
Description: Set volume for music (1.0 is max level)
Param[1]: music (type: Music)
Param[2]: volume (type: float)
Function 585: SetMusicPitch() (2 input parameters)
Function 587: SetMusicPitch() (2 input parameters)
Name: SetMusicPitch
Return type: void
Description: Set pitch for music (1.0 is base level)
Param[1]: music (type: Music)
Param[2]: pitch (type: float)
Function 586: SetMusicPan() (2 input parameters)
Function 588: SetMusicPan() (2 input parameters)
Name: SetMusicPan
Return type: void
Description: Set pan for music (-1.0 left, 0.0 center, 1.0 right)
Param[1]: music (type: Music)
Param[2]: pan (type: float)
Function 587: GetMusicTimeLength() (1 input parameters)
Function 589: GetMusicTimeLength() (1 input parameters)
Name: GetMusicTimeLength
Return type: float
Description: Get music time length (in seconds)
Param[1]: music (type: Music)
Function 588: GetMusicTimePlayed() (1 input parameters)
Function 590: GetMusicTimePlayed() (1 input parameters)
Name: GetMusicTimePlayed
Return type: float
Description: Get current music time played (in seconds)
Param[1]: music (type: Music)
Function 589: LoadAudioStream() (3 input parameters)
Function 591: LoadAudioStream() (3 input parameters)
Name: LoadAudioStream
Return type: AudioStream
Description: Load audio stream (to stream raw audio pcm data)
Param[1]: sampleRate (type: unsigned int)
Param[2]: sampleSize (type: unsigned int)
Param[3]: channels (type: unsigned int)
Function 590: IsAudioStreamValid() (1 input parameters)
Function 592: IsAudioStreamValid() (1 input parameters)
Name: IsAudioStreamValid
Return type: bool
Description: Check if an audio stream is valid (buffers initialized)
Param[1]: stream (type: AudioStream)
Function 591: UnloadAudioStream() (1 input parameters)
Function 593: UnloadAudioStream() (1 input parameters)
Name: UnloadAudioStream
Return type: void
Description: Unload audio stream and free memory
Param[1]: stream (type: AudioStream)
Function 592: UpdateAudioStream() (3 input parameters)
Function 594: UpdateAudioStream() (3 input parameters)
Name: UpdateAudioStream
Return type: void
Description: Update audio stream buffers with data
Param[1]: stream (type: AudioStream)
Param[2]: data (type: const void *)
Param[3]: frameCount (type: int)
Function 593: IsAudioStreamProcessed() (1 input parameters)
Function 595: IsAudioStreamProcessed() (1 input parameters)
Name: IsAudioStreamProcessed
Return type: bool
Description: Check if any audio stream buffers requires refill
Param[1]: stream (type: AudioStream)
Function 594: PlayAudioStream() (1 input parameters)
Function 596: PlayAudioStream() (1 input parameters)
Name: PlayAudioStream
Return type: void
Description: Play audio stream
Param[1]: stream (type: AudioStream)
Function 595: PauseAudioStream() (1 input parameters)
Function 597: PauseAudioStream() (1 input parameters)
Name: PauseAudioStream
Return type: void
Description: Pause audio stream
Param[1]: stream (type: AudioStream)
Function 596: ResumeAudioStream() (1 input parameters)
Function 598: ResumeAudioStream() (1 input parameters)
Name: ResumeAudioStream
Return type: void
Description: Resume audio stream
Param[1]: stream (type: AudioStream)
Function 597: IsAudioStreamPlaying() (1 input parameters)
Function 599: IsAudioStreamPlaying() (1 input parameters)
Name: IsAudioStreamPlaying
Return type: bool
Description: Check if audio stream is playing
Param[1]: stream (type: AudioStream)
Function 598: StopAudioStream() (1 input parameters)
Function 600: StopAudioStream() (1 input parameters)
Name: StopAudioStream
Return type: void
Description: Stop audio stream
Param[1]: stream (type: AudioStream)
Function 599: SetAudioStreamVolume() (2 input parameters)
Function 601: SetAudioStreamVolume() (2 input parameters)
Name: SetAudioStreamVolume
Return type: void
Description: Set volume for audio stream (1.0 is max level)
Param[1]: stream (type: AudioStream)
Param[2]: volume (type: float)
Function 600: SetAudioStreamPitch() (2 input parameters)
Function 602: SetAudioStreamPitch() (2 input parameters)
Name: SetAudioStreamPitch
Return type: void
Description: Set pitch for audio stream (1.0 is base level)
Param[1]: stream (type: AudioStream)
Param[2]: pitch (type: float)
Function 601: SetAudioStreamPan() (2 input parameters)
Function 603: SetAudioStreamPan() (2 input parameters)
Name: SetAudioStreamPan
Return type: void
Description: Set pan for audio stream (-1.0 left, 0.0 center, 1.0 right)
Param[1]: stream (type: AudioStream)
Param[2]: pan (type: float)
Function 602: SetAudioStreamBufferSizeDefault() (1 input parameters)
Function 604: SetAudioStreamBufferSizeDefault() (1 input parameters)
Name: SetAudioStreamBufferSizeDefault
Return type: void
Description: Default size for new audio streams
Param[1]: size (type: int)
Function 603: SetAudioStreamCallback() (2 input parameters)
Function 605: SetAudioStreamCallback() (2 input parameters)
Name: SetAudioStreamCallback
Return type: void
Description: Audio thread callback to request new data
Param[1]: stream (type: AudioStream)
Param[2]: callback (type: AudioCallback)
Function 604: AttachAudioStreamProcessor() (2 input parameters)
Function 606: AttachAudioStreamProcessor() (2 input parameters)
Name: AttachAudioStreamProcessor
Return type: void
Description: Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo)
Param[1]: stream (type: AudioStream)
Param[2]: processor (type: AudioCallback)
Function 605: DetachAudioStreamProcessor() (2 input parameters)
Function 607: DetachAudioStreamProcessor() (2 input parameters)
Name: DetachAudioStreamProcessor
Return type: void
Description: Detach audio stream processor from stream
Param[1]: stream (type: AudioStream)
Param[2]: processor (type: AudioCallback)
Function 606: AttachAudioMixedProcessor() (1 input parameters)
Function 608: AttachAudioMixedProcessor() (1 input parameters)
Name: AttachAudioMixedProcessor
Return type: void
Description: Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo)
Param[1]: processor (type: AudioCallback)
Function 607: DetachAudioMixedProcessor() (1 input parameters)
Function 609: DetachAudioMixedProcessor() (1 input parameters)
Name: DetachAudioMixedProcessor
Return type: void
Description: Detach audio stream processor from the entire audio pipeline

View File

@ -681,7 +681,7 @@
<Param type="unsigned int" name="frames" desc="" />
</Callback>
</Callbacks>
<Functions count="607">
<Functions count="609">
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
<Param type="int" name="width" desc="" />
<Param type="int" name="height" desc="" />
@ -2983,6 +2983,19 @@
<Param type="float" name="frameB" desc="" />
<Param type="float" name="blend" desc="" />
</Function>
<Function name="UpdateModelAnimationBones" retType="void" paramCount="3" desc="Update model animation pose (bones only)">
<Param type="Model" name="model" desc="" />
<Param type="ModelAnimation" name="anim" desc="" />
<Param type="float" name="frame" desc="" />
</Function>
<Function name="UpdateModelAnimationBonesEx" retType="void" paramCount="6" desc="Update model animation bones to pose, blending two animations">
<Param type="Model" name="model" desc="" />
<Param type="ModelAnimation" name="animA" desc="" />
<Param type="float" name="frameA" desc="" />
<Param type="ModelAnimation" name="animB" desc="" />
<Param type="float" name="frameB" desc="" />
<Param type="float" name="blend" desc="" />
</Function>
<Function name="UnloadModelAnimations" retType="void" paramCount="2" desc="Unload animation array data">
<Param type="ModelAnimation *" name="animations" desc="" />
<Param type="int" name="animCount" desc="" />