Skip to content

Commit e67ea46

Browse files
authored
Merge pull request #325 from chaoticgd/gltf_fixes
Fix a bunch of issues relating to materials
2 parents ce40ca4 + 901e48a commit e67ea46

15 files changed

Lines changed: 225 additions & 84 deletions

docs/asset_reference.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Asset Reference
22

3-
This file was generated from asset_schema.wtf and is for version 29 of the asset format.
3+
This file was generated from asset_schema.wtf and is for version 30 of the asset format.
44

55
## Index
66

@@ -1111,14 +1111,13 @@ No children.
11111111
| - | - | - | - | - |
11121112
| name | The name of the material being referenced. | String | Yes | RAC/GC/UYA/DL |
11131113
| wrap_mode | The UV wrapping mode, stored as an array of two strings. Possible values are ["repeat" "repeat"] (the default), ["repeat" "clamp"], ["clamp" "repeat"] and ["clamp" "clamp"]. | Array | No | RAC/GC/UYA/DL |
1114-
| glass | Only for mobies. Make the material shiny, like glass? | Boolean | *Not yet documented.* | *Not yet documented.* |
1115-
| chrome | Only for mobies. Make the material shiny, like chrome? | Boolean | *Not yet documented.* | *Not yet documented.* |
1114+
| effect_mode | List of effect modifiers, only relevant for mobies. Possible values are [], ["none"], ["chrome"] and ["glass"]. | Array | No | RAC/GC/UYA/DL |
11161115

11171116
*Children*
11181117

11191118
| Name | Description | Allowed Types | Required | Games |
11201119
| - | - | - | - | - |
1121-
| diffuse | The diffuse map (main texture). | Texture | Yes | RAC/GC/UYA/DL |
1120+
| diffuse | The diffuse map (main texture). | Texture | No | RAC/GC/UYA/DL |
11221121

11231122

11241123
### Collision

