победа над водопадами, шейдеры m2
This commit is contained in:
@@ -7,7 +7,9 @@ class_name WMOBuilder
|
||||
|
||||
const M2_BUILDER_SCRIPT := preload("res://addons/mpq_extractor/loaders/m2_builder.gd")
|
||||
const WOW_LIQUID_MATERIAL := preload("res://addons/mpq_extractor/loaders/wow_liquid_material.gd")
|
||||
const M2_RIGHT_YAW_OFFSET := PI * 0.5
|
||||
const WOW_WMO_MATERIAL := preload("res://addons/mpq_extractor/loaders/wow_wmo_material.gd")
|
||||
const WMO_BUILDER_FORMAT_VERSION := 2
|
||||
const WMO_BUILDER_FORMAT_META := "openwc_wmo_builder_format_version"
|
||||
const BUILD_OCCLUDERS := false
|
||||
const OCCLUDER_MIN_TRIANGLES := 16
|
||||
|
||||
@@ -29,11 +31,20 @@ static func clear_caches() -> void:
|
||||
_m2_missing_cache.clear()
|
||||
_texture_cache.clear()
|
||||
WOW_LIQUID_MATERIAL.clear_cache()
|
||||
WOW_WMO_MATERIAL.clear_cache()
|
||||
|
||||
|
||||
static func is_scene_cache_current(root: Node) -> bool:
|
||||
if root == null:
|
||||
return false
|
||||
return int(root.get_meta(WMO_BUILDER_FORMAT_META, 0)) >= WMO_BUILDER_FORMAT_VERSION
|
||||
|
||||
|
||||
# Returns a Node3D containing one MeshInstance3D per WMO group.
|
||||
static func build(data: Dictionary, extracted_dir: String = "") -> Node3D:
|
||||
var root := Node3D.new()
|
||||
root.name = "WMO"
|
||||
root.set_meta(WMO_BUILDER_FORMAT_META, WMO_BUILDER_FORMAT_VERSION)
|
||||
|
||||
if not data.has("groups"):
|
||||
return root
|
||||
@@ -42,7 +53,7 @@ static func build(data: Dictionary, extracted_dir: String = "") -> Node3D:
|
||||
var materials: Array = data.get("materials", [])
|
||||
|
||||
# Build Godot materials from WMO material definitions
|
||||
var godot_materials: Array[StandardMaterial3D] = []
|
||||
var godot_materials: Array[Material] = []
|
||||
for mat_def in materials:
|
||||
godot_materials.append(_build_material(mat_def, textures, extracted_dir))
|
||||
|
||||
@@ -110,7 +121,10 @@ static func _build_default_doodads(root: Node3D, data: Dictionary,
|
||||
var pos: Vector3 = p.get("pos", Vector3.ZERO)
|
||||
var rot_q: Quaternion = p.get("rot", Quaternion.IDENTITY)
|
||||
var scl: float = float(p.get("scale", 1.0))
|
||||
var basis := (Basis(rot_q) * Basis(Vector3.UP, M2_RIGHT_YAW_OFFSET)).scaled(Vector3.ONE * maxf(scl, 0.001))
|
||||
# MODD is already a local WMO doodad transform. Do not apply the ADT M2
|
||||
# yaw correction here; it rotates anchored effects like waterfalls away
|
||||
# from their authored cliff attachment points.
|
||||
var basis := Basis(rot_q).scaled(Vector3.ONE * maxf(scl, 0.001))
|
||||
var xform := Transform3D(basis, pos)
|
||||
if not groups.has(rel_path):
|
||||
groups[rel_path] = []
|
||||
@@ -207,7 +221,7 @@ static func _build_raw_m2_prototype(rel_path: String, extracted_dir: String) ->
|
||||
|
||||
static func _build_group_mesh(
|
||||
g: Dictionary,
|
||||
godot_mats: Array[StandardMaterial3D]) -> MeshInstance3D:
|
||||
godot_mats: Array[Material]) -> MeshInstance3D:
|
||||
|
||||
var verts: PackedVector3Array = g.get("vertices", PackedVector3Array())
|
||||
var normals: PackedVector3Array = g.get("normals", PackedVector3Array())
|
||||
@@ -331,37 +345,54 @@ static func _material_can_occlude(mat_id: int, material_defs: Array) -> bool:
|
||||
static func _build_material(
|
||||
mat_def: Dictionary,
|
||||
textures: PackedStringArray,
|
||||
extracted_dir: String = "") -> StandardMaterial3D:
|
||||
|
||||
var mat := StandardMaterial3D.new()
|
||||
mat.cull_mode = BaseMaterial3D.CULL_DISABLED
|
||||
mat.roughness = 0.85
|
||||
mat.metallic = 0.0
|
||||
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
mat.specular_mode = BaseMaterial3D.SPECULAR_DISABLED
|
||||
mat.vertex_color_use_as_albedo = false
|
||||
mat.set_flag(BaseMaterial3D.FLAG_USE_TEXTURE_REPEAT, true)
|
||||
extracted_dir: String = "") -> Material:
|
||||
|
||||
var blend_mode: int = mat_def.get("blend_mode", 0)
|
||||
match blend_mode:
|
||||
0: mat.transparency = BaseMaterial3D.TRANSPARENCY_DISABLED
|
||||
1: mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR
|
||||
_: mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
|
||||
var flags: int = int(mat_def.get("flags", 0))
|
||||
var shader_id: int = int(mat_def.get("shader", 0))
|
||||
var tex: Texture2D = null
|
||||
var tex2: Texture2D = null
|
||||
var tex3: Texture2D = null
|
||||
var tex_path := ""
|
||||
var tex2_path := ""
|
||||
var tex3_path := ""
|
||||
|
||||
# Texture is loaded later by the scene assembler (needs BLP→Image conversion)
|
||||
# Store the path as metadata for the assembler to pick up
|
||||
var tex0_id: int = mat_def.get("texture0", -1)
|
||||
if tex0_id >= 0 and tex0_id < textures.size():
|
||||
var tex_path: String = str(textures[tex0_id]).replace("\\", "/")
|
||||
mat.set_meta("texture0_path", tex_path)
|
||||
var tex := _load_texture(tex_path, extracted_dir)
|
||||
if tex:
|
||||
mat.albedo_texture = tex
|
||||
mat.texture_filter = BaseMaterial3D.TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC
|
||||
mat.set_flag(BaseMaterial3D.FLAG_USE_TEXTURE_REPEAT, true)
|
||||
tex_path = str(textures[tex0_id]).replace("\\", "/")
|
||||
tex = _load_texture(tex_path, extracted_dir)
|
||||
var tex1_id: int = mat_def.get("texture1", -1)
|
||||
if tex1_id >= 0 and tex1_id < textures.size():
|
||||
tex2_path = str(textures[tex1_id]).replace("\\", "/")
|
||||
tex2 = _load_texture(tex2_path, extracted_dir)
|
||||
var tex2_id: int = mat_def.get("texture2", -1)
|
||||
if tex2_id >= 0 and tex2_id < textures.size():
|
||||
tex3_path = str(textures[tex2_id]).replace("\\", "/")
|
||||
tex3 = _load_texture(tex3_path, extracted_dir)
|
||||
|
||||
mat.set_meta("wow_flags", mat_def.get("flags", 0))
|
||||
mat.set_meta("wow_shader", mat_def.get("shader", 0))
|
||||
var diffuse_color: Color = mat_def.get("diffuse_color", Color.WHITE)
|
||||
var emissive_color: Color = mat_def.get("emissive_color", Color.BLACK)
|
||||
var secondary_color: Color = mat_def.get("color2", Color.WHITE)
|
||||
var mat := WOW_WMO_MATERIAL.build(
|
||||
tex,
|
||||
tex2,
|
||||
flags,
|
||||
shader_id,
|
||||
blend_mode,
|
||||
tex_path,
|
||||
tex2_path,
|
||||
diffuse_color,
|
||||
emissive_color,
|
||||
secondary_color,
|
||||
tex3,
|
||||
tex3_path)
|
||||
mat.set_meta("texture0_path", tex_path)
|
||||
mat.set_meta("texture1_path", tex2_path)
|
||||
mat.set_meta("texture2_path", tex3_path)
|
||||
mat.set_meta("wow_flags", flags)
|
||||
mat.set_meta("wow_shader", shader_id)
|
||||
|
||||
return mat
|
||||
|
||||
|
||||
Reference in New Issue
Block a user