Skip to content

Commit 179963a

Browse files
authored
Merge pull request #166 from anirul/codex/frame-cesiumman-skinned-example
Replace fox skinned sample with Cesium Man
2 parents df4cdc5 + 4746de2 commit 179963a

10 files changed

Lines changed: 152 additions & 94 deletions

File tree

asset/json/skinned_mesh.json

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@
7171
"parent": "root",
7272
"matrix_type_enum": "STATIC_MATRIX",
7373
"matrix": {
74-
"m11": 0.01,
75-
"m22": 0.01,
76-
"m33": 0.01,
74+
"m11": 1.0,
75+
"m22": 1.0,
76+
"m33": 1.0,
7777
"m44": 1
7878
}
7979
},
@@ -109,12 +109,12 @@
109109
"far_clip": 1000.0,
110110
"position": {
111111
"x": 0,
112-
"y": 0.2,
113-
"z": -2.4
112+
"y": 0.9,
113+
"z": -3.2
114114
},
115115
"target": {
116116
"x": 0,
117-
"y": 0.1,
117+
"y": 0.75,
118118
"z": 0
119119
},
120120
"up": {
@@ -137,13 +137,12 @@
137137
"mesh_enum": "QUAD"
138138
},
139139
{
140-
"name": "FoxMesh",
140+
"name": "CesiumManMesh",
141141
"parent": "mesh_holder",
142-
"file_name": "fox/Fox.glb",
142+
"file_name": "cesium_man/CesiumMan.glb",
143143
"acceleration_structure_enum": "BVH_ACCELERATION",
144144
"play_animation": true,
145145
"animation_speed": 1.0,
146-
"animation_clip_name": "Walk",
147146
"render_time_enum": "SCENE_RENDER_TIME"
148147
}
149148
],
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:659349b0a374b73d5362a61070039bc8601401bbdeacbece4f3680fb4bfd41b0
3+
size 490956

asset/model/cesium_man/README.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Cesium Man sample assets used by 03_SkinnedMesh.
2+
3+
Source:
4+
https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/CesiumMan
5+
6+
Local files:
7+
- CesiumMan.glb
8+
- README.upstream.md
9+
10+
Attribution and license:
11+
- Donated by Cesium for glTF testing
12+
- Creative Commons Attribution 4.0 International (CC-BY-4.0)
13+
- See README.upstream.md for the upstream notice
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Cesium Man
2+
## Screenshot
3+
4+
![screenshot](screenshot/screenshot.gif)
5+
6+
## License Information
7+
8+
Donated by Cesium for glTF testing. Please follow the [Cesium Trademark Terms and Conditions](https://github.com/AnalyticalGraphicsInc/cesium/wiki/CesiumTrademark.pdf).
9+
10+
This model is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/).

examples/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ reference for the acceleration-structure path across both backends.
1919

2020
## 03 Skinned Mesh
2121

22-
Loads `asset/json/skinned_mesh.json`, which imports `asset/model/fox/Fox.glb`
23-
as raytraced scene geometry in `SCENE_RENDER_TIME` and plays the `Walk`
24-
animation through the shared raytracing pipeline.
22+
Loads `asset/json/skinned_mesh.json`, which imports
23+
`asset/model/cesium_man/CesiumMan.glb` as raytraced scene geometry in
24+
`SCENE_RENDER_TIME` and plays the model's first embedded animation through the
25+
shared raytracing pipeline.

