2
0
luboslenco 1 жил өмнө
parent
commit
4057660b61
61 өөрчлөгдсөн 1401 нэмэгдсэн , 1397 устгасан
  1. 24 24
      armorforge/Assets/plugins/hello_world.js
  2. 61 47
      armorlab/Assets/plugins/dev/texture_breakdown.js
  3. 2 2
      armorlab/Sources/make_material.ts
  4. 2 2
      armorlab/Sources/nodes/brush_output_node.ts
  5. 5 8
      armorlab/Sources/nodes/image_texture_node.ts
  6. 35 43
      armorlab/Sources/nodes/inpaint_node.ts
  7. 120 121
      armorlab/Sources/nodes/photo_to_pbr_node.ts
  8. 5 5
      armorlab/Sources/nodes/rgb_node.ts
  9. 95 93
      armorlab/Sources/nodes/text_to_photo_node.ts
  10. 19 18
      armorlab/Sources/nodes/tiling_node.ts
  11. 22 28
      armorlab/Sources/nodes/upscale_node.ts
  12. 39 43
      armorlab/Sources/nodes/variance_node.ts
  13. 64 51
      armorpaint/Assets/plugins/dev/converter.js
  14. 20 20
      armorpaint/Assets/plugins/hello_node.js
  15. 14 14
      armorpaint/Assets/plugins/hello_node_brush.js
  16. 24 24
      armorpaint/Assets/plugins/hello_world.js
  17. 35 33
      armorpaint/Assets/plugins/import_fbx.js
  18. 31 30
      armorpaint/Assets/plugins/import_gltf_glb.js
  19. 61 61
      armorpaint/Assets/plugins/import_stl.js
  20. 21 19
      armorpaint/Assets/plugins/import_svg.js
  21. 32 29
      armorpaint/Assets/plugins/import_usdc.js
  22. 60 46
      armorpaint/Assets/plugins/texture_breakdown.js
  23. 29 29
      armorpaint/Assets/plugins/uv_unwrap.js
  24. 6 6
      armorpaint/Assets/plugins/viewport_celshade.js
  25. 3 1
      armorpaint/Sources/make_material.ts
  26. 7 14
      armorpaint/Sources/nodes/brush_output_node.ts
  27. 4 8
      armorpaint/Sources/nodes/input_node.ts
  28. 5 5
      armorpaint/Sources/nodes/tex_image_node.ts
  29. 11 8
      armorpaint/Sources/render_path_paint.ts
  30. 24 24
      armorsculpt/Assets/plugins/hello_world.js
  31. 64 65
      armorsculpt/Sources/import_mesh.ts
  32. 4 4
      armorsculpt/Sources/make_material.ts
  33. 5 10
      armorsculpt/Sources/nodes/brush_output_node.ts
  34. 10 8
      base/Assets/plugins/autosave.js
  35. 9 10
      base/Assets/plugins/import_tiff.js
  36. 14 15
      base/Assets/plugins/import_txt.js
  37. 50 48
      base/Sources/base.ts
  38. 2 2
      base/Sources/context.ts
  39. 2 2
      base/Sources/file.ts
  40. 4 4
      base/Sources/history.ts
  41. 14 16
      base/Sources/import_mesh.ts
  42. 22 24
      base/Sources/import_texture.ts
  43. 11 11
      base/Sources/logic_node.ts
  44. 1 1
      base/Sources/main.ts
  45. 3 3
      base/Sources/nodes/boolean_node.ts
  46. 6 7
      base/Sources/nodes/color_node.ts
  47. 6 7
      base/Sources/nodes/float_node.ts
  48. 3 3
      base/Sources/nodes/integer_node.ts
  49. 114 116
      base/Sources/nodes/math_node.ts
  50. 2 2
      base/Sources/nodes/null_node.ts
  51. 4 6
      base/Sources/nodes/random_node.ts
  52. 11 12
      base/Sources/nodes/separate_vector_node.ts
  53. 3 3
      base/Sources/nodes/string_node.ts
  54. 4 4
      base/Sources/nodes/time_node.ts
  55. 122 124
      base/Sources/nodes/vector_math_node.ts
  56. 23 29
      base/Sources/nodes/vector_node.ts
  57. 2 2
      base/Sources/path.ts
  58. 1 1
      base/Sources/tab_fonts.ts
  59. 1 1
      base/Sources/ui_base.ts
  60. 1 1
      base/Sources/ui_view2d.ts
  61. 3 0
      base/project.js

+ 24 - 24
armorforge/Assets/plugins/hello_world.js

@@ -1,31 +1,31 @@
 
-let plugin = new arm.Plugin();
+let plugin = plugin_create();
 
-let h1 = new zui.Handle();
-let h2 = new zui.Handle();
-let h3 = new zui.Handle();
-let h4 = new zui.Handle();
-let h5 = new zui.Handle();
-let h6 = new zui.Handle();
-let h7 = new zui.Handle();
+let h1 = zui_handle_create();
+let h2 = zui_handle_create();
+let h3 = zui_handle_create();
+let h4 = zui_handle_create();
+let h5 = zui_handle_create();
+let h6 = zui_handle_create();
+let h7 = zui_handle_create();
 
