|
|
@ -96,9 +96,9 @@ |
|
|
|
#endif |
|
|
|
|
|
|
|
#if defined(SUPPORT_MESH_GENERATION) |
|
|
|
#define PAR_MALLOC(T, N) ((T*)RL_MALLOC(N*sizeof(T))) |
|
|
|
#define PAR_CALLOC(T, N) ((T*)RL_CALLOC(N*sizeof(T), 1)) |
|
|
|
#define PAR_REALLOC(T, BUF, N) ((T*)RL_REALLOC(BUF, sizeof(T)*(N))) |
|
|
|
#define PAR_MALLOC(T, N) ((T *)RL_MALLOC(N*sizeof(T))) |
|
|
|
#define PAR_CALLOC(T, N) ((T *)RL_CALLOC(N*sizeof(T), 1)) |
|
|
|
#define PAR_REALLOC(T, BUF, N) ((T *)RL_REALLOC(BUF, sizeof(T)*(N))) |
|
|
|
#define PAR_FREE RL_FREE |
|
|
|
|
|
|
|
#if defined(_MSC_VER) // Disable some MSVC warning |
|
|
@ -2308,7 +2308,7 @@ void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// at least 2x speed up vs the old method |
|
|
|
// at least 2x speed up vs the old method |
|
|
|
// Update model animated vertex data (positions and normals) for a given frame |
|
|
|
// NOTE: Updated data is uploaded to GPU |
|
|
|
void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) |
|
|
@ -2340,14 +2340,16 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) |
|
|
|
{ |
|
|
|
boneWeight = mesh.boneWeights[boneCounter]; |
|
|
|
boneId = mesh.boneIds[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 = Vector3Transform(animVertex,model.meshes[m].boneMatrices[boneId]); |
|
|
|
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; |
|
|
|
updated = true; |
|
|
|
|
|
|
|
// Normals processing |
|
|
|
// NOTE: We use meshes.baseNormals (default normal) to calculate meshes.normals (animated normals) |
|
|
|
if (mesh.normals != NULL) |
|
|
@ -2360,6 +2362,7 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (updated) |
|
|
|
{ |
|
|
|
rlUpdateVertexBuffer(mesh.vboId[0], mesh.animVertices, mesh.vertexCount*3*sizeof(float), 0); // Update vertex position |
|
|
@ -2725,11 +2728,11 @@ Mesh GenMeshCube(float width, float height, float length) |
|
|
|
#else // Use par_shapes library to generate cube mesh |
|
|
|
/* |
|
|
|
// Platonic solids: |
|
|
|
par_shapes_mesh* par_shapes_create_tetrahedron(); // 4 sides polyhedron (pyramid) |
|
|
|
par_shapes_mesh* par_shapes_create_cube(); // 6 sides polyhedron (cube) |
|
|
|
par_shapes_mesh* par_shapes_create_octahedron(); // 8 sides polyhedron (diamond) |
|
|
|
par_shapes_mesh* par_shapes_create_dodecahedron(); // 12 sides polyhedron |
|
|
|
par_shapes_mesh* par_shapes_create_icosahedron(); // 20 sides polyhedron |
|
|
|
par_shapes_mesh *par_shapes_create_tetrahedron(); // 4 sides polyhedron (pyramid) |
|
|
|
par_shapes_mesh *par_shapes_create_cube(); // 6 sides polyhedron (cube) |
|
|
|
par_shapes_mesh *par_shapes_create_octahedron(); // 8 sides polyhedron (diamond) |
|
|
|
par_shapes_mesh *par_shapes_create_dodecahedron(); // 12 sides polyhedron |
|
|
|
par_shapes_mesh *par_shapes_create_icosahedron(); // 20 sides polyhedron |
|
|
|
*/ |
|
|
|
// Platonic solid generation: cube (6 sides) |
|
|
|
// NOTE: No normals/texcoords generated by default |
|
|
@ -3840,7 +3843,7 @@ void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector |
|
|
|
for (int i = 0; i < 4; i++) |
|
|
|
{ |
|
|
|
points[i] = Vector3Subtract(points[i], origin3D); |
|
|
|
if (rotation != 0.0) points[i] = Vector3RotateByAxisAngle(points[i], forward, rotation * DEG2RAD); |
|
|
|
if (rotation != 0.0) points[i] = Vector3RotateByAxisAngle(points[i], forward, rotation*DEG2RAD); |
|
|
|
points[i] = Vector3Add(points[i], position); |
|
|
|
} |
|
|
|
|
|
|
@ -4049,7 +4052,7 @@ RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform) |
|
|
|
for (int i = 0; i < triangleCount; i++) |
|
|
|
{ |
|
|
|
Vector3 a, b, c; |
|
|
|
Vector3* vertdata = (Vector3*)mesh.vertices; |
|
|
|
Vector3 *vertdata = (Vector3 *)mesh.vertices; |
|
|
|
|
|
|
|
if (mesh.indices) |
|
|
|
{ |
|
|
@ -4213,7 +4216,7 @@ static Model LoadOBJ(const char *fileName) |
|
|
|
if (CHDIR(workingDir) != 0) TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", workingDir); |
|
|
|
|
|
|
|
unsigned int dataSize = (unsigned int)strlen(fileText); |
|
|
|
|
|
|
|
|
|
|
|
unsigned int flags = TINYOBJ_FLAG_TRIANGULATE; |
|
|
|
int ret = tinyobj_parse_obj(&objAttributes, &objShapes, &objShapeCount, &objMaterials, &objMaterialCount, fileText, dataSize, flags); |
|
|
|
|
|
|
@ -4316,7 +4319,7 @@ static Model LoadOBJ(const char *fileName) |
|
|
|
faceVertIndex += objAttributes.face_num_verts[faceId]; |
|
|
|
localMeshVertexCount += objAttributes.face_num_verts[faceId]; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
localMeshVertexCounts[meshIndex] = localMeshVertexCount; |
|
|
|
|
|
|
|
for (int i = 0; i < model.meshCount; i++) |
|
|
@ -4325,7 +4328,7 @@ static Model LoadOBJ(const char *fileName) |
|
|
|
unsigned int vertexCount = localMeshVertexCounts[i]; |
|
|
|
|
|
|
|
model.meshes[i].vertexCount = vertexCount; |
|
|
|
model.meshes[i].triangleCount = vertexCount / 3; |
|
|
|
model.meshes[i].triangleCount = vertexCount/3; |
|
|
|
|
|
|
|
model.meshes[i].vertices = (float *)MemAlloc(sizeof(float)*vertexCount*3); |
|
|
|
model.meshes[i].normals = (float *)MemAlloc(sizeof(float)*vertexCount*3); |
|
|
@ -4360,7 +4363,7 @@ static Model LoadOBJ(const char *fileName) |
|
|
|
else nextShapeEnd = objAttributes.num_face_num_verts; // This is actually the total number of face verts in the file, not faces |
|
|
|
newMesh = true; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// If this is a new material, we need to allocate a new mesh |
|
|
|
if (lastMaterial != -1 && objAttributes.material_ids[faceId] != lastMaterial) newMesh = true; |
|
|
|
lastMaterial = objAttributes.material_ids[faceId]; |
|
|
@ -5672,7 +5675,7 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
else if (attribute->component_type == cgltf_component_type_r_8u) |
|
|
|
{ |
|
|
|
// Init raylib mesh indices to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].indices = RL_MALLOC(attribute->count * sizeof(unsigned short)); |
|
|
|
model.meshes[meshIndex].indices = RL_MALLOC(attribute->count*sizeof(unsigned short)); |
|
|
|
LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned char, model.meshes[meshIndex].indices, unsigned short) |
|
|
|
|
|
|
|
} |
|
|
@ -5727,7 +5730,7 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
|
|
|
|
for (int i = 0; i < model.boneCount; i++) |
|
|
|
{ |
|
|
|
cgltf_node* node = skin.joints[i]; |
|
|
|
cgltf_node *node = skin.joints[i]; |
|
|
|
cgltf_float worldTransform[16]; |
|
|
|
cgltf_node_transform_world(node, worldTransform); |
|
|
|
Matrix worldMatrix = { |
|
|
|