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
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
#include "CSceneManager.h"
|
#include "CSceneManager.h"
|
||||||
|
#include "CSkinnedMesh.h"
|
||||||
#include "content/subgames.h"
|
#include "content/subgames.h"
|
||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
|
|
||||||
@ -365,4 +366,89 @@ SECTION("simple sparse accessor")
|
|||||||
CHECK(vertices[i].Pos == expectedPositions[i]);
|
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