|
| 1 | +@tool |
| 2 | +class_name GLTFDocumentExtensionOMIMaterialsBlend |
| 3 | +extends GLTFDocumentExtension |
| 4 | + |
| 5 | + |
| 6 | +func _import_preflight(_state: GLTFState, extensions: PackedStringArray) -> Error: |
| 7 | + if extensions.has("OMI_materials_blend"): |
| 8 | + return OK |
| 9 | + return ERR_SKIP |
| 10 | + |
| 11 | + |
| 12 | +func _get_supported_extensions() -> PackedStringArray: |
| 13 | + return PackedStringArray(["OMI_materials_blend"]) |
| 14 | + |
| 15 | + |
| 16 | +func _read_apply_material_blend_extension(mat_blend_ext: Dictionary, godot_mat: BaseMaterial3D) -> void: |
| 17 | + if mat_blend_ext.has("alwaysUseCutoff"): |
| 18 | + if mat_blend_ext["alwaysUseCutoff"]: |
| 19 | + godot_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR |
| 20 | + if mat_blend_ext.has("alphaMode"): |
| 21 | + match mat_blend_ext["alphaMode"]: |
| 22 | + "BLEND": godot_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_DEPTH_PRE_PASS |
| 23 | + "HASHED": godot_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_HASH |
| 24 | + "MULTIPLY": godot_mat.blend_mode = BaseMaterial3D.BLEND_MODE_MUL |
| 25 | + "PREMULT": godot_mat.blend_mode = BaseMaterial3D.BLEND_MODE_PREMULT_ALPHA |
| 26 | + "ADD": godot_mat.blend_mode = BaseMaterial3D.BLEND_MODE_ADD |
| 27 | + "SUBTRACT": godot_mat.blend_mode = BaseMaterial3D.BLEND_MODE_SUB |
| 28 | + "REV_SUBTRACT": push_warning("REV_SUBTRACT alpha blend mode is not supported by Godot.") |
| 29 | + "MAX": push_warning("MAX alpha blend mode is not supported by Godot.") |
| 30 | + "MIN": push_warning("MIN alpha blend mode is not supported by Godot.") |
| 31 | + |
| 32 | + |
| 33 | +func _import_post_parse(gltf_state: GLTFState) -> Error: |
| 34 | + var materials: Array[Material] = gltf_state.get_materials() |
| 35 | + var json_materials: Array = gltf_state.json.get("materials", []) |
| 36 | + assert(materials.size() == json_materials.size()) |
| 37 | + for i in range(materials.size()): |
| 38 | + var mat_dict: Dictionary = json_materials[i] |
| 39 | + if mat_dict.has("extensions") and materials[i] is BaseMaterial3D: |
| 40 | + var mat_extensions: Dictionary = mat_dict["extensions"] |
| 41 | + if mat_extensions.has("OMI_materials_blend"): |
| 42 | + var mat_blend_ext: Dictionary = mat_extensions["OMI_materials_blend"] |
| 43 | + _read_apply_material_blend_extension(mat_blend_ext, materials[i] as BaseMaterial3D) |
| 44 | + gltf_state.set_materials(materials) |
| 45 | + return OK |
| 46 | + |
| 47 | + |
| 48 | +func _write_material_blend_extension_if_needed(godot_mat: BaseMaterial3D, mat_dict: Dictionary) -> bool: |
| 49 | + if godot_mat.blend_mode == BaseMaterial3D.BLEND_MODE_MIX: |
| 50 | + if godot_mat.transparency == BaseMaterial3D.TRANSPARENCY_ALPHA_HASH: |
| 51 | + var mat_blend_ext: Dictionary = mat_dict.get_or_add("extensions", {}).get_or_add("OMI_materials_blend", {}) |
| 52 | + mat_blend_ext["alphaMode"] = "HASHED" |
| 53 | + return true |
| 54 | + return false |
| 55 | + var mat_blend_ext: Dictionary = mat_dict.get_or_add("extensions", {}).get_or_add("OMI_materials_blend", {}) |
| 56 | + match godot_mat.blend_mode: |
| 57 | + BaseMaterial3D.BLEND_MODE_ADD: |
| 58 | + mat_blend_ext["alphaMode"] = "ADD" |
| 59 | + BaseMaterial3D.BLEND_MODE_SUB: |
| 60 | + mat_blend_ext["alphaMode"] = "SUBTRACT" |
| 61 | + BaseMaterial3D.BLEND_MODE_MUL: |
| 62 | + mat_blend_ext["alphaMode"] = "MULTIPLY" |
| 63 | + BaseMaterial3D.BLEND_MODE_PREMULT_ALPHA: |
| 64 | + mat_blend_ext["alphaMode"] = "PREMULT" |
| 65 | + if godot_mat.transparency == BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR: |
| 66 | + mat_blend_ext["alwaysUseCutoff"] = true |
| 67 | + mat_dict["alphaCutoff"] = godot_mat.alpha_scissor_threshold |
| 68 | + return true |
| 69 | + |
| 70 | + |
| 71 | +func _export_post(gltf_state: GLTFState) -> Error: |
| 72 | + var materials: Array[Material] = gltf_state.get_materials() |
| 73 | + var json_materials: Array = gltf_state.json.get("materials", []) |
| 74 | + assert(materials.size() == json_materials.size()) |
| 75 | + var use_material_blend_extension: bool = false |
| 76 | + for i in range(materials.size()): |
| 77 | + var mat_dict: Dictionary = json_materials[i] |
| 78 | + var written: bool = _write_material_blend_extension_if_needed(materials[i] as BaseMaterial3D, mat_dict) |
| 79 | + use_material_blend_extension = use_material_blend_extension or written |
| 80 | + if use_material_blend_extension: |
| 81 | + gltf_state.add_used_extension("OMI_materials_blend", false) |
| 82 | + var extensions_used: Array = gltf_state.json.get_or_add("extensionsUsed", []) |
| 83 | + extensions_used.append("OMI_materials_blend") |
| 84 | + gltf_state.json["extensionsUsed"] = extensions_used |
| 85 | + return OK |
0 commit comments