Procházet zdrojové kódy

Gltf model and animations exploring problems (#1635)

* Added bone binding to whole mesh and not only set vertices.
+ Also added missed setting of the animation count.
+ Removed double ; on one line

* Added more of the gltf sample models

https://github.com/KhronosGroup/glTF-Sample-Models
We need to make it working for all of them.

* Binding to initial bind pose added.

* Fix cube disappearing bug because lerpPercent could be Inf.

* Fixed for rigged figure also
pull/1648/head
Hristo Stamenov před 4 roky
odevzdal GitHub
rodič
revize
5c2983f510
V databázi nebyl nalezen žádný známý klíč pro tento podpis ID GPG klíče: 4AEE18F83AFDEB23
6 změnil soubory, kde provedl 202 přidání a 7 odebrání
  1. binární
      examples/models/resources/gltf/AnimatedMorphCube.glb
  2. +118
    -0
      examples/models/resources/gltf/AnimatedTriangle.gltf
  3. binární
      examples/models/resources/gltf/BoxAnimated.glb
  4. binární
      examples/models/resources/gltf/GearboxAssy.glb
  5. +11
    -2
      examples/models/resources/gltf/LICENSE
  6. +73
    -5
      src/models.c

binární
examples/models/resources/gltf/AnimatedMorphCube.glb Zobrazit soubor


+ 118
- 0
examples/models/resources/gltf/AnimatedTriangle.gltf Zobrazit soubor

@ -0,0 +1,118 @@
{
"scene" : 0,
"scenes" : [
{
"nodes" : [ 0 ]
}
],
"nodes" : [
{
"mesh" : 0,
"rotation" : [ 0.0, 0.0, 0.0, 1.0 ]
}
],
"meshes" : [
{
"primitives" : [ {
"attributes" : {
"POSITION" : 1
},
"indices" : 0
} ]
}
],
"animations": [
{
"samplers" : [
{
"input" : 2,
"interpolation" : "LINEAR",
"output" : 3
}
],
"channels" : [ {
"sampler" : 0,
"target" : {
"node" : 0,
"path" : "rotation"
}
} ]
}
],
"buffers" : [
{
"uri" : "data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=",
"byteLength" : 44
},
{
"uri" : "data:application/octet-stream;base64,AAAAAAAAgD4AAAA/AABAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAD0/TQ/9P00PwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAPT9ND/0/TS/AAAAAAAAAAAAAAAAAACAPw==",
"byteLength" : 100
}
],
"bufferViews" : [
{
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 6,
"target" : 34963
},
{
"buffer" : 0,
"byteOffset" : 8,
"byteLength" : 36,
"target" : 34962
},
{
"buffer" : 1,
"byteOffset" : 0,
"byteLength" : 100
}
],
"accessors" : [
{
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5123,
"count" : 3,
"type" : "SCALAR",
"max" : [ 2 ],
"min" : [ 0 ]
},
{
"bufferView" : 1,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 3,
"type" : "VEC3",
"max" : [ 1.0, 1.0, 0.0 ],
"min" : [ 0.0, 0.0, 0.0 ]
},
{
"bufferView" : 2,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 5,
"type" : "SCALAR",
"max" : [ 1.0 ],
"min" : [ 0.0 ]
},
{
"bufferView" : 2,
"byteOffset" : 20,
"componentType" : 5126,
"count" : 5,
"type" : "VEC4",
"max" : [ 0.0, 0.0, 1.0, 1.0 ],
"min" : [ 0.0, 0.0, 0.0, -0.707 ]
}
],
"asset" : {
"version" : "2.0"
}
}

binární
examples/models/resources/gltf/BoxAnimated.glb Zobrazit soubor


binární
examples/models/resources/gltf/GearboxAssy.glb Zobrazit soubor


+ 11
- 2
examples/models/resources/gltf/LICENSE Zobrazit soubor

@ -1,11 +1,20 @@
Rigged Figure model has been created by Cesium (https://cesium.com/cesiumjs/),
and licensed as Creative Commons Attribution 4.0 International License.
Check for details: http://creativecommons.org/licenses/by/4.0/
Box Animated model has been created by Cesium (https://cesium.com/cesiumjs/)
and is licensed as Creative Commons Attribution 4.0 International License
Avocado model is provided by Microsoft
and licensed as CC0 Universal Public Domain
Check for details: https://creativecommons.org/publicdomain/zero/1.0/
Animated Morph Cube model is provided by Microsoft
and licensed as CC0 Universal Public Domain
Animated Triangle model is licensed as CC0 Universal Public Domain
Gearbox Assy model has been provided by Okino Computer Graphics, using Okino Polytrans Software.
no license information was provided
Check for details on CC0: https://creativecommons.org/publicdomain/zero/1.0/
Check for details on CC4: http://creativecommons.org/licenses/by/4.0/
GLTF sample models for testing are taken from: https://github.com/KhronosGroup/glTF-Sample-Models/

+ 73
- 5
src/models.c Zobrazit soubor

@ -754,7 +754,7 @@ Model LoadModel(const char *fileName)
if (model.meshMaterial == NULL) model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int));
}
return model;
}
@ -3979,10 +3979,75 @@ static Model LoadGLTF(const char *fileName)
}
else
{
model.meshMaterial[primitiveIndex] = model.materialCount - 1;;
model.meshMaterial[primitiveIndex] = model.materialCount - 1;
}
// if (data->meshes[i].)
if (model.meshes[primitiveIndex].boneIds == NULL && data->nodes_count > 0)
{
for (int nodeId = 0; nodeId < data->nodes_count; nodeId++)
{
if (data->nodes[nodeId].mesh == &(data->meshes[i]))
{
model.meshes[primitiveIndex].boneIds = RL_CALLOC(4 * model.meshes[primitiveIndex].vertexCount, sizeof(int));
model.meshes[primitiveIndex].boneWeights = RL_CALLOC(4 * model.meshes[primitiveIndex].vertexCount, sizeof(float));
for (int b = 0; b < 4 * model.meshes[primitiveIndex].vertexCount; b++)
{
if(b % 4 == 0)
{
model.meshes[primitiveIndex].boneIds[b] = nodeId;
model.meshes[primitiveIndex].boneWeights[b] = 1.0f;
}
else
{
model.meshes[primitiveIndex].boneIds[b] = 0;
model.meshes[primitiveIndex].boneWeights[b] = 0.0f;
}
}
Vector3 boundVertex = { 0 };
Vector3 boundNormal = { 0 };
Vector3 outTranslation = { 0 };
Quaternion outRotation = { 0 };
Vector3 outScale = { 0 };
int vCounter = 0;
int boneCounter = 0;
int boneId = 0;
for (int i = 0; i < model.meshes[primitiveIndex].vertexCount; i++)
{
boneId = model.meshes[primitiveIndex].boneIds[boneCounter];
outTranslation = model.bindPose[boneId].translation;
outRotation = model.bindPose[boneId].rotation;
outScale = model.bindPose[boneId].scale;
// Vertices processing
boundVertex = (Vector3){ model.meshes[primitiveIndex].vertices[vCounter], model.meshes[primitiveIndex].vertices[vCounter + 1], model.meshes[primitiveIndex].vertices[vCounter + 2] };
boundVertex = Vector3Multiply(boundVertex, outScale);
boundVertex = Vector3RotateByQuaternion(boundVertex, outRotation);
boundVertex = Vector3Add(boundVertex, outTranslation);
model.meshes[primitiveIndex].vertices[vCounter] = boundVertex.x;
model.meshes[primitiveIndex].vertices[vCounter + 1] = boundVertex.y;
model.meshes[primitiveIndex].vertices[vCounter + 2] = boundVertex.z;
// Normals processing
boundNormal = (Vector3){ model.meshes[primitiveIndex].normals[vCounter], model.meshes[primitiveIndex].normals[vCounter + 1], model.meshes[primitiveIndex].normals[vCounter + 2] };
boundNormal = Vector3RotateByQuaternion(boundNormal, outRotation);
model.meshes[primitiveIndex].normals[vCounter] = boundNormal.x;
model.meshes[primitiveIndex].normals[vCounter + 1] = boundNormal.y;
model.meshes[primitiveIndex].normals[vCounter + 2] = boundNormal.z;
vCounter += 3;
boneCounter += 4;
}
}
}
}
primitiveIndex++;
}
@ -4053,9 +4118,9 @@ static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCo
result = cgltf_load_buffers(&options, data, fileName);
if (result != cgltf_result_success) TRACELOG(LOG_WARNING, "MODEL: [%s] unable to load glTF animations data", fileName);
animations = RL_MALLOC(data->animations_count*sizeof(ModelAnimation));
*animCount = data->animations_count;
for (unsigned int a = 0; a < data->animations_count; a++)
{
// gltf animation consists of the following structures:
@ -4150,7 +4215,10 @@ static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCo
float previousInputTime = 0.0f;
if (GltfReadFloat(sampler->input, outputMin, (float *)&previousInputTime, 1))
{
lerpPercent = (frameTime - previousInputTime)/(inputFrameTime - previousInputTime);
if((inputFrameTime - previousInputTime) != 0)
{
lerpPercent = (frameTime - previousInputTime)/(inputFrameTime - previousInputTime);
}
}
break;

Načítá se…
Zrušit
Uložit