Browse Source

minits progress

luboslenco 1 year ago
parent
commit
d1de8efa65
50 changed files with 4456 additions and 4138 deletions
  1. 5 5
      armorforge/Sources/manifest.ts
  2. 17 21
      armorforge/Sources/tab_objects.ts
  3. 5 2
      armorlab/Sources/make_material.ts
  4. 18 4
      armorlab/Sources/make_mesh.ts
  5. 25 6
      armorlab/Sources/make_paint.ts
  6. 5 5
      armorlab/Sources/manifest.ts
  7. 17 13
      armorlab/Sources/nodes_brush.ts
  8. 4 2
      armorlab/Sources/ui_nodes_ext.ts
  9. 26 15
      armorpaint/Sources/make_material.ts
  10. 26 12
      armorpaint/Sources/make_mesh.ts
  11. 17 3
      armorpaint/Sources/make_mesh_preview.ts
  12. 21 3
      armorpaint/Sources/make_node_preview.ts
  13. 34 10
      armorpaint/Sources/make_paint.ts
  14. 9 3
      armorpaint/Sources/make_particle.ts
  15. 5 5
      armorpaint/Sources/manifest.ts
  16. 15 13
      armorpaint/Sources/nodes_brush.ts
  17. 4 4
      armorpaint/Sources/slot_layer.ts
  18. 13 7
      armorpaint/Sources/tab_layers.ts
  19. 4 2
      armorsculpt/Sources/make_material.ts
  20. 9 3
      armorsculpt/Sources/make_mesh.ts
  21. 24 10
      armorsculpt/Sources/make_mesh_preview.ts
  22. 10 4
      armorsculpt/Sources/make_sculpt.ts
  23. 5 5
      armorsculpt/Sources/manifest.ts
  24. 10 5
      armorsculpt/Sources/tab_layers.ts
  25. 43 28
      base/Sources/base.ts
  26. 46 25
      base/Sources/box_export.ts
  27. 44 22
      base/Sources/box_preferences.ts
  28. 20 12
      base/Sources/export_arm.ts
  29. 7 7
      base/Sources/import_texture.ts
  30. 2 2
      base/Sources/make_voxel.ts
  31. 14 2
      base/Sources/node_shader_context.ts
  32. 3835 3819
      base/Sources/nodes_material.ts
  33. 11 11
      base/Sources/project.ts
  34. 4 2
      base/Sources/tab_browser.ts
  35. 2 1
      base/Sources/tab_brushes.ts
  36. 8 4
      base/Sources/tab_console.ts
  37. 4 2
      base/Sources/tab_fonts.ts
  38. 2 1
      base/Sources/tab_materials.ts
  39. 8 4
      base/Sources/tab_meshes.ts
  40. 2 1
      base/Sources/tab_particles.ts
  41. 4 2
      base/Sources/tab_plugins.ts
  42. 4 2
      base/Sources/tab_script.ts
  43. 4 2
      base/Sources/tab_swatches.ts
  44. 4 2
      base/Sources/tab_textures.ts
  45. 8 1
      base/Sources/ui_base.ts
  46. 6 3
      base/Sources/ui_box.ts
  47. 13 7
      base/Sources/ui_header.ts
  48. 4 2
      base/Sources/ui_menu.ts
  49. 16 5
      base/Sources/ui_nodes.ts
  50. 13 7
      base/Sources/ui_view2d.ts

+ 5 - 5
armorforge/Sources/manifest.ts

@@ -1,6 +1,6 @@
 
-let manifest_title = "ArmorForge";
-let manifest_version = "0.1";
-let manifest_url = "https://armorforge.org";
-let manifest_url_android = "";
-let manifest_url_ios = "";
+let manifest_title: string = "ArmorForge";
+let manifest_version: string = "0.1";
+let manifest_url: string = "https://armorforge.org";
+let manifest_url_android: string = "";
+let manifest_url_ios: string = "";

+ 17 - 21
armorforge/Sources/tab_objects.ts