docs/asset_system.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ Each asset type is defined in `asset_schema.wtf` and a code generator, `asset_co
144144

145145
| Format Version | Wrench Version | Description |
146146
| - | - | - |
147+
| 30 | | Added effect_mode attribute to Material assets, removed chrome and glass attributes, and made diffuse children optional. |
147148
| 29 | | Added hero_groups attributes to Collision assets. |
148149
| 28 | | Use glTF (.glb) for the moby models instead of COLLADA. |
149150
| 27 | v0.5 | Use glTF (.glb) for the shrub and sky models instead of COLLADA. The mesh attribute of the SkyShell asset is now of type Mesh instead of Collection. The starting_rotation and angular_velocity attributes now only will only apply for UYA and DL (which is more correct). |

docs/instance_reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Instance Reference
22

3-
This file was generated from instance_schema.wtf and is for version 29 of the instance format.
3+
This file was generated from instance_schema.wtf and is for version 30 of the instance format.
44

55
## Instances
66

src/assetmgr/asset_schema.wtf

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
1818

19-
format_version: 29
19+
format_version: 30
2020

2121
// *****************************************************************************
2222

@@ -1714,19 +1714,18 @@ AssetType Material {
17141714
games: [1 2 3 4]
17151715
StringAttribute element {}
17161716
}
1717-
1718-
BooleanAttribute glass {
1719-
desc: "Only for mobies. Make the material shiny, like glass?"
1720-
}
1721-
1722-
BooleanAttribute chrome {
1723-
desc: "Only for mobies. Make the material shiny, like chrome?"
1717+
1718+
ArrayAttribute effect_mode {
1719+
desc: "List of effect modifiers, only relevant for mobies. Possible values are [], [\"none\"], [\"chrome\"] and [\"glass\"]."
1720+
required: false
1721+
games: [1 2 3 4]
1722+
StringAttribute element {}
17241723
}
17251724

17261725
Child diffuse {
17271726
desc: "The diffuse map (main texture)."
17281727
allowed_types: ["Texture"]
1729-
required: true
1728+
required: false
17301729
games: [1 2 3 4]
17311730
}
17321731
}

src/assetmgr/material_asset.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,21 @@ MaterialSet read_material_assets(const CollectionAsset& src)
2727
src.for_each_logical_child_of_type<MaterialAsset>([&](const MaterialAsset& asset) {
2828
Material& material = materials.emplace_back();
2929
material.name = asset.name();
30-
const TextureAsset& diffuse = asset.get_diffuse();
31-
std::string diffuse_path = asset.get_diffuse().src().path.string();
32-
auto key = std::make_pair(&diffuse.file(), diffuse_path);
33-
auto iter = texture_indices.find(key);
34-
if (iter == texture_indices.end()) {
35-
texture_indices[key] = next_texture_index;
36-
material.surface = MaterialSurface(next_texture_index);
37-
next_texture_index++;
38-
textures.emplace_back(diffuse.file(), asset.get_diffuse().src().path);
30+
if (asset.has_diffuse()) {
31+
const TextureAsset& diffuse = asset.get_diffuse();
32+
std::string diffuse_path = asset.get_diffuse().src().path.string();
33+
auto key = std::make_pair(&diffuse.file(), diffuse_path);
34+
auto iter = texture_indices.find(key);
35+
if (iter == texture_indices.end()) {
36+
texture_indices[key] = next_texture_index;
37+
material.surface = MaterialSurface(next_texture_index);
38+
next_texture_index++;
39+
textures.emplace_back(diffuse.file(), asset.get_diffuse().src().path);
40+
} else {
41+
material.surface = MaterialSurface(iter->second);
42+
}
3943
} else {
40-
material.surface = MaterialSurface(iter->second);
44+
material.surface = MaterialSurface(glm::vec4(1.f, 0.f, 1.f, 1.f));
4145
}
4246
if (asset.has_wrap_mode()) {
4347
std::vector<std::string> wrap_mode = asset.wrap_mode();
@@ -50,6 +54,19 @@ MaterialSet read_material_assets(const CollectionAsset& src)
5054
}
5155
}
5256
}
57+
if (asset.has_effect_mode()) {
58+
for(std::string effect : asset.effect_mode()) {
59+
if (effect == "none") {
60+
material.effect_mode = MaterialEffectMode::NONE;
61+
}
62+
if (effect == "chrome") {
63+
material.effect_mode = MaterialEffectMode::CHROME;
64+
}
65+
if (effect == "glass") {
66+
material.effect_mode = MaterialEffectMode::GLASS;
67+
}
68+
}
69+
}
5370
});
5471
return {materials, textures};
5572
}

src/core/gltf.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ struct GLTFBuffer
116116
// GLTF, Scenes & Nodes
117117
static ModelFile read_gltf(const Json& src, Buffer bin_chunk);
118118
static Json write_gltf(const ModelFile& src, OutBuffer bin_chunk);
119+
static void validate_gltf(const ModelFile& gltf);
119120
static Asset read_asset(const Json& src);
120121
static Json write_asset(const Asset& src);
121122
static Scene read_scene(const Json& src);
@@ -256,6 +257,7 @@ ModelFile read_glb(Buffer src)
256257
try {
257258
auto json = Json::parse(src.lo + json_offset, src.lo + json_offset + json_size);
258259
gltf = read_gltf(json, src.subbuf(bin_offset, bin_size));
260+
validate_gltf(gltf);
259261
} catch (Json::exception& e) {
260262
verify_not_reached("%s", e.what());
261263
}
@@ -265,6 +267,8 @@ ModelFile read_glb(Buffer src)
265267

266268
std::vector<u8> write_glb(const ModelFile& gltf)
267269
{
270+
validate_gltf(gltf);
271+
268272
std::vector<u8> result;
269273
OutBuffer dest(result);
270274

@@ -590,6 +594,71 @@ static Json write_gltf(const ModelFile& src, OutBuffer bin_chunk)
590594
return dest;
591595
}
592596

597+
static void validate_gltf(const ModelFile& gltf)
598+
{
599+
for (const Scene& scene : gltf.scenes) {
600+
const char* name = scene.name.has_value() ? scene.name->c_str() : "unnamed";
601+
602+
for (NodeIndex node : scene.nodes) {
603+
verify(node >= 0 && node < gltf.nodes.size(),
604+
"Out of bounds node index %d for scene '%s'.", node, name);
605+
}
606+
}
607+
608+
for (const Node& node : gltf.nodes) {
609+
const char* name = node.name.has_value() ? node.name->c_str() : "unnamed";
610+
611+
for (NodeIndex child : node.children) {
612+
verify(child >= 0 && child < gltf.nodes.size(),
613+
"Out of bounds child index %d for node '%s'.", child, name);
614+
}
615+
616+
if (node.mesh.has_value()) {
617+
verify(*node.mesh >= 0 && *node.mesh < gltf.meshes.size(),
618+
"Out of bounds mesh index %d for node '%s'.", *node.mesh, name);
619+
}
620+
}
621+
622+
for (const Animation& animation : gltf.animations) {
623+
const char* name = animation.name.has_value() ? animation.name->c_str() : "unnamed";
624+
625+
for (SamplerIndex sampler : animation.sampler_input) {
626+
verify(sampler >= 0 && sampler < gltf.samplers.size(),
627+
"Out of bounds sampler index %d for animation '%s'.", sampler, name);
628+
}
629+
}
630+
631+
for (const Mesh& mesh : gltf.meshes) {
632+
const char* name = mesh.name.has_value() ? mesh.name->c_str() : "unnamed";
633+
634+
for (const MeshPrimitive& primitive : mesh.primitives) {
635+
if (primitive.material.has_value()) {
636+
verify(*primitive.material >= 0 && *primitive.material < gltf.materials.size(),
637+
"Out of bounds material index %d for mesh '%s'.", *primitive.material, name);
638+
}
639+
}
640+
}
641+
642+
for (const Material& material : gltf.materials) {
643+
const char* name = material.name.has_value() ? material.name->c_str() : "unnamed";
644+
645+
if (material.pbr_metallic_roughness.has_value() && material.pbr_metallic_roughness->base_color_texture.has_value()) {
646+
const TextureInfo& info = *material.pbr_metallic_roughness->base_color_texture;
647+
verify(info.index >= 0 && info.index < gltf.textures.size(),
648+
"Out of bounds texture index %d for material '%s'.", info.index, name);
649+
}
650+
}
651+
652+
for (const Texture& texture : gltf.textures) {
653+
const char* name = texture.name.has_value() ? texture.name->c_str() : "unnamed";
654+
655+
if (texture.sampler.has_value()) {
656+
verify(*texture.sampler >= 0 && *texture.sampler < gltf.samplers.size(),
657+
"Out of bounds sampler index %d for texture '%s'.", *texture.sampler, name);
658+
}
659+
}
660+
}
661+
593662
static Asset read_asset(const Json& src)
594663
{
595664
Asset dest;

src/core/gltf.h

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@
2525

2626
namespace GLTF {
2727

28+
using SceneIndex = s32;
29+
using NodeIndex = s32;
30+
using AnimationIndex = s32;
31+
using MeshIndex = s32;
32+
using MaterialIndex = s32;
33+
using TextureIndex = s32;
34+
using ImageIndex = s32;
35+
using SamplerIndex = s32;
36+
using SkinIndex = s32;
37+
2838
struct Asset
2939
{
3040
Opt<std::string> copyright;
@@ -35,17 +45,17 @@ struct Asset
3545

3646
struct Scene
3747
{
38-
std::vector<s32> nodes;
48+
std::vector<NodeIndex> nodes;
3949
Opt<std::string> name;
4050
};
4151

4252
struct Node
4353
{
4454
// unimplemented: camera
45-
std::vector<s32> children;
46-
Opt<s32> skin;
55+
std::vector<NodeIndex> children;
56+
Opt<SkinIndex> skin;
4757
Opt<glm::mat4> matrix;
48-
Opt<s32> mesh;
58+
Opt<MeshIndex> mesh;
4959
Opt<glm::vec4> rotation;
5060
Opt<glm::vec3> scale;
5161
Opt<glm::vec3> translation;
@@ -70,12 +80,12 @@ struct Animation
7080
{
7181
Opt<std::string> name;
7282
std::vector<AnimationChannelGroup> channel_groups;
73-
std::vector<f32> sampler_input;
83+
std::vector<SamplerIndex> sampler_input;
7484
};
7585

7686
struct TextureInfo
7787
{
78-
s32 index;
88+
TextureIndex index;
7989
Opt<s32> tex_coord;
8090
};
8191

@@ -133,7 +143,7 @@ struct MeshPrimitive
133143
{
134144
u32 attributes_bitfield = 0;
135145
std::vector<s32> indices;
136-
Opt<s32> material;
146+
Opt<MaterialIndex> material;
137147
Opt<MeshPrimitiveMode> mode;
138148
// unimplemented: targets
139149
};
@@ -148,7 +158,7 @@ struct Mesh
148158

149159
struct Texture
150160
{
151-
Opt<s32> sampler;
161+
Opt<SamplerIndex> sampler;
152162
Opt<s32> source;
153163
Opt<std::string> name;
154164
};

src/core/material.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ EffectiveMaterialsOutput effective_materials(const std::vector<Material>& materi
3636
equal &= materials[i].wrap_mode_s == materials[j].wrap_mode_s;
3737
equal &= materials[i].wrap_mode_t == materials[j].wrap_mode_t;
3838
}
39-
if (attributes & MATERIAL_ATTRIB_METAL_MODE) {
40-
equal &= materials[i].metal_mode == materials[j].metal_mode;
39+
if (attributes & MATERIAL_ATTRIB_EFFECT_MODE) {
40+
equal &= materials[i].effect_mode == materials[j].effect_mode;
4141
}
4242
if (equal) {
4343
effective.materials.emplace_back((s32) j);

src/core/material.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ enum class WrapMode
5555
REPEAT, CLAMP
5656
};
5757

58-
enum class MetalEffectMode
58+
enum class MaterialEffectMode
5959
{
60-
OFF, CHROME, GLASS
60+
OFF, NONE, CHROME, GLASS
6161
};
6262

6363
struct Material
@@ -66,14 +66,14 @@ struct Material
6666
MaterialSurface surface;
6767
WrapMode wrap_mode_s = WrapMode::REPEAT;
6868
WrapMode wrap_mode_t = WrapMode::REPEAT;
69-
MetalEffectMode metal_mode = MetalEffectMode::OFF;
69+
MaterialEffectMode effect_mode = MaterialEffectMode::OFF;
7070
};
7171

7272
enum MaterialAttribute
7373
{
7474
MATERIAL_ATTRIB_SURFACE = 1 << 1,
7575
MATERIAL_ATTRIB_WRAP_MODE = 1 << 2,
76-
MATERIAL_ATTRIB_METAL_MODE = 1 << 3
76+
MATERIAL_ATTRIB_EFFECT_MODE = 1 << 3
7777
};
7878

7979
// An effective material is a set of materials that for some subset of

src/instancemgr/instance_schema.wtf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616
along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
1818

19-
format_version: 29
19+
format_version: 30
2020

2121
InstanceType Moby {
2222
desc: "Moving, interactive, or otherwise dynamic objects with an associated update function."
2323
components: "COM_TRANSFORM | COM_CLASS | COM_PVARS | COM_DRAW_DISTANCE | COM_COLOUR"
2424
transform_mode: "POSITION_ROTATION_SCALE"
2525
variable: "moby_instances"
2626
link_type: "mobylink"
27-
27+
2828
s8 mission {}
2929
s32 uid {}
3030
s32 bolts {}

0 commit comments

Comments
 (0)