frame/opengl/file/load_mesh.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,12 +1974,16 @@ std::vector<std::pair<EntityId, EntityId>> LoadMeshesFromGltfFile(
19741974

19751975
const bool has_normals = mesh->HasNormals();
19761976
const bool has_texcoords = mesh->HasTextureCoords(0);
1977+
const bool is_skinned_mesh = mesh->HasBones();
19771978
Bounds3 generated_uv_bounds;
19781979
if (!has_texcoords)
19791980
{
19801981
for (unsigned int v = 0; v < mesh->mNumVertices; ++v)
19811982
{
1982-
generated_uv_bounds.Expand(mesh_transform * mesh->mVertices[v]);
1983+
generated_uv_bounds.Expand(
1984+
is_skinned_mesh
1985+
? mesh->mVertices[v]
1986+
: mesh_transform * mesh->mVertices[v]);
19831987
}
19841988
}
19851989
const aiVector3D generated_uv_center = generated_uv_bounds.valid
@@ -2004,7 +2008,8 @@ std::vector<std::pair<EntityId, EntityId>> LoadMeshesFromGltfFile(
20042008
const aiVector3D local_p = mesh->mVertices[v];
20052009
local_mesh_bounds.Expand(local_p);
20062010
local_model_bounds.Expand(local_p);
2007-
const aiVector3D p = mesh_transform * local_p;
2011+
const aiVector3D p =
2012+
is_skinned_mesh ? local_p : mesh_transform * local_p;
20082013
transformed_mesh_bounds.Expand(p);
20092014
transformed_model_bounds.Expand(p);
20102015
points.push_back(p.x);
@@ -2013,7 +2018,10 @@ std::vector<std::pair<EntityId, EntityId>> LoadMeshesFromGltfFile(
20132018

20142019
if (has_normals)
20152020
{
2016-
aiVector3D n = normal_transform * mesh->mNormals[v];
2021+
aiVector3D n =
2022+
is_skinned_mesh
2023+
? mesh->mNormals[v]
2024+
: normal_transform * mesh->mNormals[v];
20172025
n.Normalize();
20182026
normals.push_back(n.x);
20192027
normals.push_back(n.y);
@@ -2093,10 +2101,12 @@ std::vector<std::pair<EntityId, EntityId>> LoadMeshesFromGltfFile(
20932101
mesh->mNumBones,
20942102
supported_bones);
20952103
}
2104+
aiMatrix4x4 skin_global_inverse = aiMatrix4x4();
2105+
20962106
skin_animation_data = std::make_shared<SkinAnimationData>();
20972107
skin_animation_data->nodes = scene_nodes;
20982108
skin_animation_data->node_indices = scene_node_indices;
2099-
skin_animation_data->global_inverse_transform = scene_global_inverse;
2109+
skin_animation_data->global_inverse_transform = skin_global_inverse;
21002110
skin_animation_data->bones.resize(supported_bones);
21012111
skin_animation_data->clips = scene_animation_clips;
21022112
skin_animation_data->clip_name_to_index = scene_clip_name_to_index;

frame/vulkan/json/parse_scene_tree.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3172,6 +3172,7 @@ bool ParseNodeMesh(
31723172
textures.reserve(static_cast<std::size_t>(mesh->mNumVertices) * 2);
31733173
const bool has_normals = mesh->HasNormals();
31743174
const bool has_texcoords = mesh->HasTextureCoords(0);
3175+
const bool is_skinned_mesh = mesh->HasBones();
31753176
aiVector3D generated_uv_min(
31763177
std::numeric_limits<float>::max(),
31773178
std::numeric_limits<float>::max(),
@@ -3188,7 +3189,9 @@ bool ParseNodeMesh(
31883189
++vertex_index)
31893190
{
31903191
const aiVector3D p =
3191-
mesh_transform * mesh->mVertices[vertex_index];
3192+
is_skinned_mesh
3193+
? mesh->mVertices[vertex_index]
3194+
: mesh_transform * mesh->mVertices[vertex_index];
31923195
generated_uv_min.x = std::min(generated_uv_min.x, p.x);
31933196
generated_uv_min.y = std::min(generated_uv_min.y, p.y);
31943197
generated_uv_min.z = std::min(generated_uv_min.z, p.z);
@@ -3223,14 +3226,18 @@ bool ParseNodeMesh(
32233226
++vertex_index)
32243227
{
32253228
const aiVector3D p =
3226-
mesh_transform * mesh->mVertices[vertex_index];
3229+
is_skinned_mesh
3230+
? mesh->mVertices[vertex_index]
3231+
: mesh_transform * mesh->mVertices[vertex_index];
32273232
points.push_back(p.x);
32283233
points.push_back(p.y);
32293234
points.push_back(p.z);
32303235
if (has_normals)
32313236
{
32323237
aiVector3D n =
3233-
normal_transform * mesh->mNormals[vertex_index];
3238+
is_skinned_mesh
3239+
? mesh->mNormals[vertex_index]
3240+
: normal_transform * mesh->mNormals[vertex_index];
32343241
n.Normalize();
32353242
normals.push_back(n.x);
32363243
normals.push_back(n.y);
@@ -3306,11 +3313,13 @@ bool ParseNodeMesh(
33063313
constexpr std::size_t kMaxBones = 128;
33073314
const std::size_t supported_bones =
33083315
std::min<std::size_t>(mesh->mNumBones, kMaxBones);
3316+
aiMatrix4x4 skin_global_inverse = aiMatrix4x4();
3317+
33093318
skin_animation_data = std::make_shared<SkinAnimationData>();
33103319
skin_animation_data->nodes = scene_nodes;
33113320
skin_animation_data->node_indices = scene_node_indices;
33123321
skin_animation_data->global_inverse_transform =
3313-
scene_global_inverse;
3322+
skin_global_inverse;
33143323
skin_animation_data->bones.resize(supported_bones);
33153324
skin_animation_data->clips = scene_animation_clips;
33163325
skin_animation_data->clip_name_to_index =

tests/frame/opengl/raytracing_test.cpp

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,16 @@ namespace test
1919
namespace
2020
{
2121

22-
frame::proto::Level LoadLevelProtoWithFoxAnimationEnabled(bool enabled)
22+
constexpr const char* kSkinnedMeshNodeName = "CesiumManMesh";
23+
24+
frame::proto::Level LoadLevelProtoWithSkinnedMeshAnimationEnabled(bool enabled)
2325
{
2426
auto level_proto = frame::json::LoadLevelProto(
2527
frame::file::FindFile("asset/json/skinned_mesh.json"));
2628
auto* scene_tree = level_proto.mutable_scene_tree();
2729
for (auto& node_mesh : *scene_tree->mutable_node_meshes())
2830
{
29-
if (node_mesh.name() != "FoxMesh")
31+
if (node_mesh.name() != kSkinnedMeshNodeName)
3032
{
3133
continue;
3234
}
@@ -942,7 +944,7 @@ TEST_F(OpenGLRayTracingLevelTest, SkinnedMeshBindPoseDoesNotUpdateAggregateScene
942944
{
943945
auto level = frame::json::ParseLevel(
944946
{1280u, 720u},
945-
LoadLevelProtoWithFoxAnimationEnabled(false));
947+
LoadLevelProtoWithSkinnedMeshAnimationEnabled(false));
946948
ASSERT_NE(level, nullptr);
947949

948950
const auto material_id = level->GetIdFromName("RayTraceMaterial");
@@ -976,7 +978,7 @@ TEST_F(OpenGLRayTracingLevelTest, SkinnedMeshBindPoseDoesNotUpdateAggregateScene
976978
EXPECT_EQ(bvh_buffer->GetRawData(), bvh_before);
977979
}
978980

979-
TEST_F(OpenGLRayTracingLevelTest, SkinnedMeshSceneMaterialUsesImportedFoxTextures)
981+
TEST_F(OpenGLRayTracingLevelTest, SkinnedMeshSceneMaterialUsesImportedCharacterTextures)
980982
{
981983
auto level = LoadLevel("asset/json/skinned_mesh.json");
982984
ASSERT_NE(level, nullptr);
@@ -987,48 +989,50 @@ TEST_F(OpenGLRayTracingLevelTest, SkinnedMeshSceneMaterialUsesImportedFoxTexture
987989
"RayTracingRendering");
988990
ASSERT_NE(scene_material_id, frame::NullId);
989991
EXPECT_EQ(scene_material_id, level->GetIdFromName("RayTraceMaterial"));
990-
const auto fox_material_id = FindMaterialForNode(
992+
const auto mesh_material_id = FindMaterialForNode(
991993
*level,
992994
frame::proto::NodeMesh::SCENE_RENDER_TIME,
993-
"FoxMesh");
994-
ASSERT_NE(fox_material_id, frame::NullId);
995+
kSkinnedMeshNodeName);
996+
ASSERT_NE(mesh_material_id, frame::NullId);
995997

996998
const auto& scene_material = level->GetMaterialFromId(scene_material_id);
997-
const auto& fox_material = level->GetMaterialFromId(fox_material_id);
999+
const auto& mesh_material = level->GetMaterialFromId(mesh_material_id);
9981000

9991001
const auto scene_albedo_id = FindTextureByInnerName(
10001002
scene_material, "opaque_albedo_texture");
10011003
const auto scene_normal_id = FindTextureByInnerName(
10021004
scene_material, "opaque_normal_texture");
1003-
const auto fox_albedo_id = FindTextureByInnerName(
1004-
fox_material, "albedo_texture");
1005-
const auto fox_normal_id = FindTextureByInnerName(
1006-
fox_material, "normal_texture");
1005+
const auto mesh_albedo_id = FindTextureByInnerName(
1006+
mesh_material, "albedo_texture");
1007+
const auto mesh_normal_id = FindTextureByInnerName(
1008+
mesh_material, "normal_texture");
10071009

10081010
ASSERT_NE(scene_albedo_id, frame::NullId);
1009-
ASSERT_NE(scene_normal_id, frame::NullId);
1010-
ASSERT_NE(fox_albedo_id, frame::NullId);
1011-
ASSERT_NE(fox_normal_id, frame::NullId);
1012-
EXPECT_EQ(scene_albedo_id, fox_albedo_id);
1013-
EXPECT_EQ(scene_normal_id, fox_normal_id);
1014-
EXPECT_GT(level->GetTextureFromId(fox_albedo_id).GetSize().x, 1u);
1015-
EXPECT_GT(level->GetTextureFromId(fox_albedo_id).GetSize().y, 1u);
1011+
ASSERT_NE(mesh_albedo_id, frame::NullId);
1012+
EXPECT_EQ(scene_albedo_id, mesh_albedo_id);
1013+
EXPECT_GT(level->GetTextureFromId(mesh_albedo_id).GetSize().x, 1u);
1014+
EXPECT_GT(level->GetTextureFromId(mesh_albedo_id).GetSize().y, 1u);
1015+
if (mesh_normal_id != frame::NullId)
1016+
{
1017+
ASSERT_NE(scene_normal_id, frame::NullId);
1018+
EXPECT_EQ(scene_normal_id, mesh_normal_id);
1019+
}
10161020
}
10171021

1018-
TEST_F(OpenGLRayTracingLevelTest, SkinnedMeshFoxMaterialRemainsOpaque)
1022+
TEST_F(OpenGLRayTracingLevelTest, SkinnedMeshMaterialRemainsOpaque)
10191023
{
10201024
auto level = LoadLevel("asset/json/skinned_mesh.json");
10211025
ASSERT_NE(level, nullptr);
10221026

1023-
const auto fox_material_id = FindMaterialForNode(
1027+
const auto mesh_material_id = FindMaterialForNode(
10241028
*level,
10251029
frame::proto::NodeMesh::SCENE_RENDER_TIME,
1026-
"FoxMesh");
1027-
ASSERT_NE(fox_material_id, frame::NullId);
1030+
kSkinnedMeshNodeName);
1031+
ASSERT_NE(mesh_material_id, frame::NullId);
10281032

1029-
const auto& fox_material = level->GetMaterialFromId(fox_material_id);
1033+
const auto& mesh_material = level->GetMaterialFromId(mesh_material_id);
10301034
const auto transmission_texture_id = FindTextureByInnerName(
1031-
fox_material, "transmission_texture");
1035+
mesh_material, "transmission_texture");
10321036
ASSERT_NE(transmission_texture_id, frame::NullId);
10331037
EXPECT_LT(ReadTextureFirstChannel(*level, transmission_texture_id), 0.01f);
10341038
}
@@ -1149,7 +1153,7 @@ TEST_F(OpenGLRayTracingLevelTest, SkinnedMeshAggregateTrianglesHaveFiniteBounds)
11491153
EXPECT_GT(max_y - min_y, 0.05f);
11501154
EXPECT_GT(max_z - min_z, 0.05f);
11511155
EXPECT_LT(min_y, 0.2f);
1152-
EXPECT_GT(max_y, 0.2f);
1156+
EXPECT_GT(max_y, 0.15f);
11531157
}
11541158

11551159
TEST_F(OpenGLRayTracingLevelTest, SkinnedMeshCpuRayHitsAggregateTriangles)

tests/frame/opengl/skinned_mesh_test.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,21 @@
88
namespace test
99
{
1010

11-
TEST_F(SkinnedMeshTest, LoadFoxGlbCreatesSkinnedMeshWithAnimationData)
11+
namespace
12+
{
13+
constexpr const char* kSkinnedMeshAssetPath =
14+
"asset/model/cesium_man/CesiumMan.glb";
15+
constexpr const char* kSkinnedMeshNodeName = "CesiumManMesh";
16+
} // namespace
17+
18+
TEST_F(SkinnedMeshTest, LoadCesiumManGlbCreatesSkinnedMeshWithAnimationData)
1219
{
1320
ASSERT_TRUE(window_);
1421
auto level = std::make_unique<frame::Level>();
1522
auto mesh_vec = frame::opengl::file::LoadMeshesFromFile(
1623
*level,
17-
frame::file::FindFile("asset/model/fox/Fox.glb"),
18-
"FoxMesh");
24+
frame::file::FindFile(kSkinnedMeshAssetPath),
25+
kSkinnedMeshNodeName);
1926
ASSERT_FALSE(mesh_vec.empty());
2027

2128
frame::opengl::SkinnedMesh* skinned = nullptr;
@@ -40,10 +47,10 @@ TEST_F(SkinnedMeshTest, LoadFoxGlbCreatesSkinnedMeshWithAnimationData)
4047
EXPECT_FALSE(skinned->HasRaytraceBvhCallback());
4148

4249
skinned->SetSkinningAnimation(true, 1.5f);
43-
skinned->SetSkinningAnimationClip("Walk", 0);
50+
skinned->SetSkinningAnimationClip("", 0);
4451
EXPECT_TRUE(skinned->IsSkinningAnimationEnabled());
4552
EXPECT_FLOAT_EQ(1.5f, skinned->GetSkinningAnimationSpeed());
46-
EXPECT_EQ("Walk", skinned->GetSkinningAnimationClipName());
53+
EXPECT_EQ("", skinned->GetSkinningAnimationClipName());
4754
EXPECT_TRUE(skinned->GetSkinningAnimationClipIndex().has_value());
4855
EXPECT_DOUBLE_EQ(3.0, skinned->GetSkinningTime(2.0));
4956

@@ -54,14 +61,14 @@ TEST_F(SkinnedMeshTest, LoadFoxGlbCreatesSkinnedMeshWithAnimationData)
5461
EXPECT_FALSE(triangles.empty());
5562
}
5663

57-
TEST_F(SkinnedMeshTest, LoadFoxGlbWithBvhCreatesSkinnedBvhData)
64+
TEST_F(SkinnedMeshTest, LoadCesiumManGlbWithBvhCreatesSkinnedBvhData)
5865
{
5966
ASSERT_TRUE(window_);
6067
auto level = std::make_unique<frame::Level>();
6168
auto mesh_vec = frame::opengl::file::LoadMeshesFromFile(
6269
*level,
63-
frame::file::FindFile("asset/model/fox/Fox.glb"),
64-
"FoxMesh",
70+
frame::file::FindFile(kSkinnedMeshAssetPath),
71+
kSkinnedMeshNodeName,
6572
"",
6673
frame::proto::NodeMesh::BVH_ACCELERATION);
6774
ASSERT_FALSE(mesh_vec.empty());
@@ -90,4 +97,3 @@ TEST_F(SkinnedMeshTest, LoadFoxGlbWithBvhCreatesSkinnedBvhData)
9097
}
9198

9299
} // End namespace test.
93-

0 commit comments

Comments
 (0)