Skip to content

Commit aa6c82d

Browse files
authored
Ambient Occlusion Baker (#61)
1 parent e1507d2 commit aa6c82d

File tree

11 files changed

+816
-19
lines changed

11 files changed

+816
-19
lines changed

native/Cargo.lock

+14-14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

native/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ edition = "2021"
77
crate-type = ["cdylib"]
88

99
[dependencies]
10-
godot = { version = "0.2.2", features = ["experimental-threads", "api-4-3"] }
10+
godot = { version = "0.2.3", features = ["experimental-threads", "api-4-3"] }
1111
godot-rust-script = { git = "https://github.com/titannano/godot-rust-script", rev = "46b151f558370c260fa1e79502637f128ea7bb7f" }
1212
lerp = "0.4.0"
1313
backtrace = "0.3.64"

native/src/editor.rs

+84-2
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,124 @@
1+
mod ao_baker;
12
mod building_imports;
3+
mod gltf;
4+
pub mod ui;
25

6+
use std::num::NonZero;
7+
8+
use ao_baker::AoBaker;
9+
use gltf::GltfImporter;
10+
use godot::builtin::{Dictionary, VariantType};
311
use godot::classes::notify::NodeNotification;
4-
use godot::classes::{EditorPlugin, IEditorPlugin};
5-
use godot::obj::{Base, Gd, WithBaseField};
12+
use godot::classes::{EditorPlugin, GltfDocument, IEditorPlugin, ProjectSettings};
13+
use godot::global::PropertyHint;
14+
use godot::obj::{Base, Gd, NewGd, OnReady, WithBaseField};
615
use godot::register::{godot_api, GodotClass};
716

817
use building_imports::SetupBuildingImports;
918

1019
use crate::engine_callable;
20+
use crate::util::variant_type_default_value;
1121

1222
#[derive(GodotClass)]
1323
#[class(tool, base=EditorPlugin)]
1424
struct EditorExtension {
1525
setup_building_imports: Gd<SetupBuildingImports>,
26+
gltf_importer: Gd<GltfImporter>,
27+
ao_baker: OnReady<Gd<AoBaker>>,
28+
1629
base: Base<EditorPlugin>,
1730
}
1831

32+
const fn new_non_zero(value: u32) -> NonZero<u32> {
33+
NonZero::new(value).unwrap()
34+
}
35+
36+
#[godot_api]
37+
impl EditorExtension {
38+
fn define_project_settings(
39+
settings: &[(&'static str, VariantType, PropertyHint, &'static str)],
40+
project_settings: &mut Gd<ProjectSettings>,
41+
) {
42+
for (name, ty, hint, hint_str) in settings {
43+
Self::define_project_settings_property(name, *ty, *hint, hint_str, project_settings);
44+
}
45+
}
46+
47+
fn define_project_settings_property(
48+
name: &'static str,
49+
ty: VariantType,
50+
hint: PropertyHint,
51+
hint_str: &'static str,
52+
project_settings: &mut Gd<ProjectSettings>,
53+
) {
54+
let default_value = variant_type_default_value(ty);
55+
56+
if !project_settings.has_setting(name) {
57+
project_settings.set_setting(name, &default_value);
58+
}
59+
60+
project_settings.set_initial_value(name, &default_value);
61+
62+
let mut property = Dictionary::new();
63+
64+
property.set("name", name);
65+
property.set("type", ty);
66+
property.set("hint", hint);
67+
property.set("hint_string", hint_str);
68+
69+
project_settings.add_property_info(&property);
70+
}
71+
}
72+
1973
#[godot_api]
2074
impl IEditorPlugin for EditorExtension {
2175
fn init(base: Base<EditorPlugin>) -> Self {
2276
Self {
2377
setup_building_imports: SetupBuildingImports::new(base.to_gd().get_editor_interface()),
78+
gltf_importer: GltfImporter::new_gd(),
79+
ao_baker: OnReady::manual(),
2480
base,
2581
}
2682
}
2783

2884
fn enter_tree(&mut self) {
2985
let building_imports = self.setup_building_imports.clone();
3086

87+
Self::define_project_settings(&AoBaker::SETTINGS, &mut ProjectSettings::singleton());
88+
3189
self.base_mut().add_tool_menu_item(
3290
"Setup Building Imports...",
3391
&engine_callable!(&building_imports, SetupBuildingImports::start),
3492
);
93+
94+
let ao_baker = {
95+
let mut base = self.base_mut();
96+
97+
AoBaker::new(
98+
base.get_editor_interface()
99+
.expect("editor interface should be available after entering the tree"),
100+
base.get_tree()
101+
.expect("SceneTree should be available after entering the tree"),
102+
)
103+
};
104+
105+
self.ao_baker.init(ao_baker);
106+
107+
let callable = &engine_callable!(&self.ao_baker, AoBaker::bake);
108+
109+
self.base_mut()
110+
.add_tool_menu_item("Bake Ambient Occlusion...", callable);
111+
112+
GltfDocument::register_gltf_document_extension(&self.gltf_importer);
35113
}
36114

37115
fn on_notification(&mut self, what: NodeNotification) {
38116
if what == NodeNotification::PREDELETE {
39117
self.setup_building_imports.clone().free();
40118
}
41119
}
120+
121+
fn exit_tree(&mut self) {
122+
GltfDocument::unregister_gltf_document_extension(&self.gltf_importer);
123+
}
42124
}

0 commit comments

Comments
 (0)