3.x backport glTF: Fix override materials and non-empty arrays
Keep track of MeshInstance and GeometryInstance override materials in the GLTFMesh object. Ensure all arrays are non-empty to conform with "minItems":1 in glTF spec.
This commit is contained in:
parent
bf59549f68
commit
e575b27b15
@ -11,6 +11,8 @@
|
|||||||
<members>
|
<members>
|
||||||
<member name="blend_weights" type="PoolRealArray" setter="set_blend_weights" getter="get_blend_weights" default="PoolRealArray( )">
|
<member name="blend_weights" type="PoolRealArray" setter="set_blend_weights" getter="get_blend_weights" default="PoolRealArray( )">
|
||||||
</member>
|
</member>
|
||||||
|
<member name="instance_materials" type="Array" setter="set_instance_materials" getter="get_instance_materials" default="[ ]">
|
||||||
|
</member>
|
||||||
<member name="mesh" type="ArrayMesh" setter="set_mesh" getter="get_mesh">
|
<member name="mesh" type="ArrayMesh" setter="set_mesh" getter="get_mesh">
|
||||||
</member>
|
</member>
|
||||||
</members>
|
</members>
|
||||||
|
@ -739,6 +739,9 @@ Error GLTFDocument::_encode_buffer_glb(Ref<GLTFState> state, const String &p_pat
|
|||||||
gltf_buffer["byteLength"] = buffer_data.size();
|
gltf_buffer["byteLength"] = buffer_data.size();
|
||||||
buffers.push_back(gltf_buffer);
|
buffers.push_back(gltf_buffer);
|
||||||
}
|
}
|
||||||
|
if (!buffers.size()) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
state->json["buffers"] = buffers;
|
state->json["buffers"] = buffers;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@ -843,6 +846,9 @@ Error GLTFDocument::_encode_buffer_views(Ref<GLTFState> state) {
|
|||||||
buffers.push_back(d);
|
buffers.push_back(d);
|
||||||
}
|
}
|
||||||
print_verbose("glTF: Total buffer views: " + itos(state->buffer_views.size()));
|
print_verbose("glTF: Total buffer views: " + itos(state->buffer_views.size()));
|
||||||
|
if (!buffers.size()) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
state->json["bufferViews"] = buffers;
|
state->json["bufferViews"] = buffers;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -942,6 +948,9 @@ Error GLTFDocument::_encode_accessors(Ref<GLTFState> state) {
|
|||||||
accessors.push_back(d);
|
accessors.push_back(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!accessors.size()) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
state->json["accessors"] = accessors;
|
state->json["accessors"] = accessors;
|
||||||
ERR_FAIL_COND_V(!state->json.has("accessors"), ERR_FILE_CORRUPT);
|
ERR_FAIL_COND_V(!state->json.has("accessors"), ERR_FILE_CORRUPT);
|
||||||
print_verbose("glTF: Total accessors: " + itos(state->accessors.size()));
|
print_verbose("glTF: Total accessors: " + itos(state->accessors.size()));
|
||||||
@ -2287,6 +2296,7 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
|
|||||||
if (import_mesh.is_null()) {
|
if (import_mesh.is_null()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Array instance_materials = state->meshes.write[gltf_mesh_i]->get_instance_materials();
|
||||||
Array primitives;
|
Array primitives;
|
||||||
Dictionary gltf_mesh;
|
Dictionary gltf_mesh;
|
||||||
Array target_names;
|
Array target_names;
|
||||||
@ -2531,8 +2541,14 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
|
|||||||
targets.push_back(t);
|
targets.push_back(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Variant v;
|
||||||
Ref<SpatialMaterial> mat = import_mesh->surface_get_material(surface_i);
|
if (surface_i < instance_materials.size()) {
|
||||||
|
v = instance_materials.get(surface_i);
|
||||||
|
}
|
||||||
|
Ref<SpatialMaterial> mat = v;
|
||||||
|
if (!mat.is_valid()) {
|
||||||
|
mat = import_mesh->surface_get_material(surface_i);
|
||||||
|
}
|
||||||
if (mat.is_valid()) {
|
if (mat.is_valid()) {
|
||||||
Map<Ref<Material>, GLTFMaterialIndex>::Element *material_cache_i = state->material_cache.find(mat);
|
Map<Ref<Material>, GLTFMaterialIndex>::Element *material_cache_i = state->material_cache.find(mat);
|
||||||
if (material_cache_i && material_cache_i->get() != -1) {
|
if (material_cache_i && material_cache_i->get() != -1) {
|
||||||
@ -2576,6 +2592,9 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
|
|||||||
meshes.push_back(gltf_mesh);
|
meshes.push_back(gltf_mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!meshes.size()) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
state->json["meshes"] = meshes;
|
state->json["meshes"] = meshes;
|
||||||
print_verbose("glTF: Total meshes: " + itos(meshes.size()));
|
print_verbose("glTF: Total meshes: " + itos(meshes.size()));
|
||||||
|
|
||||||
@ -3442,6 +3461,9 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
|
|||||||
}
|
}
|
||||||
materials.push_back(d);
|
materials.push_back(d);
|
||||||
}
|
}
|
||||||
|
if (!materials.size()) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
state->json["materials"] = materials;
|
state->json["materials"] = materials;
|
||||||
print_verbose("Total materials: " + itos(state->materials.size()));
|
print_verbose("Total materials: " + itos(state->materials.size()));
|
||||||
|
|
||||||
@ -4835,6 +4857,9 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!animations.size()) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
state->json["animations"] = animations;
|
state->json["animations"] = animations;
|
||||||
|
|
||||||
print_verbose("glTF: Total animations '" + itos(state->animations.size()) + "'.");
|
print_verbose("glTF: Total animations '" + itos(state->animations.size()) + "'.");
|
||||||
@ -5066,6 +5091,18 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> state, MeshInst
|
|||||||
}
|
}
|
||||||
Ref<GLTFMesh> gltf_mesh;
|
Ref<GLTFMesh> gltf_mesh;
|
||||||
gltf_mesh.instance();
|
gltf_mesh.instance();
|
||||||
|
Array instance_materials;
|
||||||
|
for (int32_t surface_i = 0; surface_i < import_mesh->get_surface_count(); surface_i++) {
|
||||||
|
Ref<Material> mat = import_mesh->surface_get_material(surface_i);
|
||||||
|
if (p_mesh_instance->get_surface_material(surface_i).is_valid()) {
|
||||||
|
mat = p_mesh_instance->get_surface_material(surface_i);
|
||||||
|
}
|
||||||
|
if (p_mesh_instance->get_material_override().is_valid()) {
|
||||||
|
mat = p_mesh_instance->get_material_override();
|
||||||
|
}
|
||||||
|
instance_materials.append(mat);
|
||||||
|
}
|
||||||
|
gltf_mesh->set_instance_materials(instance_materials);
|
||||||
gltf_mesh->set_mesh(import_mesh);
|
gltf_mesh->set_mesh(import_mesh);
|
||||||
gltf_mesh->set_blend_weights(blend_weights);
|
gltf_mesh->set_blend_weights(blend_weights);
|
||||||
GLTFMeshIndex mesh_i = state->meshes.size();
|
GLTFMeshIndex mesh_i = state->meshes.size();
|
||||||
|
@ -35,9 +35,12 @@ void GLTFMesh::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &GLTFMesh::set_mesh);
|
ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &GLTFMesh::set_mesh);
|
||||||
ClassDB::bind_method(D_METHOD("get_blend_weights"), &GLTFMesh::get_blend_weights);
|
ClassDB::bind_method(D_METHOD("get_blend_weights"), &GLTFMesh::get_blend_weights);
|
||||||
ClassDB::bind_method(D_METHOD("set_blend_weights", "blend_weights"), &GLTFMesh::set_blend_weights);
|
ClassDB::bind_method(D_METHOD("set_blend_weights", "blend_weights"), &GLTFMesh::set_blend_weights);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_instance_materials"), &GLTFMesh::get_instance_materials);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_instance_materials", "instance_materials"), &GLTFMesh::set_instance_materials);
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh"), "set_mesh", "get_mesh");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh"), "set_mesh", "get_mesh");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_REAL_ARRAY, "blend_weights"), "set_blend_weights", "get_blend_weights"); // Vector<float>
|
ADD_PROPERTY(PropertyInfo(Variant::POOL_REAL_ARRAY, "blend_weights"), "set_blend_weights", "get_blend_weights"); // Vector<float>
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "instance_materials"), "set_instance_materials", "get_instance_materials");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<ArrayMesh> GLTFMesh::get_mesh() {
|
Ref<ArrayMesh> GLTFMesh::get_mesh() {
|
||||||
@ -48,6 +51,14 @@ void GLTFMesh::set_mesh(Ref<ArrayMesh> p_mesh) {
|
|||||||
mesh = p_mesh;
|
mesh = p_mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array GLTFMesh::get_instance_materials() {
|
||||||
|
return instance_materials;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLTFMesh::set_instance_materials(Array p_instance_materials) {
|
||||||
|
instance_materials = p_instance_materials;
|
||||||
|
}
|
||||||
|
|
||||||
Vector<float> GLTFMesh::get_blend_weights() {
|
Vector<float> GLTFMesh::get_blend_weights() {
|
||||||
return blend_weights;
|
return blend_weights;
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ class GLTFMesh : public Resource {
|
|||||||
private:
|
private:
|
||||||
Ref<ArrayMesh> mesh;
|
Ref<ArrayMesh> mesh;
|
||||||
Vector<float> blend_weights;
|
Vector<float> blend_weights;
|
||||||
|
Array instance_materials;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
@ -50,5 +51,7 @@ public:
|
|||||||
void set_mesh(Ref<ArrayMesh> p_mesh);
|
void set_mesh(Ref<ArrayMesh> p_mesh);
|
||||||
Vector<float> get_blend_weights();
|
Vector<float> get_blend_weights();
|
||||||
void set_blend_weights(Vector<float> p_blend_weights);
|
void set_blend_weights(Vector<float> p_blend_weights);
|
||||||
|
Array get_instance_materials();
|
||||||
|
void set_instance_materials(Array p_instance_materials);
|
||||||
};
|
};
|
||||||
#endif // GLTF_MESH_H
|
#endif // GLTF_MESH_H
|
||||||
|
Loading…
Reference in New Issue
Block a user