Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 30 additions & 31 deletions addons/func_godot/src/fgd/func_godot_fgd_model_point_class.gd
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@tool
@icon("res://addons/func_godot/icons/icon_godambler3d.svg")
class_name FuncGodotFGDModelPointClass extends FuncGodotFGDPointClass
## A special type of [FuncGodotFGDPointClass] entity that automatically generates a special simplified GLB model file for the map editor display.
## A special type of [FuncGodotFGDPointClass] entity that automatically generates a special simplified GLB model file for the map editor display.
## Only supported in map editors that support GLTF or GLB.
##
## @tutorial(Quake Wiki Entity Article): https://quakewiki.org/wiki/Entity
Expand Down Expand Up @@ -54,8 +54,7 @@ func build_def_text(target_editor: FuncGodotFGDFile.FuncGodotTargetMapEditors =

func _generate_model() -> void:
if not scene_file:
return

return
var gltf_state := GLTFState.new()
var path: String = _get_export_dir()
var node: Node3D = _get_node()
Expand All @@ -65,28 +64,28 @@ func _generate_model() -> void:
printerr("could not create gltf file")
return
node.queue_free()

if target_map_editor == TargetMapEditor.TRENCHBROOM:
const model_key: String = "model"
if scale_expression.is_empty():
meta_properties[model_key] = '{"path": "%s", "scale": %s }' % [
_get_local_path(),
_get_local_path(),
ProjectSettings.get_setting("func_godot/default_inverse_scale_factor", 32.0) as float
]
else:
meta_properties[model_key] = '{"path": "%s", "scale": %s }' % [
_get_local_path(),
_get_local_path(),
scale_expression
]
else:
meta_properties["studio"] = '"%s"' % _get_local_path()

if generate_size_property:
meta_properties["size"] = _generate_size_from_aabb(gltf_state.meshes, gltf_state.get_nodes())
meta_properties["size"] = _generate_size_from_aabb(scene_file.instantiate())

func _get_node() -> Node3D:
var node := scene_file.instantiate()
if node is Node3D:
if node is Node3D:
return node as Node3D
node.queue_free()
printerr("Scene is not of type 'Node3D'")
Expand All @@ -113,11 +112,11 @@ func _create_gltf_file(gltf_state: GLTFState, path: String, node: Node3D) -> boo
var global_export_path = path
var gltf_document := GLTFDocument.new()
gltf_state.create_animations = false

node.rotate_x(deg_to_rad(rotation_offset.x))
node.rotate_y(deg_to_rad(rotation_offset.y))
node.rotate_z(deg_to_rad(rotation_offset.z))

# With TrenchBroom we can specify a scale expression, but for other editors we need to scale our models manually.
if target_map_editor != TargetMapEditor.TRENCHBROOM:
var scale_factor: Vector3 = Vector3.ONE
Expand All @@ -133,46 +132,46 @@ func _create_gltf_file(gltf_state: GLTFState, path: String, node: Node3D) -> boo
if scale_factor.length() == 0:
scale_factor = Vector3.ONE # Don't let the node scale into oblivion!
node.scale *= scale_factor

var error: Error = gltf_document.append_from_scene(node, gltf_state)
if error != Error.OK:
printerr("Failed appending to gltf document", error)
return false

call_deferred("_save_to_file_system", gltf_document, gltf_state, global_export_path)
return true

func _save_to_file_system(gltf_document: GLTFDocument, gltf_state: GLTFState, path: String) -> void:
var error: Error = DirAccess.make_dir_recursive_absolute(path.get_base_dir())
if error != Error.OK:
printerr("Failed creating dir", error)
return
return

error = gltf_document.write_to_filesystem(gltf_state, path)
if error != Error.OK:
printerr("Failed writing to file system", error)
return
return
print('Exported model to ', path)

func _generate_size_from_aabb(meshes: Array[GLTFMesh], nodes: Array[GLTFNode]) -> AABB:
func _get_node_aabb(node: Node3D, parent_global_transform: Transform3D) -> AABB:
var aabb := AABB()
for mesh in meshes:
aabb = aabb.merge(mesh.mesh.get_mesh().get_aabb())
var pos_ofs := Vector3.ZERO
if not nodes.is_empty():
var ct: int = 0
for node in nodes:
if node.parent == 0:
pos_ofs += node.position
ct += 1
pos_ofs /= maxi(ct, 1)
aabb.position += pos_ofs
var current_global_transform = parent_global_transform * node.transform
if node is MeshInstance3D:
aabb = current_global_transform * node.mesh.get_aabb()

for child in node.get_children():
aabb = aabb.merge(_get_node_aabb(child, current_global_transform))

return aabb

func _generate_size_from_aabb(scene: Node3D) -> AABB:
var aabb := _get_node_aabb(scene, Transform3D.IDENTITY)

# Reorient the AABB so it matches TrenchBroom's coordinate system
var size_prop := AABB()
size_prop.position = Vector3(aabb.position.z, aabb.position.x, aabb.position.y)
size_prop.size = Vector3(aabb.size.z, aabb.size.x, aabb.size.y)

# Scale the size bounds to our scale factor
# Scale factor will need to be set if we decide to auto-generate our bounds
var scale_factor: Vector3 = Vector3.ONE
Expand All @@ -186,7 +185,7 @@ func _generate_size_from_aabb(meshes: Array[GLTFMesh], nodes: Array[GLTFNode]) -
scale_factor *= Vector3(scale_arr[0], scale_arr[1], scale_arr[2])
elif scale_expression.to_float() > 0:
scale_factor *= scale_expression.to_float()

size_prop.position *= scale_factor
size_prop.size *= scale_factor
size_prop.size += size_prop.position
Expand Down