Skip to content

Commit b00894e

Browse files
committed
init
0 parents  commit b00894e

File tree

8 files changed

+182
-0
lines changed

8 files changed

+182
-0
lines changed

.editorconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Normalize EOL for all files that Git considers text files.
2+
* text=auto eol=lf

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Godot 4+ specific ignores
2+
.godot/
3+
/android/

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# 🍞 BakeIt!
2+
3+
Simply create a mesh, collisions, occluder and unwrap your csg combiners with one click.

addons/bake_it/bake_it.gd

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
@tool
2+
extends EditorPlugin
3+
4+
const BUTTON_NAME = "BakeIt"
5+
const COMPILED_MESH_NAME = "CompiledMesh"
6+
7+
var button_bake_it: Button
8+
var toolbar_container: HBoxContainer
9+
10+
func find_node_by_name(base_node: Node, name = "Node3DEditor") -> Node:
11+
if base_node.name.contains(name):
12+
return base_node
13+
14+
for child in base_node.get_children():
15+
var result = find_node_by_name(child, name)
16+
if result:
17+
return result
18+
19+
return null
20+
21+
func _enter_tree() -> void:
22+
toolbar_container = find_node_by_name(find_node_by_name(get_editor_interface().get_base_control(), "Node3DEditor"), "HBoxContainer")
23+
if (!toolbar_container):
24+
return
25+
26+
button_bake_it = Button.new()
27+
button_bake_it.text = BUTTON_NAME
28+
button_bake_it.tooltip_text = "Build CSG Meshes, Unwrap Model, Build Occluder"
29+
button_bake_it.pressed.connect(_on_button_pressed)
30+
toolbar_container.add_child(button_bake_it)
31+
32+
func _exit_tree() -> void:
33+
if button_bake_it:
34+
button_bake_it.queue_free()
35+
36+
func _on_button_pressed() -> void:
37+
print_rich("[BakeIt] [color=green]Started - Ensure game is closed when baking![/color]")
38+
var node_root = get_editor_interface().get_edited_scene_root()
39+
40+
var node_csg: CSGCombiner3D
41+
var node_occluder: OccluderInstance3D
42+
43+
for child in node_root.get_children():
44+
if (child is CSGCombiner3D):
45+
node_csg = child
46+
continue
47+
48+
if (child is OccluderInstance3D):
49+
node_occluder = child
50+
continue
51+
52+
if (child.name.contains(COMPILED_MESH_NAME)): \
53+
child.queue_free()
54+
55+
if (!node_csg):
56+
print_rich("[BakeIt] [color=red]Failed to find CSG Combiner for Baking[/color]")
57+
return
58+
59+
if (node_occluder):
60+
node_occluder.queue_free()
61+
print_rich("[BakeIt] [color=yellow]Removed old NodeOccluder3D[/color]")
62+
63+
if (node_csg.use_collision):
64+
node_csg.use_collision = false
65+
print_rich("[BakeIt] [color=yellow]Turned off Collision for CSG Mesh, not necessary.[/color]")
66+
67+
var meshes = node_csg.bake_static_mesh()
68+
var instance = MeshInstance3D.new()
69+
node_root.add_child(instance)
70+
instance.mesh = meshes
71+
72+
var old_mesh = instance.mesh
73+
var new_mesh = ArrayMesh.new()
74+
for surface_id in range(old_mesh.get_surface_count()):
75+
new_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, old_mesh.surface_get_arrays(surface_id))
76+
var old_mat = old_mesh.surface_get_material(surface_id)
77+
new_mesh.surface_set_material(surface_id, old_mat)
78+
new_mesh.lightmap_unwrap(instance.global_transform, 0.4)
79+
80+
instance.create_trimesh_collision()
81+
instance.mesh = new_mesh
82+
instance.owner = node_root
83+
instance.name = COMPILED_MESH_NAME
84+
85+
var static_body = StaticBody3D.new()
86+
node_root.add_child(static_body)
87+
static_body.owner = node_root
88+
static_body.name = "StaticBody3D"
89+
static_body.reparent(instance)
90+
static_body.collision_layer = 3
91+
92+
var collision_shape = CollisionShape3D.new()
93+
collision_shape.shape = instance.mesh.create_trimesh_shape()
94+
collision_shape.name = "CollisionShape3D"
95+
96+
node_root.add_child(collision_shape)
97+
collision_shape.owner = node_root
98+
collision_shape.reparent(static_body)
99+
100+
get_editor_interface().mark_scene_as_unsaved()
101+
102+
node_occluder = OccluderInstance3D.new()
103+
node_root.add_child(node_occluder)
104+
node_occluder.owner = node_root
105+
node_occluder.name = "OccluderInstance3D"
106+
107+
if (!node_occluder):
108+
print_rich("[BakeIt] [color=red]Failed to find Occluder for BakeIt[/color]")
109+
return
110+
111+
var occluder = create_occluder_from_mesh(instance.mesh)
112+
var occ_path = node_root.scene_file_path.replace(".tscn", ".occ")
113+
if (FileAccess.file_exists(occ_path)):
114+
DirAccess.remove_absolute(occ_path)
115+
116+
var result = ResourceSaver.save(occluder, occ_path)
117+
if result == OK:
118+
print_rich("[BakeIt] [color=green]Occluder saved at: [/color][color=yellow]" + occ_path + "[/color]")
119+
node_occluder.occluder = load(occ_path)
120+
else:
121+
print_rich("[BakeIt] [color=red]Failed to save occluder![/color]")
122+
123+
get_editor_interface().mark_scene_as_unsaved()
124+
print_rich("[BakeIt] [color=green]Complete[/color]")
125+
126+
func create_occluder_from_mesh(mesh: Mesh) -> ArrayOccluder3D:
127+
var occluder = ArrayOccluder3D.new()
128+
var vertices = PackedVector3Array()
129+
var indices = PackedInt32Array()
130+
var vertex_offset = 0
131+
132+
for surface_index in range(mesh.get_surface_count()):
133+
var arrays = mesh.surface_get_arrays(surface_index)
134+
var surface_vertices = arrays[Mesh.ARRAY_VERTEX]
135+
var surface_indices = arrays[Mesh.ARRAY_INDEX]
136+
137+
vertices.append_array(surface_vertices)
138+
for index in surface_indices:
139+
indices.append(index + vertex_offset)
140+
141+
vertex_offset += surface_vertices.size()
142+
143+
occluder.set_arrays(vertices, indices)
144+
return occluder

addons/bake_it/bake_it.gd.uid

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://dm4v2rb33w3co

addons/bake_it/plugin.cfg

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[plugin]
2+
3+
name="BakeIt"
4+
description="Bake CSG's and create Collisions with one click!"
5+
author="Vyntrix"
6+
version="1.0"
7+
script="bake_it.gd"

project.godot

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
; Engine configuration file.
2+
; It's best edited using the editor UI and not directly,
3+
; since the parameters that go here are not all obvious.
4+
;
5+
; Format:
6+
; [section] ; section goes between []
7+
; param=value ; assign values to parameters
8+
9+
config_version=5
10+
11+
[application]
12+
13+
config/name="BakeIt!"
14+
config/features=PackedStringArray("4.4", "Forward Plus")
15+
16+
[editor_plugins]
17+
18+
enabled=PackedStringArray("res://addons/bake_it/plugin.cfg")

0 commit comments

Comments
 (0)