bool MeshInstance::_set(const StringName &p_name, const Variant &p_value) { //this is not _too_ bad performance wise, really. it only arrives here if the property was not set anywhere else. //add to it that it's probably found on first call to _set anyway. if (!get_instance().is_valid()) return false; Map<StringName, BlendShapeTrack>::Element *E = blend_shape_tracks.find(p_name); if (E) { E->get().value = p_value; VisualServer::get_singleton()->instance_set_blend_shape_weight(get_instance(), E->get().idx, E->get().value); return true; } if (p_name.operator String().begins_with("material/")) { int idx = p_name.operator String().get_slicec('/', 1).to_int(); if (idx >= materials.size() || idx < 0) return false; set_surface_material(idx, p_value); return true; } return false; }
void SoftBody::become_mesh_owner() { if (mesh.is_null()) return; if (!mesh_owner) { mesh_owner = true; Vector<Ref<Material> > copy_materials; copy_materials.append_array(materials); ERR_FAIL_COND(!mesh->get_surface_count()); // Get current mesh array and create new mesh array with necessary flag for softbody Array surface_arrays = mesh->surface_get_arrays(0); Array surface_blend_arrays = mesh->surface_get_blend_shape_arrays(0); uint32_t surface_format = mesh->surface_get_format(0); surface_format &= ~(Mesh::ARRAY_COMPRESS_VERTEX | Mesh::ARRAY_COMPRESS_NORMAL); surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE; Ref<ArrayMesh> soft_mesh; soft_mesh.instance(); soft_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface_arrays, surface_blend_arrays, surface_format); soft_mesh->surface_set_material(0, mesh->surface_get_material(0)); set_mesh(soft_mesh); for (int i = copy_materials.size() - 1; 0 <= i; --i) { set_surface_material(i, copy_materials[i]); } } }