@@ -9,7 +9,7 @@ function tab_objects_roundfp(f: f32, precision: i32 = 2): f32 {
 }
 
 function tab_objects_import_mesh_done() {
-	object_set_parent(project_paint_objects.pop().base, null);
+	object_set_parent(array_pop(project_paint_objects).base, null);
 }
 
 function tab_objects_draw_menu(ui: zui_t) {
@@ -65,7 +65,8 @@ function tab_objects_draw_list(ui: zui_t, list_handle: zui_handle_t, current_obj
 	}
 
 	if (current_object.children.length > 0) {
-		zui_row([1 / 13, 12 / 13]);
+		let row: f32[] = [1 / 13, 12 / 13];
+		zui_row(row);
 		let h: zui_handle_t = zui_nest(list_handle, tab_objects_line_counter);
 		if (h.init) {
 			h.selected = true;
@@ -115,10 +116,11 @@ function tab_objects_draw_list(ui: zui_t, list_handle: zui_handle_t, current_obj
 }
 
 function tab_objects_draw(htab: zui_handle_t) {
-	let ui = ui_base_ui;
+	let ui: zui_t = ui_base_ui;
 	if (zui_tab(htab, tr("Objects"))) {
 		zui_begin_sticky();
-		zui_row([1 / 4]);
+		let row: f32[] = [1 / 4];
+		zui_row(row);
 		if (zui_button("Import")) {
 			project_import_mesh(false, tab_objects_import_mesh_done);
 		}
@@ -130,7 +132,6 @@ function tab_objects_draw(htab: zui_handle_t) {
 		}
 
 		if (zui_panel(outliner_handle, "Outliner")) {
-			// ui.indent();
 			ui._y -= zui_ELEMENT_OFFSET(ui);
 
 			tab_objects_line_counter = 0;
@@ -139,8 +140,6 @@ function tab_objects_draw(htab: zui_handle_t) {
 				let c: object_t = _scene_root.children[i];
 				tab_objects_draw_list(ui, zui_handle(__ID__), c);
 			}
-
-			// ui.unindent();
 		}
 
 		let properties_handle: zui_handle_t = zui_handle(__ID__);
@@ -149,22 +148,21 @@ function tab_objects_draw(htab: zui_handle_t) {
 		}
 
 		if (zui_panel(properties_handle, "Properties")) {
-			// ui.indent();
-
 			if (context_raw.selected_object != null) {
-				let h = zui_handle(__ID__);
+				let h: zui_handle_t = zui_handle(__ID__);
 				h.selected = context_raw.selected_object.visible;
 				context_raw.selected_object.visible = zui_check(h, "Visible");
 
-				let t = context_raw.selected_object.transform;
-				let local_pos = t.loc;
-				let scale = t.scale;
-				let rot = quat_get_euler(t.rot);
-				let dim = t.dim;
+				let t: transform_t = context_raw.selected_object.transform;
+				let local_pos: vec4_t = t.loc;
+				let scale: vec4_t = t.scale;
+				let rot: quat_t = quat_get_euler(t.rot);
+				let dim: vec4_t = t.dim;
 				vec4_mult(rot, 180 / 3.141592);
 				let f: f32 = 0.0;
 
-				zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
+				let row: f32[] = [1 / 4, 1 / 4, 1 / 4, 1 / 4];
+				zui_row(row);
 				zui_text("Loc");
 
 				h = zui_handle(__ID__);
@@ -188,7 +186,7 @@ function tab_objects_draw(htab: zui_handle_t) {
 					local_pos.z = f;
 				}
 
-				zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
+				zui_row(row);
 				zui_text("Rotation");
 
 				h = zui_handle(__ID__);
@@ -225,7 +223,7 @@ function tab_objects_draw(htab: zui_handle_t) {
 					// ///end
 				}
 
-				zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
+				zui_row(row);
 				zui_text("Scale");
 
 				h = zui_handle(__ID__);
@@ -249,7 +247,7 @@ function tab_objects_draw(htab: zui_handle_t) {
 					scale.z = f;
 				}
 
-				zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
+				zui_row(row);
 				zui_text("Dimensions");
 
 				h = zui_handle(__ID__);
@@ -301,8 +299,6 @@ function tab_objects_draw(htab: zui_handle_t) {
 					}
 				}
 			}
-
-			// ui.unindent();
 		}
 	}
 }

+ 5 - 2
armorlab/Sources/make_material.ts

@@ -16,7 +16,8 @@ function make_material_parse_mesh_material() {
 		}
 	}
 
-	let con = make_mesh_run({ name: "Material", canvas: null });
+	let mm: material_t = { name: "Material", canvas: null };
+	let con = make_mesh_run(mm);
 	let scon: shader_context_t = shader_context_create(con.data);
 	scon._.override_context = {};
 	if (con.frag.shared_samplers.length > 0) {
@@ -67,7 +68,9 @@ function make_material_parse_paint_material() {
 		if (c.name == "paint") {
 			array_remove(m._.shader.contexts, c);
 			array_remove(m._.shader._.contexts, c);
-			if (c != make_material_default_scon) make_material_delete_context(c);
+			if (c != make_material_default_scon) {
+				make_material_delete_context(c);
+			}
 			break;
 		}
 	}

+ 18 - 4
armorlab/Sources/make_mesh.ts

@@ -2,15 +2,29 @@
 let make_mesh_layer_pass_count: i32 = 1;
 
 function make_mesh_run(data: material_t, layer_pass: i32 = 0): node_shader_context_t {
-	let con_mesh = node_shader_context_create(data, {
+	let props: shader_context_t = {
 		name: "mesh",
 		depth_write: layer_pass == 0 ? true : false,
 		compare_mode: layer_pass == 0 ? "less" : "equal",
 		cull_mode: (context_raw.cull_backfaces || layer_pass > 0) ? "clockwise" : "none",
-		vertex_elements: [{name: "pos", data: "short4norm"}, {name: "nor", data: "short2norm"}, {name: "tex", data: "short2norm"}],
+		vertex_elements: [
+			{
+				name: "pos",
+				data: "short4norm"
+			},
+			{
+				name: "nor",
+				data: "short2norm"
+			},
+			{
+				name: "tex",
+				data: "short2norm"
+			}
+		],
 		color_attachments: ["RGBA64", "RGBA64", "RGBA64"],
 		depth_attachment: "DEPTH32"
-	});
+	};
+	let con_mesh = node_shader_context_create(data, props);
 
 	let vert = node_shader_context_make_vert(con_mesh);
 	let frag = node_shader_context_make_frag(con_mesh);
@@ -23,7 +37,7 @@ function make_mesh_run(data: material_t, layer_pass: i32 = 0): node_shader_conte
 	node_shader_add_uniform(vert, "mat4 prevWVP", "_prev_world_view_proj_matrix");
 	vert.wposition = true;
 
-	let texture_count = 0;
+	let texture_count: i32 = 0;
 	let displace_strength = make_material_get_displace_strength();
 	if (make_material_height_used && displace_strength > 0.0) {
 		vert.n = true;

+ 25 - 6
armorlab/Sources/make_paint.ts

@@ -1,16 +1,35 @@
 
+function make_paint_color_attachments(): string[] {
+	if (context_raw.tool == workspace_tool_t.PICKER) {
+		return ["RGBA32", "RGBA32", "RGBA32", "RGBA32"];
+	}
+	return ["RGBA32", "RGBA32", "RGBA32", "R8"];
+}
+
 function make_paint_run(data: material_t, matcon: material_context_t): node_shader_context_t {
-	let con_paint = node_shader_context_create(data, {
+	let props: shader_context_t = {
 		name: "paint",
 		depth_write: false,
 		compare_mode: "always", // TODO: align texcoords winding order
 		// cull_mode: "counter_clockwise",
 		cull_mode: "none",
-		vertex_elements: [{name: "pos", data: "short4norm"}, {name: "nor", data: "short2norm"}, {name: "tex", data: "short2norm"}],
-		color_attachments:
-			context_raw.tool == workspace_tool_t.PICKER ? ["RGBA32", "RGBA32", "RGBA32", "RGBA32"] :
-				["RGBA32", "RGBA32", "RGBA32", "R8"]
-	});
+		vertex_elements: [
+			{
+				name: "pos",
+				data: "short4norm"
+			},
+			{
+				name: "nor",
+				data: "short2norm"
+			},
+			{
+				name: "tex",
+				data: "short2norm"
+			}
+		],
+		color_attachments: make_paint_color_attachments();
+	};
+	let con_paint = node_shader_context_create(data, props);
 
 	con_paint.data.color_writes_red = [true, true, true, true];
 	con_paint.data.color_writes_green = [true, true, true, true];

+ 5 - 5
armorlab/Sources/manifest.ts

@@ -1,6 +1,6 @@
 
-let manifest_title = "ArmorLab";
-let manifest_version = "0.1";
-let manifest_url = "https://armorlab.org";
-let manifest_url_android = "";
-let manifest_url_ios = "";
+let manifest_title: string = "ArmorLab";
+let manifest_version: string = "0.1";
+let manifest_url: string = "https://armorlab.org";
+let manifest_url_android: string = "";
+let manifest_url_ios: string = "";

+ 17 - 13
armorlab/Sources/nodes_brush.ts

@@ -9,21 +9,25 @@
 
 let nodes_brush_categories: string[] = [_tr("Input"), _tr("Model")];
 
-let nodes_brush_list: zui_node_t[][] = [
-	[ // Input
-		image_texture_node_def,
-		rgb_node_def,
-	],
-	[ // Model
-		inpaint_node_def,
-		photo_to_pbr_node_def,
-		text_to_photo_node_def,
-		tiling_node_def,
-		upscale_node_def,
-		variance_node_def,
-	]
+let nodes_brush_input: zui_node_t[] = [
+	image_texture_node_def,
+	rgb_node_def,
 ];
 
+let nodes_brush_model: zui_node_t[] = [
+	inpaint_node_def,
+	photo_to_pbr_node_def,
+	text_to_photo_node_def,
+	tiling_node_def,
+	upscale_node_def,
+	variance_node_def,
+];
+
+let nodes_brush_list: node_list_t[] = [
+	nodes_brush_input,
+	nodes_brush_model
+]
+
 let nodes_brush_creates: map_t<string, any>;
 
 function nodes_brush_init() {

+ 4 - 2
armorlab/Sources/ui_nodes_ext.ts

@@ -121,9 +121,11 @@ function ui_nodes_ext_draw_buttons(ew: f32, start_y: f32) {
 	ui._y = 2 + start_y;
 
 	///if (krom_android || krom_ios)
-	zui_combo(base_res_handle, ["2K", "4K"], tr("Resolution"));
+	let base_res_combo: string[] = ["2K", "4K"];
+	zui_combo(base_res_handle, base_res_combo, tr("Resolution"));
 	///else
-	zui_combo(base_res_handle, ["2K", "4K", "8K", "16K"], tr("Resolution"));
+	let base_res_combo: string[] = ["2K", "4K", "8K", "16K"];
+	zui_combo(base_res_handle, base_res_combo, tr("Resolution"));
 	///end
 	if (base_res_handle.changed) {
 		base_on_layers_resized();

+ 26 - 15
armorpaint/Sources/make_material.ts

@@ -60,35 +60,40 @@ function make_material_parse_mesh_material() {
 		}
 	}
 
-	let con: node_shader_context_t = make_mesh_run({ name: "Material", canvas: null });
+	let mm: material_t = { name: "Material", canvas: null };
+	let con: node_shader_context_t = make_mesh_run(mm);
 	let scon: shader_context_t = shader_context_create(con.data);
-	scon._.override_context = {};
+	let override_context: _shader_override_t = {};
 	if (con.frag.shared_samplers.length > 0) {
 		let sampler: string = con.frag.shared_samplers[0];
-		scon._.override_context.shared_sampler = substring(sampler, string_last_index_of(sampler, " ") + 1, sampler.length);
+		override_context.shared_sampler = substring(sampler, string_last_index_of(sampler, " ") + 1, sampler.length);
 	}
 	if (!context_raw.texture_filter) {
-		scon._.override_context.filter = "point";
+		override_context.filter = "point";
 	}
+	scon._.override_context = override_context;
 	array_push(m._.shader.contexts, scon);
 	array_push(m._.shader._.contexts, scon);
 
 	for (let i: i32 = 1; i < make_mesh_layer_pass_count; ++i) {
-		let con: node_shader_context_t = make_mesh_run({ name: "Material", canvas: null }, i);
+		let mm: material_t = { name: "Material", canvas: null };
+		let con: node_shader_context_t = make_mesh_run(mm, i);
 		let scon: shader_context_t = shader_context_create(con.data);
-		scon._.override_context = {};
+		let override_context: _shader_override_t = {};
 		if (con.frag.shared_samplers.length > 0) {
 			let sampler: string = con.frag.shared_samplers[0];
-			scon._.override_context.shared_sampler = substring(sampler, string_last_index_of(sampler, " ") + 1, sampler.length);
+			override_context.shared_sampler = substring(sampler, string_last_index_of(sampler, " ") + 1, sampler.length);
 		}
 		if (!context_raw.texture_filter) {
-			scon._.override_context.filter = "point";
+			override_context.filter = "point";
 		}
+		scon._.override_context = override_context;
 		array_push(m._.shader.contexts, scon);
 		array_push(m._.shader._.contexts, scon);
 
 		let mcon: material_context_t;
-		mcon = material_context_create({ name: "mesh" + i, bind_textures: [] });
+		let mmcon: material_context_t = { name: "mesh" + i, bind_textures: [] };
+		mcon = material_context_create(mmcon);
 		array_push(m.contexts, mcon);
 		array_push(m._.contexts, mcon);
 	}
@@ -118,7 +123,8 @@ function make_material_parse_particle_material() {
 		array_remove(m._.shader.contexts, sc);
 		array_remove(m._.shader._.contexts, sc);
 	}
-	let con: node_shader_context_t = make_particle_run({ name: "MaterialParticle", canvas: null });
+	let mm: material_t = { name: "MaterialParticle", canvas: null };
+	let con: node_shader_context_t = make_particle_run(mm);
 	if (sc != null) {
 		make_material_delete_context(sc);
 	}
@@ -128,7 +134,9 @@ function make_material_parse_particle_material() {
 }
 
 function make_material_parse_mesh_preview_material(md: material_data_t = null) {
-	if (!make_material_get_mout()) return;
+	if (!make_material_get_mout()) {
+		return;
+	}
 
 	let m: material_data_t = md == null ? project_materials[0].data : md;
 	let scon: shader_context_t = null;
@@ -192,7 +200,7 @@ function make_material_make_voxel(m: material_data_t) {
 }
 ///end
 
-function make_material_parse_paint_material(bake_previews = true) {
+function make_material_parse_paint_material(bake_previews: bool = true) {
 	if (!make_material_get_mout()) return;
 
 	if (bake_previews) {
@@ -211,7 +219,9 @@ function make_material_parse_paint_material(bake_previews = true) {
 		if (c.name == "paint") {
 			array_remove(m._.shader.contexts, c);
 			array_remove(m._.shader._.contexts, c);
-			if (c != make_material_default_scon) make_material_delete_context(c);
+			if (c != make_material_default_scon) {
+				make_material_delete_context(c);
+			}
 			break;
 		}
 	}
@@ -238,8 +248,9 @@ function make_material_parse_paint_material(bake_previews = true) {
 	if (compile_error) {
 		return;
 	}
-	scon._.override_context = {};
-	scon._.override_context.addressing = "repeat";
+	let override_context: _shader_override_t = {};
+	override_context.addressing = "repeat";
+	scon._.override_context = override_context;
 	let mcon: material_context_t = material_context_create(tmcon);
 
 	array_push(m._.shader.contexts, scon);

+ 26 - 12
armorpaint/Sources/make_mesh.ts

@@ -1,17 +1,31 @@
 
-let make_mesh_layer_pass_count = 1;
+let make_mesh_layer_pass_count: i32 = 1;
 
-function make_mesh_run(data: material_t, layerPass = 0): node_shader_context_t {
-	let context_id: string = layerPass == 0 ? "mesh" : "mesh" + layerPass;
-	let con_mesh: node_shader_context_t = node_shader_context_create(data, {
+function make_mesh_run(data: material_t, layer_pass: i32 = 0): node_shader_context_t {
+	let context_id: string = layer_pass == 0 ? "mesh" : "mesh" + layer_pass;
+	let props: shader_context_t = {
 		name: context_id,
-		depth_write: layerPass == 0 ? true : false,
-		compare_mode: layerPass == 0 ? "less" : "equal",
-		cull_mode: (context_raw.cull_backfaces || layerPass > 0) ? "clockwise" : "none",
-		vertex_elements: [{name: "pos", data: "short4norm"}, {name: "nor", data: "short2norm"}, {name: "tex", data: "short2norm"}],
+		depth_write: layer_pass == 0 ? true : false,
+		compare_mode: layer_pass == 0 ? "less" : "equal",
+		cull_mode: (context_raw.cull_backfaces || layer_pass > 0) ? "clockwise" : "none",
+		vertex_elements: [
+			{
+				name: "pos",
+				data: "short4norm"
+			},
+			{
+				name: "nor",
+				data: "short2norm"
+			},
+			{
+				name: "tex",
+				data: "short2norm"
+			}
+		],
 		color_attachments: ["RGBA64", "RGBA64", "RGBA64"],
 		depth_attachment: "DEPTH32"
-	});
+	};
+	let con_mesh: node_shader_context_t = node_shader_context_create(data, props);
 
 	let vert: node_shader_t = node_shader_context_make_vert(con_mesh);
 	let frag: node_shader_t = node_shader_context_make_frag(con_mesh);
@@ -82,7 +96,7 @@ function make_mesh_run(data: material_t, layerPass = 0): node_shader_context_t {
 	else {
 		node_shader_add_function(frag, str_octahedron_wrap);
 		node_shader_add_function(frag, str_cotangent_frame);
-		if (layerPass > 0) {
+		if (layer_pass > 0) {
 			node_shader_add_uniform(frag, "sampler2D gbuffer0");
 			node_shader_add_uniform(frag, "sampler2D gbuffer1");
 			node_shader_add_uniform(frag, "sampler2D gbuffer2");
@@ -172,12 +186,12 @@ function make_mesh_run(data: material_t, layerPass = 0): node_shader_context_t {
 				texture_count = start_count + count + 3; // gbuffer0_copy, gbuffer1_copy, gbuffer2_copy
 				make_mesh_layer_pass_count++;
 			}
-			if (layerPass == make_mesh_layer_pass_count - 1) {
+			if (layer_pass == make_mesh_layer_pass_count - 1) {
 				array_push(layers, l);
 			}
 		}
 
-		let last_pass: bool = layerPass == make_mesh_layer_pass_count - 1;
+		let last_pass: bool = layer_pass == make_mesh_layer_pass_count - 1;
 
 		for (let i: i32 = 0; i < layers.length; ++i) {
 			let l: slot_layer_t = layers[i];

+ 17 - 3
armorpaint/Sources/make_mesh_preview.ts

@@ -3,15 +3,29 @@ let make_mesh_preview_opacity_discard_decal: f32 = 0.05;
 
 function make_mesh_preview_run(data: material_t, matcon: material_context_t): node_shader_context_t {
 	let context_id: string = "mesh";
-	let con_mesh: node_shader_context_t = node_shader_context_create(data, {
+	let props: shader_context_t = {
 		name: context_id,
 		depth_write: true,
 		compare_mode: "less",
 		cull_mode: "clockwise",
-		vertex_elements: [{name: "pos", data: "short4norm"}, {name: "nor", data: "short2norm"}, {name: "tex", data: "short2norm"}],
+		vertex_elements: [
+			{
+				name: "pos",
+				data: "short4norm"
+			},
+			{
+				name: "nor",
+				data: "short2norm"
+			},
+			{
+				name: "tex",
+				data: "short2norm"
+			}
+		],
 		color_attachments: ["RGBA64", "RGBA64", "RGBA64"],
 		depth_attachment: "DEPTH32"
-	});
+	};
+	let con_mesh: node_shader_context_t = node_shader_context_create(data, props);
 
 	let vert: node_shader_t = node_shader_context_make_vert(con_mesh);
 	let frag: node_shader_t = node_shader_context_make_frag(con_mesh);

+ 21 - 3
armorpaint/Sources/make_node_preview.ts

@@ -1,14 +1,32 @@
 
 function make_node_preview_run(data: material_t, matcon: material_context_t, node: zui_node_t, group: zui_node_canvas_t, parents: zui_node_t[]): node_shader_context_t {
 	let context_id: string = "mesh";
-	let con_mesh: node_shader_context_t = node_shader_context_create(data, {
+	let props: shader_context_t = {
 		name: context_id,
 		depth_write: false,
 		compare_mode: "always",
 		cull_mode: "clockwise",
-		vertex_elements: [{name: "pos", data: "short4norm"}, {name: "nor", data: "short2norm"}, {name: "tex", data: "short2norm"}, {name: "col", data: "short4norm"}],
+		vertex_elements: [
+			{
+				name: "pos",
+				data: "short4norm"
+			},
+			{
+				name: "nor",
+				data: "short2norm"
+			},
+			{
+				name: "tex",
+				data: "short2norm"
+			},
+			{
+				name: "col",
+				data: "short4norm"
+			}
+		],
 		color_attachments: ["RGBA32"]
-	});
+	};
+	let con_mesh: node_shader_context_t = node_shader_context_create(data, props);
 
 	con_mesh.allow_vcols = true;
 	let vert: node_shader_t = node_shader_context_make_vert(con_mesh);

+ 34 - 10
armorpaint/Sources/make_paint.ts

@@ -9,23 +9,47 @@ function make_paint_is_raytraced_bake(): bool {
 	///end
 }
 
+function make_paint_color_attachments(): string[] {
+	if (context_raw.tool == workspace_tool_t.COLORID) {
+		return ["RGBA32"];
+	}
+	if (context_raw.tool == workspace_tool_t.PICKER && context_raw.pick_pos_nor_tex) {
+		return ["RGBA128", "RGBA128"];
+	}
+	if (context_raw.tool == workspace_tool_t.PICKER || context_raw.tool == workspace_tool_t.MATERIAL) {
+		return ["RGBA32", "RGBA32", "RGBA32", "RGBA32"];
+	}
+	if (context_raw.tool == workspace_tool_t.BAKE && make_paint_is_raytraced_bake()) {
+		return ["RGBA64", "RGBA64"];
+	}
+	return ["RGBA32", "RGBA32", "RGBA32", "R8"];
+}
+
 function make_paint_run(data: material_t, matcon: material_context_t): node_shader_context_t {
 	let context_id: string = "paint";
-
-	let con_paint: node_shader_context_t = node_shader_context_create(data, {
+	let props: shader_context_t = {
 		name: context_id,
 		depth_write: false,
 		compare_mode: "always", // TODO: align texcoords winding order
 		// cull_mode: "counter_clockwise",
 		cull_mode: "none",
-		vertex_elements: [{name: "pos", data: "short4norm"}, {name: "nor", data: "short2norm"}, {name: "tex", data: "short2norm"}],
-		color_attachments:
-			context_raw.tool == workspace_tool_t.COLORID ? ["RGBA32"] :
-			(context_raw.tool == workspace_tool_t.PICKER && context_raw.pick_pos_nor_tex) ? ["RGBA128", "RGBA128"] :
-			(context_raw.tool == workspace_tool_t.PICKER || context_raw.tool == workspace_tool_t.MATERIAL) ? ["RGBA32", "RGBA32", "RGBA32", "RGBA32"] :
-			(context_raw.tool == workspace_tool_t.BAKE && make_paint_is_raytraced_bake()) ? ["RGBA64", "RGBA64"] :
-				["RGBA32", "RGBA32", "RGBA32", "R8"]
-	});
+		vertex_elements: [
+			{
+				name: "pos",
+				data: "short4norm"
+			},
+			{
+				name: "nor",
+				data: "short2norm"
+			},
+			{
+				name: "tex",
+				data: "short2norm"
+			}
+		],
+		color_attachments: make_paint_color_attachments()
+	};
+	let con_paint: node_shader_context_t = node_shader_context_create(data, props);
 
 	con_paint.data.color_writes_red = [true, true, true, true];
 	con_paint.data.color_writes_green = [true, true, true, true];

+ 9 - 3
armorpaint/Sources/make_particle.ts

@@ -1,14 +1,20 @@
 
 function make_particle_run(data: material_t): node_shader_context_t {
 	let context_id: string = "mesh";
-	let con_part: node_shader_context_t = node_shader_context_create(data, {
+	let props: shader_context_t = {
 		name: context_id,
 		depth_write: false,
 		compare_mode: "always",
 		cull_mode: "clockwise",
-		vertex_elements: [{name: "pos", data: "short4norm"}],
+		vertex_elements: [
+			{
+				name: "pos",
+				data: "short4norm"
+			}
+		],
 		color_attachments: ["R8"]
-	});
+	};
+	let con_part: node_shader_context_t = node_shader_context_create(data, props);
 
 	let vert: node_shader_t = node_shader_context_make_vert(con_part);
 	let frag: node_shader_t = node_shader_context_make_frag(con_part);

+ 5 - 5
armorpaint/Sources/manifest.ts

@@ -1,6 +1,6 @@
 
-let manifest_title = "ArmorPaint";
-let manifest_version = "1.0 alpha";
-let manifest_url = "https://armorpaint.org";
-let manifest_url_android = "https://play.google.com/store/apps/details?id=org.armorpaint";
-let manifest_url_ios = "https://apps.apple.com/app/armorpaint/id1533967534";
+let manifest_title: string = "ArmorPaint";
+let manifest_version: string = "1.0 alpha";
+let manifest_url: string = "https://armorpaint.org";
+let manifest_url_android: string = "https://play.google.com/store/apps/details?id=org.armorpaint";
+let manifest_url_ios: string = "https://apps.apple.com/app/armorpaint/id1533967534";

+ 15 - 13
armorpaint/Sources/nodes_brush.ts

@@ -2,20 +2,22 @@
 /// <reference path="./nodes/input_node.ts"/>
 /// <reference path="./nodes/brush_output_node.ts"/>
 
-let nodes_brush_categories = [_tr("Nodes")];
+let nodes_brush_categories: string[] = [_tr("Nodes")];
 
-let nodes_brush_list: zui_node_t[][] = [
-	[ // Category 0
-		tex_image_node_def,
-		input_node_def,
-		math_node_def,
-		random_node_def,
-		separate_vector_node_def,
-		time_node_def,
-		float_node_def,
-		vector_node_def,
-		vector_math_node_def
-	]
+let nodes_brush_category0: zui_node_t[] = [
+	tex_image_node_def,
+	input_node_def,
+	math_node_def,
+	random_node_def,
+	separate_vector_node_def,
+	time_node_def,
+	float_node_def,
+	vector_node_def,
+	vector_math_node_def
+];
+
+let nodes_brush_list: node_list_t[] = [
+	nodes_brush_category0
 ];
 
 let nodes_brush_creates: map_t<string, any>;

+ 4 - 4
armorpaint/Sources/slot_layer.ts

@@ -248,13 +248,13 @@ function slot_layer_swap(raw: slot_layer_t, other: slot_layer_t) {
 	///end
 }
 
-function slot_layer_clear(raw: slot_layer_t, baseColor = 0x00000000, baseImage: image_t = null, occlusion = 1.0, roughness = base_default_rough, metallic = 0.0) {
+function slot_layer_clear(raw: slot_layer_t, base_color: i32 = 0x00000000, base_image: image_t = null, occlusion: f32 = 1.0, roughness: f32 = base_default_rough, metallic: f32 = 0.0) {
 	g4_begin(raw.texpaint);
-	g4_clear(baseColor); // Base
+	g4_clear(base_color); // Base
 	g4_end();
-	if (baseImage != null) {
+	if (base_image != null) {
 		g2_begin(raw.texpaint);
-		g2_draw_scaled_image(baseImage, 0, 0, raw.texpaint.width, raw.texpaint.height);
+		g2_draw_scaled_image(base_image, 0, 0, raw.texpaint.width, raw.texpaint.height);
 		g2_end();
 	}
 

+ 13 - 7
armorpaint/Sources/tab_layers.ts

@@ -35,7 +35,8 @@ function tab_layers_draw_full(htab: zui_handle_t) {
 	let ui: zui_t = ui_base_ui;
 	if (zui_tab(htab, tr("Layers"))) {
 		zui_begin_sticky();
-		zui_row([1 / 4, 1 / 4, 1 / 2]);
+		let row: f32[] = [1 / 4, 1 / 4, 1 / 2];
+		zui_row(row);
 
 		tab_layers_button_new(tr("New"));
 		tab_layers_button_2d_view();
@@ -315,7 +316,8 @@ function tab_layers_draw_layer_slot(l: slot_layer_t, i: i32, mini: bool) {
 function tab_layers_draw_layer_slot_mini(l: slot_layer_t, i: i32) {
 	let ui = ui_base_ui;
 
-	zui_row([1, 1]);
+	let row: f32[] = [1, 1];
+	zui_row(row);
 	let uix: f32 = ui._x;
 	let uiy: f32 = ui._y;
 	let state: zui_state_t = tab_layers_draw_layer_icon(l, i, uix, uiy, true);
@@ -333,10 +335,12 @@ function tab_layers_draw_layer_slot_full(l: slot_layer_t, i: i32) {
 
 	let has_panel: bool = slot_layer_is_group(l) || (slot_layer_is_layer(l) && slot_layer_get_masks(l, false) != null);
 	if (has_panel) {
-		zui_row([8 / 100, 16 / 100, 36 / 100, 30 / 100, 10 / 100]);
+		let row: f32[] = [8 / 100, 16 / 100, 36 / 100, 30 / 100, 10 / 100];
+		zui_row(row);
 	}
 	else {
-		zui_row([8 / 100, 16 / 100, 36 / 100, 30 / 100]);
+		let row: f32[] = [8 / 100, 16 / 100, 36 / 100, 30 / 100];
+		zui_row(row);
 	}
 
 	// Draw eye icon
@@ -464,7 +468,8 @@ function tab_layers_draw_layer_slot_full(l: slot_layer_t, i: i32) {
 	else {
 		ui._y -= zui_ELEMENT_OFFSET(ui);
 
-		zui_row([8 / 100, 16 / 100, 36 / 100, 30 / 100, 10 / 100]);
+		let row: f32[] = [8 / 100, 16 / 100, 36 / 100, 30 / 100, 10 / 100];
+		zui_row(row);
 		zui_end_element();
 		zui_end_element();
 		zui_end_element();
@@ -516,7 +521,7 @@ function tab_layers_combo_object(ui: zui_t, l: slot_layer_t, label: bool = false
 function tab_layers_combo_blending(ui: zui_t, l: slot_layer_t, label: bool = false): zui_handle_t {
 	let blending_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
 	blending_handle.position = l.blending;
-	zui_combo(blending_handle, [
+	let blending_combo: string[] = [
 		tr("Mix"),
 		tr("Darken"),
 		tr("Multiply"),
@@ -535,7 +540,8 @@ function tab_layers_combo_blending(ui: zui_t, l: slot_layer_t, label: bool = fal
 		tr("Saturation"),
 		tr("Color"),
 		tr("Value"),
-	], tr("Blending"), label);
+	];
+	zui_combo(blending_handle, blending_combo, tr("Blending"), label);
 	if (blending_handle.changed) {
 		context_set_layer(l);
 		history_layer_blending();

+ 4 - 2
armorsculpt/Sources/make_material.ts

@@ -60,7 +60,8 @@ function make_material_parse_mesh_material() {
 		}
 	}
 
-	let con = make_mesh_run({ name: "Material", canvas: null });
+	let mm: material_t = { name: "Material", canvas: null };
+	let con = make_mesh_run(mm);
 	let scon: shader_context_t = shader_context_create(con.data);
 	scon._.override_context = {};
 	if (con.frag.shared_samplers.length > 0) {
@@ -74,7 +75,8 @@ function make_material_parse_mesh_material() {
 	array_push(m._.shader._.contexts, scon);
 
 	for (let i: i32 = 1; i < make_mesh_layer_pass_count; ++i) {
-		let con = make_mesh_run({ name: "Material", canvas: null }, i);
+		let mm: material_t = { name: "Material", canvas: null };
+		let con = make_mesh_run(mm, i);
 		let scon: shader_context_t = shader_context_create(con.data);
 		scon._.override_context = {};
 		if (con.frag.shared_samplers.length > 0) {

+ 9 - 3
armorsculpt/Sources/make_mesh.ts

@@ -3,15 +3,21 @@ let make_mesh_layer_pass_count = 1;
 
 function make_mesh_run(data: material_t, layer_pass: i32 = 0): node_shader_context_t {
 	let context_id = layer_pass == 0 ? "mesh" : "mesh" + layer_pass;
-	let con_mesh = node_shader_context_create(data, {
+	let props: shader_context_t = {
 		name: context_id,
 		depth_write: layer_pass == 0 ? true : false,
 		compare_mode: layer_pass == 0 ? "less" : "equal",
 		cull_mode: (context_raw.cull_backfaces || layer_pass > 0) ? "clockwise" : "none",
-		vertex_elements: [{name: "pos", data: "short4norm"}],
+		vertex_elements: [
+			{
+				name: "pos",
+				data: "short4norm"
+			}
+		],
 		color_attachments: ["RGBA64", "RGBA64", "RGBA64"],
 		depth_attachment: "DEPTH32"
-	});
+	};
+	let con_mesh = node_shader_context_create(data, props);
 
 	let vert = node_shader_context_make_vert(con_mesh);
 	let frag = node_shader_context_make_frag(con_mesh);

+ 24 - 10
armorsculpt/Sources/make_mesh_preview.ts

@@ -3,15 +3,29 @@ let make_mesh_preview_opacity_discard_decal: f32 = 0.05;
 
 function make_mesh_preview_run(data: material_t, matcon: material_context_t): node_shader_context_t {
 	let context_id = "mesh";
-	let con_mesh = node_shader_context_create(data, {
+	let props: shader_context_t = {
 		name: context_id,
 		depth_write: true,
 		compare_mode: "less",
 		cull_mode: "clockwise",
-		vertex_elements: [{name: "pos", data: "short4norm"}, {name: "nor", data: "short2norm"}, {name: "tex", data: "short2norm"}],
+		vertex_elements: [
+			{
+				name: "pos",
+				data: "short4norm"
+			},
+			{
+				name: "nor",
+				data: "short2norm"
+			},
+			{
+				name: "tex",
+				data: "short2norm"
+			}
+		],
 		color_attachments: ["RGBA64", "RGBA64", "RGBA64"],
 		depth_attachment: "DEPTH32"
-	});
+	};
+	let con_mesh = node_shader_context_create(data, props);
 
 	let vert = node_shader_context_make_vert(con_mesh);
 	let frag = node_shader_context_make_frag(con_mesh);
@@ -54,13 +68,13 @@ function make_mesh_preview_run(data: material_t, matcon: material_context_t): no
 	parser_material_parse_height = false;
 	parser_material_parse_height_as_channel = false;
 	parser_material_sample_keep_aspect = false;
-	let base = "vec3(1.0, 1.0, 1.0)";//sout.out_basecol;
-	let rough = "0.0";//sout.out_roughness;
-	let met = "0.0";//sout.out_metallic;
-	let occ = "0.0";//sout.out_occlusion;
-	let opac = "0.0";//sout.out_opacity;
-	let height = "0.0";//sout.out_height;
-	let nortan = "vec3(1.0, 1.0, 1.0)";//parser_material_out_normaltan;
+	let base: string = "vec3(1.0, 1.0, 1.0)";//sout.out_basecol;
+	let rough: string = "0.0";//sout.out_roughness;
+	let met: string = "0.0";//sout.out_metallic;
+	let occ: string = "0.0";//sout.out_occlusion;
+	let opac: string = "0.0";//sout.out_opacity;
+	let height: string = "0.0";//sout.out_height;
+	let nortan: string = "vec3(1.0, 1.0, 1.0)";//parser_material_out_normaltan;
 	node_shader_write(frag, "vec3 basecol = pow(" + base + ", vec3(2.2, 2.2, 2.2));");
 	node_shader_write(frag, "float roughness = " + rough + ";");
 	node_shader_write(frag, "float metallic = " + met + ";");

+ 10 - 4
armorsculpt/Sources/make_sculpt.ts

@@ -1,15 +1,21 @@
 
 function make_sculpt_run(data: material_t, matcon: material_context_t): node_shader_context_t {
 	let context_id = "paint";
-	let con_paint = node_shader_context_create(data, {
+	let props: shader_context_t = {
 		name: context_id,
 		depth_write: false,
 		compare_mode: "always", // TODO: align texcoords winding order
 		// cull_mode: "counter_clockwise",
 		cull_mode: "none",
-		vertex_elements: [{name: "pos", data: "float2"}],
+		vertex_elements: [
+			{
+				name: "pos",
+				data: "float2"
+			}
+		],
 		color_attachments: ["RGBA32", "RGBA32", "RGBA32", "R8"]
-	});
+	};
+	let con_paint = node_shader_context_create(data, props);
 
 	con_paint.data.color_writes_red = [true, true, true, true];
 	con_paint.data.color_writes_green = [true, true, true, true];
@@ -21,7 +27,7 @@ function make_sculpt_run(data: material_t, matcon: material_context_t): node_sha
 	let frag = node_shader_context_make_frag(con_paint);
 	frag.ins = vert.outs;
 
-	let faceFill = context_raw.tool == workspace_tool_t.FILL && context_raw.fill_type_handle.position == fill_type_t.FACE;
+	let face_fill = context_raw.tool == workspace_tool_t.FILL && context_raw.fill_type_handle.position == fill_type_t.FACE;
 	let decal = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT;
 
 	node_shader_add_out(vert, "vec2 texCoord");

+ 5 - 5
armorsculpt/Sources/manifest.ts

@@ -1,6 +1,6 @@
 
-let manifest_title = "ArmorSculpt";
-let manifest_version = "0.1";
-let manifest_url = "https://armorsculpt.org";
-let manifest_url_android = "";
-let manifest_url_ios = "";
+let manifest_title: string = "ArmorSculpt";
+let manifest_version: string = "0.1";
+let manifest_url: string = "https://armorsculpt.org";
+let manifest_url_android: string = "";
+let manifest_url_ios: string = "";

+ 10 - 5
armorsculpt/Sources/tab_layers.ts

@@ -34,7 +34,8 @@ function tab_layers_draw_full(htab: zui_handle_t) {
 	let ui = ui_base_ui;
 	if (zui_tab(htab, tr("Layers"))) {
 		zui_begin_sticky();
-		zui_row([1 / 4, 3 / 4]);
+		let row: f32[] = [1 / 4, 3 / 4];
+		zui_row(row);
 
 		tab_layers_button_new(tr("New"));
 		tab_layers_combo_filter();
@@ -197,7 +198,8 @@ function tab_layers_draw_layer_slot(l: slot_layer_t, i: i32, mini: bool) {
 function tab_layers_draw_layer_slot_mini(l: slot_layer_t, i: i32) {
 	let ui = ui_base_ui;
 
-	zui_row([1, 1]);
+	let row: f32[] = [1, 1];
+	zui_row(row);
 	let uix = ui._x;
 	let uiy = ui._y;
 	zui_end_element();
@@ -214,10 +216,12 @@ function tab_layers_draw_layer_slot_full(l: slot_layer_t, i: i32) {
 
 	let hasPanel = slot_layer_is_group(l) || (slot_layer_is_layer(l) && slot_layer_get_masks(l, false) != null);
 	if (hasPanel) {
-		zui_row([8 / 100, 52 / 100, 30 / 100, 10 / 100]);
+		let row: f32[] = [8 / 100, 52 / 100, 30 / 100, 10 / 100];
+		zui_row(row);
 	}
 	else {
-		zui_row([8 / 100, 52 / 100, 30 / 100]);
+		let row: f32[] = [8 / 100, 52 / 100, 30 / 100];
+		zui_row(row);
 	}
 
 	// Draw eye icon
@@ -331,7 +335,8 @@ function tab_layers_draw_layer_slot_full(l: slot_layer_t, i: i32) {
 	else {
 		ui._y -= zui_ELEMENT_OFFSET(ui);
 
-		zui_row([8 / 100, 16 / 100, 36 / 100, 30 / 100, 10 / 100]);
+		let row: f32 = [8 / 100, 16 / 100, 36 / 100, 30 / 100, 10 / 100];
+		zui_row(row);
 		zui_end_element();
 		zui_end_element();
 		zui_end_element();

+ 43 - 28
base/Sources/base.ts

@@ -238,8 +238,15 @@ function base_init() {
 	base_color_wheel_gradient = image_color_wheel_gradient;
 	zui_set_enum_texts(base_enum_texts);
 	zui_tr = tr;
-	base_ui_box = zui_create({ theme: base_theme, font: f, scale_factor: config_raw.window_scale, color_wheel: base_color_wheel, black_white_gradient: base_color_wheel_gradient });
-	base_ui_menu = zui_create({ theme: base_theme, font: f, scale_factor: config_raw.window_scale, color_wheel: base_color_wheel, black_white_gradient: base_color_wheel_gradient });
+	let ops: zui_options_t = {
+		theme: base_theme,
+		font: f,
+		scale_factor: config_raw.window_scale,
+		color_wheel: base_color_wheel,
+		black_white_gradient: base_color_wheel_gradient
+	}
+	base_ui_box = zui_create(ops);
+	base_ui_menu = zui_create(ops);
 	base_default_element_h = base_ui_menu.ops.theme.ELEMENT_H;
 
 	// Init plugins
@@ -732,10 +739,12 @@ function base_get_drag_image(): image_t {
 	if (base_drag_swatch != null) {
 		base_drag_tint = base_drag_swatch.base;
 		base_drag_size = 26;
-		return tab_swatches_empty_get()
+		return tab_swatches_empty_get();
 	}
 	if (base_drag_file != null) {
-		if (base_drag_file_icon != null) return base_drag_file_icon;
+		if (base_drag_file_icon != null) {
+			return base_drag_file_icon;
+		}
 		let icons: image_t = resource_get("icons.k");
 		base_drag_rect = string_index_of(base_drag_file, ".") > 0 ? resource_tile50(icons, 3, 1) : resource_tile50(icons, 2, 1);
 		base_drag_tint = ui_base_ui.ops.theme.HIGHLIGHT_COL;
@@ -859,8 +868,12 @@ function base_render() {
 
 	let using_menu: bool = ui_menu_show && mouse_y > ui_header_h;
 	base_ui_enabled = !ui_box_show && !using_menu && !base_is_combo_selected();
-	if (ui_box_show) ui_box_render();
-	if (ui_menu_show) ui_menu_render();
+	if (ui_box_show) {
+		ui_box_render();
+	}
+	if (ui_menu_show) {
+		ui_menu_render();
+	}
 
 	// Save last pos for continuos paint
 	context_raw.last_paint_vec_x = context_raw.paint_vec.x;
@@ -979,30 +992,30 @@ function base_init_layout() {
 	let show2d: bool = ui_nodes_show || ui_view2d_show;
 
 	let raw: config_t = config_raw;
-	raw.layout = [
-		///if (is_paint || is_sculpt)
-		math_floor(ui_base_default_sidebar_w * raw.window_scale), // LayoutSidebarW
-		math_floor(sys_height() / 2), // LayoutSidebarH0
-		math_floor(sys_height() / 2), // LayoutSidebarH1
-		///end
+	raw.layout = [];
 
-		///if krom_ios
-		show2d ? math_floor((app_w() + raw.layout[layout_size_t.NODES_W]) * 0.473) : math_floor(app_w() * 0.473), // LayoutNodesW
-		///elseif krom_android
-		show2d ? math_floor((app_w() + raw.layout[layout_size_t.NODES_W]) * 0.473) : math_floor(app_w() * 0.473),
-		///else
-		show2d ? math_floor((app_w() + raw.layout[layout_size_t.NODES_W]) * 0.515) : math_floor(app_w() * 0.515), // Align with ui header controls
-		///end
+	///if (is_paint || is_sculpt)
+	array_push(raw.layout, math_floor(ui_base_default_sidebar_w * raw.window_scale)); // LayoutSidebarW
+	array_push(raw.layout, math_floor(sys_height() / 2)); // LayoutSidebarH0
+	array_push(raw.layout, math_floor(sys_height() / 2)); // LayoutSidebarH1
+	///end
+
+	///if krom_ios
+	array_push(raw.layout, show2d ? math_floor((app_w() + raw.layout[layout_size_t.NODES_W]) * 0.473) : math_floor(app_w() * 0.473)); // LayoutNodesW
+	///elseif krom_android
+	array_push(raw.layout, show2d ? math_floor((app_w() + raw.layout[layout_size_t.NODES_W]) * 0.473) : math_floor(app_w() * 0.473));
+	///else
+	array_push(raw.layout, show2d ? math_floor((app_w() + raw.layout[layout_size_t.NODES_W]) * 0.515) : math_floor(app_w() * 0.515)); // Align with ui header controls
+	///end
 
-		math_floor(app_h() / 2), // LayoutNodesH
-		math_floor(ui_status_default_status_h * raw.window_scale), // LayoutStatusH
+	array_push(raw.layout, math_floor(app_h() / 2)); // LayoutNodesH
+	array_push(raw.layout, math_floor(ui_status_default_status_h * raw.window_scale)); // LayoutStatusH
 
-		///if (krom_android || krom_ios)
-		0, // LayoutHeader
-		///else
-		1,
-		///end
-	];
+	///if (krom_android || krom_ios)
+	array_push(raw.layout, 0); // LayoutHeader
+	///else
+	array_push(raw.layout, 1);
+	///end
 
 	raw.layout_tabs = [
 		///if (is_paint || is_sculpt)
@@ -1171,7 +1184,9 @@ function base_resize_layers() {
 		map_get(rts, "texpaint_blur").height = size_y;
 		map_get(rts, "texpaint_blur")._image = image_create_render_target(size_x, size_y);
 	}
-	if (render_path_paint_live_layer != null) slot_layer_resize_and_set_bits(render_path_paint_live_layer);
+	if (render_path_paint_live_layer != null) {
+		slot_layer_resize_and_set_bits(render_path_paint_live_layer);
+	}
 	///if (krom_direct3d12 || krom_vulkan || krom_metal)
 	render_path_raytrace_ready = false; // Rebuild baketex
 	///end

+ 46 - 25
base/Sources/box_export.ts

@@ -64,21 +64,26 @@ function box_export_tab_export_textures(ui: zui_t, title: string, bake_material:
 	let tab_vertical: bool = config_raw.touch_ui;
 	if (zui_tab(box_export_htab, title, tab_vertical)) {
 
-		zui_row([0.5, 0.5]);
+		let row: f32[] = [0.5, 0.5];
+		zui_row(row);
 
 		///if is_paint
 		///if (krom_android || krom_ios)
-		zui_combo(base_res_handle, ["128", "256", "512", "1K", "2K", "4K"], tr("Resolution"), true);
+		let base_res_combo: string[] = ["128", "256", "512", "1K", "2K", "4K"];
+		zui_combo(base_res_handle, base_res_combo, tr("Resolution"), true);
 		///else
-		zui_combo(base_res_handle, ["128", "256", "512", "1K", "2K", "4K", "8K", "16K"], tr("Resolution"), true);
+		let base_res_combo: string[] = ["128", "256", "512", "1K", "2K", "4K", "8K", "16K"];
+		zui_combo(base_res_handle, base_res_combo, tr("Resolution"), true);
 		///end
 		///end
 
 		///if is_lab
 		///if (krom_android || krom_ios)
-		zui_combo(base_res_handle, ["2K", "4K"], tr("Resolution"), true);
+		let base_res_combo: string[] = ["2K", "4K"];
+		zui_combo(base_res_handle, base_res_combo, tr("Resolution"), true);
 		///else
-		zui_combo(base_res_handle, ["2K", "4K", "8K", "16K"], tr("Resolution"), true);
+		let base_res_combo: string[] = ["2K", "4K", "8K", "16K"];
+		zui_combo(base_res_handle, base_res_combo, tr("Resolution"), true);
 		///end
 		///end
 
@@ -87,9 +92,11 @@ function box_export_tab_export_textures(ui: zui_t, title: string, bake_material:
 		}
 
 		///if (is_lab || krom_android || krom_ios)
-		zui_combo(base_bits_handle, ["8bit"], tr("Color"), true);
+		let base_bits_combo: string[] = ["8bit"];
+		zui_combo(base_bits_handle, base_bits_combo, tr("Color"), true);
 		///else
-		zui_combo(base_bits_handle, ["8bit", "16bit", "32bit"], tr("Color"), true);
+		let base_bits_combo: string[] = ["8bit", "16bit", "32bit"];
+		zui_combo(base_bits_handle, base_bits_combo, tr("Color"), true);
 		///end
 
 		///if is_paint
@@ -98,20 +105,22 @@ function box_export_tab_export_textures(ui: zui_t, title: string, bake_material:
 		}
 		///end
 
-		zui_row([0.5, 0.5]);
+		zui_row(row);
 		if (base_bits_handle.position == texture_bits_t.BITS8) {
 			let h: zui_handle_t = zui_handle(__ID__);
 			if (h.init) {
 				h.position = context_raw.format_type;
 			}
-			context_raw.format_type = zui_combo(h, ["png", "jpg"], tr("Format"), true);
+			let format_combo: string[] = ["png", "jpg"];
+			context_raw.format_type = zui_combo(h, format_combo, tr("Format"), true);
 		}
 		else {
 			let h: zui_handle_t = zui_handle(__ID__);
 			if (h.init) {
 				h.position = context_raw.format_type;
 			}
-			context_raw.format_type = zui_combo(h, ["exr"], tr("Format"), true);
+			let format_combo: string[] = ["exr"];
+			context_raw.format_type = zui_combo(h, format_combo, tr("Format"), true);
 		}
 
 		ui.enabled = context_raw.format_type == texture_ldr_format_t.JPG && base_bits_handle.position == texture_bits_t.BITS8;
@@ -123,11 +132,12 @@ function box_export_tab_export_textures(ui: zui_t, title: string, bake_material:
 		ui.enabled = true;
 
 		///if is_paint
-		zui_row([0.5, 0.5]);
+		zui_row(row);
 		ui.enabled = !bake_material;
 		let layers_export_handle: zui_handle_t = zui_handle(__ID__);
 		layers_export_handle.position = context_raw.layers_export;
-		context_raw.layers_export = zui_combo(layers_export_handle, [tr("Visible"), tr("Selected"), tr("Per Object"), tr("Per Udim Tile")], tr("Layers"), true);
+		let layers_export_combo: string[] = [tr("Visible"), tr("Selected"), tr("Per Object"), tr("Per Udim Tile")];
+		context_raw.layers_export = zui_combo(layers_export_handle, layers_export_combo, tr("Layers"), true);
 		ui.enabled = true;
 		///end
 
@@ -136,11 +146,12 @@ function box_export_tab_export_textures(ui: zui_t, title: string, bake_material:
 
 		let layers_destination_handle: zui_handle_t = zui_handle(__ID__);
 		layers_destination_handle.position = context_raw.layers_destination;
-		context_raw.layers_destination = zui_combo(layers_destination_handle, [tr("Disk"), tr("Packed")], tr("Destination"), true);
+		let layers_destination_combo: string[] = [tr("Disk"), tr("Packed")];
+		context_raw.layers_destination = zui_combo(layers_destination_handle, layers_destination_combo, tr("Destination"), true);
 
 		zui_end_element();
 
-		zui_row([0.5, 0.5]);
+		zui_row(row);
 		if (zui_button(tr("Cancel"))) {
 			ui_box_hide();
 		}
@@ -189,7 +200,9 @@ let _box_export_t: export_preset_texture_t;
 function box_export_tab_presets(ui: zui_t) {
 	let tab_vertical: bool = config_raw.touch_ui;
 	if (zui_tab(box_export_htab, tr("Presets"), tab_vertical)) {
-		zui_row([3 / 5, 1 / 5, 1 / 5]);
+
+		let row: f32[] = [3 / 5, 1 / 5, 1 / 5];
+		zui_row(row);
 
 		zui_combo(box_export_hpreset, box_export_files, tr("Preset"));
 		if (box_export_hpreset.changed) {
@@ -200,7 +213,8 @@ function box_export_tab_presets(ui: zui_t) {
 			ui_box_show_custom(function (ui: zui_t) {
 				let tab_vertical: bool = config_raw.touch_ui;
 				if (zui_tab(zui_handle(__ID__), tr("New Preset"), tab_vertical)) {
-					zui_row([0.5, 0.5]);
+					let row: f32[] = [0.5, 0.5];
+					zui_row(row);
 					let h_preset: zui_handle_t = zui_handle(__ID__);
 					if (h_preset.init) {
 						h_preset.text = "new_preset";
@@ -244,7 +258,8 @@ function box_export_tab_presets(ui: zui_t) {
 
 		// Texture list
 		zui_separator(10, false);
-		zui_row([1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6]);
+		row = [1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6];
+		zui_row(row);
 		zui_text(tr("Texture"));
 		zui_text(tr("R"));
 		zui_text(tr("G"));
@@ -254,7 +269,7 @@ function box_export_tab_presets(ui: zui_t) {
 		ui.changed = false;
 		for (let i: i32 = 0; i < box_export_preset.textures.length; ++i) {
 			let t: export_preset_texture_t = box_export_preset.textures[i];
-			zui_row([1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6]);
+			zui_row(row);
 			let htex: zui_handle_t = zui_nest(box_export_hpreset, i);
 			htex.text = t.name;
 			t.name = zui_text_input(htex);
@@ -307,7 +322,8 @@ function box_export_tab_presets(ui: zui_t) {
 			box_export_save_preset();
 		}
 
-		zui_row([1 / 8]);
+		row = [1 / 8];
+		zui_row(row);
 		if (zui_button(tr("Add"))) {
 			array_push(box_export_preset.textures, { name: "base", channels: ["base_r", "base_g", "base_b", "1.0"], color_space: "linear" });
 			box_export_hpreset.children = null;
@@ -330,7 +346,8 @@ function box_export_tab_atlases(ui: zui_t) {
 			}
 		}
 		for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
-			zui_row([1 / 2, 1 / 2]);
+			let row: f32[] = [1 / 2, 1 / 2];
+			zui_row(row);
 			zui_text(project_paint_objects[i].base.name);
 			let hatlas: zui_handle_t = zui_nest(zui_handle(__ID__), i);
 			hatlas.position = project_atlas_objects[i];
@@ -352,13 +369,15 @@ function box_export_tab_export_mesh(ui: zui_t, htab: zui_handle_t) {
 	let tab_vertical: bool = config_raw.touch_ui;
 	if (zui_tab(htab, tr("Export Mesh"), tab_vertical)) {
 
-		zui_row([1 / 2, 1 / 2]);
+		let row: f32[] = [1 / 2, 1 / 2];
+		zui_row(row);
 
 		let h_export_mesh_format: zui_handle_t = zui_handle(__ID__);
 		if (h_export_mesh_format.init) {
 			h_export_mesh_format.position = context_raw.export_mesh_format;
 		}
-		context_raw.export_mesh_format = zui_combo(h_export_mesh_format, ["obj", "arm"], tr("Format"), true);
+		let export_mesh_format_combo: string[] = ["obj", "arm"];
+		context_raw.export_mesh_format = zui_combo(h_export_mesh_format, export_mesh_format_combo, tr("Format"), true);
 
 		let ar: string[] = [tr("All")];
 		for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
@@ -381,7 +400,7 @@ function box_export_tab_export_mesh(ui: zui_t, htab: zui_handle_t) {
 		}
 		zui_text(tris + " " + tr("triangles"));
 
-		zui_row([0.5, 0.5]);
+		zui_row(row);
 		if (zui_button(tr("Cancel"))) {
 			ui_box_hide();
 		}
@@ -418,7 +437,8 @@ function box_export_show_material() {
 			h2.selected = context_raw.write_icon_on_export;
 			context_raw.pack_assets_on_export = zui_check(h1, tr("Pack Assets"));
 			context_raw.write_icon_on_export = zui_check(h2, tr("Export Icon"));
-			zui_row([0.5, 0.5]);
+			let row: f32[] = [0.5, 0.5];
+			zui_row(row);
 			if (zui_button(tr("Cancel"))) {
 				ui_box_hide();
 			}
@@ -449,7 +469,8 @@ function box_export_show_brush() {
 			h2.selected = context_raw.write_icon_on_export;
 			context_raw.pack_assets_on_export = zui_check(h1, tr("Pack Assets"));
 			context_raw.write_icon_on_export = zui_check(h2, tr("Export Icon"));
-			zui_row([0.5, 0.5]);
+			let row: f32[] = [0.5, 0.5];
+			zui_row(row);
 			if (zui_button(tr("Cancel"))) {
 				ui_box_hide();
 			}

+ 44 - 22
base/Sources/box_preferences.ts

@@ -67,7 +67,8 @@ function box_preferences_show() {
 			if (zoom_direction_handle.init) {
 				zoom_direction_handle.position = config_raw.zoom_direction;
 			}
-			zui_combo(zoom_direction_handle, [tr("Vertical"), tr("Vertical Inverted"), tr("Horizontal"), tr("Horizontal Inverted"), tr("Vertical and Horizontal"), tr("Vertical and Horizontal Inverted")], tr("Direction to Zoom"), true);
+			let zoom_direction_combo: string[] = [tr("Vertical"), tr("Vertical Inverted"), tr("Horizontal"), tr("Horizontal Inverted"), tr("Vertical and Horizontal"), tr("Vertical and Horizontal Inverted")];
+			zui_combo(zoom_direction_handle, zoom_direction_combo, tr("Direction to Zoom"), true);
 			if (zoom_direction_handle.changed) {
 				config_raw.zoom_direction = zoom_direction_handle.position;
 			}
@@ -124,7 +125,8 @@ function box_preferences_show() {
 			// let grid_snap: bool = Zui.check(Zui.handle("boxpreferences_11", { selected: false }), "Grid Snap");
 
 			zui_end_element();
-			zui_row([0.5, 0.5]);
+			let row: f32[] = [0.5, 0.5];
+			zui_row(row);
 			if (zui_button(tr("Restore")) && !ui_menu_show) {
 				ui_menu_draw(function (ui: zui_t) {
 					if (ui_menu_button(ui, tr("Confirm"))) {
@@ -180,7 +182,8 @@ function box_preferences_show() {
 			}
 
 			zui_begin_sticky();
-			zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
+			let row: f32[] = [1 / 4, 1 / 4, 1 / 4, 1 / 4];
+			zui_row(row);
 
 			zui_combo(box_preferences_theme_handle, box_preferences_themes, tr("Theme"));
 			if (box_preferences_theme_handle.changed) {
@@ -191,7 +194,8 @@ function box_preferences_show() {
 			if (zui_button(tr("New"))) {
 				ui_box_show_custom(function (ui: zui_t) {
 					if (zui_tab(zui_handle(__ID__), tr("New Theme"))) {
-						zui_row([0.5, 0.5]);
+						let row: f32[] = [0.5, 0.5];
+						zui_row(row);
 						let h: zui_handle_t = zui_handle(__ID__);
 						if (h.init) {
 							h.text = "new_theme";
@@ -242,7 +246,8 @@ function box_preferences_show() {
 			if (h.init) {
 				h.color = box_preferences_world_color;
 			}
-			zui_row([1 / 8, 7 / 8]);
+			row = [1 / 8, 7 / 8];
+			zui_row(row);
 			zui_text("", 0, h.color);
 			if (ui.is_hovered && ui.input_released) {
 				ui_menu_draw(function (ui: zui_t) {
@@ -288,7 +293,8 @@ function box_preferences_show() {
 				}
 
 				if (is_hex) {
-					zui_row([1 / 8, 7 / 8]);
+					let row: f32[] = [1 / 8, 7 / 8];
+					zui_row(row);
 					zui_text("", 0, val);
 					if (ui.is_hovered && ui.input_released) {
 						h.color = theme[key];
@@ -383,7 +389,8 @@ function box_preferences_show() {
 			if (dilate_handle.init) {
 				dilate_handle.position = config_raw.dilate;
 			}
-			zui_combo(dilate_handle, [tr("Instant"), tr("Delayed")], tr("Dilate"), true);
+			let dilate_combo: string[] = [tr("Instant"), tr("Delayed")];
+			zui_combo(dilate_handle, dilate_combo, tr("Dilate"), true);
 			if (dilate_handle.changed) {
 				config_raw.dilate = dilate_handle.position;
 			}
@@ -394,7 +401,8 @@ function box_preferences_show() {
 			if (workspace_handle.init) {
 				workspace_handle.position = config_raw.workspace;
 			}
-			zui_combo(workspace_handle, [tr("3D View"), tr("2D View")], tr("Default Workspace"), true);
+			let workspace_combo: string[] = [tr("3D View"), tr("2D View")];
+			zui_combo(workspace_handle, workspace_combo, tr("Default Workspace"), true);
 			if (workspace_handle.changed) {
 				config_raw.workspace = workspace_handle.position;
 			}
@@ -404,7 +412,8 @@ function box_preferences_show() {
 			if (camera_controls_handle.init) {
 				camera_controls_handle.position = config_raw.camera_controls;
 			}
-			zui_combo(camera_controls_handle, [tr("Orbit"), tr("Rotate"), tr("Fly")], tr("Default Camera Controls"), true);
+			let camera_controls_combo: string[] = [tr("Orbit"), tr("Rotate"), tr("Fly")];
+			zui_combo(camera_controls_handle, camera_controls_combo, tr("Default Camera Controls"), true);
 			if (camera_controls_handle.changed) {
 				config_raw.camera_controls = camera_controls_handle.position;
 			}
@@ -416,17 +425,21 @@ function box_preferences_show() {
 
 			///if is_paint
 			///if (krom_android || krom_ios)
-			zui_combo(layer_res_handle, ["128", "256", "512", "1K", "2K", "4K"], tr("Default Layer Resolution"), true);
+			let layer_res_combo: string[] = ["128", "256", "512", "1K", "2K", "4K"];
+			zui_combo(layer_res_handle, layer_res_combo, tr("Default Layer Resolution"), true);
 			///else
-			zui_combo(layer_res_handle, ["128", "256", "512", "1K", "2K", "4K", "8K"], tr("Default Layer Resolution"), true);
+			let layer_res_combo: string[] = ["128", "256", "512", "1K", "2K", "4K", "8K"];
+			zui_combo(layer_res_handle, layer_res_combo, tr("Default Layer Resolution"), true);
 			///end
 			///end
 
 			///if is_lab
 			///if (krom_android || krom_ios)
-			zui_combo(layer_res_handle, ["2K", "4K"], tr("Default Layer Resolution"), true);
+			let layer_res_combo: string[] = ["2K", "4K"];
+			zui_combo(layer_res_handle, layer_res_combo, tr("Default Layer Resolution"), true);
 			///else
-			zui_combo(layer_res_handle, ["2K", "4K", "8K", "16K"], tr("Default Layer Resolution"), true);
+			let layer_res_combo: string[] = ["2K", "4K", "8K", "16K"];
+			zui_combo(layer_res_handle, layer_res_combo, tr("Default Layer Resolution"), true);
 			///end
 			///end
 
@@ -481,7 +494,8 @@ function box_preferences_show() {
 				make_material_parse_paint_material();
 			}
 
-			zui_row([0.5, 0.5]);
+			let row: f32[] = [0.5, 0.5];
+			zui_row(row);
 
 			let brush_angle_reject_handle: zui_handle_t = zui_handle(__ID__);
 			if (brush_angle_reject_handle.init) {
@@ -558,7 +572,8 @@ function box_preferences_show() {
 			///end
 
 			zui_end_element();
-			zui_row([0.5]);
+			let row: f32[] = [0.5];
+			zui_row(row);
 			if (zui_button(tr("Help"))) {
 				///if (is_paint || is_sculpt)
 				file_load_url("https://github.com/armory3d/armorpaint_docs///pen");
@@ -601,7 +616,8 @@ function box_preferences_show() {
 			if (hpathtrace_mode.init) {
 				hpathtrace_mode.position = context_raw.pathtrace_mode;
 			}
-			context_raw.pathtrace_mode = zui_combo(hpathtrace_mode, [tr("Core"), tr("Full")], tr("Path Tracer"), true);
+			let pathtrace_mode_combo: string[] = [tr("Core"), tr("Full")];
+			context_raw.pathtrace_mode = zui_combo(hpathtrace_mode, pathtrace_mode_combo, tr("Path Tracer"), true);
 			if (hpathtrace_mode.changed) {
 				render_path_raytrace_ready = false;
 			}
@@ -612,12 +628,14 @@ function box_preferences_show() {
 			if (hrender_mode.init) {
 				hrender_mode.position = context_raw.render_mode;
 			}
-			context_raw.render_mode = zui_combo(hrender_mode, [tr("Full"), tr("Mobile")], tr("Renderer"), true);
+			let render_mode_combo: string[] = [tr("Full"), tr("Mobile")];
+			context_raw.render_mode = zui_combo(hrender_mode, render_mode_combo, tr("Renderer"), true);
 			if (hrender_mode.changed) {
 				context_set_render_path();
 			}
 
-			zui_combo(context_raw.hsupersample, ["0.25x", "0.5x", "1.0x", "1.5x", "2.0x", "4.0x"], tr("Super Sample"), true);
+			let supersample_combo: string[] = ["0.25x", "0.5x", "1.0x", "1.5x", "2.0x", "4.0x"];
+			zui_combo(context_raw.hsupersample, supersample_combo, tr("Super Sample"), true);
 			if (context_raw.hsupersample.changed) {
 				config_apply();
 			}
@@ -717,7 +735,8 @@ function box_preferences_show() {
 			}
 
 			zui_begin_sticky();
-			zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
+			let row: f32[] = [1 / 4, 1 / 4, 1 / 4, 1 / 4];
+			zui_row(row);
 
 			box_preferences_preset_handle = zui_handle(__ID__);
 			if (box_preferences_preset_handle.init) {
@@ -733,7 +752,8 @@ function box_preferences_show() {
 			if (zui_button(tr("New"))) {
 				ui_box_show_custom(function (ui: zui_t) {
 					if (zui_tab(zui_handle(__ID__), tr("New Keymap"))) {
-						zui_row([0.5, 0.5]);
+						let row: f32[] = [0.5, 0.5];
+						zui_row(row);
 						let h: zui_handle_t = zui_handle(__ID__);
 						if (h.init) {
 							h.text = "new_keymap";
@@ -793,11 +813,13 @@ function box_preferences_show() {
 		}
 		if (zui_tab(box_preferences_htab, tr("Plugins"), true)) {
 			zui_begin_sticky();
-			zui_row([1 / 4, 1 / 4]);
+			let row: f32[] = [1 / 4, 1 / 4];
+			zui_row(row);
 			if (zui_button(tr("New"))) {
 				ui_box_show_custom(function (ui: zui_t) {
 					if (zui_tab(zui_handle(__ID__), tr("New Plugin"))) {
-						zui_row([0.5, 0.5]);
+						let row: f32[] = [0.5, 0.5];
+						zui_row(row);
 						let h: zui_handle_t = zui_handle(__ID__);
 						if (h.init) {
 							h.text = "new_plugin";

+ 20 - 12
base/Sources/export_arm.ts

@@ -291,16 +291,20 @@ function export_arm_run_material(path: string) {
 		packed_assets = export_arm_get_packed_assets(path, texture_files);
 	}
 
+	let micons: buffer_t[] = null;
+	if (!is_cloud) {
+		///if (krom_metal || krom_vulkan)
+		micons = [lz4_encode(export_arm_bgra_swap(image_get_pixels(m.image)))];
+		///else
+		micons = [lz4_encode(image_get_pixels(m.image))];
+		///end
+	}
+
 	let raw: project_format_t = {
 		version: manifest_version,
 		material_nodes: mnodes,
 		material_groups: mgroups,
-		material_icons: is_cloud ? null :
-			///if (krom_metal || krom_vulkan)
-			[lz4_encode(export_arm_bgra_swap(image_get_pixels(m.image)))],
-			///else
-			[lz4_encode(image_get_pixels(m.image))],
-			///end
+		material_icons: micons,
 		assets: texture_files,
 		packed_assets: packed_assets
 	};
@@ -358,15 +362,19 @@ function export_arm_run_brush(path: string) {
 		packed_assets = export_arm_get_packed_assets(path, texture_files);
 	}
 
-	let raw: project_format_t = {
-		version: manifest_version,
-		brush_nodes: bnodes,
-		brush_icons: is_cloud ? null :
+	let bicons: buffer_t[] = null;
+	if (!is_cloud) {
 		///if (krom_metal || krom_vulkan)
-		[lz4_encode(export_arm_bgra_swap(image_get_pixels(b.image)))],
+		bicons = [lz4_encode(export_arm_bgra_swap(image_get_pixels(b.image)))];
 		///else
-		[lz4_encode(image_get_pixels(b.image))],
+		bicons = [lz4_encode(image_get_pixels(b.image))];
 		///end
+	}
+
+	let raw: project_format_t = {
+		version: manifest_version,
+		brush_nodes: bnodes,
+		brush_icons: bicons,
 		assets: texture_files,
 		packed_assets: packed_assets
 	};

+ 7 - 7
base/Sources/import_texture.ts

@@ -1,8 +1,8 @@
 
-type import_texture_data = {
+type import_texture_data_t = {
 	path: string;
-	image: image_t
-}
+	image: image_t;
+};
 
 function import_texture_run(path: string, hdr_as_envmap: bool = true) {
 	if (!path_is_texture(path)) {
@@ -19,8 +19,8 @@ function import_texture_run(path: string, hdr_as_envmap: bool = true) {
 			// Set as envmap
 			if (hdr_as_envmap && ends_with(to_lower_case(path), ".hdr")) {
 				let image: image_t = data_get_image(path);
-				let itd: import_texture_data = { path: path, image: image };
-				app_notify_on_next_frame(function (itd: import_texture_data) { // Make sure file browser process did finish
+				let itd: import_texture_data_t = { path: path, image: image };
+				app_notify_on_next_frame(function (itd: import_texture_data_t) { // Make sure file browser process did finish
 					import_envmap_run(itd.path, itd.image);
 				}, itd);
 			}
@@ -52,8 +52,8 @@ function import_texture_run(path: string, hdr_as_envmap: bool = true) {
 
 	// Set as envmap
 	if (hdr_as_envmap && ends_with(to_lower_case(path), ".hdr")) {
-		let itd: import_texture_data = { path: path, image: image };
-		app_notify_on_next_frame(function (itd: import_texture_data) { // Make sure file browser process did finish
+		let itd: import_texture_data_t = { path: path, image: image };
+		app_notify_on_next_frame(function (itd: import_texture_data_t) { // Make sure file browser process did finish
 			import_envmap_run(itd.path, itd.image);
 		}, itd);
 	}

+ 2 - 2
base/Sources/make_voxel.ts

@@ -59,7 +59,7 @@ function make_voxel_source(): string {
 	struct SPIRV_Cross_Output { float4 svpos : SV_POSITION; }; \
 	SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { \
 		SPIRV_Cross_Output stage_output; \
-		" + make_material_voxelgi_half_extents + ")} \
+		" + make_material_voxelgi_half_extents() + ")} \
 		stage_output.svpos.xyz = mul(float4(stage_input.pos.xyz, 1.0), W).xyz / voxelgiHalfExtents.xxx; \
 		float3 wnormal = normalize(mul(float3(stage_input.nor.xy, stage_input.pos.w), N)); \
 		float height = texpaint_pack.SampleLevel(_texpaint_pack_sampler, stage_input.tex, 0.0).a; \
@@ -77,7 +77,7 @@ function make_voxel_source(): string {
 	uniform mat3 N; \
 	uniform sampler2D texpaint_pack; \
 	void main() { \
-		" + make_material_voxelgi_half_extents + ")} \
+		" + make_material_voxelgi_half_extents() + ")} \
 		voxpositionGeom = vec3(W * vec4(pos.xyz, 1.0)) / voxelgiHalfExtents; \
 		vec3 wnormal = normalize(N * vec3(nor.xy, pos.w)); \
 		float height = textureLod(texpaint_pack, tex, 0.0).a; \

+ 14 - 2
base/Sources/node_shader_context.ts

@@ -9,9 +9,21 @@ type node_shader_context_t = {
 	tunits?: tex_unit_t[];
 };
 
-function node_shader_context_create(material: material_t, props: any): node_shader_context_t {
+function node_shader_context_create(material: material_t, props: shader_context_t): node_shader_context_t {
 	let raw: node_shader_context_t = {};
 	raw.material = material;
+
+	let vertex_elements_default: vertex_element_t[] = [
+		{
+			name: "pos",
+			data: "short4norm"
+		},
+		{
+			name: "nor",
+			data: "short2norm"
+		}
+	];
+
 	raw.data = {
 		name: props.name,
 		depth_write: props.depth_write,
@@ -25,7 +37,7 @@ function node_shader_context_create(material: material_t, props: any): node_shad
 		alpha_blend_operation: props.alpha_blend_operation,
 		fragment_shader: "",
 		vertex_shader: "",
-		vertex_elements: props.vertex_elements != null ? props.vertex_elements : [ {name: "pos", data: "short4norm"}, {name: "nor", data: "short2norm"}],
+		vertex_elements: props.vertex_elements != null ? props.vertex_elements : vertex_elements_default,
 		color_attachments: props.color_attachments,
 		depth_attachment: props.depth_attachment
 	};

File diff suppressed because it is too large
+ 3835 - 3819
base/Sources/nodes_material.ts


+ 11 - 11
base/Sources/project.ts

@@ -102,7 +102,8 @@ function project_new_box() {
 				project_mesh_list.unshift("rounded_cube");
 			}
 
-			zui_row([0.5, 0.5]);
+			let row: f32[] = [0.5, 0.5];
+			zui_row(row);
 			let h_project_type: zui_handle_t = zui_handle(__ID__);
 			if (h_project_type.init) {
 				h_project_type.position = context_raw.project_type;
@@ -113,10 +114,11 @@ function project_new_box() {
 			if (h_project_aspect_ratio.init) {
 				h_project_aspect_ratio.position = context_raw.project_aspect_ratio;
 			}
-			context_raw.project_aspect_ratio = zui_combo(h_project_aspect_ratio, ["1:1", "2:1", "1:2"], tr("Aspect Ratio"), true);
+			let project_aspect_ratio_combo: string[] = ["1:1", "2:1", "1:2"];
+			context_raw.project_aspect_ratio = zui_combo(h_project_aspect_ratio, project_aspect_ratio_combo, tr("Aspect Ratio"), true);
 
 			zui_end_element();
-			zui_row([0.5, 0.5]);
+			zui_row(row);
 			if (zui_button(tr("Cancel"))) {
 				ui_box_hide();
 			}
@@ -429,12 +431,8 @@ function project_import_mesh_box(path: string, replace_existing: bool = true, cl
 		if (zui_tab(zui_handle(__ID__), tr("Import Mesh"), tab_vertical)) {
 
 			if (ends_with(to_lower_case(path), ".obj")) {
-				context_raw.split_by = zui_combo(zui_handle(__ID__), [
-					tr("Object"),
-					tr("Group"),
-					tr("Material"),
-					tr("UDIM Tile"),
-				], tr("Split By"), true);
+				let split_by_combo: string[] = [tr("Object"), tr("Group"), tr("Material"), tr("UDIM Tile")];
+				context_raw.split_by = zui_combo(zui_handle(__ID__), split_by_combo, tr("Split By"), true);
 				if (ui.is_hovered) {
 					zui_tooltip(tr("Split .obj mesh into objects"));
 				}
@@ -459,7 +457,8 @@ function project_import_mesh_box(path: string, replace_existing: bool = true, cl
 			}
 			///end
 
-			zui_row([0.45, 0.45, 0.1]);
+			let row: f32 [] = [0.45, 0.45, 0.1];
+			zui_row(row);
 			if (zui_button(tr("Cancel"))) {
 				ui_box_hide();
 			}
@@ -532,7 +531,8 @@ function project_unwrap_mesh_box(mesh: any, done: (a: any)=>void, skip_ui: bool
 
 			let unwrap_by: i32 = zui_combo(zui_handle(__ID__), unwrap_plugins, tr("Plugin"), true);
 
-			zui_row([0.5, 0.5]);
+			let row: f32[] = [0.5, 0.5];
+			zui_row(row);
 			if (zui_button(tr("Cancel"))) {
 				ui_box_hide();
 			}

+ 4 - 2
base/Sources/tab_browser.ts

@@ -31,10 +31,12 @@ function tab_browser_draw(htab: zui_handle_t) {
 		zui_begin_sticky();
 		let step: i32 = (1 - bookmarks_w / ui._w);
 		if (tab_browser_hsearch.text != "") {
-			zui_row([bookmarks_w / ui._w, step * 0.73, step * 0.07, step * 0.17, step * 0.03]);
+			let row: f32[] = [bookmarks_w / ui._w, step * 0.73, step * 0.07, step * 0.17, step * 0.03];
+			zui_row(row);
 		}
 		else {
-			zui_row([bookmarks_w / ui._w, step * 0.73, step * 0.07, step * 0.2]);
+			let row: f32[] = [bookmarks_w / ui._w, step * 0.73, step * 0.07, step * 0.2];
+			zui_row(row);
 		}
 
 		if (zui_button("+")) {

+ 2 - 1
base/Sources/tab_brushes.ts

@@ -7,7 +7,8 @@ function tab_brushes_draw(htab: zui_handle_t) {
 	let ui: zui_t = ui_base_ui;
 	if (zui_tab(htab, tr("Brushes"))) {
 		zui_begin_sticky();
-		zui_row([1 / 4, 1 / 4, 1 / 4]);
+		let row: f32[] = [1 / 4, 1 / 4, 1 / 4];
+		zui_row(row);
 		if (zui_button(tr("New"))) {
 			context_raw.brush = slot_brush_create();
 			array_push(project_brushes, context_raw.brush);

+ 8 - 4
base/Sources/tab_console.ts

@@ -11,17 +11,21 @@ function tab_console_draw(htab: zui_handle_t) {
 		zui_begin_sticky();
 		///if (krom_windows || krom_linux || krom_darwin) // Copy
 		if (config_raw.touch_ui) {
-			zui_row([1 / 4, 1 / 4, 1 / 4]);
+			let row: f32[] = [1 / 4, 1 / 4, 1 / 4];
+			zui_row(row);
 		}
 		else {
-			zui_row([1 / 14, 1 / 14, 1 / 14]);
+			let row: f32[] = [1 / 14, 1 / 14, 1 / 14];
+			zui_row(row);
 		}
 		///else
 		if (config_raw.touch_ui) {
-			zui_row([1 / 4, 1 / 4]);
+			let row: f32[] = [1 / 4, 1 / 4];
+			zui_row(row);
 		}
 		else {
-			zui_row([1 / 14, 1 / 14]);
+			let row: f32[] = [1 / 14, 1 / 14];
+			zui_row(row);
 		}
 		///end
 

+ 4 - 2
base/Sources/tab_fonts.ts

@@ -10,10 +10,12 @@ function tab_fonts_draw(htab: zui_handle_t) {
 
 		zui_begin_sticky();
 		if (config_raw.touch_ui) {
-			zui_row([1 / 4, 1 / 4]);
+			let row: f32[] = [1 / 4, 1 / 4];
+			zui_row(row);
 		}
 		else {
-			zui_row([1 / 14, 1 / 14]);
+			let row: f32[] = [1 / 14, 1 / 14];
+			zui_row(row);
 		}
 
 		if (zui_button(tr("Import"))) {

+ 2 - 1
base/Sources/tab_materials.ts

@@ -23,7 +23,8 @@ function tab_materials_draw_mini(htab: zui_handle_t) {
 function tab_materials_draw_full(htab: zui_handle_t) {
 	if (zui_tab(htab, tr("Materials"))) {
 		zui_begin_sticky();
-		zui_row([1 / 4, 1 / 4, 1 / 4]);
+		let row: f32[] = [1 / 4, 1 / 4, 1 / 4];
+		zui_row(row);
 
 		tab_materials_button_new(tr("New"));
 		if (zui_button(tr("Import"))) {

+ 8 - 4
base/Sources/tab_meshes.ts

@@ -10,19 +10,23 @@ function tab_meshes_draw(htab: zui_handle_t) {
 
 		///if (is_paint || is_sculpt)
 		if (config_raw.touch_ui) {
-			zui_row([1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6]);
+			let row: f32[] = [1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6];
+			zui_row(row);
 		}
 		else {
-			zui_row([1 / 14, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 14]);
+			let row: f32[] = [1 / 14, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 14];
+			zui_row(row);
 		}
 		///end
 
 		///if is_lab
 		if (config_raw.touch_ui) {
-			zui_row([1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7]);
+			let row: f32[] = [1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7];
+			zui_row(row);
 		}
 		else {
-			zui_row([1 / 14, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 14]);
+			let row: f32[] = [1 / 14, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 14];
+			zui_row(row);
 		}
 		///end
 

+ 2 - 1
base/Sources/tab_particles.ts

@@ -4,7 +4,8 @@
 function tab_particles_draw(htab: zui_handle_t) {
 	if (zui_tab(htab, tr("Particles"))) {
 		zui_begin_sticky();
-		zui_row([1 / 4, 1 / 4, 1 / 4]);
+		let row: f32[] = [1 / 4, 1 / 4, 1 / 4];
+		zui_row(row);
 		if (zui_button(tr("New"))) {
 
 		}

+ 4 - 2
base/Sources/tab_plugins.ts

@@ -6,10 +6,12 @@ function tab_plugins_draw(htab: zui_handle_t) {
 		zui_begin_sticky();
 
 		///if (is_paint || is_sculpt)
-		zui_row([1 / 4]);
+		let row: f32[] = [1 / 4];
+		zui_row(row);
 		///end
 		///if is_lab
-		zui_row([1 / 14]);
+		let row: f32[] = [1 / 14];
+		zui_row(row);
 		///end
 
 		if (zui_button(tr("Manager"))) {

+ 4 - 2
base/Sources/tab_script.ts

@@ -9,10 +9,12 @@ function tab_script_draw(htab: zui_handle_t) {
 
 		zui_begin_sticky();
 		if (config_raw.touch_ui) {
-			zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
+			let row: f32[] = [1 / 4, 1 / 4, 1 / 4, 1 / 4];
+			zui_row(row);
 		}
 		else {
-			zui_row([1 / 14, 1 / 14, 1 / 14, 1 / 14]);
+			let row: f32[] = [1 / 14, 1 / 14, 1 / 14, 1 / 14];
+			zui_row(row);
 		}
 		if (zui_button(tr("Run"))) {
 			js_eval(tab_script_hscript.text);

+ 4 - 2
base/Sources/tab_swatches.ts

@@ -27,10 +27,12 @@ function tab_swatches_draw(htab: zui_handle_t) {
 
 		zui_begin_sticky();
 		if (config_raw.touch_ui) {
-			zui_row([1 / 5, 1 / 5, 1 / 5, 1 / 5, 1 / 5]);
+			let row: f32[] = [1 / 5, 1 / 5, 1 / 5, 1 / 5, 1 / 5];
+			zui_row(row);
 		}
 		else {
-			zui_row([1 / 14, 1 / 14, 1 / 14, 1 / 14, 1 / 14]);
+			let row: f32[] = [1 / 14, 1 / 14, 1 / 14, 1 / 14, 1 / 14];
+			zui_row(row);
 		}
 
 		if (zui_button(tr("New"))) {

+ 4 - 2
base/Sources/tab_textures.ts

@@ -11,10 +11,12 @@ function tab_textures_draw(htab: zui_handle_t) {
 		zui_begin_sticky();
 
 		if (config_raw.touch_ui) {
-			zui_row([1 / 4, 1 / 4]);
+			let row: f32[] = [1 / 4, 1 / 4];
+			zui_row(row);
 		}
 		else {
-			zui_row([1 / 14, 1 / 14]);
+			let row: f32[] = [1 / 14, 1 / 14];
+			zui_row(row);
 		}
 
 		if (zui_button(tr("Import"))) {

+ 8 - 1
base/Sources/ui_base.ts

@@ -176,7 +176,14 @@ function ui_base_init() {
 	history_reset();
 
 	let scale: f32 = config_raw.window_scale;
-	ui_base_ui = zui_create({ theme: base_theme, font: base_font, scale_factor: scale, color_wheel: base_color_wheel, black_white_gradient: base_color_wheel_gradient });
+	let ops: zui_options_t = {
+		theme: base_theme,
+		font: base_font,
+		scale_factor: scale,
+		color_wheel: base_color_wheel,
+		black_white_gradient: base_color_wheel_gradient
+	};
+	ui_base_ui = zui_create(ops);
 	zui_set_on_border_hover(ui_base_on_border_hover);
 	zui_set_on_text_hover(ui_base_on_text_hover);
 	zui_set_on_deselect_text(ui_base_on_deselect_text);

+ 6 - 3
base/Sources/ui_box.ts

@@ -86,13 +86,16 @@ function ui_box_render() {
 
 				///if (krom_windows || krom_linux || krom_darwin)
 				if (ui_box_copyable) {
-					zui_row([1 / 3, 1 / 3, 1 / 3]);
+					let row: f32[] = [1 / 3, 1 / 3, 1 / 3];
+					zui_row(row);
 				}
 				else {
-					zui_row([2 / 3, 1 / 3]);
+					let row: f32[] = [2 / 3, 1 / 3];
+					zui_row(row);
 				}
 				///else
-				zui_row([2 / 3, 1 / 3]);
+				let row: f32[] = [2 / 3, 1 / 3];
+				zui_row(row);
 				///end
 
 				zui_end_element();

+ 13 - 7
base/Sources/ui_header.ts

@@ -176,7 +176,8 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 			h_select_mat.selected = context_raw.picker_select_material;
 		}
 		context_raw.picker_select_material = zui_check(h_select_mat, tr("Select Material"));
-		zui_combo(context_raw.picker_mask_handle, [tr("None"), tr("Material")], tr("Mask"), true);
+		let picker_mask_combo: string[] = [tr("None"), tr("Material")];
+		zui_combo(context_raw.picker_mask_handle, picker_mask_combo, tr("Mask"), true);
 		if (context_raw.picker_mask_handle.changed) {
 			make_material_parse_paint_material();
 		}
@@ -260,14 +261,16 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 			if (bake_up_axis_handle.init) {
 				bake_up_axis_handle.position = context_raw.bake_up_axis;
 			}
-			context_raw.bake_up_axis = zui_combo(bake_up_axis_handle, [tr("Z"), tr("Y")], tr("Up Axis"), true);
+			let bake_up_axis_combo: string[] = [tr("Z"), tr("Y")];
+			context_raw.bake_up_axis = zui_combo(bake_up_axis_handle, bake_up_axis_combo, tr("Up Axis"), true);
 		}
 		if (context_raw.bake_type == bake_type_t.AO || context_raw.bake_type == bake_type_t.CURVATURE) {
 			let bake_axis_handle: zui_handle_t = zui_handle(__ID__);
 			if (bake_axis_handle.init) {
 				bake_axis_handle.position = context_raw.bake_axis;
 			}
-			context_raw.bake_axis = zui_combo(bake_axis_handle, [tr("XYZ"), tr("X"), tr("Y"), tr("Z"), tr("-X"), tr("-Y"), tr("-Z")], tr("Axis"), true);
+			let bake_axis_combo: string[] = [tr("XYZ"), tr("X"), tr("Y"), tr("Z"), tr("-X"), tr("-Y"), tr("-Z")];
+			context_raw.bake_axis = zui_combo(bake_axis_handle, bake_axis_combo, tr("Axis"), true);
 		}
 		if (context_raw.bake_type == bake_type_t.AO) {
 			let strength_handle: zui_handle_t = zui_handle(__ID__);
@@ -428,7 +431,7 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 			if (brush_blending_handle.init) {
 				brush_blending_handle.value = context_raw.brush_blending;
 			}
-			context_raw.brush_blending = zui_combo(brush_blending_handle, [
+			let brush_blending_combo: string[] = [
 				tr("Mix"),
 				tr("Darken"),
 				tr("Multiply"),
@@ -447,7 +450,8 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 				tr("Saturation"),
 				tr("Color"),
 				tr("Value"),
-			], tr("Blending"));
+			];
+			context_raw.brush_blending = zui_combo(brush_blending_handle, brush_blending_combo, tr("Blending"));
 			if (brush_blending_handle.changed) {
 				make_material_parse_paint_material();
 			}
@@ -455,7 +459,8 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 
 		if (context_raw.tool == workspace_tool_t.BRUSH || context_raw.tool == workspace_tool_t.FILL) {
 			let paint_handle: zui_handle_t = zui_handle(__ID__);
-			context_raw.brush_paint = zui_combo(paint_handle, [tr("UV Map"), tr("Triplanar"), tr("Project")], tr("TexCoord"));
+			let texcoord_combo: string[] = [tr("UV Map"), tr("Triplanar"), tr("Project")];
+			context_raw.brush_paint = zui_combo(paint_handle, texcoord_combo, tr("TexCoord"));
 			if (paint_handle.changed) {
 				make_material_parse_paint_material();
 			}
@@ -481,7 +486,8 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 		}
 
 		if (context_raw.tool == workspace_tool_t.FILL) {
-			zui_combo(context_raw.fill_type_handle, [tr("Object"), tr("Face"), tr("Angle"), tr("UV Island")], tr("Fill Mode"));
+			let fill_mode_combo: string[] = [tr("Object"), tr("Face"), tr("Angle"), tr("UV Island")];
+			zui_combo(context_raw.fill_type_handle, fill_mode_combo, tr("Fill Mode"));
 			if (context_raw.fill_type_handle.changed) {
 				if (context_raw.fill_type_handle.position == fill_type_t.FACE) {
 					let current: image_t = _g2_current;

+ 4 - 2
base/Sources/ui_menu.ts

@@ -594,7 +594,8 @@ function ui_menu_render() {
 						}
 						zui_text_area(h, zui_align_t.LEFT, false);
 
-						zui_row([1 / 3, 1 / 3, 1 / 3]);
+						let row: f32[] = [1 / 3, 1 / 3, 1 / 3];
+						zui_row(row);
 
 						///if (krom_windows || krom_linux || krom_darwin)
 						if (zui_button(tr("Copy"))) {
@@ -703,7 +704,8 @@ function ui_menu_button(ui: zui_t, text: string, label: string = ""): bool {
 
 function ui_menu_align(ui: zui_t) {
 	if (!config_raw.touch_ui) {
-		zui_row([12 / 100, 88 / 100]);
+		let row: f32[] = [12 / 100, 88 / 100];
+		zui_row(row);
 		zui_end_element();
 	}
 }

+ 16 - 5
base/Sources/ui_nodes.ts

@@ -42,7 +42,14 @@ function ui_nodes_init() {
 	zui_set_on_canvas_control(ui_nodes_on_canvas_control);
 
 	let scale: f32 = config_raw.window_scale;
-	ui_nodes_ui = zui_create({ theme: base_theme, font: base_font, color_wheel: base_color_wheel, black_white_gradient: base_color_wheel_gradient, scale_factor: scale });
+	let ops: zui_options_t = {
+		theme: base_theme,
+		font: base_font,
+		color_wheel: base_color_wheel,
+		black_white_gradient: base_color_wheel_gradient,
+		scale_factor: scale
+	};
+	ui_nodes_ui = zui_create(ops);
 	ui_nodes_ui.scroll_enabled = false;
 }
 
@@ -161,7 +168,8 @@ function ui_nodes_on_socket_released(socket_id: i32) {
 								let node: zui_node_t = _ui_nodes_on_socket_released_node;
 
 								if (zui_tab(zui_handle(__ID__), tr("Socket"))) {
-									let type: i32 = zui_combo(_ui_nodes_htype, [tr("Color"), tr("Vector"), tr("Value")], tr("Type"), true);
+									let type_combo: string[] = [tr("Color"), tr("Vector"), tr("Value")];
+									let type: i32 = zui_combo(_ui_nodes_htype, type_combo, tr("Type"), true);
 									if (_ui_nodes_htype.changed) {
 										_ui_nodes_hname.text = type == 0 ? tr("Color") : type == 1 ? tr("Vector") : tr("Value");
 									}
@@ -170,7 +178,8 @@ function ui_nodes_on_socket_released(socket_id: i32) {
 									let max: f32 = zui_float_input(_ui_nodes_hmax, tr("Max"));
 									let default_value: any = null;
 									if (type == 0) {
-										zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
+										let row: f32[] = [1 / 4, 1 / 4, 1 / 4, 1 / 4];
+										zui_row(row);
 										zui_float_input(_ui_nodes_hval0, tr("R"));
 										zui_float_input(_ui_nodes_hval1, tr("G"));
 										zui_float_input(_ui_nodes_hval2, tr("B"));
@@ -178,7 +187,8 @@ function ui_nodes_on_socket_released(socket_id: i32) {
 										default_value = f32_array_create_xyzw(_ui_nodes_hval0.value, _ui_nodes_hval1.value, _ui_nodes_hval2.value, _ui_nodes_hval3.value);
 									}
 									else if (type == 1) {
-										zui_row([1 / 3, 1 / 3, 1 / 3]);
+										let row: f32[] = [1 / 3, 1 / 3, 1 / 3];
+										zui_row(row);
 										_ui_nodes_hval0.value = zui_float_input(_ui_nodes_hval0, tr("X"));
 										_ui_nodes_hval1.value = zui_float_input(_ui_nodes_hval1, tr("Y"));
 										_ui_nodes_hval2.value = zui_float_input(_ui_nodes_hval2, tr("Z"));
@@ -1206,7 +1216,8 @@ function ui_nodes_render() {
 				zui_fill(1, 1, ui_nodes_ui._w / zui_SCALE(ui_nodes_ui) - 2, ui_nodes_ui.ops.theme.BUTTON_H + 1, ui_nodes_ui.ops.theme.SEPARATOR_COL);
 				ui_nodes_ui.enabled = ui_nodes_can_place_group(g.canvas.name);
 				ui_menu_fill(ui_nodes_ui);
-				zui_row([5 / 6, 1 / 6]);
+				let row: f32[] = [5 / 6, 1 / 6];
+				zui_row(row);
 				if (zui_button(config_button_spacing + g.canvas.name, zui_align_t.LEFT)) {
 					ui_nodes_push_undo();
 					let canvas: zui_node_canvas_t = ui_nodes_get_canvas(true);

+ 13 - 7
base/Sources/ui_view2d.ts

@@ -45,7 +45,14 @@ function ui_view2d_init() {
 	///end
 
 	let scale: f32 = config_raw.window_scale;
-	ui_view2d_ui = zui_create({ theme: base_theme, font: base_font, color_wheel: base_color_wheel, black_white_gradient: base_color_wheel_gradient, scale_factor: scale });
+	let ops: zui_options_t = {
+		theme: base_theme,
+		font: base_font,
+		color_wheel: base_color_wheel,
+		black_white_gradient: base_color_wheel_gradient,
+		scale_factor: scale
+	};
+	ui_view2d_ui = zui_create(ops);
 	ui_view2d_ui.scroll_enabled = false;
 }
 
@@ -355,10 +362,8 @@ function ui_view2d_render() {
 			if (h_layer_mode.init) {
 				h_layer_mode.position = ui_view2d_layer_mode;
 			}
-			ui_view2d_layer_mode = zui_combo(h_layer_mode, [
-				tr("Visible"),
-				tr("Selected"),
-			], tr("Layers"));
+			let layer_mode_combo: string[] = [tr("Visible"), tr("Selected")];
+			ui_view2d_layer_mode = zui_combo(h_layer_mode, layer_mode_combo, tr("Layers"));
 			ui_view2d_ui._x += ew + 3;
 			ui_view2d_ui._y = 2 + start_y;
 
@@ -367,7 +372,7 @@ function ui_view2d_render() {
 				if (h_tex_type.init) {
 					h_tex_type.position = ui_view2d_tex_type;
 				}
-				ui_view2d_tex_type = zui_combo(h_tex_type, [
+				let tex_type_combo: string[] = [
 					tr("Base Color"),
 					tr("Normal Map"),
 					tr("Occlusion"),
@@ -375,7 +380,8 @@ function ui_view2d_render() {
 					tr("Metallic"),
 					tr("Opacity"),
 					tr("Height"),
-				], tr("Texture"));
+				];
+				ui_view2d_tex_type = zui_combo(h_tex_type, tex_type_combo, tr("Texture"));
 				ui_view2d_ui._x += ew + 3;
 				ui_view2d_ui._y = 2 + start_y;
 			}

Some files were not shown because too many files changed in this diff