mirror of
https://github.com/minetest/minetest.git
synced 2024-07-04 15:05:27 +02:00
Bring over test sources (not compiled yet!)
This commit is contained in:
parent
72cecd1b6a
commit
cbc6b2b394
0
games/devtest/mods/gltf/models/invalid/empty.gltf
Normal file
0
games/devtest/mods/gltf/models/invalid/empty.gltf
Normal file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"scene" : 0,
|
||||
"scenes" : [
|
||||
{
|
||||
"nodes" : [ 0 ]
|
||||
}
|
||||
],
|
||||
|
||||
"nodes" : [
|
||||
{
|
||||
"mesh" : 0
|
||||
}
|
||||
],
|
||||
|
||||
"meshes" : [
|
||||
{
|
||||
"primitives" : [ {
|
||||
"attributes" : {
|
||||
"POSITION" : 0
|
||||
}
|
||||
} ]
|
||||
}
|
||||
],
|
||||
|
||||
"buffers" : [
|
||||
{
|
||||
"uri" : "data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAA",
|
||||
"byteLength" : 36
|
||||
}
|
||||
],
|
||||
"bufferViews" : [
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteOffset" : 1,
|
||||
"byteLength" : 36,
|
||||
"target" : 34962
|
||||
}
|
||||
],
|
||||
"accessors" : [
|
||||
{
|
||||
"bufferView" : 0,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 3,
|
||||
"type" : "VEC3",
|
||||
"max" : [ 1.0, 1.0, 0.0 ],
|
||||
"min" : [ 0.0, 0.0, 0.0 ]
|
||||
}
|
||||
],
|
||||
|
||||
"asset" : {
|
||||
"version" : "2.0"
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
{
|
131
games/devtest/mods/gltf/models/simple_skin.gltf
Normal file
131
games/devtest/mods/gltf/models/simple_skin.gltf
Normal file
@ -0,0 +1,131 @@
|
||||
{
|
||||
"scene" : 0,
|
||||
"scenes" : [ {
|
||||
"nodes" : [ 0, 1 ]
|
||||
} ],
|
||||
|
||||
"nodes" : [ {
|
||||
"skin" : 0,
|
||||
"mesh" : 0
|
||||
}, {
|
||||
"children" : [ 2 ]
|
||||
}, {
|
||||
"translation" : [ 0.0, 1.0, 0.0 ],
|
||||
"rotation" : [ 0.0, 0.0, 0.0, 1.0 ]
|
||||
} ],
|
||||
|
||||
"meshes" : [ {
|
||||
"primitives" : [ {
|
||||
"attributes" : {
|
||||
"POSITION" : 1,
|
||||
"JOINTS_0" : 2,
|
||||
"WEIGHTS_0" : 3
|
||||
},
|
||||
"indices" : 0
|
||||
} ]
|
||||
} ],
|
||||
|
||||
"skins" : [ {
|
||||
"inverseBindMatrices" : 4,
|
||||
"joints" : [ 1, 2 ]
|
||||
} ],
|
||||
|
||||
"animations" : [ {
|
||||
"channels" : [ {
|
||||
"sampler" : 0,
|
||||
"target" : {
|
||||
"node" : 2,
|
||||
"path" : "rotation"
|
||||
}
|
||||
} ],
|
||||
"samplers" : [ {
|
||||
"input" : 5,
|
||||
"interpolation" : "LINEAR",
|
||||
"output" : 6
|
||||
} ]
|
||||
} ],
|
||||
|
||||
"buffers" : [ {
|
||||
"uri" : "data:application/gltf-buffer;base64,AAABAAMAAAADAAIAAgADAAUAAgAFAAQABAAFAAcABAAHAAYABgAHAAkABgAJAAgAAAAAvwAAAAAAAAAAAAAAPwAAAAAAAAAAAAAAvwAAAD8AAAAAAAAAPwAAAD8AAAAAAAAAvwAAgD8AAAAAAAAAPwAAgD8AAAAAAAAAvwAAwD8AAAAAAAAAPwAAwD8AAAAAAAAAvwAAAEAAAAAAAAAAPwAAAEAAAAAA",
|
||||
"byteLength" : 168
|
||||
}, {
|
||||
"uri" : "data:application/gltf-buffer;base64,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAAAAQD8AAIA+AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAgD4AAEA/AAAAAAAAAAAAAIA+AABAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAA=",
|
||||
"byteLength" : 320
|
||||
}, {
|
||||
"uri" : "data:application/gltf-buffer;base64,AACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAgD8=",
|
||||
"byteLength" : 128
|
||||
}, {
|
||||
"uri" : "data:application/gltf-buffer;base64,AAAAAAAAAD8AAIA/AADAPwAAAEAAACBAAABAQAAAYEAAAIBAAACQQAAAoEAAALBAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAkxjEPkSLbD8AAAAAAAAAAPT9ND/0/TQ/AAAAAAAAAAD0/TQ/9P00PwAAAAAAAAAAkxjEPkSLbD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAkxjEvkSLbD8AAAAAAAAAAPT9NL/0/TQ/AAAAAAAAAAD0/TS/9P00PwAAAAAAAAAAkxjEvkSLbD8AAAAAAAAAAAAAAAAAAIA/",
|
||||
"byteLength" : 240
|
||||
} ],
|
||||
|
||||
"bufferViews" : [ {
|
||||
"buffer" : 0,
|
||||
"byteLength" : 48,
|
||||
"target" : 34963
|
||||
}, {
|
||||
"buffer" : 0,
|
||||
"byteOffset" : 48,
|
||||
"byteLength" : 120,
|
||||
"target" : 34962
|
||||
}, {
|
||||
"buffer" : 1,
|
||||
"byteLength" : 320,
|
||||
"byteStride" : 16
|
||||
}, {
|
||||
"buffer" : 2,
|
||||
"byteLength" : 128
|
||||
}, {
|
||||
"buffer" : 3,
|
||||
"byteLength" : 240
|
||||
} ],
|
||||
|
||||
"accessors" : [ {
|
||||
"bufferView" : 0,
|
||||
"componentType" : 5123,
|
||||
"count" : 24,
|
||||
"type" : "SCALAR"
|
||||
}, {
|
||||
"bufferView" : 1,
|
||||
"componentType" : 5126,
|
||||
"count" : 10,
|
||||
"type" : "VEC3",
|
||||
"max" : [ 0.5, 2.0, 0.0 ],
|
||||
"min" : [ -0.5, 0.0, 0.0 ]
|
||||
}, {
|
||||
"bufferView" : 2,
|
||||
"componentType" : 5123,
|
||||
"count" : 10,
|
||||
"type" : "VEC4"
|
||||
}, {
|
||||
"bufferView" : 2,
|
||||
"byteOffset" : 160,
|
||||
"componentType" : 5126,
|
||||
"count" : 10,
|
||||
"type" : "VEC4"
|
||||
}, {
|
||||
"bufferView" : 3,
|
||||
"componentType" : 5126,
|
||||
"count" : 2,
|
||||
"type" : "MAT4"
|
||||
}, {
|
||||
"bufferView" : 4,
|
||||
"componentType" : 5126,
|
||||
"count" : 12,
|
||||
"type" : "SCALAR",
|
||||
"max" : [ 5.5 ],
|
||||
"min" : [ 0.0 ]
|
||||
}, {
|
||||
"bufferView" : 4,
|
||||
"byteOffset" : 48,
|
||||
"componentType" : 5126,
|
||||
"count" : 12,
|
||||
"type" : "VEC4",
|
||||
"max" : [ 0.0, 0.0, 0.707, 1.0 ],
|
||||
"min" : [ 0.0, 0.0, -0.707, 0.707 ]
|
||||
} ],
|
||||
|
||||
"asset" : {
|
||||
"version" : "2.0"
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#include "CSceneManager.h"
|
||||
#include "CSkinnedMesh.h"
|
||||
#include "content/subgames.h"
|
||||
#include "filesys.h"
|
||||
|
||||
@ -365,4 +366,89 @@ SECTION("simple sparse accessor")
|
||||
CHECK(vertices[i].Pos == expectedPositions[i]);
|
||||
}
|
||||
|
||||
// https://github.com/KhronosGroup/glTF-Sample-Models/tree/main/2.0/SimpleSkin
|
||||
SECTION("simple skin")
|
||||
{
|
||||
using CSkinnedMesh = irr::scene::CSkinnedMesh;
|
||||
const auto mesh = loadMesh(model_path + "simple_skin.gltf");
|
||||
REQUIRE(mesh != nullptr);
|
||||
auto csm = dynamic_cast<const CSkinnedMesh*>(mesh);
|
||||
const auto joints = csm->getAllJoints();
|
||||
REQUIRE(joints.size() == 3);
|
||||
|
||||
const auto findJoint = [&](const std::function<bool(CSkinnedMesh::SJoint*)> &predicate) {
|
||||
for (std::size_t i = 0; i < joints.size(); ++i) {
|
||||
if (predicate(joints[i])) {
|
||||
return joints[i];
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("joint not found");
|
||||
};
|
||||
|
||||
// Check the node hierarchy
|
||||
const auto parent = findJoint([](auto joint) {
|
||||
return !joint->Children.empty();
|
||||
});
|
||||
REQUIRE(parent->Children.size() == 1);
|
||||
const auto child = parent->Children[0];
|
||||
REQUIRE(child != parent);
|
||||
|
||||
SECTION("transformations are correct")
|
||||
{
|
||||
CHECK(parent->Animatedposition == v3f(0, 0, 0));
|
||||
CHECK(parent->Animatedrotation == irr::core::quaternion());
|
||||
CHECK(parent->Animatedscale == v3f(1, 1, 1));
|
||||
CHECK(parent->GlobalInversedMatrix == irr::core::matrix4());
|
||||
const v3f childTranslation(0, 1, 0);
|
||||
CHECK(child->Animatedposition == childTranslation);
|
||||
CHECK(child->Animatedrotation == irr::core::quaternion());
|
||||
CHECK(child->Animatedscale == v3f(1, 1, 1));
|
||||
irr::core::matrix4 inverseBindMatrix;
|
||||
inverseBindMatrix.setInverseTranslation(childTranslation);
|
||||
CHECK(child->GlobalInversedMatrix == inverseBindMatrix);
|
||||
}
|
||||
|
||||
SECTION("weights are correct")
|
||||
{
|
||||
const auto weights = [&](const CSkinnedMesh::SJoint* joint) {
|
||||
std::unordered_map<irr::u32, irr::f32> weights;
|
||||
for (std::size_t i = 0; i < joint->Weights.size(); ++i) {
|
||||
const auto weight = joint->Weights[i];
|
||||
REQUIRE(weight.buffer_id == 0);
|
||||
weights[weight.vertex_id] = weight.strength;
|
||||
}
|
||||
return weights;
|
||||
};
|
||||
const auto parentWeights = weights(parent);
|
||||
const auto childWeights = weights(child);
|
||||
|
||||
const auto checkWeights = [&](irr::u32 index, irr::f32 parentWeight, irr::f32 childWeight) {
|
||||
const auto getWeight = [](auto weights, auto index) {
|
||||
const auto it = weights.find(index);
|
||||
return it == weights.end() ? 0.0f : it->second;
|
||||
};
|
||||
CHECK(getWeight(parentWeights, index) == parentWeight);
|
||||
CHECK(getWeight(childWeights, index) == childWeight);
|
||||
};
|
||||
checkWeights(0, 1.00, 0.00);
|
||||
checkWeights(1, 1.00, 0.00);
|
||||
checkWeights(2, 0.75, 0.25);
|
||||
checkWeights(3, 0.75, 0.25);
|
||||
checkWeights(4, 0.50, 0.50);
|
||||
checkWeights(5, 0.50, 0.50);
|
||||
checkWeights(6, 0.25, 0.75);
|
||||
checkWeights(7, 0.25, 0.75);
|
||||
checkWeights(8, 0.00, 1.00);
|
||||
checkWeights(9, 0.00, 1.00);
|
||||
}
|
||||
|
||||
SECTION("there should be a third node not involved in skinning")
|
||||
{
|
||||
const auto other = findJoint([&](auto joint) {
|
||||
return joint != child && joint != parent;
|
||||
});
|
||||
CHECK(other->Weights.empty());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user