-plugin.drawUI = function(ui) {
-	if (Zui.panel(h1, "My Plugin")) {
-		Zui.text("Label");
-		Zui.textInput(h7, "Text Input");
-		if (Zui.button("Button")) {
+plugin.draw_ui = function(ui) {
+	if (zui_panel(h1, "My Plugin")) {
+		zui_text("Label");
+		zui_text_input(h7, "Text Input");
+		if (zui_button("Button")) {
 			console.error("Hello");
 		}
-		Zui.row([1/2, 1/2]);
-		Zui.button("Button A");
-		Zui.button("Button B");
-		Zui.combo(h5, ["Item 1", "Item 2"], "Combo");
-		Zui.row([1/2, 1/2]);
-		Zui.slider(h2, "Slider", 0, 1, true);
-		Zui.slider(h3, "Slider", 0, 1, true);
-		Zui.check(h4, "Check");
-		Zui.radio(h6, 0, "Radio 1");
-		Zui.radio(h6, 1, "Radio 2");
-		Zui.radio(h6, 2, "Radio 3");
+		zui_row([1/2, 1/2]);
+		zui_button("Button A");
+		zui_button("Button B");
+		zui_combo(h5, ["Item 1", "Item 2"], "Combo");
+		zui_row([1/2, 1/2]);
+		zui_slider(h2, "Slider", 0, 1, true);
+		zui_slider(h3, "Slider", 0, 1, true);
+		zui_check(h4, "Check");
+		zui_radio(h6, 0, "Radio 1");
+		zui_radio(h6, 1, "Radio 2");
+		zui_radio(h6, 2, "Radio 3");
 	}
 }

+ 61 - 47
armorlab/Assets/plugins/dev/texture_breakdown.js

@@ -1,72 +1,86 @@
 
-let plugin = new arm.Plugin();
-let h1 = new zui.Handle();
-let h2 = new zui.Handle();
+let plugin = plugin_create();
+let h1 = zui_handle_create();
+let h2 = zui_handle_create();
 
 let slots = ["base", "occ", "rough", "nor"];
 let breakdown = null;
 
-plugin.drawUI = function(ui) {
-	if (Zui.panel(h1, "Texture Breakdown")) {
+plugin.draw_ui = function(ui) {
+	if (zui_panel(h1, "Texture Breakdown")) {
 
-		ui.g.end();
-		drawBreakdown();
-		ui.g.begin(false);
+		g2_end();
+		draw_breakdown();
+		g2_begin(ui);
 
-		// Zui.row([1 / 4]);
-		// Zui.combo(h2, ["Material", "Viewport"], "Type");
+		// zui_row([1 / 4]);
+		// zui_combo(h2, ["Material", "Viewport"], "Type");
 
-		Zui.image(breakdown);
-		if (ui.isHovered && ui.inputReleasedR) {
-			let x = ui.inputX - ui._windowX;
-			let w = ui._windowW / slots.length;
+		zui_image(breakdown);
+		if (ui.is_hovered && ui.input_released_r) {
+			let x = ui.input_x - ui._window_x;
+			let w = ui._window_w / slots.length;
 			let i = (x / w) | 0;
-			arm.UIMenu.draw(function(ui) {
-				Zui.text(slots[i], 2, ui.t.HIGHLIGHT_COL);
-				if (Zui.button("Delete", 0)) {
+			ui_menu_draw(function(ui) {
+				zui_text(slots[i], 2, ui.t.HIGHLIGHT_COL);
+				if (zui_button("Delete", 0)) {
 					slots.splice(i, 1);
 				}
 			}, 2);
 		}
 
-		Zui.row([1 / 4, 1 / 4]);
+		zui_row([1 / 4, 1 / 4]);
 
-		if (Zui.button("Add")) {
-			arm.UIMenu.draw(function(ui) {
-				Zui.text("Channel", 2, ui.t.HIGHLIGHT_COL);
-				if (Zui.button("Base Color", 0)) { slots.push("base"); }
-				if (Zui.button("Occlusion", 0)) { slots.push("occ"); }
-				if (Zui.button("Roughness", 0)) { slots.push("rough"); }
-				if (Zui.button("Metallic", 0)) { slots.push("metal"); }
-				if (Zui.button("Normal Map", 0)) { slots.push("nor"); }
+		if (zui_button("Add")) {
+			ui_menu_draw(function(ui) {
+				zui_text("Channel", 2, ui.t.HIGHLIGHT_COL);
+				if (zui_button("Base Color", 0)) {
+					slots.push("base");
+				}
+				if (zui_button("Occlusion", 0)) {
+					slots.push("occ");
+				}
+				if (zui_button("Roughness", 0)) {
+					slots.push("rough");
+				}
+				if (zui_button("Metallic", 0)) {
+					slots.push("metal");
+				}
+				if (zui_button("Normal Map", 0)) {
+					slots.push("nor");
+				}
 			}, 6);
 		}
 
-		if (Zui.button("Export")) {
-			arm.UIFiles.show("png", true, false, function(path) {
-				Base.notifyOnNextFrame(function() {
-					var f = arm.UIFiles.filename;
-					if (f === "") f = "untitled";
-					if (!f.endsWith(".png")) f += ".png";
-					Krom.writePng(path + arm.Path.sep + f, breakdown.getPixels(), breakdown.get_width(), breakdown.get_height(), 2);
+		if (zui_button("Export")) {
+			ui_files_show("png", true, false, function(path) {
+				base_notify_on_next_frame(function() {
+					var f = ui_files_filename;
+					if (f === "") {
+						f = "untitled";
+					}
+					if (!f.endsWith(".png")) {
+						f += ".png";
+					}
+					krom_write_png(path + path_sep + f, image_get_pixels(breakdown), breakdown.width, breakdown.height, 2);
 				});
 			});
 		}
 	}
 }
 
-function drawBreakdown(type) {
+function draw_breakdown(type) {
 	if (breakdown === null) {
-		breakdown = core.Image.createRenderTarget(4096, 4096);
+		breakdown = image_create_render_target(4096, 4096);
 	}
-	let g2 = breakdown.get_g2();
-	g2.begin(true, 0xff000000);
-	g2.disableScissor();
+	g2_begin(breakdown);
+	g2_clear(0xff000000);
+	g2_disable_scissor();
 
 	if (h2.position === 0) { // Material
-		var lay = arm.BrushOutputNode.inst;
+		var lay = brush_output_node_inst;
 		for (let i = 0; i < slots.length; ++i) {
-			g2.set_pipeline(arm.UIView2D.pipe);
+			g2_set_pipeline(ui_view2d_pipe);
 			let image = lay.texpaint;
 			let channel = 0;
 			if (slots[i] === "occ") {
@@ -85,16 +99,16 @@ function drawBreakdown(type) {
 				image = lay.texpaint_nor;
 				channel = 5;
 			}
-			breakdown.get_g4().setInt(arm.UIView2D.channelLocation, channel);
-			var step_source = image.get_width() / slots.length;
-			var step_dest = breakdown.get_width() / slots.length;
-			g2.drawScaledSubImage(image, step_source * i, 0, step_source, image.get_height(), step_dest * i, 0, step_dest, breakdown.get_height());
-			g2.end(); // Flush
-			g2.begin(false);
+			g4_set_int(ui_view2d_channel_location, channel);
+			var step_source = image.width / slots.length;
+			var step_dest = breakdown.width / slots.length;
+			g2_draw_scaled_sub_image(image, step_source * i, 0, step_source, image.height, step_dest * i, 0, step_dest, breakdown.height);
+			g2_end(); // Flush
+			g2_begin();
 		}
 	}
 	else { // Viewport
 	}
 
-	g2.end();
+	g2_end();
 }

+ 2 - 2
armorlab/Sources/make_material.ts

@@ -123,7 +123,7 @@ function make_material_voxelgi_half_extents(): string {
 }
 
 function make_material_delete_context(c: shader_context_t) {
-	base_notify_on_next_frame(function () { // Ensure pipeline is no longer in use
+	base_notify_on_next_frame(function (c: shader_context_t) { // Ensure pipeline is no longer in use
 		shader_context_delete(c);
-	});
+	}, c);
 }

+ 2 - 2
armorlab/Sources/nodes/brush_output_node.ts

@@ -67,6 +67,6 @@ function brush_output_node_create(arg: any): brush_output_node_t {
 	return n;
 }
 
-function brush_output_node_get_as_image(self: brush_output_node_t, from: i32, done: (img: image_t)=>void) {
-	self.base.inputs[from].get_as_image(done);
+function brush_output_node_get_as_image(self: brush_output_node_t, from: i32): image_t {
+	return self.base.inputs[from].get_as_image();
 }

+ 5 - 8
armorlab/Sources/nodes/image_texture_node.ts

@@ -13,17 +13,14 @@ function image_texture_node_create(arg: any): image_texture_node_t {
 	return n;
 }
 
-function image_texture_node_get_as_image(self: image_texture_node_t, from: i32, done: (img: image_t)=>void) {
+function image_texture_node_get_as_image(self: image_texture_node_t, from: i32): image_t {
 	let index = array_index_of(project_asset_names, self.file);
 	let asset = project_assets[index];
-	done(project_get_image(asset));
+	return project_get_image(asset);
 }
 
 function image_texture_node_get_cached_image(self: image_texture_node_t): image_t {
-	let image: image_t;
-	self.base.get_as_image(self, 0, function (img: image_t) {
-		image = img;
-	});
+	let image: image_t = self.base.get_as_image(self, 0);
 	return image;
 }
 
@@ -41,7 +38,7 @@ let image_texture_node_def: zui_node_t = {
 			name: _tr("Vector"),
 			type: "VECTOR",
 			color: 0xff6363c7,
-			default_value: new f32_array_t([0.0, 0.0, 0.0])
+			default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 		}
 	],
 	outputs: [
@@ -51,7 +48,7 @@ let image_texture_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 		},
 		{
 			id: 0,

+ 35 - 43
armorlab/Sources/nodes/inpaint_node.ts

@@ -60,38 +60,35 @@ function inpaint_node_buttons(ui: zui_t, nodes: zui_nodes_t, node: zui_node_t) {
 	}
 }
 
-function inpaint_node_get_as_image(self: inpaint_node_t, from: i32, done: (img: image_t)=>void) {
-	self.base.inputs[0].get_as_image(function (source: image_t) {
+function inpaint_node_get_as_image(self: inpaint_node_t, from: i32): image_t {
+	let source: image_t = self.base.inputs[0].get_as_image();
+	console_progress(tr("Processing") + " - " + tr("Inpaint"));
+	krom_g4_swap_buffers();
 
-		console_progress(tr("Processing") + " - " + tr("Inpaint"));
-		base_notify_on_next_frame(function () {
-			g2_begin(inpaint_node_image);
-			g2_draw_scaled_image(source, 0, 0, config_get_texture_res_x(), config_get_texture_res_y());
-			g2_end();
+	g2_begin(inpaint_node_image);
+	g2_draw_scaled_image(source, 0, 0, config_get_texture_res_x(), config_get_texture_res_y());
+	g2_end();
 
-			inpaint_node_auto ? inpaint_node_texsynth_inpaint(inpaint_node_image, false, inpaint_node_mask, done) : inpaint_node_inpaint_node_sd_inpaint(inpaint_node_image, inpaint_node_mask, done);
-		});
-	});
+	return inpaint_node_auto ? inpaint_node_texsynth_inpaint(inpaint_node_image, false, inpaint_node_mask) : inpaint_node_inpaint_node_sd_inpaint(inpaint_node_image, inpaint_node_mask);
 }
 
 function inpaint_node_get_cached_image(self: inpaint_node_t): image_t {
 	base_notify_on_next_frame(function () {
-		self.base.inputs[0].get_as_image(function (source: image_t) {
-			if (base_pipe_copy == null) {
-				base_make_pipe();
-			}
-			if (const_data_screen_aligned_vb == null) {
-				const_data_create_screen_aligned_data();
-			}
-			g4_begin(inpaint_node_image);
-			g4_set_pipeline(base_pipe_inpaint_preview);
-			g4_set_tex(base_tex0_inpaint_preview, source);
-			g4_set_tex(base_texa_inpaint_preview, inpaint_node_mask);
-			g4_set_vertex_buffer(const_data_screen_aligned_vb);
-			g4_set_index_buffer(const_data_screen_aligned_ib);
-			g4_draw();
-			g4_end();
-		});
+		let source: image_t = self.base.inputs[0].get_as_image();
+		if (base_pipe_copy == null) {
+			base_make_pipe();
+		}
+		if (const_data_screen_aligned_vb == null) {
+			const_data_create_screen_aligned_data();
+		}
+		g4_begin(inpaint_node_image);
+		g4_set_pipeline(base_pipe_inpaint_preview);
+		g4_set_tex(base_tex0_inpaint_preview, source);
+		g4_set_tex(base_texa_inpaint_preview, inpaint_node_mask);
+		g4_set_vertex_buffer(const_data_screen_aligned_vb);
+		g4_set_index_buffer(const_data_screen_aligned_ib);
+		g4_draw();
+		g4_end();
 	});
 	return inpaint_node_image;
 }
@@ -100,7 +97,7 @@ function inpaint_node_get_target(): image_t {
 	return inpaint_node_mask;
 }
 
-function inpaint_node_texsynth_inpaint(image: image_t, tiling: bool, mask: image_t, done: (img: image_t)=>void) {
+function inpaint_node_texsynth_inpaint(image: image_t, tiling: bool, mask: image_t): image_t {
 	let w = config_get_texture_res_x();
 	let h = config_get_texture_res_y();
 
@@ -110,14 +107,14 @@ function inpaint_node_texsynth_inpaint(image: image_t, tiling: bool, mask: image
 	Krom_texsynth.inpaint(w, h, bytes_out, bytes_img, bytes_mask, tiling);
 
 	inpaint_node_result = image_from_bytes(bytes_out, w, h);
-	done(inpaint_node_result);
+	return inpaint_node_result;
 }
 
-function inpaint_node_sd_inpaint(image: image_t, mask: image_t, done: (img: image_t)=>void) {
+function inpaint_node_sd_inpaint(image: image_t, mask: image_t): image_t {
 	inpaint_node_init();
 
 	let bytes_img = image_get_pixels(mask);
-	let u8 = new u8_array_t(bytes_img);
+	let u8 = u8_array_create_from_buffer(bytes_img);
 	let f32mask = f32_array_create(4 * 64 * 64);
 
 	let vae_encoder_blob: buffer_t = data_get_blob("models/sd_vae_encoder.quant.onnx");
@@ -147,7 +144,7 @@ function inpaint_node_sd_inpaint(image: image_t, mask: image_t, done: (img: imag
 			g2_end();
 
 			bytes_img = image_get_pixels(inpaint_node_temp);
-			let u8a = new u8_array_t(bytes_img);
+			let u8a = u8_array_create_from_buffer(bytes_img);
 			let f32a = f32_array_create(3 * 512 * 512);
 			for (let i: i32 = 0; i < (512 * 512); ++i) {
 				f32a[i                ] = (u8a[i * 4    ] / 255.0) * 2.0 - 1.0;
@@ -156,7 +153,7 @@ function inpaint_node_sd_inpaint(image: image_t, mask: image_t, done: (img: imag
 			}
 
 			let latents_buf = krom_ml_inference(vae_encoder_blob, [f32a.buffer], [[1, 3, 512, 512]], [1, 4, 64, 64], config_raw.gpu_inference);
-			let latents = new f32_array_t(latents_buf);
+			let latents = f32_array_create_from_buffer(latents_buf);
 			for (let i: i32 = 0; i < latents.length; ++i) {
 				latents[i] = 0.18215 * latents[i];
 			}
@@ -167,8 +164,8 @@ function inpaint_node_sd_inpaint(image: image_t, mask: image_t, done: (img: imag
 
 			let num_inference_steps = 50;
 			let init_timestep = math_floor(num_inference_steps * inpaint_node_strength);
-			let timestep = TextToPhotoNode.timesteps[num_inference_steps - init_timestep];
-			let alphas_cumprod = TextToPhotoNode.alphas_cumprod;
+			let timestep = text_to_photo_node.timesteps[num_inference_steps - init_timestep];
+			let alphas_cumprod = text_to_photo_node.alphas_cumprod;
 			let sqrt_alpha_prod = math_pow(alphas_cumprod[timestep], 0.5);
 			let sqrt_one_minus_alpha_prod = math_pow(1.0 - alphas_cumprod[timestep], 0.5);
 			for (let i: i32 = 0; i < latents.length; ++i) {
@@ -177,13 +174,8 @@ function inpaint_node_sd_inpaint(image: image_t, mask: image_t, done: (img: imag
 
 			let start = num_inference_steps - init_timestep;
 
-			text_to_photo_node_stable_diffusion(inpaint_node_prompt, function (img: image_t) {
-				// result.g2_begin();
-				// result.g2_draw_image(img, x * 512, y * 512);
-				// result.g2_end();
-				inpaint_node_result = img;
-				done(img);
-			}, latents, start, true, f32mask, latents_orig);
+			inpaint_node_result = text_to_photo_node_stable_diffusion(inpaint_node_prompt, latents, start, true, f32mask, latents_orig);
+			return inpaint_node_result;
 		// }
 	// }
 }
@@ -202,7 +194,7 @@ let inpaint_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([1.0, 1.0, 1.0, 1.0])
+			default_value: f32_array_create_xyzw(1.0, 1.0, 1.0, 1.0)
 		}
 	],
 	outputs: [
@@ -212,7 +204,7 @@ let inpaint_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 		}
 	],
 	buttons: [

+ 120 - 121
armorlab/Sources/nodes/photo_to_pbr_node.ts

@@ -35,141 +35,140 @@ function photo_to_pbr_node_init() {
 	}
 }
 
-function photo_to_pbr_node_get_as_image(self: photo_to_pbr_node_t, from: i32, done: (img: image_t)=>void) {
-	let get_source = function (done: (img: image_t)=>void) {
+function photo_to_pbr_node_get_as_image(self: photo_to_pbr_node_t, from: i32): image_t {
+	let get_source = function (): image_t {
 		if (photo_to_pbr_node_cached_source != null) {
-			done(photo_to_pbr_node_cached_source);
+			return photo_to_pbr_node_cached_source;
 		}
 		else {
-			self.base.inputs[0].get_as_image(done);
+			return self.base.inputs[0].get_as_image();
 		}
 	}
 
-	get_source(function (source: image_t) {
-		photo_to_pbr_node_cached_source = source;
-
-		console_progress(tr("Processing") + " - " + tr("Photo to PBR"));
-		base_notify_on_next_frame(function () {
-			let tile_floats: f32_array_t[] = [];
-			let tiles_x = math_floor(config_get_texture_res_x() / photo_to_pbr_node_tile_w);
-			let tiles_y = math_floor(config_get_texture_res_y() / photo_to_pbr_node_tile_w);
-			let num_tiles = tiles_x * tiles_y;
-			for (let i: i32 = 0; i < num_tiles; ++i) {
-				let x = i % tiles_x;
-				let y = math_floor(i / tiles_x);
-
-				g2_begin(photo_to_pbr_node_temp);
-				g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w, -config_get_texture_res_x(), config_get_texture_res_y());
-				g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w, config_get_texture_res_x(), -config_get_texture_res_y());
-				g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w, -config_get_texture_res_x(), -config_get_texture_res_y());
-				g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w + photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w + photo_to_pbr_node_tile_w, config_get_texture_res_x(), config_get_texture_res_y());
-				g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w + photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w + photo_to_pbr_node_tile_w, -config_get_texture_res_x(), config_get_texture_res_y());
-				g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w + photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w + photo_to_pbr_node_tile_w, config_get_texture_res_x(), -config_get_texture_res_y());
-				g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w, config_get_texture_res_x(), config_get_texture_res_y());
-				g2_end();
-
-				let bytes_img = image_get_pixels(photo_to_pbr_node_temp);
-				let u8a = new u8_array_t(bytes_img);
-				let f32a = f32_array_create(3 * photo_to_pbr_node_tile_with_border_w * photo_to_pbr_node_tile_with_border_w);
-				for (let i: i32 = 0; i < (photo_to_pbr_node_tile_with_border_w * photo_to_pbr_node_tile_with_border_w); ++i) {
-					f32a[i                                        ] = (u8a[i * 4    ] / 255 - 0.5) / 0.5;
-					f32a[i + photo_to_pbr_node_tile_with_border_w * photo_to_pbr_node_tile_with_border_w    ] = (u8a[i * 4 + 1] / 255 - 0.5) / 0.5;
-					f32a[i + photo_to_pbr_node_tile_with_border_w * photo_to_pbr_node_tile_with_border_w * 2] = (u8a[i * 4 + 2] / 255 - 0.5) / 0.5;
-				}
+	let source: image_t = get_source();
+	photo_to_pbr_node_cached_source = source;
+
+	console_progress(tr("Processing") + " - " + tr("Photo to PBR"));
+	krom_g4_swap_buffers();
+
+	let tile_floats: f32_array_t[] = [];
+	let tiles_x = math_floor(config_get_texture_res_x() / photo_to_pbr_node_tile_w);
+	let tiles_y = math_floor(config_get_texture_res_y() / photo_to_pbr_node_tile_w);
+	let num_tiles = tiles_x * tiles_y;
+	for (let i: i32 = 0; i < num_tiles; ++i) {
+		let x = i % tiles_x;
+		let y = math_floor(i / tiles_x);
+
+		g2_begin(photo_to_pbr_node_temp);
+		g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w, -config_get_texture_res_x(), config_get_texture_res_y());
+		g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w, config_get_texture_res_x(), -config_get_texture_res_y());
+		g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w, -config_get_texture_res_x(), -config_get_texture_res_y());
+		g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w + photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w + photo_to_pbr_node_tile_w, config_get_texture_res_x(), config_get_texture_res_y());
+		g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w + photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w + photo_to_pbr_node_tile_w, -config_get_texture_res_x(), config_get_texture_res_y());
+		g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w + photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w + photo_to_pbr_node_tile_w, config_get_texture_res_x(), -config_get_texture_res_y());
+		g2_draw_scaled_image(source, photo_to_pbr_node_border_w - x * photo_to_pbr_node_tile_w, photo_to_pbr_node_border_w - y * photo_to_pbr_node_tile_w, config_get_texture_res_x(), config_get_texture_res_y());
+		g2_end();
+
+		let bytes_img = image_get_pixels(photo_to_pbr_node_temp);
+		let u8a = u8_array_create_from_buffer(bytes_img);
+		let f32a = f32_array_create(3 * photo_to_pbr_node_tile_with_border_w * photo_to_pbr_node_tile_with_border_w);
+		for (let i: i32 = 0; i < (photo_to_pbr_node_tile_with_border_w * photo_to_pbr_node_tile_with_border_w); ++i) {
+			f32a[i] = (u8a[i * 4] / 255 - 0.5) / 0.5;
+			f32a[i + photo_to_pbr_node_tile_with_border_w * photo_to_pbr_node_tile_with_border_w    ] = (u8a[i * 4 + 1] / 255 - 0.5) / 0.5;
+			f32a[i + photo_to_pbr_node_tile_with_border_w * photo_to_pbr_node_tile_with_border_w * 2] = (u8a[i * 4 + 2] / 255 - 0.5) / 0.5;
+		}
 
-				let model_blob: buffer_t = data_get_blob("models/photo_to_" + photo_to_pbr_node_model_names[from] + ".quant.onnx");
-				let buf = krom_ml_inference(model_blob, [f32a.buffer], null, null, config_raw.gpu_inference);
-				let ar = new f32_array_t(buf);
-				u8a = u8_array_create(4 * photo_to_pbr_node_tile_w * photo_to_pbr_node_tile_w);
-				let offset_g = (from == channel_type_t.BASE_COLOR || from == channel_type_t.NORMAL_MAP) ? photo_to_pbr_node_tile_with_border_w * photo_to_pbr_node_tile_with_border_w : 0;
-				let offset_b = (from == channel_type_t.BASE_COLOR || from == channel_type_t.NORMAL_MAP) ? photo_to_pbr_node_tile_with_border_w * photo_to_pbr_node_tile_with_border_w * 2 : 0;
-				for (let i: i32 = 0; i < (photo_to_pbr_node_tile_w * photo_to_pbr_node_tile_w); ++i) {
-					let x = photo_to_pbr_node_border_w + i % photo_to_pbr_node_tile_w;
-					let y = photo_to_pbr_node_border_w + math_floor(i / photo_to_pbr_node_tile_w);
-					u8a[i * 4    ] = math_floor((ar[y * photo_to_pbr_node_tile_with_border_w + x          ] * 0.5 + 0.5) * 255);
-					u8a[i * 4 + 1] = math_floor((ar[y * photo_to_pbr_node_tile_with_border_w + x + offset_g] * 0.5 + 0.5) * 255);
-					u8a[i * 4 + 2] = math_floor((ar[y * photo_to_pbr_node_tile_with_border_w + x + offset_b] * 0.5 + 0.5) * 255);
-					u8a[i * 4 + 3] = 255;
-				}
-				array_push(tile_floats, ar);
-
-				// Use border pixels to blend seams
-				if (i > 0) {
-					if (x > 0) {
-						let ar = tile_floats[i - 1];
-						for (let yy: i32 = 0; yy < photo_to_pbr_node_tile_w; ++yy) {
-							for (let xx: i32 = 0; xx < photo_to_pbr_node_border_w; ++xx) {
-								let i = yy * photo_to_pbr_node_tile_w + xx;
-								let a = u8a[i * 4];
-								let b = u8a[i * 4 + 1];
-								let c = u8a[i * 4 + 2];
-
-								let aa = math_floor((ar[(photo_to_pbr_node_border_w + yy) * photo_to_pbr_node_tile_with_border_w + photo_to_pbr_node_border_w + photo_to_pbr_node_tile_w + xx          ] * 0.5 + 0.5) * 255);
-								let bb = math_floor((ar[(photo_to_pbr_node_border_w + yy) * photo_to_pbr_node_tile_with_border_w + photo_to_pbr_node_border_w + photo_to_pbr_node_tile_w + xx + offset_g] * 0.5 + 0.5) * 255);
-								let cc = math_floor((ar[(photo_to_pbr_node_border_w + yy) * photo_to_pbr_node_tile_with_border_w + photo_to_pbr_node_border_w + photo_to_pbr_node_tile_w + xx + offset_b] * 0.5 + 0.5) * 255);
-
-								let f = xx / photo_to_pbr_node_border_w;
-								let invf = 1.0 - f;
-								a = math_floor(a * f + aa * invf);
-								b = math_floor(b * f + bb * invf);
-								c = math_floor(c * f + cc * invf);
-
-								u8a[i * 4    ] = a;
-								u8a[i * 4 + 1] = b;
-								u8a[i * 4 + 2] = c;
-							}
-						}
-					}
-					if (y > 0) {
-						let ar = tile_floats[i - tiles_x];
-						for (let xx: i32 = 0; xx < photo_to_pbr_node_tile_w; ++xx) {
-							for (let yy: i32 = 0; yy < photo_to_pbr_node_border_w; ++yy) {
-								let i = yy * photo_to_pbr_node_tile_w + xx;
-								let a = u8a[i * 4];
-								let b = u8a[i * 4 + 1];
-								let c = u8a[i * 4 + 2];
-
-								let aa = math_floor((ar[(photo_to_pbr_node_border_w + photo_to_pbr_node_tile_w + yy) * photo_to_pbr_node_tile_with_border_w + photo_to_pbr_node_border_w + xx          ] * 0.5 + 0.5) * 255);
-								let bb = math_floor((ar[(photo_to_pbr_node_border_w + photo_to_pbr_node_tile_w + yy) * photo_to_pbr_node_tile_with_border_w + photo_to_pbr_node_border_w + xx + offset_g] * 0.5 + 0.5) * 255);
-								let cc = math_floor((ar[(photo_to_pbr_node_border_w + photo_to_pbr_node_tile_w + yy) * photo_to_pbr_node_tile_with_border_w + photo_to_pbr_node_border_w + xx + offset_b] * 0.5 + 0.5) * 255);
-
-								let f = yy / photo_to_pbr_node_border_w;
-								let invf = 1.0 - f;
-								a = math_floor(a * f + aa * invf);
-								b = math_floor(b * f + bb * invf);
-								c = math_floor(c * f + cc * invf);
-
-								u8a[i * 4    ] = a;
-								u8a[i * 4 + 1] = b;
-								u8a[i * 4 + 2] = c;
-							}
-						}
+		let model_blob: buffer_t = data_get_blob("models/photo_to_" + photo_to_pbr_node_model_names[from] + ".quant.onnx");
+		let buf = krom_ml_inference(model_blob, [f32a.buffer], null, null, config_raw.gpu_inference);
+		let ar = f32_array_create_from_buffer(buf);
+		u8a = u8_array_create(4 * photo_to_pbr_node_tile_w * photo_to_pbr_node_tile_w);
+		let offset_g = (from == channel_type_t.BASE_COLOR || from == channel_type_t.NORMAL_MAP) ? photo_to_pbr_node_tile_with_border_w * photo_to_pbr_node_tile_with_border_w : 0;
+		let offset_b = (from == channel_type_t.BASE_COLOR || from == channel_type_t.NORMAL_MAP) ? photo_to_pbr_node_tile_with_border_w * photo_to_pbr_node_tile_with_border_w * 2 : 0;
+		for (let i: i32 = 0; i < (photo_to_pbr_node_tile_w * photo_to_pbr_node_tile_w); ++i) {
+			let x = photo_to_pbr_node_border_w + i % photo_to_pbr_node_tile_w;
+			let y = photo_to_pbr_node_border_w + math_floor(i / photo_to_pbr_node_tile_w);
+			u8a[i * 4    ] = math_floor((ar[y * photo_to_pbr_node_tile_with_border_w + x          ] * 0.5 + 0.5) * 255);
+			u8a[i * 4 + 1] = math_floor((ar[y * photo_to_pbr_node_tile_with_border_w + x + offset_g] * 0.5 + 0.5) * 255);
+			u8a[i * 4 + 2] = math_floor((ar[y * photo_to_pbr_node_tile_with_border_w + x + offset_b] * 0.5 + 0.5) * 255);
+			u8a[i * 4 + 3] = 255;
+		}
+		array_push(tile_floats, ar);
+
+		// Use border pixels to blend seams
+		if (i > 0) {
+			if (x > 0) {
+				let ar = tile_floats[i - 1];
+				for (let yy: i32 = 0; yy < photo_to_pbr_node_tile_w; ++yy) {
+					for (let xx: i32 = 0; xx < photo_to_pbr_node_border_w; ++xx) {
+						let i = yy * photo_to_pbr_node_tile_w + xx;
+						let a = u8a[i * 4];
+						let b = u8a[i * 4 + 1];
+						let c = u8a[i * 4 + 2];
+
+						let aa = math_floor((ar[(photo_to_pbr_node_border_w + yy) * photo_to_pbr_node_tile_with_border_w + photo_to_pbr_node_border_w + photo_to_pbr_node_tile_w + xx          ] * 0.5 + 0.5) * 255);
+						let bb = math_floor((ar[(photo_to_pbr_node_border_w + yy) * photo_to_pbr_node_tile_with_border_w + photo_to_pbr_node_border_w + photo_to_pbr_node_tile_w + xx + offset_g] * 0.5 + 0.5) * 255);
+						let cc = math_floor((ar[(photo_to_pbr_node_border_w + yy) * photo_to_pbr_node_tile_with_border_w + photo_to_pbr_node_border_w + photo_to_pbr_node_tile_w + xx + offset_b] * 0.5 + 0.5) * 255);
+
+						let f = xx / photo_to_pbr_node_border_w;
+						let invf = 1.0 - f;
+						a = math_floor(a * f + aa * invf);
+						b = math_floor(b * f + bb * invf);
+						c = math_floor(c * f + cc * invf);
+
+						u8a[i * 4    ] = a;
+						u8a[i * 4 + 1] = b;
+						u8a[i * 4 + 2] = c;
 					}
 				}
-
-				///if (krom_metal || krom_vulkan)
-				if (from == channel_type_t.BASE_COLOR) {
-					photo_to_pbr_node_bgra_swap(u8a.buffer);
+			}
+			if (y > 0) {
+				let ar = tile_floats[i - tiles_x];
+				for (let xx: i32 = 0; xx < photo_to_pbr_node_tile_w; ++xx) {
+					for (let yy: i32 = 0; yy < photo_to_pbr_node_border_w; ++yy) {
+						let i = yy * photo_to_pbr_node_tile_w + xx;
+						let a = u8a[i * 4];
+						let b = u8a[i * 4 + 1];
+						let c = u8a[i * 4 + 2];
+
+						let aa = math_floor((ar[(photo_to_pbr_node_border_w + photo_to_pbr_node_tile_w + yy) * photo_to_pbr_node_tile_with_border_w + photo_to_pbr_node_border_w + xx          ] * 0.5 + 0.5) * 255);
+						let bb = math_floor((ar[(photo_to_pbr_node_border_w + photo_to_pbr_node_tile_w + yy) * photo_to_pbr_node_tile_with_border_w + photo_to_pbr_node_border_w + xx + offset_g] * 0.5 + 0.5) * 255);
+						let cc = math_floor((ar[(photo_to_pbr_node_border_w + photo_to_pbr_node_tile_w + yy) * photo_to_pbr_node_tile_with_border_w + photo_to_pbr_node_border_w + xx + offset_b] * 0.5 + 0.5) * 255);
+
+						let f = yy / photo_to_pbr_node_border_w;
+						let invf = 1.0 - f;
+						a = math_floor(a * f + aa * invf);
+						b = math_floor(b * f + bb * invf);
+						c = math_floor(c * f + cc * invf);
+
+						u8a[i * 4    ] = a;
+						u8a[i * 4 + 1] = b;
+						u8a[i * 4 + 2] = c;
+					}
 				}
-				///end
-
-				let temp2 = image_from_bytes(u8a.buffer, photo_to_pbr_node_tile_w, photo_to_pbr_node_tile_w);
-				g2_begin(photo_to_pbr_node_images[from]);
-				g2_draw_image(temp2, x * photo_to_pbr_node_tile_w, y * photo_to_pbr_node_tile_w);
-				g2_end();
-				base_notify_on_next_frame(function () {
-					image_unload(temp2);
-				});
 			}
+		}
+
+		///if (krom_metal || krom_vulkan)
+		if (from == channel_type_t.BASE_COLOR) {
+			photo_to_pbr_node_bgra_swap(u8a.buffer);
+		}
+		///end
 
-			done(photo_to_pbr_node_images[from]);
+		let temp2 = image_from_bytes(u8a.buffer, photo_to_pbr_node_tile_w, photo_to_pbr_node_tile_w);
+		g2_begin(photo_to_pbr_node_images[from]);
+		g2_draw_image(temp2, x * photo_to_pbr_node_tile_w, y * photo_to_pbr_node_tile_w);
+		g2_end();
+		base_notify_on_next_frame(function () {
+			image_unload(temp2);
 		});
-	});
+	}
+
+	return photo_to_pbr_node_images[from];
 }
 
 ///if (krom_metal || krom_vulkan)
 function photo_to_pbr_node_bgra_swap(buffer: buffer_t) {
-	let u8a = new u8_array_t(buffer);
+	let u8a = u8_array_create_from_buffer(buffer);
 	for (let i: i32 = 0; i < math_floor(buffer_size(buffer) / 4); ++i) {
 		let r = u8a[i * 4];
 		u8a[i * 4] = u8a[i * 4 + 2];
@@ -193,7 +192,7 @@ let photo_to_pbr_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 		}
 	],
 	outputs: [
@@ -203,7 +202,7 @@ let photo_to_pbr_node_def: zui_node_t = {
 			name: _tr("Base Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 		},
 		{
 			id: 0,
@@ -235,7 +234,7 @@ let photo_to_pbr_node_def: zui_node_t = {
 			name: _tr("Normal Map"),
 			type: "VECTOR",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 		},
 		{
 			id: 0,

+ 5 - 5
armorlab/Sources/nodes/rgb_node.ts

@@ -12,7 +12,7 @@ function rgb_node_create(arg: any): rgb_node_t {
 	return n;
 }
 
-function rgb_node_get_as_image(self: rgb_node_t, from: i32, done: (img: image_t)=>void) {
+function rgb_node_get_as_image(self: rgb_node_t, from: i32): image_t {
 	if (self.image != null) {
 		base_notify_on_next_frame(function () {
 			image_unload(self.image);
@@ -27,11 +27,11 @@ function rgb_node_get_as_image(self: rgb_node_t, from: i32, done: (img: image_t)
 	f32a[2] = default_value[2];
 	f32a[3] = default_value[3];
 	self.image = image_from_bytes(f32a.buffer, 1, 1, tex_format_t.RGBA128);
-	done(self.image);
+	return self.image;
 }
 
 function rgb_node_get_cached_image(self: rgb_node_t): image_t {
-	self.base.get_as_image(self, 0, function (img: image_t) {});
+	self.base.get_as_image(self, 0);
 	return self.image;
 }
 
@@ -50,7 +50,7 @@ let rgb_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+			default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 		}
 	],
 	buttons: [
@@ -58,7 +58,7 @@ let rgb_node_def: zui_node_t = {
 			name: _tr("default_value"),
 			type: "RGBA",
 			output: 0,
-			default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+			default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 		}
 	]
 };

+ 95 - 93
armorlab/Sources/nodes/text_to_photo_node.ts

@@ -6,9 +6,9 @@ type text_to_photo_node_t = {
 let text_to_photo_node_prompt: string = "";
 let text_to_photo_node_image: image_t = null;
 let text_to_photo_node_tiling: bool = false;
-let text_to_photo_node_text_encoder_blob : buffer_t;
-let text_to_photo_node_unet_blob : buffer_t;
-let text_to_photo_node_vae_decoder_blob : buffer_t;
+let text_to_photo_node_text_encoder_blob: buffer_t;
+let text_to_photo_node_unet_blob: buffer_t;
+let text_to_photo_node_vae_decoder_blob: buffer_t;
 
 function text_to_photo_node_create(arg: any): text_to_photo_node_t {
 	let n: text_to_photo_node_t = {};
@@ -18,11 +18,9 @@ function text_to_photo_node_create(arg: any): text_to_photo_node_t {
 	return n;
 }
 
-function text_to_photo_node_get_as_image(self: text_to_photo_node_t, from: i32, done: (img: image_t)=>void) {
-	text_to_photo_node_stable_diffusion(text_to_photo_node_prompt, function (_image: image_t) {
-		text_to_photo_node_image = _image;
-		done(text_to_photo_node_image);
-	});
+function text_to_photo_node_get_as_image(self: text_to_photo_node_t, from: i32): image_t {
+	text_to_photo_node_image = text_to_photo_node_stable_diffusion(text_to_photo_node_prompt);
+	return text_to_photo_node_image;
 }
 
 function text_to_photo_node_get_cached_image(self: text_to_photo_node_t): image_t {
@@ -35,59 +33,63 @@ function text_to_photo_node_buttons(ui: zui_t, nodes: zui_nodes_t, node: zui_nod
 	node.buttons[1].height = string_split(text_to_photo_node_prompt, "\n").length;
 }
 
-function stable_diffusion(prompt: string, done: (img: image_t)=>void, inpaint_latents: f32_array_t = null, offset: i32 = 0, upscale: bool = true, mask: f32_array_t = null, latents_orig: f32_array_t = null) {
+function stable_diffusion(prompt: string, inpaint_latents: f32_array_t = null, offset: i32 = 0, upscale: bool = true, mask: f32_array_t = null, latents_orig: f32_array_t = null): image_t {
 	let _text_encoder_blob: buffer_t = data_get_blob("models/sd_text_encoder.quant.onnx");
 	let _unet_blob: buffer_t = data_get_blob("models/sd_unet.quant.onnx");
 	let _vae_decoder_blob: buffer_t = data_get_blob("models/sd_vae_decoder.quant.onnx");
 	text_to_photo_node_text_encoder_blob = _text_encoder_blob;
 	text_to_photo_node_unet_blob = _unet_blob;
 	text_to_photo_node_vae_decoder_blob = _vae_decoder_blob;
-	text_to_photo_node_text_encoder(prompt, inpaint_latents, function (latents: f32_array_t, text_embeddings: f32_array_t) {
-		text_to_photo_node_unet(latents, text_embeddings, mask, latents_orig, offset, function (latents: f32_array_t) {
-			text_to_photo_node_vae_decoder(latents, upscale, done);
-		});
-	});
+	let enc: text_encoder_result_t = text_to_photo_node_text_encoder(prompt, inpaint_latents);
+	let latents: f32_array_t = text_to_photo_node_unet(enc.latents, enc.text_embeddings, mask, latents_orig, offset);
+	return text_to_photo_node_vae_decoder(latents, upscale);
 }
 
-function text_to_photo_node_text_encoder(prompt: string, inpaint_latents: f32_array_t, done: (a: f32_array_t, b: f32_array_t)=>void) {
+type text_encoder_result_t = {
+	latents?: f32_array_t;
+	text_embeddings?: f32_array_t;
+};
+
+function text_to_photo_node_text_encoder(prompt: string, inpaint_latents: f32_array_t): text_encoder_result_t {
 	console_progress(tr("Processing") + " - " + tr("Text to Photo"));
-	base_notify_on_next_frame(function () {
-		let words = string_split(string_replace_all(string_replace_all(string_replace_all(prompt, "\n", " "), ",", " , "), "  ", " ").trim(), " ");
-		for (let i: i32 = 0; i < words.length; ++i) {
-			text_to_photo_node_text_input_ids[i + 1] = to_lower_case(text_to_photo_node_vocab[words[i]) + "</w>"];
-		}
-		for (let i: i32 = words.length; i < (text_to_photo_node_text_input_ids.length - 1); ++i) {
-			text_to_photo_node_text_input_ids[i + 1] = 49407; // <|endoftext|>
-		}
+	krom_g4_swap_buffers();
+
+	let words = string_split(string_replace_all(string_replace_all(string_replace_all(prompt, "\n", " "), ",", " , "), "  ", " ").trim(), " ");
+	for (let i: i32 = 0; i < words.length; ++i) {
+		text_to_photo_node_text_input_ids[i + 1] = to_lower_case(text_to_photo_node_vocab[words[i]) + "</w>"];
+	}
+	for (let i: i32 = words.length; i < (text_to_photo_node_text_input_ids.length - 1); ++i) {
+		text_to_photo_node_text_input_ids[i + 1] = 49407; // <|endoftext|>
+	}
 
-		let i32a = new i32_array_t(text_to_photo_node_text_input_ids);
-		let text_embeddings_buf = krom_ml_inference(text_to_photo_node_text_encoder_blob, [i32a.buffer], [[1, 77]], [1, 77, 768], config_raw.gpu_inference);
-		let text_embeddings = new f32_array_t(text_embeddings_buf);
+	let i32a = i32_array_create_from_array(text_to_photo_node_text_input_ids);
+	let text_embeddings_buf = krom_ml_inference(text_to_photo_node_text_encoder_blob, [i32a.buffer], [[1, 77]], [1, 77, 768], config_raw.gpu_inference);
+	let text_embeddings = f32_array_create_from_array(text_embeddings_buf);
 
-		i32a = new i32_array_t(text_to_photo_node_uncond_input_ids);
-		let uncond_embeddings_buf = krom_ml_inference(text_to_photo_node_text_encoder_blob, [i32a.buffer], [[1, 77]], [1, 77, 768], config_raw.gpu_inference);
-		let uncond_embeddings = new f32_array_t(uncond_embeddings_buf);
+	i32a = i32_array_create_from_array(text_to_photo_node_uncond_input_ids);
+	let uncond_embeddings_buf = krom_ml_inference(text_to_photo_node_text_encoder_blob, [i32a.buffer], [[1, 77]], [1, 77, 768], config_raw.gpu_inference);
+	let uncond_embeddings = f32_array_create_from_buffer(uncond_embeddings_buf);
 
-		let f32a = f32_array_create(uncond_embeddings.length + text_embeddings.length);
-		for (let i: i32 = 0; i < uncond_embeddings.length; ++i) f32a[i] = uncond_embeddings[i];
-		for (let i: i32 = 0; i < text_embeddings.length; ++i) f32a[i + uncond_embeddings.length] = text_embeddings[i];
-		text_embeddings = f32a;
+	let f32a = f32_array_create(uncond_embeddings.length + text_embeddings.length);
+	for (let i: i32 = 0; i < uncond_embeddings.length; ++i) f32a[i] = uncond_embeddings[i];
+	for (let i: i32 = 0; i < text_embeddings.length; ++i) f32a[i + uncond_embeddings.length] = text_embeddings[i];
+	text_embeddings = f32a;
 
-		let width = 512;
-		let height = 512;
-		let latents = f32_array_create(1 * 4 * math_floor(height / 8) * math_floor(width / 8));
-		if (inpaint_latents == null) {
-			for (let i: i32 = 0; i < latents.length; ++i) latents[i] = math_cos(2.0 * 3.14 * random_node_get_float()) * math_sqrt(-2.0 * math_log(random_node_get_float()));
-		}
-		else {
-			for (let i: i32 = 0; i < latents.length; ++i) latents[i] = inpaint_latents[i];
-		}
+	let width = 512;
+	let height = 512;
+	let latents = f32_array_create(1 * 4 * math_floor(height / 8) * math_floor(width / 8));
+	if (inpaint_latents == null) {
+		for (let i: i32 = 0; i < latents.length; ++i) latents[i] = math_cos(2.0 * 3.14 * random_node_get_float()) * math_sqrt(-2.0 * math_log(random_node_get_float()));
+	}
+	else {
+		for (let i: i32 = 0; i < latents.length; ++i) latents[i] = inpaint_latents[i];
+	}
 
-		done(latents, text_embeddings);
-	});
+	let res: text_encoder_result_t = { latents: latents, text_embeddings: text_embeddings };
+	return res;
 }
 
-function text_to_photo_node_unet(latents: f32_array_t, text_embeddings: f32_array_t, mask: f32_array_t, latents_orig: f32_array_t, offset: i32, done: (ar: f32_array_t)=>void) {
+function text_to_photo_node_unet(latents: f32_array_t, text_embeddings: f32_array_t, mask: f32_array_t, latents_orig: f32_array_t, offset: i32): f32_array_t {
 	let latent_model_input = f32_array_create(latents.length * 2);
 	let noise_pred_uncond = f32_array_create(latents.length);
 	let noise_pred_text = f32_array_create(latents.length);
@@ -98,8 +100,9 @@ function text_to_photo_node_unet(latents: f32_array_t, text_embeddings: f32_arra
 	let ets: f32_array_t[] = [];
 	let counter = 0;
 
-	let processing = function () {
+	while (true) {
 		console_progress(tr("Processing") + " - " + tr("Text to Photo") + " (" + (counter + 1) + "/" + (50 - offset) + ")");
+		krom_g4_swa_buffers();
 
 		let timestep = text_to_photo_node_timesteps[counter + offset];
 		for (let i: i32 = 0; i < latents.length; ++i) latent_model_input[i] = latents[i];
@@ -108,7 +111,7 @@ function text_to_photo_node_unet(latents: f32_array_t, text_embeddings: f32_arra
 		let t32 = i32_array_create(2);
 		t32[0] = timestep;
 		let noise_pred_buf = krom_ml_inference(text_to_photo_node_unet_blob, [latent_model_input.buffer, t32.buffer, text_embeddings.buffer], [[2, 4, 64, 64], [1], [2, 77, 768]], [2, 4, 64, 64], config_raw.gpu_inference);
-		let noise_pred = new f32_array_t(noise_pred_buf);
+		let noise_pred = f32_array_create_from_buffer(noise_pred_buf);
 
 		for (let i: i32 = 0; i < noise_pred_uncond.length; ++i) noise_pred_uncond[i] = noise_pred[i];
 		for (let i: i32 = 0; i < noise_pred_text.length; ++i) noise_pred_text[i] = noise_pred[noise_pred_uncond.length + i];
@@ -193,59 +196,58 @@ function text_to_photo_node_unet(latents: f32_array_t, text_embeddings: f32_arra
 		}
 
 		if (counter == (51 - offset)) {
-			app_remove_render_2d(processing);
-			done(latents);
+			break;
 		}
 	}
-	app_notify_on_render_2d(processing);
+
+	return latents;
 }
 
-function text_to_photo_node_vae_decoder(latents: f32_array_t, upscale: bool, done: (img: image_t)=>void) {
+function text_to_photo_node_vae_decoder(latents: f32_array_t, upscale: bool): image_t {
 	console_progress(tr("Processing") + " - " + tr("Text to Photo"));
-	base_notify_on_next_frame(function () {
-		for (let i: i32 = 0; i < latents.length; ++i) {
-			latents[i] = 1.0 / 0.18215 * latents[i];
-		}
+	krom_g4_swap_buffers();
 
-		let pyimage_buf = krom_ml_inference(text_to_photo_node_vae_decoder_blob, [latents.buffer], [[1, 4, 64, 64]], [1, 3, 512, 512], config_raw.gpu_inference);
-		let pyimage = new f32_array_t(pyimage_buf);
+	for (let i: i32 = 0; i < latents.length; ++i) {
+		latents[i] = 1.0 / 0.18215 * latents[i];
+	}
 
-		for (let i: i32 = 0; i < pyimage.length; ++i) {
-			pyimage[i] = pyimage[i] / 2.0 + 0.5;
-			if (pyimage[i] < 0) pyimage[i] = 0;
-			else if (pyimage[i] > 1) pyimage[i] = 1;
-		}
+	let pyimage_buf = krom_ml_inference(text_to_photo_node_vae_decoder_blob, [latents.buffer], [[1, 4, 64, 64]], [1, 3, 512, 512], config_raw.gpu_inference);
+	let pyimage = f32_array_create_from_buffer(pyimage_buf);
 
-		let u8a = u8_array_create(4 * 512 * 512);
-		for (let i: i32 = 0; i < (512 * 512); ++i) {
-			u8a[i * 4    ] = math_floor(pyimage[i                ] * 255);
-			u8a[i * 4 + 1] = math_floor(pyimage[i + 512 * 512    ] * 255);
-			u8a[i * 4 + 2] = math_floor(pyimage[i + 512 * 512 * 2] * 255);
-			u8a[i * 4 + 3] = 255;
-		}
-		let image = image_from_bytes(u8a.buffer, 512, 512);
+	for (let i: i32 = 0; i < pyimage.length; ++i) {
+		pyimage[i] = pyimage[i] / 2.0 + 0.5;
+		if (pyimage[i] < 0) pyimage[i] = 0;
+		else if (pyimage[i] > 1) pyimage[i] = 1;
+	}
 
-		if (text_to_photo_node_tiling) {
-			TilingNode.prompt = text_to_photo_node_prompt;
-			let seed = RandomNode.getSeed();
-			TilingNode.sd_tiling(image, seed, done);
+	let u8a = u8_array_create(4 * 512 * 512);
+	for (let i: i32 = 0; i < (512 * 512); ++i) {
+		u8a[i * 4    ] = math_floor(pyimage[i                ] * 255);
+		u8a[i * 4 + 1] = math_floor(pyimage[i + 512 * 512    ] * 255);
+		u8a[i * 4 + 2] = math_floor(pyimage[i + 512 * 512 * 2] * 255);
+		u8a[i * 4 + 3] = 255;
+	}
+	let image = image_from_bytes(u8a.buffer, 512, 512);
+
+	if (text_to_photo_node_tiling) {
+		tiling_node_prompt = text_to_photo_node_prompt;
+		let seed = random_node_get_seed();
+		return tiling_node_sd_tiling(image, seed);
+	}
+	else {
+		if (upscale) {
+			upscale_node_load_blob();
+			while (image.width < config_get_texture_res_x()) {
+				let last_image = image;
+				image = upscale_node_esrgan(image);
+				image_unload(last_image);
+			}
+			return image;
 		}
 		else {
-			if (upscale) {
-				UpscaleNode.load_blob(function () {
-					while (image.width < config_get_texture_res_x()) {
-						let lastImage = image;
-						image = UpscaleNode.esrgan(image);
-						image_unload(lastImage);
-					}
-					done(image);
-				});
-			}
-			else {
-				done(image);
-			}
+			return image;
 		}
-	});
+	}
 }
 
 let text_to_photo_node_def: zui_node_t = {
@@ -263,7 +265,7 @@ let text_to_photo_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 		}
 	],
 	buttons: [
@@ -281,7 +283,7 @@ let text_to_photo_node_def: zui_node_t = {
 	]
 };
 
-let text_to_photo_node_text_input_ids = [49406,  49407,  49407, 49407, 49407, 49407, 49407, 49407, 49407,
+let text_to_photo_node_text_input_ids: i32[] = [49406,  49407,  49407, 49407, 49407, 49407, 49407, 49407, 49407,
 	49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
 	49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
 	49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
@@ -291,7 +293,7 @@ let text_to_photo_node_text_input_ids = [49406,  49407,  49407, 49407, 49407, 49
 	49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
 	49407, 49407, 49407, 49407, 49407];
 
-let text_to_photo_node_uncond_input_ids = [49406, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
+let text_to_photo_node_uncond_input_ids: i32[] = [49406, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
 	49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
 	49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
 	49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
@@ -301,7 +303,7 @@ let text_to_photo_node_uncond_input_ids = [49406, 49407, 49407, 49407, 49407, 49
 	49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,
 	49407, 49407, 49407, 49407, 49407];
 
-let text_to_photo_node_alphas_cumprod = [0.99915, 0.998296, 0.9974381, 0.99657613, 0.99571025, 0.9948404,
+let text_to_photo_node_alphas_cumprod: f32[] = [0.99915, 0.998296, 0.9974381, 0.99657613, 0.99571025, 0.9948404,
 	0.9939665,  0.99308866, 0.9922069,  0.9913211,  0.9904313,  0.98953754,
 	0.9886398,  0.9877381,  0.9868324,  0.9859227,  0.985009,   0.98409134,
 	0.9831697,  0.982244,   0.98131436, 0.9803807,  0.97944313, 0.97850156,
@@ -469,7 +471,7 @@ let text_to_photo_node_alphas_cumprod = [0.99915, 0.998296, 0.9974381, 0.9965761
 	0.00519163, 0.00513006, 0.00506913, 0.00500883, 0.00494917, 0.00489013,
 	0.0048317,  0.00477389, 0.00471669, 0.00466009];
 
-let text_to_photo_node_timesteps = [981, 961, 961, 941, 921, 901, 881, 861, 841, 821, 801, 781, 761, 741, 721, 701, 681, 661,
+let text_to_photo_node_timesteps: i32[] = [981, 961, 961, 941, 921, 901, 881, 861, 841, 821, 801, 781, 761, 741, 721, 701, 681, 661,
 	641, 621, 601, 581, 561, 541, 521, 501, 481, 461, 441, 421, 401, 381, 361, 341, 321, 301,
 	281, 261, 241, 221, 201, 181, 161, 141, 121, 101, 81, 61, 41, 21, 1];
 

+ 19 - 18
armorlab/Sources/nodes/tiling_node.ts

@@ -36,28 +36,29 @@ function tiling_node_buttons(ui: zui_t, nodes: zui_nodes_t, node: zui_node_t) {
 	}
 }
 
-function tiling_node_get_as_image(self: tiling_node_t, from: i32, done: (img: image_t)=>void) {
-	self.base.inputs[0].get_as_image(function (source: image_t) {
-		g2_begin(tiling_node_image);
-		g2_draw_scaled_image(source, 0, 0, config_get_texture_res_x(), config_get_texture_res_y());
-		g2_end();
+function tiling_node_get_as_image(self: tiling_node_t, from: i32): image_t {
+	let source: image_t = self.base.inputs[0].get_as_image();
+	g2_begin(tiling_node_image);
+	g2_draw_scaled_image(source, 0, 0, config_get_texture_res_x(), config_get_texture_res_y());
+	g2_end();
+
+	console_progress(tr("Processing") + " - " + tr("Tiling"));
+	krom_g4_swap_buffers();
 
-		console_progress(tr("Processing") + " - " + tr("Tiling"));
-		base_notify_on_next_frame(function () {
-			let _done = function (image: image_t) {
-				self.result = image;
-				done(image);
-			}
-			tiling_node_auto ? inpaint_node_texsynth_inpaint(tiling_node_image, true, null, _done) : tiling_node_sd_tiling(tiling_node_image, -1, _done);
-		});
-	});
+	if (tiling_node_auto){
+		self.result = inpaint_node_texsynth_inpaint(tiling_node_image, true, null);
+	}
+	else {
+		self.result = tiling_node_sd_tiling(tiling_node_image, -1);
+	}
+	return self.result;
 }
 
 function tiling_node_get_cached_image(self: tiling_node_t): image_t {
 	return self.result;
 }
 
-function tiling_node_sd_tiling(image: image_t, seed: i32, done: (img: image_t)=>void) {
+function tiling_node_sd_tiling(image: image_t, seed: i32): image_t {
 	text_to_photo_node_tiling = false;
 	let tile = image_create_render_target(512, 512);
 	g2_begin(tile);
@@ -92,7 +93,7 @@ function tiling_node_sd_tiling(image: image_t, seed: i32, done: (img: image_t)=>
 	if (seed >= 0) {
 		random_node_set_seed(seed);
 	}
-	inpaint_node_sd_inpaint(tile, mask, done);
+	return inpaint_node_sd_inpaint(tile, mask);
 }
 
 let tiling_node_def: zui_node_t = {
@@ -109,7 +110,7 @@ let tiling_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_xyzw(0.0, 0.0, 0.0, 1.0)
 		}
 	],
 	outputs: [
@@ -119,7 +120,7 @@ let tiling_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_xyzw(0.0, 0.0, 0.0, 1.0)
 		}
 	],
 	buttons: [

+ 22 - 28
armorlab/Sources/nodes/upscale_node.ts

@@ -15,33 +15,27 @@ function upscale_node_create(arg: any): upscale_node_t {
 	return n;
 }
 
-function upscale_node_get_as_image(self: upscale_node_t, from: i32, done: (img: image_t)=>void) {
-	self.base.inputs[0].get_as_image(function (_image: image_t) {
-		upscale_node_image = _image;
-
-		console_progress(tr("Processing") + " - " + tr("Upscale"));
-		base_notify_on_next_frame(function () {
-			upscale_node_load_blob(function () {
-				if (upscale_node_image.width < config_get_texture_res_x()) {
-					upscale_node_image = upscale_node_esrgan(upscale_node_image);
-					while (upscale_node_image.width < config_get_texture_res_x()) {
-						let lastImage = upscale_node_image;
-						upscale_node_image = upscale_node_esrgan(upscale_node_image);
-						image_unload(lastImage);
-					}
-				}
-				done(upscale_node_image);
-			});
-		});
-	});
-}
+function upscale_node_get_as_image(self: upscale_node_t, from: i32): image_t {
+	upscale_node_image = self.base.inputs[0].get_as_image();
+
+	console_progress(tr("Processing") + " - " + tr("Upscale"));
+	krom_g4_swap_buffers();
 
-function upscale_node_load_blob(done: ()=>void) {
-	let _esrgan_blob: buffer_t = data_get_blob("models/esrgan.quant.onnx");
-	upscale_node_esrgan_blob = _esrgan_blob;
-	done();
+	upscale_node_load_blob();
+	if (upscale_node_image.width < config_get_texture_res_x()) {
+		upscale_node_image = upscale_node_esrgan(upscale_node_image);
+		while (upscale_node_image.width < config_get_texture_res_x()) {
+			let last_image = upscale_node_image;
+			upscale_node_image = upscale_node_esrgan(upscale_node_image);
+			image_unload(last_image);
+		}
+	}
+	return upscale_node_image;
 }
 
+function upscale_node_load_blob() {
+	upscale_node_esrgan_blob = data_get_blob("models/esrgan.quant.onnx");
+
 function upscale_node_get_cached_image(self: upscale_node_t): image_t {
 	return upscale_node_image;
 }
@@ -61,7 +55,7 @@ function upscale_node_do_tile(source: image_t) {
 	g2_end();
 
 	let bytes_img = image_get_pixels(upscale_node_temp);
-	let u8a = new u8_array_t(bytes_img);
+	let u8a = u8_array_create_from_buffer(bytes_img);
 	let f32a = f32_array_create(3 * size1w * size1h);
 	for (let i: i32 = 0; i < (size1w * size1h); ++i) {
 		f32a[i                      ] = (u8a[i * 4    ] / 255);
@@ -70,7 +64,7 @@ function upscale_node_do_tile(source: image_t) {
 	}
 
 	let esrgan2x_buf = krom_ml_inference(upscale_node_esrgan_blob, [f32a.buffer], [[1, 3, size1w, size1h]], [1, 3, size2w, size2h], config_raw.gpu_inference);
-	let esrgan2x = new f32_array_t(esrgan2x_buf);
+	let esrgan2x = f32_array_create_from_buffer(esrgan2x_buf);
 	for (let i: i32 = 0; i < esrgan2x.length; ++i) {
 		if (esrgan2x[i] < 0) {
 			esrgan2x[i] = 0;
@@ -144,7 +138,7 @@ let upscale_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 		}
 	],
 	outputs: [
@@ -154,7 +148,7 @@ let upscale_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 		}
 	],
 	buttons: []

+ 39 - 43
armorlab/Sources/nodes/variance_node.ts

@@ -31,53 +31,49 @@ function variance_node_buttons(ui: zui_t, nodes: zui_nodes_t, node: zui_node_t)
 	node.buttons[0].height = string_split(variance_node_prompt, "\n").length;
 }
 
-function variance_node_get_as_image(self: variance_node_t, from: i32, done: (img: image_t)=>void) {
+function variance_node_get_as_image(self: variance_node_t, from: i32): image_t {
 	let strength = (variance_node_inst.inputs[1].node as any).value;
 
-	variance_node_inst.inputs[0].get_as_image(function (source: image_t) {
-		g2_begin(variance_node_temp);
-		g2_draw_scaled_image(source, 0, 0, 512, 512);
-		g2_end();
+	let source: image_t = variance_node_inst.inputs[0].get_as_image();
+	g2_begin(variance_node_temp);
+	g2_draw_scaled_image(source, 0, 0, 512, 512);
+	g2_end();
 
-		let bytes_img = image_get_pixels(variance_node_temp);
-		let u8a = new u8_array_t(bytes_img);
-		let f32a = f32_array_create(3 * 512 * 512);
-		for (let i: i32 = 0; i < (512 * 512); ++i) {
-			f32a[i                ] = (u8a[i * 4    ] / 255) * 2.0 - 1.0;
-			f32a[i + 512 * 512    ] = (u8a[i * 4 + 1] / 255) * 2.0 - 1.0;
-			f32a[i + 512 * 512 * 2] = (u8a[i * 4 + 2] / 255) * 2.0 - 1.0;
-		}
+	let bytes_img = image_get_pixels(variance_node_temp);
+	let u8a = u8_array_create_from_buffer(bytes_img);
+	let f32a = f32_array_create(3 * 512 * 512);
+	for (let i: i32 = 0; i < (512 * 512); ++i) {
+		f32a[i                ] = (u8a[i * 4    ] / 255) * 2.0 - 1.0;
+		f32a[i + 512 * 512    ] = (u8a[i * 4 + 1] / 255) * 2.0 - 1.0;
+		f32a[i + 512 * 512 * 2] = (u8a[i * 4 + 2] / 255) * 2.0 - 1.0;
+	}
 
-		console_progress(tr("Processing") + " - " + tr("Variance"));
-		base_notify_on_next_frame(function () {
-			let vae_encoder_blob: buffer_t = data_get_blob("models/sd_vae_encoder.quant.onnx");
-			let latents_buf = krom_ml_inference(vae_encoder_blob, [f32a.buffer], [[1, 3, 512, 512]], [1, 4, 64, 64], config_raw.gpu_inference);
-			let latents = new f32_array_t(latents_buf);
-			for (let i: i32 = 0; i < latents.length; ++i) {
-				latents[i] = 0.18215 * latents[i];
-			}
+	console_progress(tr("Processing") + " - " + tr("Variance"));
+	krom_g4_swap_buffers();
 
-			let noise = f32_array_create(latents.length);
-			for (let i: i32 = 0; i < noise.length; ++i) {
-				noise[i] = math_cos(2.0 * 3.14 * random_node_get_float()) * math_sqrt(-2.0 * math_log(random_node_get_float()));
-			}
-			let num_inference_steps = 50;
-			let init_timestep = math_floor(num_inference_steps * strength);
-			let timesteps = text_to_photo_node_timesteps[num_inference_steps - init_timestep];
-			let alphas_cumprod = text_to_photo_node_alphas_cumprod;
-			let sqrt_alpha_prod = math_pow(alphas_cumprod[timesteps], 0.5);
-			let sqrt_one_minus_alpha_prod = math_pow(1.0 - alphas_cumprod[timesteps], 0.5);
-			for (let i: i32 = 0; i < latents.length; ++i) {
-				latents[i] = sqrt_alpha_prod * latents[i] + sqrt_one_minus_alpha_prod * noise[i];
-			}
-			let t_start = num_inference_steps - init_timestep;
+	let vae_encoder_blob: buffer_t = data_get_blob("models/sd_vae_encoder.quant.onnx");
+	let latents_buf = krom_ml_inference(vae_encoder_blob, [f32a.buffer], [[1, 3, 512, 512]], [1, 4, 64, 64], config_raw.gpu_inference);
+	let latents = f32_array_create_from_buffer(latents_buf);
+	for (let i: i32 = 0; i < latents.length; ++i) {
+		latents[i] = 0.18215 * latents[i];
+	}
 
-			text_to_photo_node_stable_diffusion(variance_node_prompt, function (_image: image_t) {
-				variance_node_image = _image;
-				done(variance_node_image);
-			}, latents, t_start);
-		});
-	});
+	let noise = f32_array_create(latents.length);
+	for (let i: i32 = 0; i < noise.length; ++i) {
+		noise[i] = math_cos(2.0 * 3.14 * random_node_get_float()) * math_sqrt(-2.0 * math_log(random_node_get_float()));
+	}
+	let num_inference_steps = 50;
+	let init_timestep = math_floor(num_inference_steps * strength);
+	let timesteps = text_to_photo_node_timesteps[num_inference_steps - init_timestep];
+	let alphas_cumprod = text_to_photo_node_alphas_cumprod;
+	let sqrt_alpha_prod = math_pow(alphas_cumprod[timesteps], 0.5);
+	let sqrt_one_minus_alpha_prod = math_pow(1.0 - alphas_cumprod[timesteps], 0.5);
+	for (let i: i32 = 0; i < latents.length; ++i) {
+		latents[i] = sqrt_alpha_prod * latents[i] + sqrt_one_minus_alpha_prod * noise[i];
+	}
+	let t_start = num_inference_steps - init_timestep;
+	variance_node_image = text_to_photo_node_stable_diffusion(variance_node_prompt, latents, t_start);
+	return variance_node_image;
 }
 
 function variance_node_get_cached_image(self: variance_node_t): image_t {
@@ -98,7 +94,7 @@ let variance_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 		},
 		{
 			id: 0,
@@ -116,7 +112,7 @@ let variance_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "RGBA",
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 		}
 	],
 	buttons: [

+ 64 - 51
armorpaint/Assets/plugins/dev/converter.js

@@ -1,63 +1,76 @@
 
-let plugin = Plugin.create();
+let plugin = plugin_create();
 
-let h1 = new Handle();
+let h1 = zui_handle_create();
 
-plugin.drawUI = function(ui) {
-	if (Zui.panel(h1, "Converter")) {
-		Zui.row([1/2, 1/2]);
-		if (Zui.button(".arm to .json")) {
-			UIFiles.show("arm", false, true, function(path) {
-				Data.getBlob(path, function(b) {
-					let parsed = ArmPack.decode(b);
-					let out = System.stringToBuffer(JSON.stringify(parsed, function(key, value) {
-						if (value.constructor.name === "Float32Array") {
-							let ar = Array.from(value);
-							ar.unshift(0); // Annotate array type
-							return ar;
-						}
-						else if (value.constructor.name === "Uint32Array") {
-							let ar = Array.from(value);
-							ar.unshift(1);
-							return ar;
-						}
-						else if (value.constructor.name === "Int16Array") {
-							let ar = Array.from(value);
-							ar.unshift(2);
-							return ar;
-						}
-						return value;
-					}, "	"));
-					Krom.fileSaveBytes(path.substr(0, path.length - 3) + "json", out);
-				});
+plugin.draw_ui = function(ui) {
+	if (zui_panel(h1, "Converter")) {
+		zui_row([1/2, 1/2]);
+		if (zui_button(".arm to .json")) {
+			ui_files_show("arm", false, true, function(path) {
+				let b = data_get_blob(path);
+				let parsed = armpack_decode(b);
+				let out = sys_string_to_buffer(JSON.stringify(parsed, function(key, value) {
+					if (value.constructor.name === "Float32Array") {
+						let ar = Array.from(value);
+						ar.unshift(0); // Annotate array type
+						return ar;
+					}
+					else if (value.constructor.name === "Uint32Array") {
+						let ar = Array.from(value);
+						ar.unshift(1);
+						return ar;
+					}
+					else if (value.constructor.name === "Int16Array") {
+						let ar = Array.from(value);
+						ar.unshift(2);
+						return ar;
+					}
+					return value;
+				}, "	"));
+				krom_file_save_bytes(path.substr(0, path.length - 3) + "json", out);
 			});
 		}
-		if (Zui.button(".json to .arm")) {
-			UIFiles.show("json", false, true, function(path) {
-				Data.getBlob(path, function(b) {
-					let parsed = JSON.parse(System.bufferToString(b));
-					function iterate(d) {
-						for (const n of ReflectFields(d)) {
-							let v = ReflectField(d, n);
-							if (v.constructor.name === "Array") {
-								if (v[0].constructor.name === "Number") {
-									console.log(n);
-									let ar = null;
-									if (v[0] === 0) ar = new Float32Array(v.length - 1);
-									else if (v[0] === 1) ar = new Uint32Array(v.length - 1);
-									else if (v[0] === 2) ar = new Int16Array(v.length - 1);
-									for (let i = 0; i < v.length - 1; ++i) ar[i] = v[i + 1];
-									ReflectSetField(d, n, ar);
+		if (zui_button(".json to .arm")) {
+			ui_files_show("json", false, true, function(path) {
+				let b = data_get_blob(path);
+				let parsed = json_parse(sys_buffer_to_string(b));
+				function iterate(d) {
+					for (const n of ReflectFields(d)) {
+						let v = ReflectField(d, n);
+						if (v.constructor.name === "Array") {
+							if (v[0].constructor.name === "Number") {
+								let ar = null;
+								if (v[0] === 0) {
+									ar = new Float32Array(v.length - 1);
 								}
-								else for (const e of v) if (typeof e === 'object') iterate(e);
+								else if (v[0] === 1) {
+									ar = new Uint32Array(v.length - 1);
+								}
+								else if (v[0] === 2) {
+									ar = new Int16Array(v.length - 1);
+								}
+								for (let i = 0; i < v.length - 1; ++i) {
+									ar[i] = v[i + 1];
+								}
+								ReflectSetField(d, n, ar);
 							}
-							else if (typeof v === 'object') iterate(v);
+							else {
+								for (const e of v) {
+									if (typeof e === 'object') {
+										iterate(e);
+									}
+								}
+							}
+						}
+						else if (typeof v === 'object') {
+							iterate(v);
 						}
 					}
-					iterate(parsed);
-					let out = ArmPack.encode(parsed);
-					Krom.fileSaveBytes(path.substr(0, path.length - 4) + "arm", out, out.byteLength + 1);
-				});
+				}
+				iterate(parsed);
+				let out = armpack_encode(parsed);
+				krom_file_save_bytes(path.substr(0, path.length - 4) + "arm", out, out.byteLength + 1);
 			});
 		}
 	}

+ 20 - 20
armorpaint/Assets/plugins/hello_node.js

@@ -1,20 +1,20 @@
 
-let plugin = Plugin.create();
+let plugin = plugin_create();
 
-let categoryName = "My Nodes";
-let nodeName = "Hello World";
-let nodeType = "HELLO_WORLD";
+let category_name = "My Nodes";
+let node_name = "Hello World";
+let node_type = "HELLO_WORLD";
 
 // Create new node category
-let categories = NodesMaterial.categories;
-categories.push(categoryName);
+let categories = nodes_material_categories;
+categories.push(category_name);
 
 // Create new node
 let nodes = [
 	{
 		id: 0,
-		name: nodeName,
-		type: nodeType,
+		name: node_name,
+		type: node_type,
 		x: 0,
 		y: 0,
 		color: 0xffb34f5a,
@@ -51,20 +51,20 @@ let nodes = [
 		buttons: []
 	}
 ];
-NodesMaterial.list.push(nodes);
+nodes_material_list.push(nodes);
 
 // Node shader
-ParserMaterial.customNodes.set(nodeType, function(node, socket) {
-	let frag = ParserMaterial.frag;
-	let scale = ParserMaterial.parse_value_input(node.inputs[0]);
-	let my_out = ParserMaterial.node_name(node) + "_out";
+parser_material_custom_nodes.set(node_type, function(node, socket) {
+	let frag = parser_material_frag;
+	let scale = parser_material_parse_value_input(node.inputs[0]);
+	let my_out = parser_material_node_name(node) + "_out";
 
-	NodeShader.write(frag, `
-		float ${my_out} = cos(sin(texCoord.x * 200.0 * ${scale}) + cos(texCoord.y * 200.0 * ${scale}));
-	`);
+	node_shader_write(frag,
+		"float " + my_out + " = cos(sin(texCoord.x * 200.0 * " + scale + ") + cos(texCoord.y * 200.0 * " + scale + "));"
+	);
 
 	if (socket.name == "Color") {
-		return `vec3(${my_out}, ${my_out}, ${my_out})`;
+		return "vec3(" + my_out + ", " + my_out + ", " + my_out + ")";
 	}
 	else if (socket.name == "Fac") {
 		return my_out;
@@ -73,7 +73,7 @@ ParserMaterial.customNodes.set(nodeType, function(node, socket) {
 
 // Cleanup
 plugin.delete = function() {
-	ParserMaterial.customNodes.delete(nodeType);
-	NodesMaterial.list.splice(NodesMaterial.list.indexOf(nodes), 1);
-	categories.splice(categories.indexOf(categoryName), 1);
+	parser_material_custom_nodes.delete(node_type);
+	nodes_material_list.splice(nodes_material_list.indexOf(nodes), 1);
+	categories.splice(categories.indexOf(category_name), 1);
 };

+ 14 - 14
armorpaint/Assets/plugins/hello_node_brush.js

@@ -1,20 +1,20 @@
 
-let plugin = Plugin.create();
+let plugin = plugin_create();
 
-let categoryName = "My Nodes";
-let nodeName = "Hello World";
-let nodeType = "HELLO_WORLD";
+let category_name = "My Nodes";
+let node_name = "Hello World";
+let node_type = "HELLO_WORLD";
 
 // Create new node category
-let categories = NodesBrush.categories;
-categories.push(categoryName);
+let categories = nodes_brush_categories;
+categories.push(category_name);
 
 // Create new node
 let nodes = [
 	{
 		id: 0,
-		name: nodeName,
-		type: nodeType,
+		name: node_name,
+		type: node_type,
 		x: 0,
 		y: 0,
 		color: 0xffb34f5a,
@@ -43,16 +43,16 @@ let nodes = [
 		buttons: []
 	}
 ];
-NodesBrush.list.push(nodes);
+nodes_brush_list.push(nodes);
 
 // Brush node
-ParserLogic.customNodes.set(nodeType, function(node, from) {
-	return Math.sin(iron.Time.time() * node.inputs[0].get(0));
+parser_logic_custom_nodes.set(node_type, function(node, from) {
+	return Math.sin(time_time() * node.inputs[0].get(0));
 });
 
 // Cleanup
 plugin.delete = function() {
-	ParserLogic.customNodes.delete(nodeType);
-	NodesBrush.list.splice(NodesBrush.list.indexOf(nodes), 1);
-	categories.splice(categories.indexOf(categoryName), 1);
+	parser_logic_custom_nodes.delete(node_type);
+	nodes_brush_list.splice(nodes_brush_list.indexOf(nodes), 1);
+	categories.splice(categories.indexOf(category_name), 1);
 };

+ 24 - 24
armorpaint/Assets/plugins/hello_world.js

@@ -1,31 +1,31 @@
 
-let plugin = Plugin.create();
+let plugin = plugin_create();
 
-let h1 = new Handle();
-let h2 = new Handle();
-let h3 = new Handle();
-let h4 = new Handle();
-let h5 = new Handle();
-let h6 = new Handle();
-let h7 = new Handle();
+let h1 = zui_handle_create();
+let h2 = zui_handle_create();
+let h3 = zui_handle_create();
+let h4 = zui_handle_create();
+let h5 = zui_handle_create();
+let h6 = zui_handle_create();
+let h7 = zui_handle_create();
 
-plugin.drawUI = function(ui) {
-	if (Zui.panel(h1, "My Plugin")) {
-		Zui.text("Label");
-		Zui.textInput(h7, "Text Input");
-		if (Zui.button("Button")) {
+plugin.draw_ui = function(ui) {
+	if (zui_panel(h1, "My Plugin")) {
+		zui_text("Label");
+		zui_textInput(h7, "Text Input");
+		if (zui_button("Button")) {
 			console.error("Hello");
 		}
-		Zui.row([1/2, 1/2]);
-		Zui.button("Button A");
-		Zui.button("Button B");
-		Zui.combo(h5, ["Item 1", "Item 2"], "Combo");
-		Zui.row([1/2, 1/2]);
-		Zui.slider(h2, "Slider", 0, 1, true);
-		Zui.slider(h3, "Slider", 0, 1, true);
-		Zui.check(h4, "Check");
-		Zui.radio(h6, 0, "Radio 1");
-		Zui.radio(h6, 1, "Radio 2");
-		Zui.radio(h6, 2, "Radio 3");
+		zui_row([1/2, 1/2]);
+		zui_button("Button A");
+		zui_button("Button B");
+		zui_combo(h5, ["Item 1", "Item 2"], "Combo");
+		zui_row([1/2, 1/2]);
+		zui_slider(h2, "Slider", 0, 1, true);
+		zui_slider(h3, "Slider", 0, 1, true);
+		zui_check(h4, "Check");
+		zui_radio(h6, 0, "Radio 1");
+		zui_radio(h6, 1, "Radio 2");
+		zui_radio(h6, 2, "Radio 3");
 	}
 }

+ 35 - 33
armorpaint/Assets/plugins/import_fbx.js

@@ -6,42 +6,44 @@ class R {
 let r = new R();
 
 // import_fbx.js
-let import_fbx = function(path, done) {
-	Data.getBlob(path, function(b) {
-		let buf_off = a._init(b.byteLength); //// Allocate r.buffer
-		let buf = new Uint8Array(r.buffer, buf_off, b.byteLength);
-		let bbuf = new Uint8Array(b);
-		for (let i = 0; i < b.byteLength; ++i) buf[i] = bbuf[i];
-		a._parse();
-		let vertex_count = a._get_vertex_count();
-		let index_count = a._get_index_count();
-		let inda = new Uint32Array(r.buffer, a._get_indices(), index_count);
-		let posa = new Int16Array(r.buffer, a._get_positions(), vertex_count * 4);
-		let nora = new Int16Array(r.buffer, a._get_normals(), vertex_count * 2);
-		let texa = a._get_uvs() > 0 ? new Int16Array(r.buffer, a._get_uvs(), vertex_count * 2) : null;
-		let cola = a._get_colors() > 0 ? new Int16Array(r.buffer, a._get_colors(), vertex_count * 3) : null;
+let import_fbx = function(path) {
+	data_get_blob(path);
+	let buf_off = a._init(b.byteLength); //// Allocate r.buffer
+	let buf = new Uint8Array(r.buffer, buf_off, b.byteLength);
+	let bbuf = new Uint8Array(b);
+	for (let i = 0; i < b.byteLength; ++i) {
+		buf[i] = bbuf[i];
+	}
+	a._parse();
+	let vertex_count = a._get_vertex_count();
+	let index_count = a._get_index_count();
+	let inda = new Uint32Array(r.buffer, a._get_indices(), index_count);
+	let posa = new Int16Array(r.buffer, a._get_positions(), vertex_count * 4);
+	let nora = new Int16Array(r.buffer, a._get_normals(), vertex_count * 2);
+	let texa = a._get_uvs() > 0 ? new Int16Array(r.buffer, a._get_uvs(), vertex_count * 2) : null;
+	let cola = a._get_colors() > 0 ? new Int16Array(r.buffer, a._get_colors(), vertex_count * 3) : null;
 
-		// Use .slice() for now as the next mesh will overwrite buffer data corrupting the old vertex data
-		done({
-			name: a._get_name(),
-			posa: posa.slice(),
-			nora: nora.slice(),
-			texa: texa != null ? texa.slice() : null,
-			cola: cola != null ? cola.slice() : null,
-			inda: inda.slice(),
-			scale_pos: a._get_scale_pos(),
-			scale_tex: 1.0,
-			transform: a._get_transform(),
-			has_next: a._has_next()
-		});
-		// a._destroy(); //// Destroys r.buffer
-		// Data.deleteBlob(path);
-	});
+	// a._destroy(); //// Destroys r.buffer
+	// data_delete_blob(path);
+
+	// Use .slice() for now as the next mesh will overwrite buffer data corrupting the old vertex data
+	return {
+		name: a._get_name(),
+		posa: posa.slice(),
+		nora: nora.slice(),
+		texa: texa != null ? texa.slice() : null,
+		cola: cola != null ? cola.slice() : null,
+		inda: inda.slice(),
+		scale_pos: a._get_scale_pos(),
+		scale_tex: 1.0,
+		transform: a._get_transform(),
+		has_next: a._has_next()
+	};
 }
 
-let plugin = Plugin.create();
-let formats = Path.meshFormats;
-let importers = Path.meshImporters;
+let plugin = plugin_create();
+let formats = path_mesh_formats;
+let importers = path_mesh_mporters;
 formats.push("fbx");
 importers.set("fbx", import_fbx);
 

+ 31 - 30
armorpaint/Assets/plugins/import_gltf_glb.js

@@ -6,38 +6,39 @@ class R {
 let r = new R();
 
 // import_gltf_glb.js
-let import_gltf_glb = function(path, done) {
-	Data.getBlob(path, function(b) {
-		let buf_off = a._init(b.byteLength); //// Allocate r.buffer
-		let buf = new Uint8Array(r.buffer, buf_off, b.byteLength);
-		let bbuf = new Uint8Array(b);
-		for (let i = 0; i < b.byteLength; ++i) buf[i] = bbuf[i];
-		a._parse();
-		let vertex_count = a._get_vertex_count();
-		let index_count = a._get_index_count();
-		let inda = new Uint32Array(r.buffer, a._get_indices(), index_count);
-		let posa = new Int16Array(r.buffer, a._get_positions(), vertex_count * 4);
-		let nora = new Int16Array(r.buffer, a._get_normals(), vertex_count * 2);
-		let uvs = a._get_uvs();
-		let texa = uvs == 0 ? null : new Int16Array(r.buffer, uvs, vertex_count * 2);
-		let name = path.split("\\").pop().split("/").pop().split(".").shift();
-		done({
-			name: name,
-			posa: posa,
-			nora: nora,
-			texa: texa,
-			inda: inda,
-			scale_pos: a._get_scale_pos(),
-			scale_tex: 1.0
-		});
-		// a._destroy(); //// Destroys r.buffer
-		Data.deleteBlob(path);
-	});
+let import_gltf_glb = function(path) {
+	let b = data_get_blob(path);
+	let buf_off = a._init(b.byteLength); //// Allocate r.buffer
+	let buf = new Uint8Array(r.buffer, buf_off, b.byteLength);
+	let bbuf = new Uint8Array(b);
+	for (let i = 0; i < b.byteLength; ++i) {
+		buf[i] = bbuf[i];
+	}
+	a._parse();
+	let vertex_count = a._get_vertex_count();
+	let index_count = a._get_index_count();
+	let inda = new Uint32Array(r.buffer, a._get_indices(), index_count);
+	let posa = new Int16Array(r.buffer, a._get_positions(), vertex_count * 4);
+	let nora = new Int16Array(r.buffer, a._get_normals(), vertex_count * 2);
+	let uvs = a._get_uvs();
+	let texa = uvs == 0 ? null : new Int16Array(r.buffer, uvs, vertex_count * 2);
+	let name = path.split("\\").pop().split("/").pop().split(".").shift();
+	return {
+		name: name,
+		posa: posa,
+		nora: nora,
+		texa: texa,
+		inda: inda,
+		scale_pos: a._get_scale_pos(),
+		scale_tex: 1.0
+	};
+	// a._destroy(); //// Destroys r.buffer
+	data_delete_blob(path);
 }
 
-let plugin = Plugin.create();
-let formats = Path.meshFormats;
-let importers = Path.meshImporters;
+let plugin = plugin_create();
+let formats = path_mesh_formats;
+let importers = path_mesh_importers;
 formats.push("gltf");
 formats.push("glb");
 importers.set("gltf", import_gltf_glb);

+ 61 - 61
armorpaint/Assets/plugins/import_stl.js

@@ -20,73 +20,73 @@ let read_f32 = function(view) {
 }
 
 let import_stl = function(path, done) {
-	Data.getBlob(path, function(b) {
-		let view = new DataView(b);
-		pos = 0;
-		// let header = input.read(80);
-		pos += 80;
-		// if (header.getString(0, 5) == "solid") {
-			// return; // ascii not supported
-		// }
-		let faces = read_i32(view);
-		let posTemp = new Float32Array(faces * 9);
-		let norTemp = new Float32Array(faces * 3);
-		for (let i = 0; i < faces; ++i) {
-			let i3 = i * 3;
-			norTemp[i3    ] = read_f32(view);
-			norTemp[i3 + 1] = read_f32(view);
-			norTemp[i3 + 2] = read_f32(view);
-			let i9 = i * 9;
-			posTemp[i9    ] = read_f32(view);
-			posTemp[i9 + 1] = read_f32(view);
-			posTemp[i9 + 2] = read_f32(view);
-			posTemp[i9 + 3] = read_f32(view);
-			posTemp[i9 + 4] = read_f32(view);
-			posTemp[i9 + 5] = read_f32(view);
-			posTemp[i9 + 6] = read_f32(view);
-			posTemp[i9 + 7] = read_f32(view);
-			posTemp[i9 + 8] = read_f32(view);
-			read_i16(view); // attribute
-		}
-
-		let scalePos = 0.0;
-		for (let i = 0; i < posTemp.length; ++i) {
-			let f = Math.abs(posTemp[i]);
-			if (scalePos < f) scalePos = f;
-		}
-		let inv = 32767 * (1 / scalePos);
+	let b = data_get_blob(path);
+	let view = new DataView(b);
+	pos = 0;
+	// let header = input.read(80);
+	pos += 80;
+	// if (header.getString(0, 5) == "solid") {
+		// return; // ascii not supported
+	// }
+	let faces = read_i32(view);
+	let pos_temp = new Float32Array(faces * 9);
+	let nor_temp = new Float32Array(faces * 3);
+	for (let i = 0; i < faces; ++i) {
+		let i3 = i * 3;
+		nor_temp[i3    ] = read_f32(view);
+		nor_temp[i3 + 1] = read_f32(view);
+		nor_temp[i3 + 2] = read_f32(view);
+		let i9 = i * 9;
+		pos_temp[i9    ] = read_f32(view);
+		pos_temp[i9 + 1] = read_f32(view);
+		pos_temp[i9 + 2] = read_f32(view);
+		pos_temp[i9 + 3] = read_f32(view);
+		pos_temp[i9 + 4] = read_f32(view);
+		pos_temp[i9 + 5] = read_f32(view);
+		pos_temp[i9 + 6] = read_f32(view);
+		pos_temp[i9 + 7] = read_f32(view);
+		pos_temp[i9 + 8] = read_f32(view);
+		read_i16(view); // attribute
+	}
 
-		let verts = posTemp.length / 3;
-		let posa = new Int16Array(verts * 4);
-		let nora = new Int16Array(verts * 2);
-		let inda = new Uint32Array(verts);
-		for (let i = 0; i < verts; ++i) {
-			posa[i * 4    ] =  posTemp[i * 3    ] * inv;
-			posa[i * 4 + 1] = -posTemp[i * 3 + 2] * inv;
-			posa[i * 4 + 2] =  posTemp[i * 3 + 1] * inv;
-			nora[i * 2    ] =  norTemp[i    ] * 32767;
-			nora[i * 2 + 1] = -norTemp[i + 2] * 32767;
-			posa[i * 4 + 3] =  norTemp[i + 1] * 32767;
-			inda[i] = i;
+	let scale_pos = 0.0;
+	for (let i = 0; i < pos_temp.length; ++i) {
+		let f = Math.abs(pos_temp[i]);
+		if (scale_pos < f) {
+			scale_pos = f;
 		}
+	}
+	let inv = 32767 * (1 / scale_pos);
 
-		let name = path.split("\\").pop().split("/").pop().split(".").shift();
-		done({
-			name: name,
-			posa: posa,
-			nora: nora,
-			inda: inda,
-			scale_pos: scalePos,
-			scale_tex: 1.0
-		});
+	let verts = pos_temp.length / 3;
+	let posa = new Int16Array(verts * 4);
+	let nora = new Int16Array(verts * 2);
+	let inda = new Uint32Array(verts);
+	for (let i = 0; i < verts; ++i) {
+		posa[i * 4    ] =  pos_temp[i * 3    ] * inv;
+		posa[i * 4 + 1] = -pos_temp[i * 3 + 2] * inv;
+		posa[i * 4 + 2] =  pos_temp[i * 3 + 1] * inv;
+		nora[i * 2    ] =  nor_temp[i    ] * 32767;
+		nora[i * 2 + 1] = -nor_temp[i + 2] * 32767;
+		posa[i * 4 + 3] =  nor_temp[i + 1] * 32767;
+		inda[i] = i;
+	}
 
-		Data.deleteBlob(path);
-	});
+	data_delete_blob(path);
+	let name = path.split("\\").pop().split("/").pop().split(".").shift();
+	return {
+		name: name,
+		posa: posa,
+		nora: nora,
+		inda: inda,
+		scale_pos: scale_pos,
+		scale_tex: 1.0
+	};
 }
 
-let plugin = Plugin.create();
-let formats = Path.meshFormats;
-let importers = Path.meshImporters;
+let plugin = plugin_create();
+let formats = path_mesh_formats;
+let importers = path_mesh_importers;
 formats.push("stl");
 importers.set("stl", import_stl);
 

+ 21 - 19
armorpaint/Assets/plugins/import_svg.js

@@ -6,29 +6,31 @@ class R {
 let r = new R();
 
 // import_svg.js
-let import_svg = function(path, done) {
-	Data.getBlob(path, function(b) {
-		let buf_off = a._init(b.byteLength + 1); //// Allocate r.buffer
-		let buf = new Uint8Array(r.buffer, buf_off, b.byteLength + 1);
-		let bbuf = new Uint8Array(b);
-		for (let i = 0; i < b.byteLength; ++i) buf[i] = bbuf[i];
-		buf[b.byteLength] = 0;
+let import_svg = function(path) {
+	let b = data_get_blob(path);
+	let buf_off = a._init(b.byteLength + 1); //// Allocate r.buffer
+	let buf = new Uint8Array(r.buffer, buf_off, b.byteLength + 1);
+	let bbuf = new Uint8Array(b);
+	for (let i = 0; i < b.byteLength; ++i) {
+		buf[i] = bbuf[i];
+	}
+	buf[b.byteLength] = 0;
 
-		a._parse();
-		let w = a._get_pixels_w();
-		let h = a._get_pixels_h();
-		let pixels = r.buffer.slice(a._get_pixels(), a._get_pixels() + w * h * 4);
-		let image = Image.fromBytes(pixels, w, h);
-		done(image);
+	a._parse();
+	let w = a._get_pixels_w();
+	let h = a._get_pixels_h();
+	let pixels = r.buffer.slice(a._get_pixels(), a._get_pixels() + w * h * 4);
+	let image = image_from_bytes(pixels, w, h);
 
-		// a._destroy(); //// Destroys r.buffer
-		Data.deleteBlob(path);
-	});
+	// a._destroy(); //// Destroys r.buffer
+	data_delete_blob(path);
+
+	return image;
 }
 
-let plugin = Plugin.create();
-let formats = Path.textureFormats;
-let importers = Path.textureImporters;
+let plugin = plugin_create();
+let formats = path_texture_formats;
+let importers = path_texture_importers;
 formats.push("svg");
 importers.set("svg", import_svg);
 

+ 32 - 29
armorpaint/Assets/plugins/import_usdc.js

@@ -6,37 +6,40 @@ class R {
 let r = new R();
 
 // import_usdc.js
-let import_usdc = function(path, done) {
-	Data.getBlob(path, function(b) {
-		let buf_off = a._init(b.byteLength); //// Allocate r.buffer
-		let buf = new Uint8Array(r.buffer, buf_off, b.byteLength);
-		let bbuf = new Uint8Array(b);
-		for (let i = 0; i < b.byteLength; ++i) buf[i] = bbuf[i];
-		a._parse();
-		let vertex_count = a._get_vertex_count();
-		let index_count = a._get_index_count();
-		let inda = new Uint32Array(r.buffer, a._get_indices(), index_count);
-		let posa = new Int16Array(r.buffer, a._get_positions(), vertex_count * 4);
-		let nora = new Int16Array(r.buffer, a._get_normals(), vertex_count * 2);
-		let texa = new Int16Array(r.buffer, a._get_uvs(), vertex_count * 2);
-		let name = path.split("\\").pop().split("/").pop().split(".").shift();
-		done({
-			name: name,
-			posa: posa,
-			nora: nora,
-			texa: texa,
-			inda: inda,
-			scale_pos: a._get_scale_pos(),
-			scale_tex: 1.0
-		});
-		// a._destroy(); //// Destroys r.buffer
-		Data.deleteBlob(path);
-	});
+let import_usdc = function(path) {
+	let b = data_get_blob(path);
+	let buf_off = a._init(b.byteLength); //// Allocate r.buffer
+	let buf = new Uint8Array(r.buffer, buf_off, b.byteLength);
+	let bbuf = new Uint8Array(b);
+	for (let i = 0; i < b.byteLength; ++i) {
+		buf[i] = bbuf[i];
+	}
+	a._parse();
+	let vertex_count = a._get_vertex_count();
+	let index_count = a._get_index_count();
+	let inda = new Uint32Array(r.buffer, a._get_indices(), index_count);
+	let posa = new Int16Array(r.buffer, a._get_positions(), vertex_count * 4);
+	let nora = new Int16Array(r.buffer, a._get_normals(), vertex_count * 2);
+	let texa = new Int16Array(r.buffer, a._get_uvs(), vertex_count * 2);
+	let name = path.split("\\").pop().split("/").pop().split(".").shift();
+
+	// a._destroy(); //// Destroys r.buffer
+	data_delete_blob(path);
+
+	return {
+		name: name,
+		posa: posa,
+		nora: nora,
+		texa: texa,
+		inda: inda,
+		scale_pos: a._get_scale_pos(),
+		scale_tex: 1.0
+	};
 }
 
-let plugin = Plugin.create();
-let formats = Path.meshFormats;
-let importers = Path.meshImporters;
+let plugin = plugin_create();
+let formats = path_mesh_formats;
+let importers = path_mesh_importers;
 formats.push("usdc");
 importers.set("usdc", import_usdc);
 

+ 60 - 46
armorpaint/Assets/plugins/texture_breakdown.js

@@ -1,72 +1,86 @@
 
-let plugin = Plugin.create();
-let h1 = new Handle();
-let h2 = new Handle();
+let plugin = plugin_create();
+let h1 = zui_handle_create();
+let h2 = zui_handle_create();
 
 let slots = ["base", "occ", "rough", "nor"];
 let breakdown = null;
 
-plugin.drawUI = function(ui) {
-	if (Zui.panel(h1, "Texture Breakdown")) {
+plugin.draw_ui = function(ui) {
+	if (zui_panel(h1, "Texture Breakdown")) {
 
-		ui.g.end();
-		drawBreakdown();
-		ui.g.begin(false);
+		g2_end();
+		draw_breakdown();
+		g2_begin(ui);
 
-		// Zui.row([1 / 4]);
-		// Zui.combo(h2, ["Material", "Viewport"], "Type");
+		// zui_row([1 / 4]);
+		// zui_combo(h2, ["Material", "Viewport"], "Type");
 
-		Zui.image(breakdown);
-		if (ui.isHovered && ui.inputReleasedR) {
-			let x = ui.inputX - ui._windowX;
-			let w = ui._windowW / slots.length;
+		zui_image(breakdown);
+		if (ui.is_hovered && ui.input_released_r) {
+			let x = ui.input_x - ui._window_x;
+			let w = ui._window_w / slots.length;
 			let i = (x / w) | 0;
-			UIMenu.draw(function(ui) {
-				Zui.text(slots[i], 2, ui.t.HIGHLIGHT_COL);
-				if (Zui.button("Delete", 0)) {
+			ui_menu_draw(function(ui) {
+				zui_text(slots[i], 2, ui.t.HIGHLIGHT_COL);
+				if (zui_button("Delete", 0)) {
 					slots.splice(i, 1);
 				}
 			}, 2);
 		}
 
-		Zui.row([1 / 4, 1 / 4]);
+		zui_row([1 / 4, 1 / 4]);
 
-		if (Zui.button("Add")) {
-			UIMenu.draw(function(ui) {
-				Zui.text("Channel", 2, ui.t.HIGHLIGHT_COL);
-				if (Zui.button("Base Color", 0)) { slots.push("base"); }
-				if (Zui.button("Occlusion", 0)) { slots.push("occ"); }
-				if (Zui.button("Roughness", 0)) { slots.push("rough"); }
-				if (Zui.button("Metallic", 0)) { slots.push("metal"); }
-				if (Zui.button("Normal Map", 0)) { slots.push("nor"); }
+		if (zui_button("Add")) {
+			ui_menu_draw(function(ui) {
+				zui_text("Channel", 2, ui.t.HIGHLIGHT_COL);
+				if (zui_button("Base Color", 0)) {
+					slots.push("base");
+				}
+				if (zui_button("Occlusion", 0)) {
+					slots.push("occ");
+				}
+				if (zui_button("Roughness", 0)) {
+					slots.push("rough");
+				}
+				if (zui_button("Metallic", 0)) {
+					slots.push("metal");
+				}
+				if (zui_button("Normal Map", 0)) {
+					slots.push("nor");
+				}
 			}, 6);
 		}
 
-		if (Zui.button("Export")) {
-			UIFiles.show("png", true, false, function(path) {
-				Base.notifyOnNextFrame(function() {
-					var f = UIFiles.filename;
-					if (f === "") f = "untitled";
-					if (!f.endsWith(".png")) f += ".png";
-					Krom.writePng(path + Path.sep + f, breakdown.getPixels(), breakdown.get_width(), breakdown.get_height(), 2);
+		if (zui_button("Export")) {
+			ui_files_show("png", true, false, function(path) {
+				base_notify_on_next_frame(function() {
+					var f = ui_files_filename;
+					if (f === "") {
+						f = "untitled";
+					}
+					if (!f.endsWith(".png")) {
+						f += ".png";
+					}
+					krom_write_png(path + path_sep + f, image_get_pixels(breakdown), breakdown.width, breakdown.height, 2);
 				});
 			});
 		}
 	}
 }
 
-function drawBreakdown(type) {
+function draw_breakdown(type) {
 	if (breakdown === null) {
-		breakdown = core.Image.createRenderTarget(4096, 4096);
+		breakdown = image_create_render_target(4096, 4096);
 	}
-	let g2 = breakdown.get_g2();
-	g2.begin(true, 0xff000000);
-	g2.disableScissor();
+	g2_begin(breakdown);
+	g2_clear(0xff000000);
+	g2_disable_scissor();
 
 	if (h2.position === 0) { // Material
-		var lay = Context.raw.layer;
+		var lay = context_raw_layer;
 		for (let i = 0; i < slots.length; ++i) {
-			g2.set_pipeline(UIView2D.pipe);
+			g2_set_pipeline(ui_view_2d_pipe);
 			let image = lay.texpaint;
 			let channel = 0;
 			if (slots[i] === "occ") {
@@ -85,12 +99,12 @@ function drawBreakdown(type) {
 				image = lay.texpaint_nor;
 				channel = 5;
 			}
-			breakdown.get_g4().setInt(UIView2D.channelLocation, channel);
-			var step_source = image.get_width() / slots.length;
-			var step_dest = breakdown.get_width() / slots.length;
-			g2.drawScaledSubImage(image, step_source * i, 0, step_source, image.get_height(), step_dest * i, 0, step_dest, breakdown.get_height());
-			g2.end(); // Flush
-			g2.begin(false);
+			g4_set_int(ui_view_2d_channel_location, channel);
+			var step_source = image.width / slots.length;
+			var step_dest = breakdown.width / slots.length;
+			g2_draw_scaled_sub_image(image, step_source * i, 0, step_source, image.height, step_dest * i, 0, step_dest, breakdown.height);
+			g2_end(); // Flush
+			g2_begin();
 		}
 	}
 	else { // Viewport

+ 29 - 29
armorpaint/Assets/plugins/uv_unwrap.js

@@ -10,18 +10,18 @@ function unwrap_mesh(mesh) {
 	let positions = mesh.posa;
 	let normals = mesh.nora;
 	let indices = mesh.inda;
-	let vertexCount = positions.length / 4;
-	let indexCount = indices.length;
+	let vertex_count = positions.length / 4;
+	let index_count = indices.length;
 
-	a._setVertexCount(vertexCount);
-	a._setIndexCount(indexCount);
-	let pa = new Float32Array(r.buffer, a._setPositions(), vertexCount * 3);
-	let na = new Float32Array(r.buffer, a._setNormals(), vertexCount * 3);
-	let ia = new Uint32Array(r.buffer, a._setIndices(), indexCount);
+	a._setVertexCount(vertex_count);
+	a._setIndexCount(index_count);
+	let pa = new Float32Array(r.buffer, a._setPositions(), vertex_count * 3);
+	let na = new Float32Array(r.buffer, a._setNormals(), vertex_count * 3);
+	let ia = new Uint32Array(r.buffer, a._setIndices(), index_count);
 
 	let inv = 1 / 32767;
 
-	for (let i = 0; i < vertexCount; i++) {
+	for (let i = 0; i < vertex_count; i++) {
 		pa[i * 3    ] = positions[i * 4    ] * inv;
 		pa[i * 3 + 1] = positions[i * 4 + 1] * inv;
 		pa[i * 3 + 2] = positions[i * 4 + 2] * inv;
@@ -29,25 +29,25 @@ function unwrap_mesh(mesh) {
 		na[i * 3 + 1] = normals  [i * 2 + 1] * inv;
 		na[i * 3 + 2] = positions[i * 4 + 3] * inv;
 	}
-	for (let i = 0; i < indexCount; i++) {
+	for (let i = 0; i < index_count; i++) {
 		ia[i] = indices[i];
 	}
 
 	a._unwrap();
 
-	vertexCount = a._getVertexCount();
-	indexCount = a._getIndexCount();
-	pa = new Float32Array(r.buffer, a._getPositions(), vertexCount * 3);
-	na = new Float32Array(r.buffer, a._getNormals(), vertexCount * 3);
-	let ua = new Float32Array(r.buffer, a._getUVs(), vertexCount * 2);
-	ia = new Uint32Array(r.buffer, a._getIndices(), indexCount);
+	vertex_count = a._getVertexCount();
+	index_count = a._getIndexCount();
+	pa = new Float32Array(r.buffer, a._getPositions(), vertex_count * 3);
+	na = new Float32Array(r.buffer, a._getNormals(), vertex_count * 3);
+	let ua = new Float32Array(r.buffer, a._getUVs(), vertex_count * 2);
+	ia = new Uint32Array(r.buffer, a._getIndices(), index_count);
 
-	let pa16 = new Int16Array(vertexCount * 4);
-	let na16 = new Int16Array(vertexCount * 2);
-	let ua16 = new Int16Array(vertexCount * 2);
-	let ia32 = new Uint32Array(indexCount);
+	let pa16 = new Int16Array(vertex_count * 4);
+	let na16 = new Int16Array(vertex_count * 2);
+	let ua16 = new Int16Array(vertex_count * 2);
+	let ia32 = new Uint32Array(index_count);
 
-	for (let i = 0; i < vertexCount; i++) {
+	for (let i = 0; i < vertex_count; i++) {
 		pa16[i * 4    ] = pa[i * 3    ] / inv;
 		pa16[i * 4 + 1] = pa[i * 3 + 1] / inv;
 		pa16[i * 4 + 2] = pa[i * 3 + 2] / inv;
@@ -57,7 +57,7 @@ function unwrap_mesh(mesh) {
 		ua16[i * 2    ] = ua[i * 2    ] / inv;
 		ua16[i * 2 + 1] = ua[i * 2 + 1] / inv;
 	}
-	for (let i = 0; i < indexCount; i++) {
+	for (let i = 0; i < index_count; i++) {
 		ia32[i] = ia[i];
 	}
 
@@ -69,12 +69,12 @@ function unwrap_mesh(mesh) {
 	// a._destroy(); //// Destroys r.buffer
 }
 
-let plugin = Plugin.create();
-let h1 = new Handle();
-plugin.drawUI = function(ui) {
-	if (Zui.panel(h1, "UV Unwrap")) {
-		if (Zui.button("Unwrap Mesh")) {
-			for (const po of Project.paintObjects) {
+let plugin = plugin_create();
+let h1 = zui_handle_create();
+plugin.draw_ui = function(ui) {
+	if (zui_panel(h1, "UV Unwrap")) {
+		if (zui_button("Unwrap Mesh")) {
+			for (const po of project_paint_objects) {
 				let raw = po.data.raw;
 				var mesh = {
 					posa: raw.vertex_arrays[0].values,
@@ -92,12 +92,12 @@ plugin.drawUI = function(ui) {
 				geom.ready = false;
 				geom.build();
 			}
-			UtilMesh.mergeMesh();
+			util_mesh_merge_mesh();
 		}
 	}
 }
 
-let unwrappers = UtilMesh.unwrappers;
+let unwrappers = util_mesh_unwrappers;
 unwrappers.set("uv_unwrap.js", unwrap_mesh);
 plugin.delete = function() {
 	unwrappers.delete("uv_unwrap.js");

+ 6 - 6
armorpaint/Assets/plugins/viewport_celshade.js

@@ -1,16 +1,16 @@
 
-let plugin = Plugin.create();
+let plugin = plugin_create();
 
 // Register custom viewport shader
-ContextBase.setViewportShader(function(shader) {
-	shader.add_uniform('vec3 lightDir', '_light_dir');
-	shader.write(`
+context_set_viewport_shader(function(shader) {
+	node_shader_add_uniform(shader, "vec3 lightDir", "_light_dir");
+	node_shader_write(shader, `
 		float dotNL = max(dot(n, lightDir), 0.0);
 		vec3 outputColor = basecol * step(0.5, dotNL) + basecol;
 	`);
-	return 'outputColor';
+	return "outputColor";
 });
 
 plugin.delete = function() {
-	ContextBase.setViewportShader(null);
+	context_set_viewport_shader(null);
 }

+ 3 - 1
armorpaint/Sources/make_material.ts

@@ -267,7 +267,9 @@ function make_material_bake_node_previews() {
 		let key: string = keys[i];
 		if (array_index_of(context_raw.node_previews_used, key) == -1) {
 			let image: image_t = map_get(context_raw.node_previews, key);
-			base_notify_on_next_frame(function() { image_unload(image); });
+			base_notify_on_next_frame(function () {
+				image_unload(image);
+			});
 			map_delete(context_raw.node_previews, key);
 		}
 	}

+ 7 - 14
armorpaint/Sources/nodes/brush_output_node.ts

@@ -18,20 +18,13 @@ function brush_output_node_parse_inputs(self: brush_output_node_t) {
 	let last_mask: image_t = context_raw.brush_mask_image;
 	let last_stencil: image_t = context_raw.brush_stencil_image;
 
-	let input0: any;
-	let input1: any;
-	let input2: any;
-	let input3: any;
-	let input4: any;
-	let input5: any;
-	let input6: any;
-	logic_node_input_get(self.base.inputs[0], function (value: any) { input0 = value; });
-	logic_node_input_get(self.base.inputs[1], function (value: any) { input1 = value; });
-	logic_node_input_get(self.base.inputs[2], function (value: any) { input2 = value; });
-	logic_node_input_get(self.base.inputs[3], function (value: any) { input3 = value; });
-	logic_node_input_get(self.base.inputs[4], function (value: any) { input4 = value; });
-	logic_node_input_get(self.base.inputs[5], function (value: any) { input5 = value; });
-	logic_node_input_get(self.base.inputs[6], function (value: any) { input6 = value; });
+	let input0: any = logic_node_input_get(self.base.inputs[0]);
+	let input1: any = logic_node_input_get(self.base.inputs[1]);
+	let input2: any = logic_node_input_get(self.base.inputs[2]);
+	let input3: any = logic_node_input_get(self.base.inputs[3]);
+	let input4: any = logic_node_input_get(self.base.inputs[4]);
+	let input5: any = logic_node_input_get(self.base.inputs[5]);
+	let input6: any = logic_node_input_get(self.base.inputs[6]);
 
 	context_raw.paint_vec = input0;
 	context_raw.brush_nodes_radius = input1;

+ 4 - 8
armorpaint/Sources/nodes/input_node.ts

@@ -120,14 +120,10 @@ function input_node_update(self: float_node_t) {
 	context_raw.parse_brush_inputs(context_raw.brush_output_node_inst);
 }
 
-function input_node_get(self: input_node_t, from: i32, done: (a: any)=>void) {
-	logic_node_input_get(self.base.inputs[0], function (value) {
-		context_raw.brush_lazy_radius = value;
-		logic_node_input_get(self.base.inputs[1], function (value) {
-			context_raw.brush_lazy_step = value;
-			done(input_node_coords);
-		});
-	});
+function input_node_get(self: input_node_t, from: i32): any {
+	context_raw.brush_lazy_radius = logic_node_input_get(self.base.inputs[0]);
+	context_raw.brush_lazy_step = logic_node_input_get(self.base.inputs[1]);;
+	return input_node_coords;
 }
 
 let input_node_def: zui_node_t = {

+ 5 - 5
armorpaint/Sources/nodes/tex_image_node.ts

@@ -12,12 +12,12 @@ function tex_image_node_create(arg: any): tex_image_node_t {
 	return n;
 }
 
-function tex_image_node_get(self: tex_image_node_t, from: i32, done: (a: any)=>void) {
+function tex_image_node_get(self: tex_image_node_t, from: i32): any {
 	if (from == 0) {
-		done(self.file + ".rgb");
+		return self.file + ".rgb";
 	}
 	else {
-		done(self.file + ".a");
+		return self.file + ".a";
 	}
 }
 
@@ -35,7 +35,7 @@ let tex_image_node_def: zui_node_t = {
 			name: _tr("Vector"),
 			type: "VECTOR",
 			color: 0xff6363c7,
-			default_value: new f32_array_t([0.0, 0.0, 0.0])
+			default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 		}
 	],
 	outputs: [
@@ -45,7 +45,7 @@ let tex_image_node_def: zui_node_t = {
 			name: _tr("Color"),
 			type: "VALUE", // Match brush output socket type
 			color: 0xffc7c729,
-			default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+			default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 		},
 		{
 			id: 0,

+ 11 - 8
armorpaint/Sources/render_path_paint.ts

@@ -841,20 +841,23 @@ function render_path_paint_set_plane_mesh() {
 
 	let tiled: bool = ui_view2d_tiled_show;
 	if (tiled && scene_get_child(".PlaneTiled") == null) {
+
+
+
 		// 3x3 planes
-		let posa: i32[] = [32767,0,-32767,0,10922,0,-10922,0,10922,0,-32767,0,10922,0,-10922,0,-10922,0,10922,0,-10922,0,-10922,0,-10922,0,10922,0,-32767,0,32767,0,-32767,0,10922,0,10922,0,10922,0,-10922,0,32767,0,-10922,0,10922,0,32767,0,10922,0,10922,0,32767,0,10922,0,10922,0,-10922,0,-10922,0,-32767,0,10922,0,-32767,0,-10922,0,32767,0,-10922,0,10922,0,10922,0,10922,0,-10922,0,-10922,0,-32767,0,-32767,0,-10922,0,-32767,0,-32767,0,10922,0,-32767,0,-10922,0,-10922,0,-10922,0,-32767,0,32767,0,-32767,0,32767,0,-10922,0,10922,0,-10922,0,10922,0,-10922,0,10922,0,10922,0,-10922,0,10922,0,-10922,0,10922,0,-10922,0,32767,0,-32767,0,32767,0,10922,0,10922,0,10922,0,32767,0,-10922,0,32767,0,32767,0,10922,0,32767,0,32767,0,10922,0,32767,0,-10922,0,-10922,0,-10922,0,10922,0,-32767,0,10922,0,32767,0,-10922,0,32767,0,10922,0,10922,0,10922,0,-10922,0,-32767,0,-10922,0,-10922,0,-32767,0,-10922,0,10922,0,-32767,0,10922,0,-10922,0,-10922,0,-10922,0];
-		let nora: i32[] = [0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767];
-		let texa: i32[] = [32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0];
-		let inda: i32[] = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53];
+		let posa: i16[] = [32767,0,-32767,0,10922,0,-10922,0,10922,0,-32767,0,10922,0,-10922,0,-10922,0,10922,0,-10922,0,-10922,0,-10922,0,10922,0,-32767,0,32767,0,-32767,0,10922,0,10922,0,10922,0,-10922,0,32767,0,-10922,0,10922,0,32767,0,10922,0,10922,0,32767,0,10922,0,10922,0,-10922,0,-10922,0,-32767,0,10922,0,-32767,0,-10922,0,32767,0,-10922,0,10922,0,10922,0,10922,0,-10922,0,-10922,0,-32767,0,-32767,0,-10922,0,-32767,0,-32767,0,10922,0,-32767,0,-10922,0,-10922,0,-10922,0,-32767,0,32767,0,-32767,0,32767,0,-10922,0,10922,0,-10922,0,10922,0,-10922,0,10922,0,10922,0,-10922,0,10922,0,-10922,0,10922,0,-10922,0,32767,0,-32767,0,32767,0,10922,0,10922,0,10922,0,32767,0,-10922,0,32767,0,32767,0,10922,0,32767,0,32767,0,10922,0,32767,0,-10922,0,-10922,0,-10922,0,10922,0,-32767,0,10922,0,32767,0,-10922,0,32767,0,10922,0,10922,0,10922,0,-10922,0,-32767,0,-10922,0,-10922,0,-32767,0,-10922,0,10922,0,-32767,0,10922,0,-10922,0,-10922,0,-10922,0];
+		let nora: i16[] = [0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767];
+		let texa: i16[] = [32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0,32767,32767,32767,0,0,0];
+		let inda: u32[] = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53];
 		let raw: mesh_data_t = {
 			name: ".PlaneTiled",
 			vertex_arrays: [
-				{ attrib: "pos", values: new i16_array_t(posa), data: "short4norm" },
-				{ attrib: "nor", values: new i16_array_t(nora), data: "short2norm" },
-				{ attrib: "tex", values: new i16_array_t(texa), data: "short2norm" }
+				{ attrib: "pos", values: i16_array_create_from_array(posa), data: "short4norm" },
+				{ attrib: "nor", values: i16_array_create_from_array(nora), data: "short2norm" },
+				{ attrib: "tex", values: i16_array_create_from_array(texa), data: "short2norm" }
 			],
 			index_arrays: [
-				{ values: new u32_array_t(inda), material: 0 }
+				{ values: u32_array_create_from_array(inda), material: 0 }
 			],
 			scale_pos: 1.5,
 			scale_tex: 1.0

+ 24 - 24
armorsculpt/Assets/plugins/hello_world.js

@@ -1,31 +1,31 @@
 
-let plugin = Plugin.create();
+let plugin = plugin_create();
 
-let h1 = new Handle();
-let h2 = new Handle();
-let h3 = new Handle();
-let h4 = new Handle();
-let h5 = new Handle();
-let h6 = new Handle();
-let h7 = new Handle();
+let h1 = zui_handle_create();
+let h2 = zui_handle_create();
+let h3 = zui_handle_create();
+let h4 = zui_handle_create();
+let h5 = zui_handle_create();
+let h6 = zui_handle_create();
+let h7 = zui_handle_create();
 
-plugin.drawUI = function(ui) {
-	if (Zui.panel(h1, "My Plugin")) {
-		Zui.text("Label");
-		Zui.textInput(h7, "Text Input");
-		if (Zui.button("Button")) {
+plugin.draw_ui = function(ui) {
+	if (zui_panel(h1, "My Plugin")) {
+		zui_text("Label");
+		zui_textInput(h7, "Text Input");
+		if (zui_button("Button")) {
 			console.error("Hello");
 		}
-		Zui.row([1/2, 1/2]);
-		Zui.button("Button A");
-		Zui.button("Button B");
-		Zui.combo(h5, ["Item 1", "Item 2"], "Combo");
-		Zui.row([1/2, 1/2]);
-		Zui.slider(h2, "Slider", 0, 1, true);
-		Zui.slider(h3, "Slider", 0, 1, true);
-		Zui.check(h4, "Check");
-		Zui.radio(h6, 0, "Radio 1");
-		Zui.radio(h6, 1, "Radio 2");
-		Zui.radio(h6, 2, "Radio 3");
+		zui_row([1/2, 1/2]);
+		zui_button("Button A");
+		zui_button("Button B");
+		zui_combo(h5, ["Item 1", "Item 2"], "Combo");
+		zui_row([1/2, 1/2]);
+		zui_slider(h2, "Slider", 0, 1, true);
+		zui_slider(h3, "Slider", 0, 1, true);
+		zui_check(h4, "Check");
+		zui_radio(h6, 0, "Radio 1");
+		zui_radio(h6, 1, "Radio 2");
+		zui_radio(h6, 2, "Radio 3");
 	}
 }

+ 64 - 65
armorsculpt/Sources/import_mesh.ts

@@ -22,9 +22,8 @@ function import_mesh_run(path: string, _clear_layers = true, replace_existing =
 	else {
 		let ext = substring(path, string_last_index_of(path, ".") + 1, path.length);
 		let importer = map_get(path_mesh_importers, ext);
-		importer(path, function (mesh: any) {
-			replace_existing ? import_mesh_make_mesh(mesh, path) : import_mesh_add_mesh(mesh);
-		});
+		let mesh: any = importer(path);
+		replace_existing ? import_mesh_make_mesh(mesh, path) : import_mesh_add_mesh(mesh);
 	}
 
 	project_mesh_assets = [path];
@@ -45,7 +44,7 @@ function import_mesh_finish_import() {
 
 	if (project_paint_objects.length > 1) {
 		// Sort by name
-		array_sort(project_paint_objects, function (a: string, b: string): i32 {
+		array_sort(project_paint_objects, function (a: mesh_object_t, b: mesh_object_t): i32 {
 			if (a.base.name < b.base.name) {
 				return -1;
 			}
@@ -82,79 +81,79 @@ function import_mesh_finish_import() {
 	///end
 }
 
-function import_mesh_make_mesh(mesh: any, path: string) {
-	if (mesh == null || mesh.posa == null || mesh.nora == null || mesh.inda == null || mesh.posa.length == 0) {
-		console_error(strings_error3());
-		return;
+function _import_mesh_make_mesh(mesh: any) {
+	let raw = import_mesh_raw_mesh(mesh);
+	if (mesh.cola != null) {
+		array_push(raw.vertex_arrays, { values: mesh.cola, attrib: "col", data: "short4norm" });
 	}
 
-	let _make_mesh = function() {
-		let raw = import_mesh_raw_mesh(mesh);
-		if (mesh.cola != null) {
-			array_push(raw.vertex_arrays, { values: mesh.cola, attrib: "col", data: "short4norm" });
-		}
-
-		let md: mesh_data_t = mesh_data_create(raw);
-		context_raw.paint_object = context_main_object();
+	let md: mesh_data_t = mesh_data_create(raw);
+	context_raw.paint_object = context_main_object();
 
-		context_select_paint_object(context_main_object());
-		for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
-			let p = project_paint_objects[i];
-			if (p == context_raw.paint_object) {
-				continue;
-			}
-			data_delete_mesh(p.data._.handle);
-			mesh_object_remove(p);
-		}
-		let handle = context_raw.paint_object.data._.handle;
-		if (handle != "SceneSphere" && handle != "ScenePlane") {
-			data_delete_mesh(handle);
+	context_select_paint_object(context_main_object());
+	for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
+		let p = project_paint_objects[i];
+		if (p == context_raw.paint_object) {
+			continue;
 		}
+		data_delete_mesh(p.data._.handle);
+		mesh_object_remove(p);
+	}
+	let handle = context_raw.paint_object.data._.handle;
+	if (handle != "SceneSphere" && handle != "ScenePlane") {
+		data_delete_mesh(handle);
+	}
 
-		if (import_mesh_clear_layers) {
-			while (project_layers.length > 0) {
-				let l = project_layers.pop();
-				slot_layer_unload(l);
-			}
-			base_new_layer(false);
-			app_notify_on_init(base_init_layers);
-			history_reset();
+	if (import_mesh_clear_layers) {
+		while (project_layers.length > 0) {
+			let l = project_layers.pop();
+			slot_layer_unload(l);
 		}
+		base_new_layer(false);
+		app_notify_on_init(base_init_layers);
+		history_reset();
+	}
 
-		mesh_object_set_data(context_raw.paint_object, md);
-		context_raw.paint_object.base.name = mesh.name;
-		project_paint_objects = [context_raw.paint_object];
-
-		md._.handle = raw.name;
-		map_set(data_cached_meshes, md._.handle, md);
+	mesh_object_set_data(context_raw.paint_object, md);
+	context_raw.paint_object.base.name = mesh.name;
+	project_paint_objects = [context_raw.paint_object];
 
-		context_raw.ddirty = 4;
-		ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2;
-		ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2;
+	md._.handle = raw.name;
+	map_set(data_cached_meshes, md._.handle, md);
 
-		// Wait for add_mesh calls to finish
-		app_notify_on_init(import_mesh_finish_import);
+	context_raw.ddirty = 4;
+	ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2;
+	ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2;
+
+	// Wait for add_mesh calls to finish
+	app_notify_on_init(import_mesh_finish_import);
+
+	base_notify_on_next_frame(function (mesh: any) {
+		let f32 = f32_array_create(config_get_texture_res_x() * config_get_texture_res_y() * 4);
+		for (let i: i32 = 0; i < math_floor(mesh.inda.length); ++i) {
+			let index = mesh.inda[i];
+			f32[i * 4]     = mesh.posa[index * 4]     / 32767;
+			f32[i * 4 + 1] = mesh.posa[index * 4 + 1] / 32767;
+			f32[i * 4 + 2] = mesh.posa[index * 4 + 2] / 32767;
+			f32[i * 4 + 3] = 1.0;
+		}
+		let imgmesh = image_from_bytes(f32.buffer, config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.RGBA128);
+		let texpaint = project_layers[0].texpaint;
+		g2_begin(texpaint);
+		g2_set_pipeline(base_pipe_copy128);
+		g2_draw_scaled_image(imgmesh, 0, 0, config_get_texture_res_x(), config_get_texture_res_y());
+		g2_set_pipeline(null);
+		g2_end();
+	}, mesh);
+}
 
-		base_notify_on_next_frame(function () {
-			let f32 = f32_array_create(config_get_texture_res_x() * config_get_texture_res_y() * 4);
-			for (let i: i32 = 0; i < math_floor(mesh.inda.length); ++i) {
-				let index = mesh.inda[i];
-				f32[i * 4]     = mesh.posa[index * 4]     / 32767;
-				f32[i * 4 + 1] = mesh.posa[index * 4 + 1] / 32767;
-				f32[i * 4 + 2] = mesh.posa[index * 4 + 2] / 32767;
-				f32[i * 4 + 3] = 1.0;
-			}
-			let imgmesh = image_from_bytes(f32.buffer, config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.RGBA128);
-			let texpaint = project_layers[0].texpaint;
-			g2_begin(texpaint);
-			g2_set_pipeline(base_pipe_copy128);
-			g2_draw_scaled_image(imgmesh, 0, 0, config_get_texture_res_x(), config_get_texture_res_y());
-			g2_set_pipeline(null);
-			g2_end();
-		});
+function import_mesh_make_mesh(mesh: any, path: string) {
+	if (mesh == null || mesh.posa == null || mesh.nora == null || mesh.inda == null || mesh.posa.length == 0) {
+		console_error(strings_error3());
+		return;
 	}
 
-	_make_mesh();
+	_import_mesh_make_mesh(mesh);
 }
 
 function import_mesh_add_mesh(mesh: any) {

+ 4 - 4
armorsculpt/Sources/make_material.ts

@@ -268,9 +268,9 @@ function make_material_bake_node_previews() {
 		let key: string = keys[i];
 		if (array_index_of(context_raw.node_previews_used, key) == -1) {
 			let image = map_get(context_raw.node_previews, key);
-			base_notify_on_next_frame(function() {
+			base_notify_on_next_frame(function (image: image_t) {
 				image_unload(image);
-			});
+			}, image);
 			map_delete(context_raw.node_previews, key);
 		}
 	}
@@ -370,7 +370,7 @@ function make_material_voxelgi_half_extents(): string {
 }
 
 function make_material_delete_context(c: shader_context_t) {
-	base_notify_on_next_frame(function () { // Ensure pipeline is no longer in use
+	base_notify_on_next_frame(function (c: shader_context_t) { // Ensure pipeline is no longer in use
 		shader_context_delete(c);
-	});
+	}, c);
 }

+ 5 - 10
armorsculpt/Sources/nodes/brush_output_node.ts

@@ -16,16 +16,11 @@ function brush_output_node_parse_inputs(self: brush_output_node_t) {
 	let last_mask = context_raw.brush_mask_image;
 	let last_stencil = context_raw.brush_stencil_image;
 
-	let input0: any;
-	let input1: any;
-	let input2: any;
-	let input3: any;
-	let input4: any;
-	logic_node_input_get(self.base.inputs[0], function (value: any) { input0 = value; });
-	logic_node_input_get(self.base.inputs[1], function (value: any) { input1 = value; });
-	logic_node_input_get(self.base.inputs[2], function (value: any) { input2 = value; });
-	logic_node_input_get(self.base.inputs[3], function (value: any) { input3 = value; });
-	logic_node_input_get(self.base.inputs[4], function (value: any) { input4 = value; });
+	let input0: any = logic_node_input_get(self.base.inputs[0]);
+	let input1: any = logic_node_input_get(self.base.inputs[1]);
+	let input2: any = logic_node_input_get(self.base.inputs[2]);
+	let input3: any = logic_node_input_get(self.base.inputs[3]);
+	let input4: any = logic_node_input_get(self.base.inputs[4]);
 
 	context_raw.paint_vec = input0;
 	context_raw.brush_nodes_radius = input1;

+ 10 - 8
base/Assets/plugins/autosave.js

@@ -1,21 +1,23 @@
 
-let plugin = Plugin.create();
+let plugin = plugin_create();
 
-let h1 = new Handle();
-let h2 = new Handle({value: 5});
+let h1 = zui_handle_create();
+let h2 = zui_handle_create({value: 5});
 let timer = 0.0;
 
-plugin.drawUI = function(ui) {
-	if (Zui.panel(h1, "Auto Save")) {
-		Zui.slider(h2, "min", 1, 15, false, 1);
+plugin.draw_ui = function(ui) {
+	if (zui_panel(h1, "Auto Save")) {
+		zui_slider(h2, "min", 1, 15, false, 1);
 	}
 }
 
 plugin.update = function() {
-	if (Project.filepath == "") return;
+	if (project_filepath == "") {
+		return;
+	}
 	timer += 1 / 60;
 	if (timer >= h2.value * 60) {
 		timer = 0.0;
-		Project.projectSave();
+		project_save();
 	}
 }

+ 9 - 10
base/Assets/plugins/import_tiff.js

@@ -5,18 +5,17 @@ var UTIF={},pako=null;function log(){console.log(arguments)}!function(x,A){funct
 
 // Register as ArmorPaint plugin
 let import_tiff = function(path, done) {
-	Data.getBlob(path, function(b) {
-		let ifds = UTIF.decode(b);
-		UTIF.decodeImage(b, ifds[0]);
-		let rgba = UTIF.toRGBA8(ifds[0]);
-		let image = Image.fromBytes(rgba.buffer, ifds[0].width, ifds[0].height);
-		done(image);
-	});
+	let b = data_get_blob(path);
+	let ifds = UTIF.decode(b);
+	UTIF.decodeImage(b, ifds[0]);
+	let rgba = UTIF.toRGBA8(ifds[0]);
+	let image = image_from_bytes(rgba.buffer, ifds[0].width, ifds[0].height);
+	return image;
 }
 
-let plugin = Plugin.create();
-let formats = Path.textureFormats;
-let importers = Path.textureImporters;
+let plugin = plugin_create();
+let formats = path_texture_formats;
+let importers = path_texture_importers;
 formats.push("tif");
 formats.push("tiff");
 importers.set("tif", import_tiff);

+ 14 - 15
base/Assets/plugins/import_txt.js

@@ -1,21 +1,20 @@
 
-let import_txt = function(path, done) {
-	Data.getBlob(path, function(b) {
-		var filename = path.split('\\').pop().split('/').pop();
-		try {
-			UIBox.showMessage(filename, System.bufferToString(b), true);
-			UIBox.clickToHide = false;
-			Data.deleteBlob(path);
-		}
-		catch(e) {
-			console.error(e);
-		}
-	});
+let import_txt = function(path) {
+	let b = data_get_blob(path);
+	var filename = path.split('\\').pop().split('/').pop();
+	try {
+		ui_box_show_message(filename, sys_buffer_to_string(b), true);
+		ui_box_click_to_hide = false;
+		data_delete_blob(path);
+	}
+	catch(e) {
+		console.error(e);
+	}
 }
 
-let plugin = Plugin.create();
-let formats = Path.textureFormats;
-let importers = Path.textureImporters;
+let plugin = plugin_create();
+let formats = path_texture_formats;
+let importers = path_texture_importers;
 formats.push("txt");
 importers.set("txt", import_txt);
 

+ 50 - 48
base/Sources/base.ts

@@ -252,28 +252,30 @@ function base_init() {
 	base_last_window_width = sys_width();
 	base_last_window_height = sys_height();
 
-	sys_notify_on_drop_files(function(drop_path: string) {
+	sys_notify_on_drop_files(function (drop_path: string) {
 		///if krom_linux
-		drop_path = decodeURIComponent(drop_path);
+		krom_log(drop_path);
+		drop_path = uri_decode(drop_path);
+		krom_log(drop_path);
 		///end
 		drop_path = trim_end(drop_path);
 		array_push(base_drop_paths, drop_path);
 	});
 
 	sys_notify_on_app_state(
-		function() { // Foreground
+		function () { // Foreground
 			context_raw.foreground_event = true;
 			context_raw.last_paint_x = -1;
 			context_raw.last_paint_y = -1;
 		},
-		function() {}, // Resume
-		function() {}, // Pause
-		function() { // Background
+		function () {}, // Resume
+		function () {}, // Pause
+		function () { // Background
 			// Release keys after alt-tab / win-tab
 			keyboard_up_listener(key_code_t.ALT);
 			keyboard_up_listener(key_code_t.WIN);
 		},
-		function() { // Shutdown
+		function () { // Shutdown
 			///if (krom_android || krom_ios)
 			project_save();
 			///end
@@ -562,7 +564,7 @@ function base_resize() {
 
 	if (ui_nodes_grid != null) {
 		let _grid: image_t = ui_nodes_grid;
-		let _next = function() {
+		let _next = function () {
 			image_unload(_grid);
 		}
 		base_notify_on_next_frame(_next);
@@ -688,7 +690,7 @@ function base_update() {
 
 				///if (is_paint || is_sculpt)
 				let material_count: i32 = project_materials.length;
-				import_asset_run(base_drag_file, base_drop_x, base_drop_y, true, true, function() {
+				import_asset_run(base_drag_file, base_drop_x, base_drop_y, true, true, function () {
 					// Asset was material
 					if (project_materials.length > material_count) {
 						base_drag_material = context_raw.material;
@@ -873,16 +875,16 @@ function base_render() {
 		context_raw.camera_controls = config_raw.camera_controls;
 
 		///if is_lab
-		base_notify_on_next_frame(function() {
-			base_notify_on_next_frame(function() {
+		base_notify_on_next_frame(function () {
+			base_notify_on_next_frame(function () {
 				tab_meshes_set_default_mesh(".Sphere");
 			});
 		});
 		///end
 
 		///if is_sculpt
-		base_notify_on_next_frame(function() {
-			base_notify_on_next_frame(function() {
+		base_notify_on_next_frame(function () {
+			base_notify_on_next_frame(function () {
 				context_raw.project_type = project_model_t.SPHERE;
 				project_new();
 			});
@@ -985,18 +987,18 @@ function base_get_asset_index(file_name: string): i32 {
 	return i >= 0 ? i : 0;
 }
 
-function base_notify_on_next_frame(f: ()=>void) {
-	let _render = function() {
-		app_notify_on_init(function() {
-			let _update = function() {
-				app_notify_on_init(f);
+function base_notify_on_next_frame(f: (data?: any)=>void, data: any = null) {
+	let _render = function (data: any) {
+		app_notify_on_init(function (data: any) {
+			let _update = function (data: any) {
+				app_notify_on_init(f, data);
 				app_remove_update(_update);
 			}
-			app_notify_on_update(_update);
-		});
+			app_notify_on_update(_update, data);
+		}, data);
 		app_remove_render(_render);
 	}
-	app_notify_on_render(_render);
+	app_notify_on_render(_render, data);
 }
 
 function base_toggle_fullscreen() {
@@ -1218,7 +1220,7 @@ function base_resize_layers() {
 		}
 		while (history_undo_layers.length > conf.undo_steps) {
 			let l: slot_layer_t = history_undo_layers.pop();
-			base_notify_on_next_frame(function() {
+			base_notify_on_next_frame(function () {
 				slot_layer_unload(l);
 			});
 		}
@@ -1233,14 +1235,14 @@ function base_resize_layers() {
 	}
 	let rts: map_t<string, render_target_t> = render_path_render_targets;
 	let _texpaint_blend0: image_t = map_get(rts, "texpaint_blend0")._image;
-	base_notify_on_next_frame(function() {
+	base_notify_on_next_frame(function () {
 		image_unload(_texpaint_blend0);
 	});
 	map_get(rts, "texpaint_blend0").width = config_get_texture_res_x();
 	map_get(rts, "texpaint_blend0").height = config_get_texture_res_y();
 	map_get(rts, "texpaint_blend0")._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8);
 	let _texpaint_blend1: image_t = map_get(rts, "texpaint_blend1")._image;
-	base_notify_on_next_frame(function() {
+	base_notify_on_next_frame(function () {
 		image_unload(_texpaint_blend1);
 	});
 	map_get(rts, "texpaint_blend1").width = config_get_texture_res_x();
@@ -1249,7 +1251,7 @@ function base_resize_layers() {
 	context_raw.brush_blend_dirty = true;
 	if (map_get(rts, "texpaint_blur") != null) {
 		let _texpaint_blur: image_t = map_get(rts, "texpaint_blur")._image;
-		base_notify_on_next_frame(function() {
+		base_notify_on_next_frame(function () {
 			image_unload(_texpaint_blur);
 		});
 		let size_x: f32 = math_floor(config_get_texture_res_x() * 0.95);
@@ -1546,7 +1548,7 @@ function base_make_temp_img() {
 
 	if (base_temp_image != null && (base_temp_image.width != l.texpaint.width || base_temp_image.height != l.texpaint.height || base_temp_image.format != l.texpaint.format)) {
 		let _temptex0: render_target_t = map_get(render_path_render_targets, "temptex0");
-		base_notify_on_next_frame(function() {
+		base_notify_on_next_frame(function () {
 			render_target_unload(_temptex0);
 		});
 		map_delete(render_path_render_targets, "temptex0");
@@ -1576,7 +1578,7 @@ function base_make_temp_img() {
 function base_make_temp_mask_img() {
 	if (base_temp_mask_image != null && (base_temp_mask_image.width != config_get_texture_res_x() || base_temp_mask_image.height != config_get_texture_res_y())) {
 		let _temp_mask_image: image_t = base_temp_mask_image;
-		base_notify_on_next_frame(function() {
+		base_notify_on_next_frame(function () {
 			image_unload(_temp_mask_image);
 		});
 		base_temp_mask_image = null;
@@ -1599,7 +1601,7 @@ function base_make_export_img() {
 		let _expa: image_t = base_expa;
 		let _expb: image_t = base_expb;
 		let _expc: image_t = base_expc;
-		base_notify_on_next_frame(function() {
+		base_notify_on_next_frame(function () {
 			image_unload(_expa);
 			image_unload(_expb);
 			image_unload(_expc);
@@ -2306,7 +2308,7 @@ function base_new_layer(clear: bool = true, position: i32 = -1): slot_layer_t {
 		}
 	}
 	if (clear) {
-		app_notify_on_init(function() { slot_layer_clear(l); });
+		app_notify_on_init(function () { slot_layer_clear(l); });
 	}
 	context_raw.layer_preview_dirty = true;
 	return l;
@@ -2323,7 +2325,7 @@ function base_new_mask(clear: bool = true, parent: slot_layer_t, position: i32 =
 	array_insert(project_layers, position, l);
 	context_set_layer(l);
 	if (clear) {
-		app_notify_on_init(function() { slot_layer_clear(l); });
+		app_notify_on_init(function () { slot_layer_clear(l); });
 	}
 	context_raw.layer_preview_dirty = true;
 	return l;
@@ -2340,7 +2342,7 @@ function base_new_group(): slot_layer_t {
 }
 
 function base_create_fill_layer(uv_type: uv_type_t = uv_type_t.UVMAP, decal_mat: mat4_t = null, position: i32 = -1) {
-	let _init = function() {
+	let _init = function () {
 		let l: slot_layer_t = base_new_layer(false, position);
 		history_new_layer();
 		l.uv_type = uv_type;
@@ -2364,19 +2366,19 @@ function base_create_image_mask(asset: asset_t) {
 	context_raw.layer_preview_dirty = true;
 }
 
-function base_create_color_layer(baseColor: i32, occlusion: f32 = 1.0, roughness: f32 = base_default_rough, metallic: f32 = 0.0, position: i32 = -1) {
-	let _init = function() {
+function base_create_color_layer(base_color: i32, occlusion: f32 = 1.0, roughness: f32 = base_default_rough, metallic: f32 = 0.0, position: i32 = -1) {
+	let _init = function () {
 		let l: slot_layer_t = base_new_layer(false, position);
 		history_new_layer();
 		l.uv_type = uv_type_t.UVMAP;
 		l.object_mask = context_raw.layer_filter;
-		slot_layer_clear(l, baseColor, null, occlusion, roughness, metallic);
+		slot_layer_clear(l, base_color, null, occlusion, roughness, metallic);
 	}
 	app_notify_on_init(_init);
 }
 
 function base_on_layers_resized() {
-	app_notify_on_init(function() {
+	app_notify_on_init(function () {
 		base_resize_layers();
 		let _layer: slot_layer_t = context_raw.layer;
 		let _material: slot_material_t = context_raw.material;
@@ -2404,7 +2406,7 @@ function base_on_layers_resized() {
 ///end
 
 ///if is_lab
-function base_flatten(heightToNormal: bool = false): any {
+function base_flatten(height_to_normal: bool = false): any {
 	let texpaint: image_t = brush_output_node_inst.texpaint;
 	let texpaint_nor: image_t = brush_output_node_inst.texpaint_nor;
 	let texpaint_pack: image_t = brush_output_node_inst.texpaint_pack;
@@ -2432,12 +2434,12 @@ function base_on_layers_resized() {
 	image_unload(brush_output_node_inst.texpaint_pack);
 	brush_output_node_inst.texpaint_pack = map_get(render_path_render_targets, "texpaint_pack")._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y());
 
-	if (InpaintNode.image != null) {
-		image_unload(InpaintNode.image);
-		InpaintNode.image = null;
-		image_unload(InpaintNode.mask);
-		InpaintNode.mask = null;
-		InpaintNode.init();
+	if (inpaint_node_image != null) {
+		image_unload(inpaint_node_image);
+		inpaint_node_image = null;
+		image_unload(inpaint_node_mask);
+		inpaint_node_mask = null;
+		inpaint_node_init();
 	}
 
 	if (photo_to_pbr_node_images != null) {
@@ -2446,13 +2448,13 @@ function base_on_layers_resized() {
 			image_unload(image);
 		}
 		photo_to_pbr_node_images = null;
-		PhotoToPBRNode.init();
+		photo_to_pbr_node_init();
 	}
 
-	if (TilingNode.image != null) {
-		image_unload(TilingNode.image);
-		TilingNode.image = null;
-		TilingNode.init();
+	if (tiling_node_image != null) {
+		image_unload(tiling_node_image);
+		tiling_node_image = null;
+		tiling_node_init();
 	}
 
 	image_unload(map_get(render_path_render_targets, "texpaint_blend0")._image);
@@ -2467,7 +2469,7 @@ function base_on_layers_resized() {
 		map_delete(render_path_render_targets, "texpaint_node_target");
 	}
 
-	base_notify_on_next_frame(function() {
+	base_notify_on_next_frame(function () {
 		base_init_layers();
 	});
 

+ 2 - 2
base/Sources/context.ts

@@ -560,7 +560,7 @@ function context_set_material(m: slot_material_t) {
 
 	let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT;
 	if (decal) {
-		let _next = function() {
+		let _next = function () {
 			util_render_make_decal_preview();
 		}
 		base_notify_on_next_frame(_next);
@@ -871,7 +871,7 @@ function context_set_render_path() {
 	else {
 		render_path_commands = render_path_deferred_commands;
 	}
-	app_notify_on_init(function() {
+	app_notify_on_init(function () {
 		make_material_parse_mesh_material();
 	});
 }

+ 2 - 2
base/Sources/file.ts

@@ -84,7 +84,7 @@ function file_download(url: string, dstPath: string, done: ()=>void, size: i32 =
 
 function file_download_bytes(url: string, done: (ab: buffer_t)=>void) {
 	let save: string = (path_is_protected() ? krom_save_path() : path_data() + path_sep) + "download.bin";
-	file_download(url, save, function() {
+	file_download(url, save, function () {
 		let buffer: buffer_t = krom_load_blob(save);
 		done(buffer);
 	});
@@ -114,7 +114,7 @@ function file_cache_cloud(path: string, done: (s: string)=>void) {
 	path = string_replace_all(path, "\\", "/");
 	///end
 	let url: string = config_raw.server + "/" + path;
-	file_download(url, dest, function() {
+	file_download(url, dest, function () {
 		if (!file_exists(dest)) {
 			console_error(strings_error5());
 			done(null);

+ 4 - 4
base/Sources/history.ts

@@ -285,7 +285,7 @@ function history_redo() {
 				while (history_steps[active + n].layer_type == layer_slot_type_t.MASK) {
 					++n;
 				}
-				base_notify_on_next_frame(function() {
+				base_notify_on_next_frame(function () {
 					for (let i: i32 = 0; i < n; ++i) {
 						history_redo();
 					}
@@ -300,7 +300,7 @@ function history_redo() {
 		}
 		else if (step.name == tr("Duplicate Layer")) {
 			context_raw.layer = project_layers[step.layer];
-			let _next = function() {
+			let _next = function () {
 				base_duplicate_layer(context_raw.layer);
 			}
 			base_notify_on_next_frame(_next);
@@ -327,7 +327,7 @@ function history_redo() {
 					history_copy_merging_layers2([context_raw.layer, context_raw.layer.parent]);
 				}
 
-			let _next = function() {
+			let _next = function () {
 				slot_layer_apply_mask(context_raw.layer);
 				context_set_layer(context_raw.layer);
 				context_raw.layers_preview_dirty = true;
@@ -335,7 +335,7 @@ function history_redo() {
 			base_notify_on_next_frame(_next);
 		}
 		else if (step.name == tr("Invert Mask")) {
-			let _next = function() {
+			let _next = function () {
 				context_raw.layer = project_layers[step.layer];
 				slot_layer_invert_mask(context_raw.layer);
 			}

+ 14 - 16
base/Sources/import_mesh.ts

@@ -36,22 +36,20 @@ function import_mesh_run(path: string, replace_existing: bool = true) {
 	}
 	else {
 		let ext: string = substring(path, string_last_index_of(path, ".") + 1, path.length);
-		let importer: (s: string, f: (a: any)=>void)=>void = map_get(path_mesh_importers, ext);
-		importer(path, function (mesh: any) {
-			replace_existing ? import_mesh_make_mesh(mesh, path) : import_mesh_add_mesh(mesh);
-
-			let has_next: bool = mesh.has_next;
-			while (has_next) {
-				importer(path, function (mesh: any) {
-					has_next = mesh.has_next;
-					import_mesh_add_mesh(mesh);
-
-					// let m: mat4_t = fromFloat32Array(mesh.transform);
-					// paintObjects[paintObjects.length - 1].transform.localOnly = true;
-					// paintObjects[paintObjects.length - 1].transform.setMatrix(m);
-				});
-			}
-		});
+		let importer: (s: string)=>any = map_get(path_mesh_importers, ext);
+		let mesh: any = importer(path);
+		replace_existing ? import_mesh_make_mesh(mesh, path) : import_mesh_add_mesh(mesh);
+
+		let has_next: bool = mesh.has_next;
+		while (has_next) {
+			let mesh: any = importer(path);
+			has_next = mesh.has_next;
+			import_mesh_add_mesh(mesh);
+
+			// let m: mat4_t = fromFloat32Array(mesh.transform);
+			// paintObjects[paintObjects.length - 1].transform.localOnly = true;
+			// paintObjects[paintObjects.length - 1].transform.setMatrix(m);
+		}
 	}
 
 	project_mesh_assets = [path];

+ 22 - 24
base/Sources/import_texture.ts

@@ -24,36 +24,34 @@ function import_texture_run(path: string, hdr_as_envmap: bool = true) {
 	}
 
 	let ext: string = substring(path, string_last_index_of(path, ".") + 1, path.length);
-	let importer: (s: string, f: (img: image_t)=>void)=>void = map_get(path_texture_importers, ext);
+	let importer: (s: string)=>image_t = map_get(path_texture_importers, ext);
 	let cached: bool = map_get(data_cached_images, path) != null; // Already loaded or pink texture for missing file
 	if (importer == null || cached) {
 		importer = import_texture_default_importer;
 	}
 
-	importer(path, function (image: image_t) {
-		map_set(data_cached_images, path, image);
-		let ar: string[] = string_split(path, path_sep);
-		let name: string = ar[ar.length - 1];
-		let asset: asset_t = {name: name, file: path, id: project_asset_id++};
-		array_push(project_assets, asset);
-		if (context_raw.texture == null) {
-			context_raw.texture = asset;
-		}
-		array_push(project_asset_names, name);
-		map_set(project_asset_map, asset.id, image);
-		ui_base_hwnds[tab_area_t.STATUS].redraws = 2;
-		console_info(tr("Texture imported:") + " " + name);
+	let image: image_t = importer(path);
+	map_set(data_cached_images, path, image);
+	let ar: string[] = string_split(path, path_sep);
+	let name: string = ar[ar.length - 1];
+	let asset: asset_t = {name: name, file: path, id: project_asset_id++};
+	array_push(project_assets, asset);
+	if (context_raw.texture == null) {
+		context_raw.texture = asset;
+	}
+	array_push(project_asset_names, name);
+	map_set(project_asset_map, asset.id, image);
+	ui_base_hwnds[tab_area_t.STATUS].redraws = 2;
+	console_info(tr("Texture imported:") + " " + name);
 
-		// Set as envmap
-		if (hdr_as_envmap && ends_with(to_lower_case(path), ".hdr")) {
-			base_notify_on_next_frame(function () { // Make sure file browser process did finish
-				import_envmap_run(path, image);
-			});
-		}
-	});
+	// Set as envmap
+	if (hdr_as_envmap && ends_with(to_lower_case(path), ".hdr")) {
+		base_notify_on_next_frame(function () { // Make sure file browser process did finish
+			import_envmap_run(path, image);
+		});
+	}
 }
 
-function import_texture_default_importer(path: string, done: (img: image_t)=>void) {
-	let img: image_t = data_get_image(path);
-	done(img);
+function import_texture_default_importer(path: string): image_t {
+	return data_get_image(path);
 }

+ 11 - 11
base/Sources/logic_node.ts

@@ -2,9 +2,9 @@
 type logic_node_t = {
 	inputs?: logic_node_input_t[];
 	outputs?: logic_node_t[][];
-	get?: (self: any, from: i32, done: (a: any)=>void)=>void;
-	get_as_image?: (self: any, from: i32, done: (img: image_t)=>void)=>void;
-	get_cached_image?: (self: any)=>image_t ;
+	get?: (self: any, from: i32)=>any;
+	get_as_image?: (self: any, from: i32)=>image_t;
+	get_cached_image?: (self: any)=>image_t;
 	set?: (self: any, value: any)=>void;
 };
 
@@ -32,12 +32,12 @@ function logic_node_add_outputs(self: logic_node_t, nodes: logic_node_t[]) {
 	array_push(self.outputs, nodes);
 }
 
-function logic_node_get(self: logic_node_t, from: i32, done: (a: any)=>void) {
-	done(null);
+function logic_node_get(self: logic_node_t, from: i32): any {
+	return null;
 }
 
-function logic_node_get_as_image(self: logic_node_t, from: i32, done: (img: image_t)=>void) {
-	done(null);
+function logic_node_get_as_image(self: logic_node_t, from: i32): image_t {
+	return null;
 }
 
 function logic_node_get_cached_image(self: logic_node_t): image_t {
@@ -53,12 +53,12 @@ function logic_node_input_create(node: logic_node_t, from: i32): logic_node_inpu
 	return inp;
 }
 
-function logic_node_input_get(self: logic_node_input_t, done: (a: any)=>void) {
-	self.node.base.get(self.node, self.from, done);
+function logic_node_input_get(self: logic_node_input_t): any {
+	return self.node.base.get(self.node, self.from);
 }
 
-function logic_node_input_get_as_image(self: logic_node_input_t, done: (img: image_t)=>void) {
-	self.node.base.get_as_image(self.node, self.from, done);
+function logic_node_input_get_as_image(self: logic_node_input_t): image_t {
+	return self.node.base.get_as_image(self.node, self.from);
 }
 
 function logic_node_input_set(self: logic_node_input_t, value: any) {

+ 1 - 1
base/Sources/main.ts

@@ -43,7 +43,7 @@ function main_start() {
 		base_init_layout();
 	}
 	krom_set_app_name(manifest_title);
-	app_init(function() {
+	app_init(function () {
 		let o: object_t = scene_set_active("Scene");
 		uniforms_ext_init();
 		render_path_base_init();

+ 3 - 3
base/Sources/nodes/boolean_node.ts

@@ -13,12 +13,12 @@ function boolean_node_create(arg: bool): boolean_node_t {
 	return n;
 }
 
-function boolean_node_get(self: boolean_node_t, from: i32, done: (a: any)=>void) {
+function boolean_node_get(self: boolean_node_t, from: i32): any {
 	if (self.base.inputs.length > 0) {
-		logic_node_input_get(self.base.inputs[0], done);
+		return logic_node_input_get(self.base.inputs[0]);
 	}
 	else {
-		done(self.value);
+		return self.value;
 	}
 }
 

+ 6 - 7
base/Sources/nodes/color_node.ts

@@ -19,19 +19,18 @@ function color_node_create(args: any): color_node_t {
 	return n;
 }
 
-function color_node_get(self: color_node_t, from: i32, done: (a: any)=>void) {
+function color_node_get(self: color_node_t, from: i32): any {
 	if (self.base.inputs.length > 0) {
-		logic_node_input_get(self.base.inputs[0], done);
+		return logic_node_input_get(self.base.inputs[0]);
 	}
 	else {
-		done(self.value);
+		return self.value;
 	}
 }
 
-function color_node_get_as_image(self: color_node_t, from: i32, done: (img: image_t)=>void) {
+function color_node_get_as_image(self: color_node_t, from: i32): image_t {
 	if (self.base.inputs.length > 0) {
-		logic_node_input_get_as_image(self.base.inputs[0], done);
-		return;
+		return logic_node_input_get_as_image(self.base.inputs[0]);
 	}
 	if (self.image != null) {
 		image_unload(self.image);
@@ -43,7 +42,7 @@ function color_node_get_as_image(self: color_node_t, from: i32, done: (img: imag
 	buffer_view_set_f32(v, 8, self.value.z);
 	buffer_view_set_f32(v, 12, self.value.w);
 	self.image = image_from_bytes(b, 1, 1, tex_format_t.RGBA128);
-	done(self.image);
+	return self.image;
 }
 
 function color_node_set(self: color_node_t, value: any) {

+ 6 - 7
base/Sources/nodes/float_node.ts

@@ -15,19 +15,18 @@ function float_node_create(arg: f32): float_node_t {
 	return n;
 }
 
-function float_node_get(self: float_node_t, from: i32, done: (a: any)=>void) {
+function float_node_get(self: float_node_t, from: i32): any {
 	if (self.base.inputs.length > 0) {
-		logic_node_input_get(self.base.inputs[0], done);
+		return logic_node_input_get(self.base.inputs[0]);
 	}
 	else {
-		done(self.value);
+		return self.value;
 	}
 }
 
-function float_node_get_as_image(self: float_node_t, from: i32, done: (img: image_t)=>void) {
+function float_node_get_as_image(self: float_node_t, from: i32): image_t {
 	if (self.base.inputs.length > 0) {
-		logic_node_input_get_as_image(self.base.inputs[0], done);
-		return;
+		return logic_node_input_get_as_image(self.base.inputs[0]);
 	}
 	if (self.image != null) {
 		image_unload(self.image);
@@ -39,7 +38,7 @@ function float_node_get_as_image(self: float_node_t, from: i32, done: (img: imag
 	buffer_view_set_f32(v, 8, self.value);
 	buffer_view_set_f32(v, 12, 1.0);
 	self.image = image_from_bytes(b, 1, 1, tex_format_t.RGBA128);
-	done(self.image);
+	return self.image;
 }
 
 function float_node_set(self: float_node_t, value: any) {

+ 3 - 3
base/Sources/nodes/integer_node.ts

@@ -13,12 +13,12 @@ function integer_node_create(arg: i32): integer_node_t {
 	return n;
 }
 
-function integer_node_get(self: integer_node_t, from: i32, done: (a: any)=>void) {
+function integer_node_get(self: integer_node_t, from: i32) {
 	if (self.base.inputs.length > 0) {
-		logic_node_input_get(self.base.inputs[0], done);
+		return logic_node_input_get(self.base.inputs[0]);
 	}
 	else {
-		done(self.value);
+		return self.value;
 	}
 }
 

+ 114 - 116
base/Sources/nodes/math_node.ts

@@ -12,124 +12,122 @@ function math_node_create(arg: any): math_node_t {
 	return n;
 }
 
-function math_node_get(self: math_node_t, from: i32, done: (a: any)=>void) {
-	logic_node_input_get(self.base.inputs[0], function (v1: f32) {
-		logic_node_input_get(self.base.inputs[1], function (v2: f32) {
-			let f: f32 = 0.0;
-			let op: string = self.operation;
-			if (op == "Add") {
-				f = v1 + v2;
-			}
-			else if (op == "Multiply") {
-				f = v1 * v2;
-			}
-			else if (op == "Sine") {
-				f = math_sin(v1);
-			}
-			else if (op == "Cosine") {
-				f = math_cos(v1);
-			}
-			else if (op == "Max") {
-				f = math_max(v1, v2);
-			}
-			else if (op == "Min") {
-				f = math_min(v1, v2);
-			}
-			else if (op == "Absolute") {
-				f = math_abs(v1);
-			}
-			else if (op == "Subtract") {
-				f = v1 - v2;
-			}
-			else if (op == "Divide") {
-				f = v1 / (v2 == 0.0 ? 0.000001 : v2);
-			}
-			else if (op == "Tangent") {
-				f = math_tan(v1);
-			}
-			else if (op == "Arcsine") {
-				f = math_asin(v1);
-			}
-			else if (op == "Arccosine") {
-				f = math_acos(v1);
-			}
-			else if (op == "Arctangent") {
-				f = math_atan(v1);
-			}
-			else if (op == "Arctan2") {
-				f = math_atan2(v2, v1);
-			}
-			else if (op == "Power") {
-				f = math_pow(v1, v2);
-			}
-			else if (op == "Logarithm") {
-				f = math_log(v1);
-			}
-			else if (op == "Round") {
-				f = math_round(v1);
-			}
-			else if (op == "Floor") {
-				f = math_floor(v1);
-			}
-			else if (op == "Ceil") {
-				f = math_ceil(v1);
-			}
-			else if (op == "Truncate") {
-				f = math_floor(v1);
-			}
-			else if (op == "Fraction") {
-				f = v1 - math_floor(v1);
-			}
-			else if (op == "Less Than") {
-				f = v1 < v2 ? 1.0 : 0.0;
-			}
-			else if (op == "Greater Than") {
-				f = v1 > v2 ? 1.0 : 0.0;
-			}
-			else if (op == "Modulo") {
-				f = v1 % v2;
-			}
-			else if (op == "Snap") {
-				f = math_floor(v1 / v2) * v2;
-			}
-			else if (op == "Square Root") {
-				f = math_sqrt(v1);
-			}
-			else if (op == "Inverse Square Root") {
-				f = 1.0 / math_sqrt(v1);
-			}
-			else if (op == "Exponent") {
-				f = math_exp(v1);
-			}
-			else if (op == "Sign") {
-				f = v1 > 0 ? 1.0 : (v1 < 0 ? -1.0 : 0);
-			}
-			else if (op == "Ping-Pong") {
-				f = (v2 != 0.0) ? v2 - math_abs((math_abs(v1) % (2 * v2)) - v2) : 0.0;
-			}
-			else if (op == "Hyperbolic Sine") {
-				f = (math_exp(v1) - math_exp(-v1)) / 2.0;
-			}
-			else if (op == "Hyperbolic Cosine") {
-				f = (math_exp(v1) + math_exp(-v1)) / 2.0;
-			}
-			else if (op == "Hyperbolic Tangent") {
-				f = 1.0 - (2.0 / (math_exp(2 * v1) + 1));
-			}
-			else if (op == "To Radians") {
-				f = v1 / 180.0 * math_pi();
-			}
-			else if (op == "To Degrees") {
-				f = v1 / math_pi() * 180.0;
-			}
+function math_node_get(self: math_node_t, from: i32): any {
+	let v1: f32 = logic_node_input_get(self.base.inputs[0]);
+	let v2: f32 = logic_node_input_get(self.base.inputs[1]);
+	let f: f32 = 0.0;
+	let op: string = self.operation;
+	if (op == "Add") {
+		f = v1 + v2;
+	}
+	else if (op == "Multiply") {
+		f = v1 * v2;
+	}
+	else if (op == "Sine") {
+		f = math_sin(v1);
+	}
+	else if (op == "Cosine") {
+		f = math_cos(v1);
+	}
+	else if (op == "Max") {
+		f = math_max(v1, v2);
+	}
+	else if (op == "Min") {
+		f = math_min(v1, v2);
+	}
+	else if (op == "Absolute") {
+		f = math_abs(v1);
+	}
+	else if (op == "Subtract") {
+		f = v1 - v2;
+	}
+	else if (op == "Divide") {
+		f = v1 / (v2 == 0.0 ? 0.000001 : v2);
+	}
+	else if (op == "Tangent") {
+		f = math_tan(v1);
+	}
+	else if (op == "Arcsine") {
+		f = math_asin(v1);
+	}
+	else if (op == "Arccosine") {
+		f = math_acos(v1);
+	}
+	else if (op == "Arctangent") {
+		f = math_atan(v1);
+	}
+	else if (op == "Arctan2") {
+		f = math_atan2(v2, v1);
+	}
+	else if (op == "Power") {
+		f = math_pow(v1, v2);
+	}
+	else if (op == "Logarithm") {
+		f = math_log(v1);
+	}
+	else if (op == "Round") {
+		f = math_round(v1);
+	}
+	else if (op == "Floor") {
+		f = math_floor(v1);
+	}
+	else if (op == "Ceil") {
+		f = math_ceil(v1);
+	}
+	else if (op == "Truncate") {
+		f = math_floor(v1);
+	}
+	else if (op == "Fraction") {
+		f = v1 - math_floor(v1);
+	}
+	else if (op == "Less Than") {
+		f = v1 < v2 ? 1.0 : 0.0;
+	}
+	else if (op == "Greater Than") {
+		f = v1 > v2 ? 1.0 : 0.0;
+	}
+	else if (op == "Modulo") {
+		f = v1 % v2;
+	}
+	else if (op == "Snap") {
+		f = math_floor(v1 / v2) * v2;
+	}
+	else if (op == "Square Root") {
+		f = math_sqrt(v1);
+	}
+	else if (op == "Inverse Square Root") {
+		f = 1.0 / math_sqrt(v1);
+	}
+	else if (op == "Exponent") {
+		f = math_exp(v1);
+	}
+	else if (op == "Sign") {
+		f = v1 > 0 ? 1.0 : (v1 < 0 ? -1.0 : 0);
+	}
+	else if (op == "Ping-Pong") {
+		f = (v2 != 0.0) ? v2 - math_abs((math_abs(v1) % (2 * v2)) - v2) : 0.0;
+	}
+	else if (op == "Hyperbolic Sine") {
+		f = (math_exp(v1) - math_exp(-v1)) / 2.0;
+	}
+	else if (op == "Hyperbolic Cosine") {
+		f = (math_exp(v1) + math_exp(-v1)) / 2.0;
+	}
+	else if (op == "Hyperbolic Tangent") {
+		f = 1.0 - (2.0 / (math_exp(2 * v1) + 1));
+	}
+	else if (op == "To Radians") {
+		f = v1 / 180.0 * math_pi();
+	}
+	else if (op == "To Degrees") {
+		f = v1 / math_pi() * 180.0;
+	}
 
-			if (self.use_clamp) {
-				f = f < 0.0 ? 0.0 : (f > 1.0 ? 1.0 : f);
-			}
+	if (self.use_clamp) {
+		f = f < 0.0 ? 0.0 : (f > 1.0 ? 1.0 : f);
+	}
 
-			done(f);
-		});
-	});
+	return f;
 }
 
 let math_node_def: zui_node_t = {

+ 2 - 2
base/Sources/nodes/null_node.ts

@@ -10,6 +10,6 @@ function null_node_create(arg: any): null_node_t {
 	return n;
 }
 
-function null_node_get(self: null_node_t, from: i32, done: (a: any)=>void) {
-	done(null);
+function null_node_get(self: null_node_t, from: i32): any {
+	return null;
 }

+ 4 - 6
base/Sources/nodes/random_node.ts

@@ -15,12 +15,10 @@ function random_node_create(arg: any): random_node_t {
 	return n;
 }
 
-function random_node_get(self: random_node_t, from: i32, done: (a: any)=>void) {
-	logic_node_input_get(self.base.inputs[0], function (min: f32) {
-		logic_node_input_get(self.base.inputs[1], function (max: f32) {
-			done(min + random_node_get_float() * (max - min));
-		});
-	});
+function random_node_get(self: random_node_t, from: i32): any {
+	let min: f32 = logic_node_input_get(self.base.inputs[0]);
+	let max: f32 = logic_node_input_get(self.base.inputs[1]);
+	return min + random_node_get_float() * (max - min);
 }
 
 function random_node_get_int(): i32 {

+ 11 - 12
base/Sources/nodes/separate_vector_node.ts

@@ -10,18 +10,17 @@ function separate_vector_node_create(arg: any): separate_vector_node_t {
 	return n;
 }
 
-function separate_vector_node_get(self: separate_vector_node_t, from: i32, done: (a: any)=>void) {
-	logic_node_input_get(self.base.inputs[0], function (vector: vec4_t) {
-		if (from == 0) {
-			done(vector.x);
-		}
-		else if (from == 1) {
-			done(vector.y);
-		}
-		else {
-			done(vector.z);
-		}
-	});
+function separate_vector_node_get(self: separate_vector_node_t, from: i32): any {
+	let vector: vec4_t = logic_node_input_get(self.base.inputs[0]);
+	if (from == 0) {
+		return vector.x;
+	}
+	else if (from == 1) {
+		return vector.y;
+	}
+	else {
+		return vector.z;
+	}
 }
 
 let separate_vector_node_def: zui_node_t = {

+ 3 - 3
base/Sources/nodes/string_node.ts

@@ -13,12 +13,12 @@ function string_node_create(arg: string): string_node_t {
 	return n;
 }
 
-function string_node_get(self: string_node_t, from: i32, done: (a: any)=>void) {
+function string_node_get(self: string_node_t, from: i32): any {
 	if (self.base.inputs.length > 0) {
-		logic_node_input_get(self.base.inputs[0], done);
+		return logic_node_input_get(self.base.inputs[0]);
 	}
 	else {
-		done(self.value);
+		return self.value;
 	}
 }
 

+ 4 - 4
base/Sources/nodes/time_node.ts

@@ -10,15 +10,15 @@ function time_node_create(arg: any): time_node_t {
 	return n;
 }
 
-function time_node_get(self: time_node_t, from: i32, done: (a: any)=>void) {
+function time_node_get(self: time_node_t, from: i32): any {
 	if (from == 0) {
-		done(time_time());
+		return time_time();
 	}
 	else if (from == 1) {
-		done(time_delta());
+		return time_delta();
 	}
 	else {
-		done(context_raw.brush_time);
+		return context_raw.brush_time;
 	}
 }
 

+ 122 - 124
base/Sources/nodes/vector_math_node.ts

@@ -13,131 +13,129 @@ function vector_math_node_create(arg: any): vector_math_node_t {
 	return n;
 }
 
-function vector_math_node_get(self: vector_math_node_t, from: i32, done: (a: any)=>void) {
-	logic_node_input_get(self.base.inputs[0], function (v1: vec4_t) {
-		logic_node_input_get(self.base.inputs[1], function (v2: vec4_t) {
-			vec4_set_from(self.v, v1);
-			let f: f32 = 0.0;
-			let op: string = self.operation;
-			if (op == "Add") {
-				vec4_add(self.v, v2);
-			}
-			else if (op == "Subtract") {
-				vec4_sub(self.v, v2);
-			}
-			else if (op == "Average") {
-				vec4_add(self.v, v2);
-				self.v.x *= 0.5;
-				self.v.y *= 0.5;
-				self.v.z *= 0.5;
-			}
-			else if (op == "Dot Product") {
-				f = vec4_dot(self.v, v2);
-				vec4_set(self.v, f, f, f);
-			}
-			else if (op == "Cross Product") {
-				vec4_cross(self.v, v2);
-			}
-			else if (op == "Normalize") {
-				vec4_normalize(self.v, );
-			}
-			else if (op == "Multiply") {
-				self.v.x *= v2.x;
-				self.v.y *= v2.y;
-				self.v.z *= v2.z;
-			}
-			else if (op == "Divide") {
-				self.v.x /= v2.x == 0.0 ? 0.000001 : v2.x;
-				self.v.y /= v2.y == 0.0 ? 0.000001 : v2.y;
-				self.v.z /= v2.z == 0.0 ? 0.000001 : v2.z;
-			}
-			else if (op == "Length") {
-				f = vec4_len(self.v);
-				vec4_set(self.v, f, f, f);
-			}
-			else if (op == "Distance") {
-				f = vec4_dist_to(self.v, v2);
-				vec4_set(self.v, f, f, f);
-			}
-			else if (op == "Project") {
-				vec4_set_from(self.v, v2);
-				vec4_mult(self.v, vec4_dot(v1, v2) / vec4_dot(v2, v2));
-			}
-			else if (op == "Reflect") {
-				let tmp: vec4_t = vec4_create();
-				vec4_set_from(tmp, v2);
-				vec4_normalize(tmp);
-				vec4_reflect(self.v, tmp);
-			}
-			else if (op == "Scale") {
-				self.v.x *= v2.x;
-				self.v.y *= v2.x;
-				self.v.z *= v2.x;
-			}
-			else if (op == "Absolute") {
-				self.v.x = math_abs(self.v.x);
-				self.v.y = math_abs(self.v.y);
-				self.v.z = math_abs(self.v.z);
-			}
-			else if (op == "Minimum") {
-				self.v.x = math_min(v1.x, v2.x);
-				self.v.y = math_min(v1.y, v2.y);
-				self.v.z = math_min(v1.z, v2.z);
-			}
-			else if (op == "Maximum") {
-				self.v.x = math_max(v1.x, v2.x);
-				self.v.y = math_max(v1.y, v2.y);
-				self.v.z = math_max(v1.z, v2.z);
-			}
-			else if (op == "Floor") {
-				self.v.x = math_floor(v1.x);
-				self.v.y = math_floor(v1.y);
-				self.v.z = math_floor(v1.z);
-			}
-			else if (op == "Ceil") {
-				self.v.x = math_ceil(v1.x);
-				self.v.y = math_ceil(v1.y);
-				self.v.z = math_ceil(v1.z);
-			}
-			else if (op == "Fraction") {
-				self.v.x = v1.x - math_floor(v1.x);
-				self.v.y = v1.y - math_floor(v1.y);
-				self.v.z = v1.z - math_floor(v1.z);
-			}
-			else if (op == "Modulo") {
-				self.v.x = v1.x % v2.x;
-				self.v.y = v1.y % v2.y;
-				self.v.z = v1.z % v2.z;
-			}
-			else if (op == "Snap") {
-				self.v.x = math_floor(v1.x / v2.x) * v2.x;
-				self.v.y = math_floor(v1.y / v2.y) * v2.y;
-				self.v.z = math_floor(v1.z / v2.z) * v2.z;
-			}
-			else if (op == "Sine") {
-				self.v.x = math_sin(v1.x);
-				self.v.y = math_sin(v1.y);
-				self.v.z = math_sin(v1.z);
-			}
-			else if (op == "Cosine") {
-				self.v.x = math_cos(v1.x);
-				self.v.y = math_cos(v1.y);
-				self.v.z = math_cos(v1.z);
-			}
-			else if (op == "Tangent") {
-				self.v.x = math_tan(v1.x);
-				self.v.y = math_tan(v1.y);
-				self.v.z = math_tan(v1.z);
-			}
+function vector_math_node_get(self: vector_math_node_t, from: i32): any {
+	let v1: vec4_t = logic_node_input_get(self.base.inputs[0]);
+	let v2: vec4_t = logic_node_input_get(self.base.inputs[1]);
+	vec4_set_from(self.v, v1);
+	let f: f32 = 0.0;
+	let op: string = self.operation;
+	if (op == "Add") {
+		vec4_add(self.v, v2);
+	}
+	else if (op == "Subtract") {
+		vec4_sub(self.v, v2);
+	}
+	else if (op == "Average") {
+		vec4_add(self.v, v2);
+		self.v.x *= 0.5;
+		self.v.y *= 0.5;
+		self.v.z *= 0.5;
+	}
+	else if (op == "Dot Product") {
+		f = vec4_dot(self.v, v2);
+		vec4_set(self.v, f, f, f);
+	}
+	else if (op == "Cross Product") {
+		vec4_cross(self.v, v2);
+	}
+	else if (op == "Normalize") {
+		vec4_normalize(self.v, );
+	}
+	else if (op == "Multiply") {
+		self.v.x *= v2.x;
+		self.v.y *= v2.y;
+		self.v.z *= v2.z;
+	}
+	else if (op == "Divide") {
+		self.v.x /= v2.x == 0.0 ? 0.000001 : v2.x;
+		self.v.y /= v2.y == 0.0 ? 0.000001 : v2.y;
+		self.v.z /= v2.z == 0.0 ? 0.000001 : v2.z;
+	}
+	else if (op == "Length") {
+		f = vec4_len(self.v);
+		vec4_set(self.v, f, f, f);
+	}
+	else if (op == "Distance") {
+		f = vec4_dist_to(self.v, v2);
+		vec4_set(self.v, f, f, f);
+	}
+	else if (op == "Project") {
+		vec4_set_from(self.v, v2);
+		vec4_mult(self.v, vec4_dot(v1, v2) / vec4_dot(v2, v2));
+	}
+	else if (op == "Reflect") {
+		let tmp: vec4_t = vec4_create();
+		vec4_set_from(tmp, v2);
+		vec4_normalize(tmp);
+		vec4_reflect(self.v, tmp);
+	}
+	else if (op == "Scale") {
+		self.v.x *= v2.x;
+		self.v.y *= v2.x;
+		self.v.z *= v2.x;
+	}
+	else if (op == "Absolute") {
+		self.v.x = math_abs(self.v.x);
+		self.v.y = math_abs(self.v.y);
+		self.v.z = math_abs(self.v.z);
+	}
+	else if (op == "Minimum") {
+		self.v.x = math_min(v1.x, v2.x);
+		self.v.y = math_min(v1.y, v2.y);
+		self.v.z = math_min(v1.z, v2.z);
+	}
+	else if (op == "Maximum") {
+		self.v.x = math_max(v1.x, v2.x);
+		self.v.y = math_max(v1.y, v2.y);
+		self.v.z = math_max(v1.z, v2.z);
+	}
+	else if (op == "Floor") {
+		self.v.x = math_floor(v1.x);
+		self.v.y = math_floor(v1.y);
+		self.v.z = math_floor(v1.z);
+	}
+	else if (op == "Ceil") {
+		self.v.x = math_ceil(v1.x);
+		self.v.y = math_ceil(v1.y);
+		self.v.z = math_ceil(v1.z);
+	}
+	else if (op == "Fraction") {
+		self.v.x = v1.x - math_floor(v1.x);
+		self.v.y = v1.y - math_floor(v1.y);
+		self.v.z = v1.z - math_floor(v1.z);
+	}
+	else if (op == "Modulo") {
+		self.v.x = v1.x % v2.x;
+		self.v.y = v1.y % v2.y;
+		self.v.z = v1.z % v2.z;
+	}
+	else if (op == "Snap") {
+		self.v.x = math_floor(v1.x / v2.x) * v2.x;
+		self.v.y = math_floor(v1.y / v2.y) * v2.y;
+		self.v.z = math_floor(v1.z / v2.z) * v2.z;
+	}
+	else if (op == "Sine") {
+		self.v.x = math_sin(v1.x);
+		self.v.y = math_sin(v1.y);
+		self.v.z = math_sin(v1.z);
+	}
+	else if (op == "Cosine") {
+		self.v.x = math_cos(v1.x);
+		self.v.y = math_cos(v1.y);
+		self.v.z = math_cos(v1.z);
+	}
+	else if (op == "Tangent") {
+		self.v.x = math_tan(v1.x);
+		self.v.y = math_tan(v1.y);
+		self.v.z = math_tan(v1.z);
+	}
 
-			if (from == 0) {
-				done(self.v);
-			}
-			else {
-				done(f);
-			}
-		});
-	});
+	if (from == 0) {
+		return self.v;
+	}
+	else {
+		return f;
+	}
 }
 
 let vector_math_node_def: zui_node_t = {

+ 23 - 29
base/Sources/nodes/vector_node.ts

@@ -22,37 +22,31 @@ function vector_node_create(args: any): vector_node_t {
 	return n;
 }
 
-function vector_node_get(self: vector_node_t, from: i32, done: (a: any)=>void) {
-	logic_node_input_get(self.base.inputs[0], function (x: f32) {
-		logic_node_input_get(self.base.inputs[1], function (y: f32) {
-			logic_node_input_get(self.base.inputs[2], function (z: f32) {
-				self.value.x = x;
-				self.value.y = y;
-				self.value.z = z;
-				done(self.value);
-			});
-		});
-	});
+function vector_node_get(self: vector_node_t, from: i32): any {
+	let x: f32 = logic_node_input_get(self.base.inputs[0]);
+	let y: f32 = logic_node_input_get(self.base.inputs[1]);
+	let z: f32 = logic_node_input_get(self.base.inputs[2]);
+	self.value.x = x;
+	self.value.y = y;
+	self.value.z = z;
+	return self.value;
 }
 
-function vector_node_get_as_image(self: vector_node_t, from: i32, done: (img: image_t)=>void) {
-	logic_node_input_get(self.base.inputs[0], function (x: f32) {
-		logic_node_input_get(self.base.inputs[1], function (y: f32) {
-			logic_node_input_get(self.base.inputs[2], function (z: f32) {
-				if (self.image != null) {
-					image_unload(self.image);
-				}
-				let b: buffer_t = buffer_create(16);
-				let v: buffer_view_t = buffer_view_create(b);
-				buffer_view_set_f32(v, 0, (self.base.inputs[0].node as any).value);
-				buffer_view_set_f32(v, 4, (self.base.inputs[1].node as any).value);
-				buffer_view_set_f32(v, 8, (self.base.inputs[2].node as any).value);
-				buffer_view_set_f32(v, 12, 1.0);
-				self.image = image_from_bytes(b, 1, 1, tex_format_t.RGBA128);
-				done(self.image);
-			});
-		});
-	});
+function vector_node_get_as_image(self: vector_node_t, from: i32): image_t {
+	// let x: f32 = logic_node_input_get(self.base.inputs[0]);
+	// let y: f32 = logic_node_input_get(self.base.inputs[1]);
+	// let z: f32 = logic_node_input_get(self.base.inputs[2]);
+	if (self.image != null) {
+		image_unload(self.image);
+	}
+	let b: buffer_t = buffer_create(16);
+	let v: buffer_view_t = buffer_view_create(b);
+	buffer_view_set_f32(v, 0, (self.base.inputs[0].node as any).value);
+	buffer_view_set_f32(v, 4, (self.base.inputs[1].node as any).value);
+	buffer_view_set_f32(v, 8, (self.base.inputs[2].node as any).value);
+	buffer_view_set_f32(v, 12, 1.0);
+	self.image = image_from_bytes(b, 1, 1, tex_format_t.RGBA128);
+	return self.image;
 }
 
 function vector_node_set(self: vector_node_t, value: any) {

+ 2 - 2
base/Sources/path.ts

@@ -14,8 +14,8 @@ let path_pwd: string = "echo $PWD";
 let path_mesh_formats: string[] = ["obj", "blend"];
 let path_texture_formats: string[] = ["jpg", "jpeg", "png", "tga", "bmp", "psd", "gif", "hdr", "k"];
 
-let path_mesh_importers: map_t<string, (s: string, f: (a: any)=>void)=>void> = map_create();
-let path_texture_importers: map_t<string, (s: string, f: (img: image_t)=>void)=>void> = map_create();
+let path_mesh_importers: map_t<string, (s: string)=>any> = map_create();
+let path_texture_importers: map_t<string, (s: string)=>image_t> = map_create();
 
 let path_base_color_ext: string[] = ["albedo", "alb", "basecol", "basecolor", "diffuse", "diff", "base", "bc", "d", "color", "col"];
 let path_opacity_ext: string[] = ["opac", "opacity", "alpha"];

+ 1 - 1
base/Sources/tab_fonts.ts

@@ -109,7 +109,7 @@ function tab_fonts_draw(htab: zui_handle_t) {
 				}
 				if (ui.is_hovered) {
 					if (img == null) {
-						app_notify_on_init(function() {
+						app_notify_on_init(function () {
 							let _font: slot_font_t = context_raw.font;
 							context_raw.font = project_fonts[i];
 							util_render_make_font_preview();

+ 1 - 1
base/Sources/ui_base.ts

@@ -823,7 +823,7 @@ function ui_base_update() {
 			let ray: ray_t = raycast_get_ray(mouse_view_x(), mouse_view_y(), camera);
 			physics_body_apply_impulse(body, vec4_mult(ray.dir, 0.15));
 
-			context_raw.particle_timer = tween_timer(5, function() { mesh_object_remove(mo); });
+			context_raw.particle_timer = tween_timer(5, function () { mesh_object_remove(mo); });
 		}
 
 		let pairs: pair_t[] = physics_world_get_contact_pairs(world, context_raw.paint_body);

+ 1 - 1
base/Sources/ui_view2d.ts

@@ -242,7 +242,7 @@ function ui_view2d_render() {
 			if ((context_in_2d_view(view_2d_type_t.ASSET) || context_in_2d_view(view_2d_type_t.NODE)) && context_raw.tool == workspace_tool_t.PICKER && ui_view2d_ui.input_down) {
 				let x: f32 = ui_view2d_ui.input_x - tx - ui_view2d_wx;
 				let y: f32 = ui_view2d_ui.input_y - ty - ui_view2d_wy;
-				base_notify_on_next_frame(function() {
+				base_notify_on_next_frame(function () {
 					let texpaint_picker: image_t = map_get(render_path_render_targets, "texpaint_picker")._image;
 					g2_begin(texpaint_picker);
 					g2_draw_scaled_image(tex, -x, -y, tw, th);

+ 3 - 0
base/project.js

@@ -19,6 +19,9 @@ flags.with_g2 = true;
 flags.with_iron = true;
 flags.with_zui = true;
 
+// flags.with_minits = true; ////
+// flags.physics = false; ////
+
 flags.on_c_project_created = async function(c_project, platform, graphics) {
 	c_project.addDefine("IDLE_SLEEP");
 	let dir = flags.name.toLowerCase();