diff --git a/armorforge/Assets/Scene.arm b/armorforge/Assets/Scene.arm index 99400c8c..f98eb448 100644 Binary files a/armorforge/Assets/Scene.arm and b/armorforge/Assets/Scene.arm differ diff --git a/armorforge/Sources/TabObjects.ts b/armorforge/Sources/TabObjects.ts index 17fa64e9..a991d7d9 100644 --- a/armorforge/Sources/TabObjects.ts +++ b/armorforge/Sources/TabObjects.ts @@ -4,12 +4,12 @@ class TabObjects { static materialId = 0; static roundfp = (f: f32, precision = 2): f32 => { - f *= Math.pow(10, precision); - return Math.round(f) / Math.pow(10, precision); + f *= math_pow(10, precision); + return math_round(f) / math_pow(10, precision); } static draw = (htab: zui_handle_t) => { - let ui = UIBase.ui; + let ui = ui_base_ui; if (zui_tab(htab, tr("Objects"))) { zui_begin_sticky(); zui_row([1 / 4]); @@ -72,13 +72,13 @@ class TabObjects { } if (ui.is_hovered && ui.input_released_r) { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, "Assign Material")) { + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, "Assign Material")) { TabObjects.materialId++; for (let sh of _scene_raw.shader_datas) { if (sh.name == "Material_data") { - let s: shader_data_t = JSON.parse(JSON.stringify(sh)); + let s: shader_data_t = json_parse(json_stringify(sh)); s.name = "TempMaterial_data" + TabObjects.materialId; _scene_raw.shader_datas.push(s); break; @@ -87,7 +87,7 @@ class TabObjects { for (let mat of _scene_raw.material_datas) { if (mat.name == "Material") { - let m: material_data_t = JSON.parse(JSON.stringify(mat)); + let m: material_data_t = json_parse(json_stringify(mat)); m.name = "TempMaterial" + TabObjects.materialId; m.shader = "TempMaterial_data" + TabObjects.materialId; _scene_raw.material_datas.push(m); @@ -238,7 +238,7 @@ class TabObjects { else if (context_context_raw.selected_object.ext_type == "camera_object_t") { let cam = context_context_raw.selected_object.ext; let fovHandle = zui_handle("tabobjects_18"); - fovHandle.value = Math.floor(cam.data.fov * 100) / 100; + fovHandle.value = math_floor(cam.data.fov * 100) / 100; cam.data.fov = zui_slider(fovHandle, "FoV", 0.3, 2.0, true); if (fovHandle.changed) { camera_object_build_proj(cam); diff --git a/armorlab/Assets/Scene.arm b/armorlab/Assets/Scene.arm index 23dab05a..5df71984 100644 Binary files a/armorlab/Assets/Scene.arm and b/armorlab/Assets/Scene.arm differ diff --git a/armorlab/Sources/MakeMesh.ts b/armorlab/Sources/MakeMesh.ts index 6d15b08b..705cb0a8 100644 --- a/armorlab/Sources/MakeMesh.ts +++ b/armorlab/Sources/MakeMesh.ts @@ -48,9 +48,9 @@ class MakeMesh { NodeShader.add_out(frag, 'vec4 fragColor[3]'); frag.n = true; - NodeShader.add_function(frag, ShaderFunctions.str_packFloatInt16); - NodeShader.add_function(frag, ShaderFunctions.str_octahedronWrap); - NodeShader.add_function(frag, ShaderFunctions.str_cotangentFrame); + NodeShader.add_function(frag, str_packFloatInt16); + NodeShader.add_function(frag, str_octahedronWrap); + NodeShader.add_function(frag, str_cotangentFrame); NodeShader.write(frag, 'vec3 basecol = vec3(0.0, 0.0, 0.0);'); NodeShader.write(frag, 'float roughness = 0.0;'); @@ -155,13 +155,13 @@ class MakeMesh { NodeShader.add_uniform(frag, 'vec4 envmapData', '_envmapData'); // angle, sin(angle), cos(angle), strength NodeShader.write(frag, 'vec3 wreflect = reflect(-vVec, n);'); NodeShader.write(frag, 'float envlod = roughness * float(envmapNumMipmaps);'); - NodeShader.add_function(frag, ShaderFunctions.str_envMapEquirect); + NodeShader.add_function(frag, str_envMapEquirect); NodeShader.write(frag, 'vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(wreflect, envmapData.x), envlod).rgb;'); NodeShader.add_uniform(frag, 'vec3 lightArea0', '_light_area0'); NodeShader.add_uniform(frag, 'vec3 lightArea1', '_light_area1'); NodeShader.add_uniform(frag, 'vec3 lightArea2', '_light_area2'); NodeShader.add_uniform(frag, 'vec3 lightArea3', '_light_area3'); - NodeShader.add_function(frag, ShaderFunctions.str_ltcEvaluate); + NodeShader.add_function(frag, str_ltcEvaluate); NodeShader.add_uniform(frag, 'vec3 lightPos', '_point_pos'); NodeShader.add_uniform(frag, 'vec3 lightColor', '_point_color'); NodeShader.write(frag, 'float ldist = distance(wposition, lightPos);'); @@ -181,7 +181,7 @@ class MakeMesh { NodeShader.write(frag, 'direct *= lightColor * (1.0 / (ldist * ldist));'); NodeShader.add_uniform(frag, 'vec4 shirr[7]', '_envmap_irradiance'); - NodeShader.add_function(frag, ShaderFunctions.str_shIrradiance); + NodeShader.add_function(frag, str_shIrradiance); NodeShader.write(frag, 'vec3 indirect = albedo * (shIrradiance(vec3(n.x * envmapData.z - n.y * envmapData.y, n.x * envmapData.y + n.y * envmapData.z, n.z), shirr) / 3.14159265);'); NodeShader.write(frag, 'indirect += prefilteredColor * (f0 * envBRDF.x + envBRDF.y) * 1.5;'); NodeShader.write(frag, 'indirect *= envmapData.w * occlusion;'); diff --git a/armorlab/Sources/NodesBrush.ts b/armorlab/Sources/NodesBrush.ts index 3d8b80fb..0616047b 100644 --- a/armorlab/Sources/NodesBrush.ts +++ b/armorlab/Sources/NodesBrush.ts @@ -32,7 +32,7 @@ class NodesBrush { if (n.type == nodeType) { let canvas = project_canvas; let nodes = project_nodes; - let node = UINodes.makeNode(n, nodes, canvas); + let node = ui_nodes_makeNode(n, nodes, canvas); canvas.nodes.push(node); return node; } diff --git a/armorlab/Sources/RenderPathPaint.ts b/armorlab/Sources/RenderPathPaint.ts index 6f28223c..af472aa2 100644 --- a/armorlab/Sources/RenderPathPaint.ts +++ b/armorlab/Sources/RenderPathPaint.ts @@ -82,7 +82,7 @@ class RenderPathPaint { render_path_bind_target("texpaint_nor" + tid, "texpaint_nor"); render_path_bind_target("texpaint_pack" + tid, "texpaint_pack"); render_path_draw_meshes("paint"); - UIHeader.headerHandle.redraws = 2; + ui_header_headerHandle.redraws = 2; let texpaint_picker = render_path_render_targets.get("texpaint_picker")._image; let texpaint_nor_picker = render_path_render_targets.get("texpaint_nor_picker")._image; @@ -163,8 +163,8 @@ class RenderPathPaint { return; } - let nodes = UINodes.getNodes(); - let canvas = UINodes.getCanvas(true); + let nodes = ui_nodes_getNodes(); + let canvas = ui_nodes_getCanvas(true); let inpaint = nodes.nodesSelectedId.length > 0 && zui_get_node(canvas.nodes, nodes.nodesSelectedId[0]).type == "InpaintNode"; if (!base_uiEnabled || base_isDragging || !inpaint) { @@ -252,8 +252,8 @@ class RenderPathPaint { static bindLayers = () => { let image: image_t = null; - let nodes = UINodes.getNodes(); - let canvas = UINodes.getCanvas(true); + let nodes = ui_nodes_getNodes(); + let canvas = ui_nodes_getCanvas(true); if (nodes.nodesSelectedId.length > 0) { let node = zui_get_node(canvas.nodes, nodes.nodesSelectedId[0]); let brushNode = ParserLogic.getLogicNode(node); @@ -283,8 +283,8 @@ class RenderPathPaint { render_path_bind_target("texpaint_nor_empty", "texpaint_nor"); render_path_bind_target("texpaint_pack_empty", "texpaint_pack"); - let nodes = UINodes.getNodes(); - let canvas = UINodes.getCanvas(true); + let nodes = ui_nodes_getNodes(); + let canvas = ui_nodes_getCanvas(true); let node = zui_get_node(canvas.nodes, nodes.nodesSelectedId[0]); let inpaint = node.type == "InpaintNode"; if (inpaint) { diff --git a/armorlab/Sources/UINodesExt.ts b/armorlab/Sources/UINodesExt.ts index 27c658d7..ce23a26e 100644 --- a/armorlab/Sources/UINodesExt.ts +++ b/armorlab/Sources/UINodesExt.ts @@ -4,7 +4,7 @@ class UINodesExt { static lastVertices: DataView = null; // Before displacement static drawButtons = (ew: f32, startY: f32) => { - let ui = UINodes.ui; + let ui = ui_nodes_ui; if (zui_button(tr("Run"))) { console_progress(tr("Processing")); @@ -84,7 +84,7 @@ class UINodesExt { g4_draw(); g4_end(); - if (UIHeader.worktab.position == SpaceType.Space3D && + if (ui_header_worktab.position == SpaceType.Space3D && BrushOutputNode.inst.inputs[ChannelType.ChannelHeight].node.constructor != FloatNode) { // Make copy of vertices before displacement @@ -93,12 +93,12 @@ class UINodesExt { let vertices = g4_vertex_buffer_lock(g._.vertex_buffer); if (UINodesExt.lastVertices == null || UINodesExt.lastVertices.byteLength != vertices.byteLength) { UINodesExt.lastVertices = new DataView(new ArrayBuffer(vertices.byteLength)); - for (let i = 0; i < Math.floor(vertices.byteLength / 2); ++i) { + for (let i = 0; i < math_floor(vertices.byteLength / 2); ++i) { UINodesExt.lastVertices.setInt16(i * 2, vertices.getInt16(i * 2, true), true); } } else { - for (let i = 0; i < Math.floor(vertices.byteLength / 2); ++i) { + for (let i = 0; i < math_floor(vertices.byteLength / 2); ++i) { vertices.setInt16(i * 2, UINodesExt.lastVertices.getInt16(i * 2, true), true); } } @@ -111,8 +111,8 @@ class UINodesExt { console_progress(tr("Apply Displacement")); base_notifyOnNextFrame(() => { let uv_scale = scene_meshes[0].data.scale_tex * context_raw.brushScale; - UtilMesh.applyDisplacement(texpaint_pack, 0.05 * config_raw.displace_strength, uv_scale); - UtilMesh.calcNormals(); + util_mesh_applyDisplacement(texpaint_pack, 0.05 * config_raw.displace_strength, uv_scale); + util_mesh_calcNormals(); taskDone(); }); }); diff --git a/armorlab/Sources/nodes/InpaintNode.ts b/armorlab/Sources/nodes/InpaintNode.ts index e9b028f8..1ce9fd00 100644 --- a/armorlab/Sources/nodes/InpaintNode.ts +++ b/armorlab/Sources/nodes/InpaintNode.ts @@ -107,16 +107,16 @@ class InpaintNode extends LogicNode { let f32mask = new Float32Array(4 * 64 * 64); let vae_encoder_blob: ArrayBuffer = data_get_blob("models/sd_vae_encoder.quant.onnx"); - // for (let x = 0; x < Math.floor(image.width / 512); ++x) { - // for (let y = 0; y < Math.floor(image.height / 512); ++y) { + // for (let x = 0; x < math_floor(image.width / 512); ++x) { + // for (let y = 0; y < math_floor(image.height / 512); ++y) { let x = 0; let y = 0; for (let xx = 0; xx < 64; ++xx) { for (let yy = 0; yy < 64; ++yy) { - // let step = Math.floor(512 / 64); + // let step = math_floor(512 / 64); // let j = (yy * step * mask.width + xx * step) + (y * 512 * mask.width + x * 512); - let step = Math.floor(mask.width / 64); + let step = math_floor(mask.width / 64); let j = (yy * step * mask.width + xx * step); let f = u8[j] / 255.0; let i = yy * 64 + xx; @@ -149,14 +149,14 @@ class InpaintNode extends LogicNode { let latents_orig = latents.slice(0); let noise = new Float32Array(latents.length); - for (let i = 0; i < noise.length; ++i) noise[i] = Math.cos(2.0 * 3.14 * RandomNode.getFloat()) * Math.sqrt(-2.0 * Math.log(RandomNode.getFloat())); + for (let i = 0; i < noise.length; ++i) noise[i] = math_cos(2.0 * 3.14 * RandomNode.getFloat()) * math_sqrt(-2.0 * math_log(RandomNode.getFloat())); let num_inference_steps = 50; - let init_timestep = Math.floor(num_inference_steps * InpaintNode.strength); + let init_timestep = math_floor(num_inference_steps * InpaintNode.strength); let timestep = TextToPhotoNode.timesteps[num_inference_steps - init_timestep]; let alphas_cumprod = TextToPhotoNode.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); + 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 = 0; i < latents.length; ++i) { latents[i] = sqrt_alpha_prod * latents[i] + sqrt_one_minus_alpha_prod * noise[i]; } diff --git a/armorlab/Sources/nodes/PhotoToPBRNode.ts b/armorlab/Sources/nodes/PhotoToPBRNode.ts index 5c9d2007..324a7e47 100644 --- a/armorlab/Sources/nodes/PhotoToPBRNode.ts +++ b/armorlab/Sources/nodes/PhotoToPBRNode.ts @@ -41,12 +41,12 @@ class PhotoToPBRNode extends LogicNode { console_progress(tr("Processing") + " - " + tr("Photo to PBR")); base_notifyOnNextFrame(() => { let tileFloats: Float32Array[] = []; - let tilesX = Math.floor(config_getTextureResX() / PhotoToPBRNode.tileW); - let tilesY = Math.floor(config_getTextureResY() / PhotoToPBRNode.tileW); + let tilesX = math_floor(config_getTextureResX() / PhotoToPBRNode.tileW); + let tilesY = math_floor(config_getTextureResY() / PhotoToPBRNode.tileW); let numTiles = tilesX * tilesY; for (let i = 0; i < numTiles; ++i) { let x = i % tilesX; - let y = Math.floor(i / tilesX); + let y = math_floor(i / tilesX); g2_begin(PhotoToPBRNode.temp); g2_draw_scaled_image(source, PhotoToPBRNode.borderW - x * PhotoToPBRNode.tileW, PhotoToPBRNode.borderW - y * PhotoToPBRNode.tileW, -config_getTextureResX(), config_getTextureResY()); @@ -75,10 +75,10 @@ class PhotoToPBRNode extends LogicNode { let offsetB = (from == ChannelType.ChannelBaseColor || from == ChannelType.ChannelNormalMap) ? PhotoToPBRNode.tileWithBorderW * PhotoToPBRNode.tileWithBorderW * 2 : 0; for (let i = 0; i < (PhotoToPBRNode.tileW * PhotoToPBRNode.tileW); ++i) { let x = PhotoToPBRNode.borderW + i % PhotoToPBRNode.tileW; - let y = PhotoToPBRNode.borderW + Math.floor(i / PhotoToPBRNode.tileW); - u8a[i * 4 ] = Math.floor((ar[y * PhotoToPBRNode.tileWithBorderW + x ] * 0.5 + 0.5) * 255); - u8a[i * 4 + 1] = Math.floor((ar[y * PhotoToPBRNode.tileWithBorderW + x + offsetG] * 0.5 + 0.5) * 255); - u8a[i * 4 + 2] = Math.floor((ar[y * PhotoToPBRNode.tileWithBorderW + x + offsetB] * 0.5 + 0.5) * 255); + let y = PhotoToPBRNode.borderW + math_floor(i / PhotoToPBRNode.tileW); + u8a[i * 4 ] = math_floor((ar[y * PhotoToPBRNode.tileWithBorderW + x ] * 0.5 + 0.5) * 255); + u8a[i * 4 + 1] = math_floor((ar[y * PhotoToPBRNode.tileWithBorderW + x + offsetG] * 0.5 + 0.5) * 255); + u8a[i * 4 + 2] = math_floor((ar[y * PhotoToPBRNode.tileWithBorderW + x + offsetB] * 0.5 + 0.5) * 255); u8a[i * 4 + 3] = 255; } tileFloats.push(ar); @@ -94,15 +94,15 @@ class PhotoToPBRNode extends LogicNode { let b = u8a[i * 4 + 1]; let c = u8a[i * 4 + 2]; - let aa = Math.floor((ar[(PhotoToPBRNode.borderW + yy) * PhotoToPBRNode.tileWithBorderW + PhotoToPBRNode.borderW + PhotoToPBRNode.tileW + xx ] * 0.5 + 0.5) * 255); - let bb = Math.floor((ar[(PhotoToPBRNode.borderW + yy) * PhotoToPBRNode.tileWithBorderW + PhotoToPBRNode.borderW + PhotoToPBRNode.tileW + xx + offsetG] * 0.5 + 0.5) * 255); - let cc = Math.floor((ar[(PhotoToPBRNode.borderW + yy) * PhotoToPBRNode.tileWithBorderW + PhotoToPBRNode.borderW + PhotoToPBRNode.tileW + xx + offsetB] * 0.5 + 0.5) * 255); + let aa = math_floor((ar[(PhotoToPBRNode.borderW + yy) * PhotoToPBRNode.tileWithBorderW + PhotoToPBRNode.borderW + PhotoToPBRNode.tileW + xx ] * 0.5 + 0.5) * 255); + let bb = math_floor((ar[(PhotoToPBRNode.borderW + yy) * PhotoToPBRNode.tileWithBorderW + PhotoToPBRNode.borderW + PhotoToPBRNode.tileW + xx + offsetG] * 0.5 + 0.5) * 255); + let cc = math_floor((ar[(PhotoToPBRNode.borderW + yy) * PhotoToPBRNode.tileWithBorderW + PhotoToPBRNode.borderW + PhotoToPBRNode.tileW + xx + offsetB] * 0.5 + 0.5) * 255); let f = xx / PhotoToPBRNode.borderW; 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); + 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; @@ -119,15 +119,15 @@ class PhotoToPBRNode extends LogicNode { let b = u8a[i * 4 + 1]; let c = u8a[i * 4 + 2]; - let aa = Math.floor((ar[(PhotoToPBRNode.borderW + PhotoToPBRNode.tileW + yy) * PhotoToPBRNode.tileWithBorderW + PhotoToPBRNode.borderW + xx ] * 0.5 + 0.5) * 255); - let bb = Math.floor((ar[(PhotoToPBRNode.borderW + PhotoToPBRNode.tileW + yy) * PhotoToPBRNode.tileWithBorderW + PhotoToPBRNode.borderW + xx + offsetG] * 0.5 + 0.5) * 255); - let cc = Math.floor((ar[(PhotoToPBRNode.borderW + PhotoToPBRNode.tileW + yy) * PhotoToPBRNode.tileWithBorderW + PhotoToPBRNode.borderW + xx + offsetB] * 0.5 + 0.5) * 255); + let aa = math_floor((ar[(PhotoToPBRNode.borderW + PhotoToPBRNode.tileW + yy) * PhotoToPBRNode.tileWithBorderW + PhotoToPBRNode.borderW + xx ] * 0.5 + 0.5) * 255); + let bb = math_floor((ar[(PhotoToPBRNode.borderW + PhotoToPBRNode.tileW + yy) * PhotoToPBRNode.tileWithBorderW + PhotoToPBRNode.borderW + xx + offsetG] * 0.5 + 0.5) * 255); + let cc = math_floor((ar[(PhotoToPBRNode.borderW + PhotoToPBRNode.tileW + yy) * PhotoToPBRNode.tileWithBorderW + PhotoToPBRNode.borderW + xx + offsetB] * 0.5 + 0.5) * 255); let f = yy / PhotoToPBRNode.borderW; 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); + 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; @@ -158,7 +158,7 @@ class PhotoToPBRNode extends LogicNode { ///if (krom_metal || krom_vulkan) static bgraSwap = (buffer: ArrayBuffer) => { let u8a = new Uint8Array(buffer); - for (let i = 0; i < Math.floor(buffer.byteLength / 4); ++i) { + for (let i = 0; i < math_floor(buffer.byteLength / 4); ++i) { let r = u8a[i * 4]; u8a[i * 4] = u8a[i * 4 + 2]; u8a[i * 4 + 2] = r; diff --git a/armorlab/Sources/nodes/TextToPhotoNode.ts b/armorlab/Sources/nodes/TextToPhotoNode.ts index ee3e77df..2ec7c405 100644 --- a/armorlab/Sources/nodes/TextToPhotoNode.ts +++ b/armorlab/Sources/nodes/TextToPhotoNode.ts @@ -69,9 +69,9 @@ class TextToPhotoNode extends LogicNode { let width = 512; let height = 512; - let latents = new Float32Array(1 * 4 * Math.floor(height / 8) * Math.floor(width / 8)); + let latents = new Float32Array(1 * 4 * math_floor(height / 8) * math_floor(width / 8)); if (inpaintLatents == null) { - for (let i = 0; i < latents.length; ++i) latents[i] = Math.cos(2.0 * 3.14 * RandomNode.getFloat()) * Math.sqrt(-2.0 * Math.log(RandomNode.getFloat())); + for (let i = 0; i < latents.length; ++i) latents[i] = math_cos(2.0 * 3.14 * RandomNode.getFloat()) * math_sqrt(-2.0 * math_log(RandomNode.getFloat())); } else { for (let i = 0; i < latents.length; ++i) latents[i] = inpaintLatents[i]; @@ -113,14 +113,14 @@ class TextToPhotoNode extends LogicNode { noise_pred[i] = noise_pred_uncond[i] + guidance_scale * (noise_pred_text[i] - noise_pred_uncond[i]); } - let prev_timestep = Math.floor(Math.max(timestep - Math.floor(num_train_timesteps / num_inference_steps), 0)); + let prev_timestep = math_floor(math_max(timestep - math_floor(num_train_timesteps / num_inference_steps), 0)); if (counter != 1) { ets.push(noise_pred); } else { prev_timestep = timestep; - timestep = timestep + Math.floor(num_train_timesteps / num_inference_steps); + timestep = timestep + math_floor(num_train_timesteps / num_inference_steps); } if (ets.length == 1 && counter == 0) { @@ -161,8 +161,8 @@ class TextToPhotoNode extends LogicNode { let alpha_prod_t_prev = TextToPhotoNode.alphas_cumprod[prev_timestep + 1]; let beta_prod_t = 1 - alpha_prod_t; let beta_prod_t_prev = 1 - alpha_prod_t_prev; - let latents_coeff = Math.pow(alpha_prod_t_prev / alpha_prod_t, (0.5)); - let noise_pred_denom_coeff = alpha_prod_t * Math.pow(beta_prod_t_prev, (0.5)) + Math.pow(alpha_prod_t * beta_prod_t * alpha_prod_t_prev, (0.5)); + let latents_coeff = math_pow(alpha_prod_t_prev / alpha_prod_t, (0.5)); + let noise_pred_denom_coeff = alpha_prod_t * math_pow(beta_prod_t_prev, (0.5)) + math_pow(alpha_prod_t * beta_prod_t * alpha_prod_t_prev, (0.5)); for (let i = 0; i < latents.length; ++i) { latents[i] = (latents_coeff * latents[i] - (alpha_prod_t_prev - alpha_prod_t) * noise_pred[i] / noise_pred_denom_coeff); } @@ -170,9 +170,9 @@ class TextToPhotoNode extends LogicNode { if (mask != null) { let noise = new Float32Array(latents.length); - for (let i = 0; i < noise.length; ++i) noise[i] = Math.cos(2.0 * 3.14 * RandomNode.getFloat()) * Math.sqrt(-2.0 * Math.log(RandomNode.getFloat())); - let sqrt_alpha_prod = Math.pow(TextToPhotoNode.alphas_cumprod[timestep], 0.5); - let sqrt_one_minus_alpha_prod = Math.pow(1.0 - TextToPhotoNode.alphas_cumprod[timestep], 0.5); + for (let i = 0; i < noise.length; ++i) noise[i] = math_cos(2.0 * 3.14 * RandomNode.getFloat()) * math_sqrt(-2.0 * math_log(RandomNode.getFloat())); + let sqrt_alpha_prod = math_pow(TextToPhotoNode.alphas_cumprod[timestep], 0.5); + let sqrt_one_minus_alpha_prod = math_pow(1.0 - TextToPhotoNode.alphas_cumprod[timestep], 0.5); let init_latents_proper = new Float32Array(latents.length); for (let i = 0; i < init_latents_proper.length; ++i) { @@ -210,9 +210,9 @@ class TextToPhotoNode extends LogicNode { let u8a = new Uint8Array(4 * 512 * 512); for (let i = 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 ] = 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); diff --git a/armorlab/Sources/nodes/TilingNode.ts b/armorlab/Sources/nodes/TilingNode.ts index 416a84e3..d251f327 100644 --- a/armorlab/Sources/nodes/TilingNode.ts +++ b/armorlab/Sources/nodes/TilingNode.ts @@ -62,7 +62,7 @@ class TilingNode extends LogicNode { let u8a = new Uint8Array(512 * 512); for (let i = 0; i < 512 * 512; ++i) { let x = i % 512; - let y = Math.floor(i / 512); + let y = math_floor(i / 512); let l = y < 256 ? y : (511 - y); u8a[i] = (x > 256 - l && x < 256 + l) ? 0 : 255; } diff --git a/armorlab/Sources/nodes/UpscaleNode.ts b/armorlab/Sources/nodes/UpscaleNode.ts index 7585b942..ddba3e28 100644 --- a/armorlab/Sources/nodes/UpscaleNode.ts +++ b/armorlab/Sources/nodes/UpscaleNode.ts @@ -44,8 +44,8 @@ class UpscaleNode extends LogicNode { let result: image_t = null; let size1w = source.width; let size1h = source.height; - let size2w = Math.floor(size1w * 2); - let size2h = Math.floor(size1h * 2); + let size2w = math_floor(size1w * 2); + let size2h = math_floor(size1h * 2); if (UpscaleNode.temp != null) { image_unload(UpscaleNode.temp); } @@ -72,9 +72,9 @@ class UpscaleNode extends LogicNode { u8a = new Uint8Array(4 * size2w * size2h); for (let i = 0; i < (size2w * size2h); ++i) { - u8a[i * 4 ] = Math.floor(esrgan2x[i ] * 255); - u8a[i * 4 + 1] = Math.floor(esrgan2x[i + size2w * size2w ] * 255); - u8a[i * 4 + 2] = Math.floor(esrgan2x[i + size2w * size2w * 2] * 255); + u8a[i * 4 ] = math_floor(esrgan2x[i ] * 255); + u8a[i * 4 + 1] = math_floor(esrgan2x[i + size2w * size2w ] * 255); + u8a[i * 4 + 2] = math_floor(esrgan2x[i + size2w * size2w * 2] * 255); u8a[i * 4 + 3] = 255; } @@ -87,15 +87,15 @@ class UpscaleNode extends LogicNode { let size1w = source.width; let size1h = source.height; let tileSize = 512; - let tileSize2x = Math.floor(tileSize * 2); + let tileSize2x = math_floor(tileSize * 2); if (size1w >= tileSize2x || size1h >= tileSize2x) { // Split into tiles - let size2w = Math.floor(size1w * 2); - let size2h = Math.floor(size1h * 2); + let size2w = math_floor(size1w * 2); + let size2h = math_floor(size1h * 2); result = image_create_render_target(size2w, size2h); let tileSource = image_create_render_target(tileSize + 32 * 2, tileSize + 32 * 2); - for (let x = 0; x < Math.floor(size1w / tileSize); ++x) { - for (let y = 0; y < Math.floor(size1h / tileSize); ++y) { + for (let x = 0; x < math_floor(size1w / tileSize); ++x) { + for (let y = 0; y < math_floor(size1h / tileSize); ++y) { g2_begin(tileSource); g2_draw_scaled_image(source, 32 - x * tileSize, 32 - y * tileSize, -source.width, source.height); g2_draw_scaled_image(source, 32 - x * tileSize, 32 - y * tileSize, source.width, -source.height); diff --git a/armorlab/Sources/nodes/VarianceNode.ts b/armorlab/Sources/nodes/VarianceNode.ts index 57035e75..1fb613d0 100644 --- a/armorlab/Sources/nodes/VarianceNode.ts +++ b/armorlab/Sources/nodes/VarianceNode.ts @@ -50,13 +50,13 @@ class VarianceNode extends LogicNode { } let noise = new Float32Array(latents.length); - for (let i = 0; i < noise.length; ++i) noise[i] = Math.cos(2.0 * 3.14 * RandomNode.getFloat()) * Math.sqrt(-2.0 * Math.log(RandomNode.getFloat())); + for (let i = 0; i < noise.length; ++i) noise[i] = math_cos(2.0 * 3.14 * RandomNode.getFloat()) * math_sqrt(-2.0 * math_log(RandomNode.getFloat())); let num_inference_steps = 50; - let init_timestep = Math.floor(num_inference_steps * strength); + let init_timestep = math_floor(num_inference_steps * strength); let timesteps = TextToPhotoNode.timesteps[num_inference_steps - init_timestep]; let alphas_cumprod = TextToPhotoNode.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); + 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 = 0; i < latents.length; ++i) { latents[i] = sqrt_alpha_prod * latents[i] + sqrt_one_minus_alpha_prod * noise[i]; } diff --git a/armorpaint/Assets/Scene.arm b/armorpaint/Assets/Scene.arm index 6dad3d29..52ad7584 100644 Binary files a/armorpaint/Assets/Scene.arm and b/armorpaint/Assets/Scene.arm differ diff --git a/armorpaint/Sources/ImportFolder.ts b/armorpaint/Sources/ImportFolder.ts index 4d9f4137..c2ec904a 100644 --- a/armorpaint/Sources/ImportFolder.ts +++ b/armorpaint/Sources/ImportFolder.ts @@ -115,8 +115,8 @@ class ImportFolder { } MakeMaterial.parse_paint_material(); - UtilRender.make_material_preview(); - UIBase.hwnds[1].redraws = 2; + util_render_make_material_preview(); + ui_base_hwnds[1].redraws = 2; history_new_material(); } diff --git a/armorpaint/Sources/MakeBake.ts b/armorpaint/Sources/MakeBake.ts index c316084d..995a3486 100644 --- a/armorpaint/Sources/MakeBake.ts +++ b/armorpaint/Sources/MakeBake.ts @@ -8,7 +8,7 @@ class MakeBake { frag.wposition = true; frag.n = true; frag.vvec = true; - NodeShader.add_function(frag, ShaderFunctions.str_cotangent_frame); + NodeShader.add_function(frag, str_cotangent_frame); ///if krom_direct3d11 NodeShader.write(frag, 'mat3 TBN = cotangentFrame(n, vVec, texCoord);'); ///else @@ -21,7 +21,7 @@ class MakeBake { NodeShader.write(frag, MakeMaterial.voxelgi_half_extents()); NodeShader.write(frag, 'vec3 voxpos = wposition / voxelgiHalfExtents;'); NodeShader.add_uniform(frag, 'sampler3D voxels'); - NodeShader.add_function(frag, ShaderFunctions.str_trace_ao); + NodeShader.add_function(frag, str_trace_ao); frag.n = true; let strength: f32 = context_raw.bake_ao_strength; let radius: f32 = context_raw.bake_ao_radius; @@ -58,7 +58,7 @@ class MakeBake { frag.n = true; NodeShader.add_uniform(frag, 'sampler2D texpaint_undo', '_texpaint_undo'); // Baked high-poly normals NodeShader.write(frag, 'vec3 n0 = textureLod(texpaint_undo, texCoord, 0.0).rgb * vec3(2.0, 2.0, 2.0) - vec3(1.0, 1.0, 1.0);'); - NodeShader.add_function(frag, ShaderFunctions.str_cotangent_frame); + NodeShader.add_function(frag, str_cotangent_frame); NodeShader.write(frag, 'mat3 invTBN = transpose(cotangentFrame(n, n, texCoord));'); NodeShader.write(frag, 'vec3 res = normalize(mul(n0, invTBN)) * vec3(0.5, 0.5, 0.5) + vec3(0.5, 0.5, 0.5);'); NodeShader.write(frag, 'fragColor[0] = vec4(res, 1.0);'); diff --git a/armorpaint/Sources/MakeBrush.ts b/armorpaint/Sources/MakeBrush.ts index 7ebd19a2..6a667df7 100644 --- a/armorpaint/Sources/MakeBrush.ts +++ b/armorpaint/Sources/MakeBrush.ts @@ -25,7 +25,7 @@ class MakeBrush { frag.wposition = true; if (config_raw.brush_angle_reject || context_raw.xray) { - NodeShader.add_function(frag, ShaderFunctions.str_octahedron_wrap); + NodeShader.add_function(frag, str_octahedron_wrap); NodeShader.add_uniform(frag, 'sampler2D gbuffer0'); ///if (krom_direct3d11 || krom_direct3d12 || krom_metal || krom_vulkan) NodeShader.write(frag, 'vec2 g0 = textureLod(gbuffer0, inp.xy, 0.0).rg;'); diff --git a/armorpaint/Sources/MakeColorIdPicker.ts b/armorpaint/Sources/MakeColorIdPicker.ts index 095208a1..17fb68f9 100644 --- a/armorpaint/Sources/MakeColorIdPicker.ts +++ b/armorpaint/Sources/MakeColorIdPicker.ts @@ -26,8 +26,8 @@ class MakeColorIdPicker { NodeShader.add_out(frag, 'vec4 fragColor[2]'); NodeShader.add_uniform(frag, 'sampler2D gbufferD'); NodeShader.add_uniform(frag, 'mat4 invVP', '_inv_view_proj_matrix'); - NodeShader.add_function(frag, ShaderFunctions.str_get_pos_from_depth); - NodeShader.add_function(frag, ShaderFunctions.str_get_nor_from_depth); + NodeShader.add_function(frag, str_get_pos_from_depth); + NodeShader.add_function(frag, str_get_nor_from_depth); NodeShader.write(frag, 'fragColor[0] = vec4(get_pos_from_depth(vec2(inp.x, 1.0 - inp.y), invVP, texturePass(gbufferD)), texCoordInp.x);'); NodeShader.write(frag, 'fragColor[1] = vec4(get_nor_from_depth(fragColor[0].rgb, vec2(inp.x, 1.0 - inp.y), invVP, vec2(1.0, 1.0) / gbufferSize, texturePass(gbufferD)), texCoordInp.y);'); } diff --git a/armorpaint/Sources/MakeMaterial.ts b/armorpaint/Sources/MakeMaterial.ts index f70ec2ae..6a7cbe1f 100644 --- a/armorpaint/Sources/MakeMaterial.ts +++ b/armorpaint/Sources/MakeMaterial.ts @@ -9,7 +9,7 @@ class MakeMaterial { static subs_used = false; static get_mout = (): bool => { - for (let n of UINodes.get_canvas_material().nodes) if (n.type == "OUTPUT_MATERIAL_PBR") return true; + for (let n of ui_nodes_get_canvas_material().nodes) if (n.type == "OUTPUT_MATERIAL_PBR") return true; return false; } @@ -180,9 +180,10 @@ class MakeMaterial { if (bake_previews) { let current: image_t = _g2_current; - if (current != null) g2_end(); + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); MakeMaterial.bake_node_previews(); - if (current != null) g2_begin(current); + if (g2_in_use) g2_begin(current); } let m: material_data_t = project_materials[0].data; @@ -204,7 +205,7 @@ class MakeMaterial { } } - let sdata: material_t = { name: "Material", canvas: UINodes.get_canvas_material() }; + let sdata: material_t = { name: "Material", canvas: ui_nodes_get_canvas_material() }; let tmcon: material_context_t = { name: "paint", bind_textures: [] }; let con: NodeShaderContextRaw = MakePaint.run(sdata, tmcon); @@ -229,8 +230,8 @@ class MakeMaterial { static bake_node_previews = () => { context_raw.node_previews_used = []; - if (context_raw.node_previews == null) context_raw.node_previews = new Map(); - MakeMaterial.traverse_nodes(UINodes.get_canvas_material().nodes, null, []); + if (context_raw.node_previews == null) context_raw.node_previews = map_create(); + MakeMaterial.traverse_nodes(ui_nodes_get_canvas_material().nodes, null, []); for (let key of context_raw.node_previews.keys()) { if (context_raw.node_previews_used.indexOf(key) == -1) { let image: image_t = context_raw.node_previews.get(key); @@ -261,8 +262,8 @@ class MakeMaterial { let id: string = ParserMaterial.node_name(node, parents); let image: image_t = context_raw.node_previews.get(id); context_raw.node_previews_used.push(id); - let resX: i32 = Math.floor(config_get_texture_res_x() / 4); - let resY: i32 = Math.floor(config_get_texture_res_y() / 4); + let resX: i32 = math_floor(config_get_texture_res_x() / 4); + let resY: i32 = math_floor(config_get_texture_res_y() / 4); if (image == null || image.width != resX || image.height != resY) { if (image != null) image_unload(image); image = image_create_render_target(resX, resY); @@ -270,15 +271,15 @@ class MakeMaterial { } ParserMaterial.blur_passthrough = true; - UtilRender.make_node_preview(UINodes.get_canvas_material(), node, image, group, parents); + util_render_make_node_preview(ui_nodes_get_canvas_material(), node, image, group, parents); ParserMaterial.blur_passthrough = false; } else if (node.type == "DIRECT_WARP") { let id: string = ParserMaterial.node_name(node, parents); let image: image_t = context_raw.node_previews.get(id); context_raw.node_previews_used.push(id); - let resX: i32 = Math.floor(config_get_texture_res_x()); - let resY: i32 = Math.floor(config_get_texture_res_y()); + let resX: i32 = math_floor(config_get_texture_res_x()); + let resY: i32 = math_floor(config_get_texture_res_y()); if (image == null || image.width != resX || image.height != resY) { if (image != null) image_unload(image); image = image_create_render_target(resX, resY); @@ -286,15 +287,15 @@ class MakeMaterial { } ParserMaterial.warp_passthrough = true; - UtilRender.make_node_preview(UINodes.get_canvas_material(), node, image, group, parents); + util_render_make_node_preview(ui_nodes_get_canvas_material(), node, image, group, parents); ParserMaterial.warp_passthrough = false; } else if (node.type == "BAKE_CURVATURE") { let id: string = ParserMaterial.node_name(node, parents); let image: image_t = context_raw.node_previews.get(id); context_raw.node_previews_used.push(id); - let resX: i32 = Math.floor(config_get_texture_res_x()); - let resY: i32 = Math.floor(config_get_texture_res_y()); + let resX: i32 = math_floor(config_get_texture_res_x()); + let resY: i32 = math_floor(config_get_texture_res_y()); if (image == null || image.width != resX || image.height != resY) { if (image != null) image_unload(image); image = image_create_render_target(resX, resY, tex_format_t.R8); @@ -305,10 +306,10 @@ class MakeMaterial { RenderPathPaint.live_layer = SlotLayer.create("_live"); } - let _space: i32 = UIHeader.worktab.position; + let _space: i32 = ui_header_worktab.position; let _tool: workspace_tool_t = context_raw.tool; let _bake_type: bake_type_t = context_raw.bake_type; - UIHeader.worktab.position = space_type_t.SPACE3D; + ui_header_worktab.position = space_type_t.SPACE3D; context_raw.tool = workspace_tool_t.BAKE; context_raw.bake_type = bake_type_t.CURVATURE; @@ -328,12 +329,12 @@ class MakeMaterial { RenderPathPaint.use_live_layer(false); context_raw.pdirty = 0; - UIHeader.worktab.position = _space; + ui_header_worktab.position = _space; context_raw.tool = _tool; context_raw.bake_type = _bake_type; MakeMaterial.parse_paint_material(false); - let rts: Map = render_path_render_targets; + let rts: map_t = render_path_render_targets; let texpaint_live: render_target_t = rts.get("texpaint_live"); g2_begin(image); @@ -344,7 +345,7 @@ class MakeMaterial { static parse_node_preview_material = (node: zui_node_t, group: zui_node_canvas_t = null, parents: zui_node_t[] = null): { scon: shader_context_t, mcon: material_context_t } => { if (node.outputs.length == 0) return null; - let sdata: material_t = { name: "Material", canvas: UINodes.get_canvas_material() }; + let sdata: material_t = { name: "Material", canvas: ui_nodes_get_canvas_material() }; let mcon_raw: material_context_t = { name: "mesh", bind_textures: [] }; let con: NodeShaderContextRaw = MakeNodePreview.run(sdata, mcon_raw, node, group, parents); let compile_error: bool = false; @@ -409,19 +410,19 @@ class MakeMaterial { return `vec3(1.0 - ${opac}, 1.0 - ${opac}, 1.0 - ${opac}) * ${cola} + vec3(${opac}, ${opac}, ${opac}) * ${cola} / ${colb}`; } else if (blending == blend_type_t.HUE) { - NodeShader.add_function(frag, ShaderFunctions.str_hue_sat); + NodeShader.add_function(frag, str_hue_sat); return `mix(${cola}, hsv_to_rgb(vec3(rgb_to_hsv(${colb}).r, rgb_to_hsv(${cola}).g, rgb_to_hsv(${cola}).b)), ${opac})`; } else if (blending == blend_type_t.SATURATION) { - NodeShader.add_function(frag, ShaderFunctions.str_hue_sat); + NodeShader.add_function(frag, str_hue_sat); return `mix(${cola}, hsv_to_rgb(vec3(rgb_to_hsv(${cola}).r, rgb_to_hsv(${colb}).g, rgb_to_hsv(${cola}).b)), ${opac})`; } else if (blending == blend_type_t.COLOR) { - NodeShader.add_function(frag, ShaderFunctions.str_hue_sat); + NodeShader.add_function(frag, str_hue_sat); return `mix(${cola}, hsv_to_rgb(vec3(rgb_to_hsv(${colb}).r, rgb_to_hsv(${colb}).g, rgb_to_hsv(${cola}).b)), ${opac})`; } else { // BlendValue - NodeShader.add_function(frag, ShaderFunctions.str_hue_sat); + NodeShader.add_function(frag, str_hue_sat); return `mix(${cola}, hsv_to_rgb(vec3(rgb_to_hsv(${cola}).r, rgb_to_hsv(${cola}).g, rgb_to_hsv(${colb}).b)), ${opac})`; } } diff --git a/armorpaint/Sources/MakeMesh.ts b/armorpaint/Sources/MakeMesh.ts index 68707108..e4fd3339 100644 --- a/armorpaint/Sources/MakeMesh.ts +++ b/armorpaint/Sources/MakeMesh.ts @@ -64,7 +64,7 @@ class MakeMesh { NodeShader.add_out(frag, 'vec4 fragColor[3]'); frag.n = true; - NodeShader.add_function(frag, ShaderFunctions.str_pack_float_int16); + NodeShader.add_function(frag, str_pack_float_int16); if (context_raw.tool == workspace_tool_t.COLORID) { texture_count++; @@ -74,8 +74,8 @@ class MakeMesh { NodeShader.write(frag, 'fragColor[1] = vec4(idcol.rgb, 1.0);'); // occ } else { - NodeShader.add_function(frag, ShaderFunctions.str_octahedron_wrap); - NodeShader.add_function(frag, ShaderFunctions.str_cotangent_frame); + NodeShader.add_function(frag, str_octahedron_wrap); + NodeShader.add_function(frag, str_cotangent_frame); if (layerPass > 0) { NodeShader.add_uniform(frag, 'sampler2D gbuffer0'); NodeShader.add_uniform(frag, 'sampler2D gbuffer1'); @@ -348,13 +348,13 @@ class MakeMesh { NodeShader.add_uniform(frag, 'vec4 envmapData', '_envmapData'); // angle, sin(angle), cos(angle), strength NodeShader.write(frag, 'vec3 wreflect = reflect(-vVec, n);'); NodeShader.write(frag, 'float envlod = roughness * float(envmapNumMipmaps);'); - NodeShader.add_function(frag, ShaderFunctions.str_envmap_equirect); + NodeShader.add_function(frag, str_envmap_equirect); NodeShader.write(frag, 'vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(wreflect, envmapData.x), envlod).rgb;'); NodeShader.add_uniform(frag, 'vec3 lightArea0', '_light_area0'); NodeShader.add_uniform(frag, 'vec3 lightArea1', '_light_area1'); NodeShader.add_uniform(frag, 'vec3 lightArea2', '_light_area2'); NodeShader.add_uniform(frag, 'vec3 lightArea3', '_light_area3'); - NodeShader.add_function(frag, ShaderFunctions.str_ltc_evaluate); + NodeShader.add_function(frag, str_ltc_evaluate); NodeShader.add_uniform(frag, 'vec3 lightPos', '_point_pos'); NodeShader.add_uniform(frag, 'vec3 lightColor', '_point_color'); // NodeShader.write(frag, 'float dotNL = max(dot(n, normalize(lightPos - wposition)), 0.0);'); @@ -376,7 +376,7 @@ class MakeMesh { NodeShader.write(frag, 'direct *= lightColor * (1.0 / (ldist * ldist));'); NodeShader.add_uniform(frag, 'vec4 shirr[7]', '_envmap_irradiance'); - NodeShader.add_function(frag, ShaderFunctions.str_sh_irradiance); + NodeShader.add_function(frag, str_sh_irradiance()); NodeShader.write(frag, 'vec3 indirect = albedo * (shIrradiance(vec3(n.x * envmapData.z - n.y * envmapData.y, n.x * envmapData.y + n.y * envmapData.z, n.z), shirr) / 3.14159265);'); NodeShader.write(frag, 'indirect += prefilteredColor * (f0 * envBRDF.x + envBRDF.y) * 1.5;'); NodeShader.write(frag, 'indirect *= envmapData.w * occlusion;'); diff --git a/armorpaint/Sources/MakeMeshPreview.ts b/armorpaint/Sources/MakeMeshPreview.ts index 0aca7924..4da6b434 100644 --- a/armorpaint/Sources/MakeMeshPreview.ts +++ b/armorpaint/Sources/MakeMeshPreview.ts @@ -26,7 +26,7 @@ class MakeMeshPreview { pos = "spos"; NodeShaderContext.add_elem(con_mesh, "bone", 'short4norm'); NodeShaderContext.add_elem(con_mesh, "weight", 'short4norm'); - NodeShader.add_function(vert, ShaderFunctions.str_get_skinning_dual_quat); + NodeShader.add_function(vert, str_get_skinning_dual_quat); NodeShader.add_uniform(vert, 'vec4 skinBones[128 * 2]', '_skin_bones'); NodeShader.add_uniform(vert, 'float posUnpack', '_pos_unpack'); NodeShader.write_attrib(vert, 'vec4 skinA;'); @@ -52,7 +52,7 @@ class MakeMeshPreview { ParserMaterial.sample_uv_scale = brush_scale; ParserMaterial.parse_height = MakeMaterial.height_used; ParserMaterial.parse_height_as_channel = true; - let sout: shader_out_t = ParserMaterial.parse(UINodes.get_canvas_material(), con_mesh, vert, frag, matcon); + let sout: shader_out_t = ParserMaterial.parse(ui_nodes_get_canvas_material(), con_mesh, vert, frag, matcon); ParserMaterial.parse_height = false; ParserMaterial.parse_height_as_channel = false; ParserMaterial.sample_keep_aspect = false; @@ -95,9 +95,9 @@ class MakeMeshPreview { NodeShader.add_out(frag, 'vec4 fragColor[3]'); frag.n = true; - NodeShader.add_function(frag, ShaderFunctions.str_pack_float_int16); - NodeShader.add_function(frag, ShaderFunctions.str_cotangent_frame); - NodeShader.add_function(frag, ShaderFunctions.str_octahedron_wrap); + NodeShader.add_function(frag, str_pack_float_int16); + NodeShader.add_function(frag, str_cotangent_frame); + NodeShader.add_function(frag, str_octahedron_wrap); if (MakeMaterial.height_used) { NodeShader.write(frag, 'if (height > 0.0) {'); diff --git a/armorpaint/Sources/MakePaint.ts b/armorpaint/Sources/MakePaint.ts index 45c9a302..e0264d69 100644 --- a/armorpaint/Sources/MakePaint.ts +++ b/armorpaint/Sources/MakePaint.ts @@ -138,7 +138,7 @@ class MakePaint { NodeShader.write(frag, 'float dist = 0.0;'); let angle_fill: bool = context_raw.tool == workspace_tool_t.FILL && context_raw.fill_type_handle.position == fill_type_t.ANGLE; if (angle_fill) { - NodeShader.add_function(frag, ShaderFunctions.str_octahedron_wrap); + NodeShader.add_function(frag, str_octahedron_wrap); NodeShader.add_uniform(frag, 'sampler2D gbuffer0'); NodeShader.write(frag, 'vec2 g0 = textureLod(gbuffer0, inp.xy, 0.0).rg;'); NodeShader.write(frag, 'vec3 wn;'); @@ -202,7 +202,7 @@ class MakePaint { ParserMaterial.triplanar = uv_type == uv_type_t.TRIPLANAR && !decal; ParserMaterial.sample_keep_aspect = decal; ParserMaterial.sample_uv_scale = 'brushScale'; - let sout: shader_out_t = ParserMaterial.parse(UINodes.get_canvas_material(), con_paint, vert, frag, matcon); + let sout: shader_out_t = ParserMaterial.parse(ui_nodes_get_canvas_material(), con_paint, vert, frag, matcon); ParserMaterial.parse_emission = false; ParserMaterial.parse_subsurface = false; ParserMaterial.parse_height_as_channel = false; diff --git a/armorpaint/Sources/NodesBrush.ts b/armorpaint/Sources/NodesBrush.ts index 63c3e101..3b72f171 100644 --- a/armorpaint/Sources/NodesBrush.ts +++ b/armorpaint/Sources/NodesBrush.ts @@ -32,7 +32,7 @@ class NodesBrush { if (n.type == nodeType) { let canvas: zui_node_canvas_t = context_raw.brush.canvas; let nodes: zui_nodes_t = context_raw.brush.nodes; - let node: zui_node_t = UINodes.make_node(n, nodes, canvas); + let node: zui_node_t = ui_nodes_make_node(n, nodes, canvas); canvas.nodes.push(node); return node; } diff --git a/armorpaint/Sources/RenderPathPaint.ts b/armorpaint/Sources/RenderPathPaint.ts index 43f5cc2b..3da83d44 100644 --- a/armorpaint/Sources/RenderPathPaint.ts +++ b/armorpaint/Sources/RenderPathPaint.ts @@ -139,7 +139,7 @@ class RenderPathPaint { render_path_clear_target(0xff000000); render_path_bind_target("gbuffer2", "gbuffer2"); render_path_draw_meshes("paint"); - UIHeader.header_handle.redraws = 2; + ui_header_handle.redraws = 2; } else if (context_raw.tool == workspace_tool_t.PICKER || context_raw.tool == workspace_tool_t.MATERIAL) { if (context_raw.pick_pos_nor_tex) { @@ -175,8 +175,8 @@ class RenderPathPaint { render_path_bind_target("texpaint_pack" + tid, "texpaint_pack"); render_path_draw_meshes("paint"); if (use_live_layer) RenderPathPaint.use_live_layer(false); - UIHeader.header_handle.redraws = 2; - UIBase.hwnds[2].redraws = 2; + ui_header_handle.redraws = 2; + ui_base_hwnds[2].redraws = 2; let texpaint_picker: image_t = render_path_render_targets.get("texpaint_picker")._image; let texpaint_nor_picker: image_t = render_path_render_targets.get("texpaint_nor_picker")._image; @@ -218,7 +218,7 @@ class RenderPathPaint { // Pick material if (context_raw.picker_select_material && context_raw.color_picker_callback == null) { // matid % 3 == 0 - normal, 1 - emission, 2 - subsurface - let matid: i32 = Math.floor((b.getUint8(3) - (b.getUint8(3) % 3)) / 3); + let matid: i32 = math_floor((b.getUint8(3) - (b.getUint8(3) % 3)) / 3); for (let m of project_materials) { if (m.id == matid) { context_set_material(m); @@ -301,12 +301,12 @@ class RenderPathPaint { if (render_path_render_targets.get("texpaint_blur") == null) { let t = render_target_create(); t.name = "texpaint_blur"; - t.width = Math.floor(config_get_texture_res_x() * 0.95); - t.height = Math.floor(config_get_texture_res_y() * 0.95); + t.width = math_floor(config_get_texture_res_x() * 0.95); + t.height = math_floor(config_get_texture_res_y() * 0.95); t.format = "RGBA32"; render_path_create_render_target(t); } - let blurs: i32 = Math.round(context_raw.bake_curv_smooth); + let blurs: i32 = math_round(context_raw.bake_curv_smooth); for (let i: i32 = 0; i < blurs; ++i) { render_path_set_target("texpaint_blur"); render_path_bind_target(texpaint, "tex"); @@ -432,7 +432,7 @@ class RenderPathPaint { RenderPathPaint.live_layer_drawn = 2; - UIView2D.hwnd.redraws = 2; + ui_view2d_hwnd.redraws = 2; let _x: f32 = context_raw.paint_vec.x; let _y: f32 = context_raw.paint_vec.y; if (context_raw.brush_locked) { @@ -741,7 +741,7 @@ class RenderPathPaint { ///if (krom_direct3d12 || krom_vulkan || krom_metal) else if (is_raytraced_bake) { let dirty: bool = RenderPathRaytraceBake.commands(MakeMaterial.parse_paint_material); - if (dirty) UIHeader.header_handle.redraws = 2; + if (dirty) ui_header_handle.redraws = 2; if (config_raw.dilate == dilate_type_t.INSTANT) { // && raw.pdirty == 1 RenderPathPaint.dilate(true, false); } @@ -803,9 +803,9 @@ class RenderPathPaint { camera_object_build_proj(cam); camera_object_build_mat(cam); - let tw: f32 = 0.95 * UIView2D.pan_scale; - let tx: f32 = UIView2D.pan_x / UIView2D.ww; - let ty: f32 = UIView2D.pan_y / app_h(); + let tw: f32 = 0.95 * ui_view2d_pan_scale; + let tx: f32 = ui_view2d_pan_x / ui_view2d_ww; + let ty: f32 = ui_view2d_pan_y / app_h(); mat4_set_identity(m); mat4_scale(m, vec4_create(tw, tw, 1)); mat4_set_loc(m, vec4_create(tx, ty, 0)); @@ -813,7 +813,7 @@ class RenderPathPaint { mat4_get_inv(m2, scene_camera.vp); mat4_mult_mat(m, m2); - let tiled: bool = UIView2D.tiled_show; + 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]; @@ -845,7 +845,7 @@ class RenderPathPaint { let v: vec4_t = vec4_create(); let sx: f32 = vec4_len(vec4_set(v, m.m[0], m.m[1], m.m[2])); - quat_from_euler(RenderPathPaint.planeo.base.transform.rot, -Math.PI / 2, 0, 0); + quat_from_euler(RenderPathPaint.planeo.base.transform.rot, -math_pi() / 2, 0, 0); vec4_set(RenderPathPaint.planeo.base.transform.scale, sx, 1.0, sx); RenderPathPaint.planeo.base.transform.scale.z *= config_get_texture_res_y() / config_get_texture_res_x(); vec4_set(RenderPathPaint.planeo.base.transform.loc, m.m[12], -m.m[13], 0.0); @@ -903,7 +903,7 @@ class RenderPathPaint { static dilate = (base: bool, nor_pack: bool) => { ///if is_paint if (config_raw.dilate_radius > 0 && !context_raw.paint2d) { - UtilUV.cache_dilate_map(); + util_uv_cache_dilate_map(); base_make_temp_img(); let tid: i32 = context_raw.layer.id; if (base) { diff --git a/armorpaint/Sources/RenderPathPreview.ts b/armorpaint/Sources/RenderPathPreview.ts index 4a7a02b7..cd7c98fa 100644 --- a/armorpaint/Sources/RenderPathPreview.ts +++ b/armorpaint/Sources/RenderPathPreview.ts @@ -25,8 +25,8 @@ class RenderPathPreview { { let t: render_target_t = render_target_create(); t.name = "mtex"; - t.width = Math.floor(UtilRender.material_preview_size * 2.0); - t.height = Math.floor(UtilRender.material_preview_size * 2.0); + t.width = math_floor(util_render_material_preview_size * 2.0); + t.height = math_floor(util_render_material_preview_size * 2.0); t.format = "RGBA64"; t.scale = RenderPathBase.get_super_sampling(); ///if krom_opengl @@ -38,8 +38,8 @@ class RenderPathPreview { { let t: render_target_t = render_target_create(); t.name = "mgbuffer0"; - t.width = Math.floor(UtilRender.material_preview_size * 2.0); - t.height = Math.floor(UtilRender.material_preview_size * 2.0); + t.width = math_floor(util_render_material_preview_size * 2.0); + t.height = math_floor(util_render_material_preview_size * 2.0); t.format = "RGBA64"; t.scale = RenderPathBase.get_super_sampling(); t.depth_buffer = "mmain"; @@ -49,8 +49,8 @@ class RenderPathPreview { { let t: render_target_t = render_target_create(); t.name = "mgbuffer1"; - t.width = Math.floor(UtilRender.material_preview_size * 2.0); - t.height = Math.floor(UtilRender.material_preview_size * 2.0); + t.width = math_floor(util_render_material_preview_size * 2.0); + t.height = math_floor(util_render_material_preview_size * 2.0); t.format = "RGBA64"; t.scale = RenderPathBase.get_super_sampling(); render_path_create_render_target(t); @@ -59,8 +59,8 @@ class RenderPathPreview { { let t: render_target_t = render_target_create(); t.name = "mgbuffer2"; - t.width = Math.floor(UtilRender.material_preview_size * 2.0); - t.height = Math.floor(UtilRender.material_preview_size * 2.0); + t.width = math_floor(util_render_material_preview_size * 2.0); + t.height = math_floor(util_render_material_preview_size * 2.0); t.format = "RGBA64"; t.scale = RenderPathBase.get_super_sampling(); render_path_create_render_target(t); diff --git a/armorpaint/Sources/SlotLayer.ts b/armorpaint/Sources/SlotLayer.ts index 2dca49f0..0e8d1c01 100644 --- a/armorpaint/Sources/SlotLayer.ts +++ b/armorpaint/Sources/SlotLayer.ts @@ -89,7 +89,7 @@ class SlotLayer { raw.texpaint_pack = render_path_create_render_target(t)._image; } - raw.texpaint_preview = image_create_render_target(UtilRender.layer_preview_size, UtilRender.layer_preview_size, tex_format_t.RGBA32); + raw.texpaint_preview = image_create_render_target(util_render_layer_preview_size, util_render_layer_preview_size, tex_format_t.RGBA32); ///end } @@ -108,7 +108,7 @@ class SlotLayer { raw.texpaint = render_path_create_render_target(t)._image; } - raw.texpaint_preview = image_create_render_target(UtilRender.layer_preview_size, UtilRender.layer_preview_size, tex_format_t.RGBA32); + raw.texpaint_preview = image_create_render_target(util_render_layer_preview_size, util_render_layer_preview_size, tex_format_t.RGBA32); } ///end @@ -408,7 +408,7 @@ class SlotLayer { let _next = () => { MakeMaterial.parse_paint_material(); context_raw.layer_preview_dirty = true; - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; } base_notify_on_next_frame(_next); } @@ -418,7 +418,7 @@ class SlotLayer { raw.fill_layer = null; MakeMaterial.parse_paint_material(); context_raw.layer_preview_dirty = true; - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; } static is_visible = (raw: SlotLayerRaw): bool => { @@ -631,7 +631,7 @@ class SlotLayer { context_set_layer(raw); history_order_layers(to); - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; array_remove(project_layers, raw); project_layers.splice(to, 0, raw); diff --git a/armorpaint/Sources/SlotMaterial.ts b/armorpaint/Sources/SlotMaterial.ts index 5384b075..e77ceced 100644 --- a/armorpaint/Sources/SlotMaterial.ts +++ b/armorpaint/Sources/SlotMaterial.ts @@ -27,7 +27,7 @@ class SlotMaterial { for (let mat of project_materials) if (mat.id >= raw.id) raw.id = mat.id + 1; raw.data = m; - let w: i32 = UtilRender.material_preview_size; + let w: i32 = util_render_material_preview_size; let w_icon: i32 = 50; raw.image = image_create_render_target(w, w); raw.image_icon = image_create_render_target(w_icon, w_icon); diff --git a/armorpaint/Sources/TabLayers.ts b/armorpaint/Sources/TabLayers.ts index 7221808e..fe7f24c6 100644 --- a/armorpaint/Sources/TabLayers.ts +++ b/armorpaint/Sources/TabLayers.ts @@ -6,16 +6,16 @@ class TabLayers { static show_context_menu: bool = false; static draw = (htab: zui_handle_t) => { - let mini: bool = config_raw.layout[layout_size_t.SIDEBAR_W] <= UIBase.sidebar_mini_w; + let mini: bool = config_raw.layout[layout_size_t.SIDEBAR_W] <= ui_base_sidebar_mini_w; mini ? TabLayers.draw_mini(htab) : TabLayers.draw_full(htab); } static draw_mini = (htab: zui_handle_t) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; zui_set_hovered_tab_name(tr("Layers")); let _ELEMENT_H: i32 = ui.t.ELEMENT_H; - ui.t.ELEMENT_H = Math.floor(UIBase.sidebar_mini_w / 2 / zui_SCALE(ui)); + ui.t.ELEMENT_H = math_floor(ui_base_sidebar_mini_w / 2 / zui_SCALE(ui)); zui_begin_sticky(); zui_separator(5); @@ -34,7 +34,7 @@ class TabLayers { } static draw_full = (htab: zui_handle_t) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; if (zui_tab(htab, tr("Layers"))) { zui_begin_sticky(); zui_row([1 / 4, 1 / 4, 1 / 2]); @@ -52,9 +52,9 @@ class TabLayers { } static button_2d_view = () => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; if (zui_button(tr("2D View"))) { - UIBase.show_2d_view(view_2d_type_t.LAYER); + ui_base_show_2d_view(view_2d_type_t.LAYER); } else if (ui.is_hovered) zui_tooltip(tr("Show 2D View") + ` (${config_keymap.toggle_2d_view})`); } @@ -69,10 +69,10 @@ class TabLayers { } static highlight_odd_lines = () => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; let step: i32 = ui.t.ELEMENT_H * 2; - let full_h: i32 = ui._window_h - UIBase.hwnds[0].scroll_offset; - for (let i: i32 = 0; i < Math.floor(full_h / step); ++i) { + let full_h: i32 = ui._window_h - ui_base_hwnds[0].scroll_offset; + for (let i: i32 = 0; i < math_floor(full_h / step); ++i) { if (i % 2 == 0) { zui_fill(0, i * step, (ui._w / zui_SCALE(ui) - 2), step, ui.t.WINDOW_BG_COL - 0x00040404); } @@ -81,19 +81,19 @@ class TabLayers { static button_new = (text: string) => { if (zui_button(text)) { - UIMenu.draw((ui: zui_t) => { + ui_menu_draw((ui: zui_t) => { let l: SlotLayerRaw = context_raw.layer; - if (UIMenu.menu_button(ui, tr("Paint Layer"))) { + if (ui_menu_button(ui, tr("Paint Layer"))) { base_new_layer(); history_new_layer(); } - if (UIMenu.menu_button(ui, tr("Fill Layer"))) { + if (ui_menu_button(ui, tr("Fill Layer"))) { base_create_fill_layer(uv_type_t.UVMAP); } - if (UIMenu.menu_button(ui, tr("Decal Layer"))) { + if (ui_menu_button(ui, tr("Decal Layer"))) { base_create_fill_layer(uv_type_t.PROJECT); } - if (UIMenu.menu_button(ui, tr("Black Mask"))) { + if (ui_menu_button(ui, tr("Black Mask"))) { if (SlotLayer.is_mask(l)) context_set_layer(l.parent); // let l: SlotLayerRaw = raw.layer; @@ -106,7 +106,7 @@ class TabLayers { history_new_black_mask(); base_update_fill_layers(); } - if (UIMenu.menu_button(ui, tr("White Mask"))) { + if (ui_menu_button(ui, tr("White Mask"))) { if (SlotLayer.is_mask(l)) context_set_layer(l.parent); // let l: SlotLayerRaw = raw.layer; @@ -119,7 +119,7 @@ class TabLayers { history_new_white_mask(); base_update_fill_layers(); } - if (UIMenu.menu_button(ui, tr("Fill Mask"))) { + if (ui_menu_button(ui, tr("Fill Mask"))) { if (SlotLayer.is_mask(l)) context_set_layer(l.parent); // let l: SlotLayerRaw = raw.layer; @@ -133,7 +133,7 @@ class TabLayers { base_update_fill_layers(); } ui.enabled = !SlotLayer.is_group(context_raw.layer) && !SlotLayer.is_in_group(context_raw.layer); - if (UIMenu.menu_button(ui, tr("Group"))) { + if (ui_menu_button(ui, tr("Group"))) { if (SlotLayer.is_group(l) || SlotLayer.is_in_group(l)) return; if (SlotLayer.is_layer_mask(l)) l = l.parent; @@ -166,15 +166,15 @@ class TabLayers { p.base.visible = context_raw.layer_filter == 0 || p.base.name == ar[context_raw.layer_filter] || project_is_atlas_object(p); } if (context_raw.layer_filter == 0 && context_raw.merged_object_is_atlas) { // All - UtilMesh.merge_mesh(); + util_mesh_merge(); } else if (context_raw.layer_filter > project_paint_objects.length) { // Atlas let visibles: mesh_object_t[] = []; for (let p of project_paint_objects) if (p.base.visible) visibles.push(p); - UtilMesh.merge_mesh(visibles); + util_mesh_merge(visibles); } base_set_object_mask(); - UtilUV.uvmap_cached = false; + util_uv_uvmap_cached = false; context_raw.ddirty = 2; ///if (krom_direct3d12 || krom_vulkan || krom_metal) RenderPathRaytrace.ready = false; @@ -182,7 +182,7 @@ class TabLayers { } } - static remap_layer_pointers = (nodes: zui_node_t[], pointerMap: Map) => { + static remap_layer_pointers = (nodes: zui_node_t[], pointerMap: map_t) => { for (let n of nodes) { if (n.type == "LAYER" || n.type == "LAYER_MASK") { let i: any = n.buttons[0].default_value; @@ -193,14 +193,14 @@ class TabLayers { } } - static init_layer_map = (): Map => { - let res: Map = new Map(); + static init_layer_map = (): map_t => { + let res: map_t = map_create(); for (let i: i32 = 0; i < project_layers.length; ++i) res.set(project_layers[i], i); return res; } - static fill_layer_map = (map: Map): Map => { - let res: Map = new Map(); + static fill_layer_map = (map: map_t): map_t => { + let res: map_t = map_create(); for (let l of map.keys()) res.set(map.get(l), project_layers.indexOf(l) > -1 ? project_layers.indexOf(l) : 9999); return res; } @@ -213,7 +213,7 @@ class TabLayers { } static draw_layer_slot = (l: SlotLayerRaw, i: i32, mini: bool) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; if (context_raw.layer_filter > 0 && SlotLayer.get_object_mask(l) > 0 && @@ -278,7 +278,7 @@ class TabLayers { } static draw_layer_slot_mini = (l: SlotLayerRaw, i: i32) => { - let ui = UIBase.ui; + let ui = ui_base_ui; zui_row([1, 1]); let uix: f32 = ui._x; @@ -292,7 +292,7 @@ class TabLayers { } static draw_layer_slot_full = (l: SlotLayerRaw, i: i32) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; let step: i32 = ui.t.ELEMENT_H; @@ -504,12 +504,12 @@ class TabLayers { static layer_toggle_visible = (l: SlotLayerRaw) => { l.visible = !l.visible; - UIView2D.hwnd.redraws = 2; + ui_view2d_hwnd.redraws = 2; MakeMaterial.parse_mesh_material(); } static draw_layer_highlight = (l: SlotLayerRaw, mini: bool) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; let step: i32 = ui.t.ELEMENT_H; // Separator line @@ -527,7 +527,7 @@ class TabLayers { } static handle_layer_icon_state = (l: SlotLayerRaw, i: i32, state: zui_state_t, uix: f32, uiy: f32) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; ///if is_paint let texpaint_preview: image_t = l.texpaint_preview; @@ -563,7 +563,7 @@ class TabLayers { } else if (state == zui_state_t.RELEASED) { if (time_time() - context_raw.select_time < 0.2) { - UIBase.show_2d_view(view_2d_type_t.LAYER); + ui_base_show_2d_view(view_2d_type_t.LAYER); } if (time_time() - context_raw.select_time > 0.2) { context_raw.select_time = time_time(); @@ -573,7 +573,7 @@ class TabLayers { } static draw_layer_icon = (l: SlotLayerRaw, i: i32, uix: f32, uiy: f32, mini: bool) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; let icons: image_t = resource_get("icons.k"); let icon_h: i32 = (zui_ELEMENT_H(ui) - (mini ? 2 : 3)) * 2; @@ -612,11 +612,11 @@ class TabLayers { ui._w = _w; } if (l.fill_layer == null && SlotLayer.is_mask(l)) { - g2_set_pipeline(UIView2D.pipe); + g2_set_pipeline(ui_view2d_pipe); ///if krom_opengl - krom_g4_set_pipeline(UIView2D.pipe.pipeline_); + krom_g4_set_pipeline(ui_view2d_pipe.pipeline_); ///end - krom_g4_set_int(UIView2D.channel_location, 1); + krom_g4_set_int(ui_view2d_channel_loc, 1); } let state: zui_state_t = zui_image(icon, 0xffffffff, icon_h); @@ -626,7 +626,7 @@ class TabLayers { } // Draw layer numbers when selecting a layer via keyboard shortcut - let is_typing: bool = ui.is_typing || UIView2D.ui.is_typing || UINodes.ui.is_typing; + let is_typing: bool = ui.is_typing || ui_view2d_ui.is_typing || ui_nodes_ui.is_typing; if (!is_typing) { if (i < 9 && operator_shortcut(config_keymap.select_layer, shortcut_type_t.DOWN)) { let number: string = String(i + 1) ; @@ -676,36 +676,36 @@ class TabLayers { } let menu_elements: i32 = SlotLayer.is_group(l) ? 7 : (19 + add); - UIMenu.draw((ui: zui_t) => { + ui_menu_draw((ui: zui_t) => { if (mini) { let visible_handle: zui_handle_t = zui_handle("tablayers_4"); visible_handle.selected = l.visible; - UIMenu.menu_fill(ui); + ui_menu_fill(ui); zui_check(visible_handle, tr("Visible")); if (visible_handle.changed) { TabLayers.layer_toggle_visible(l); - UIMenu.keep_open = true; + ui_menu_keep_open = true; } if (!SlotLayer.is_group(l)) { - UIMenu.menu_fill(ui); + ui_menu_fill(ui); if (TabLayers.combo_blending(ui, l, true).changed) { - UIMenu.keep_open = true; + ui_menu_keep_open = true; } } if (SlotLayer.is_layer(l)) { - UIMenu.menu_fill(ui); + ui_menu_fill(ui); if (TabLayers.combo_object(ui, l, true).changed) { - UIMenu.keep_open = true; + ui_menu_keep_open = true; } } } - if (UIMenu.menu_button(ui, tr("Export"))) { + if (ui_menu_button(ui, tr("Export"))) { if (SlotLayer.is_mask(l)) { - UIFiles.show("png", true, false, (path: string) => { - let f: string = UIFiles.filename; + ui_files_show("png", true, false, (path: string) => { + let f: string = ui_files_filename; if (f == "") f = tr("untitled"); if (!f.endsWith(".png")) f += ".png"; krom_write_png(path + path_sep + f, image_get_pixels(l.texpaint), l.texpaint.width, l.texpaint.height, 3); // RRR1 @@ -723,14 +723,14 @@ class TabLayers { let to_fill_string: string = SlotLayer.is_layer(l) ? tr("To Fill Layer") : tr("To Fill Mask"); let to_paint_string: string = SlotLayer.is_layer(l) ? tr("To Paint Layer") : tr("To Paint Mask"); - if (l.fill_layer == null && UIMenu.menu_button(ui, to_fill_string)) { + if (l.fill_layer == null && ui_menu_button(ui, to_fill_string)) { let _init = () => { SlotLayer.is_layer(l) ? history_to_fill_layer() : history_to_fill_mask(); SlotLayer.to_fill_layer(l); } app_notify_on_init(_init); } - if (l.fill_layer != null && UIMenu.menu_button(ui, to_paint_string)) { + if (l.fill_layer != null && ui_menu_button(ui, to_paint_string)) { let _init = () => { SlotLayer.is_layer(l) ? history_to_paint_layer() : history_to_paint_mask(); SlotLayer.to_paint_layer(l); @@ -740,7 +740,7 @@ class TabLayers { } ui.enabled = TabLayers.can_delete(l); - if (UIMenu.menu_button(ui, tr("Delete"), "delete")) { + if (ui_menu_button(ui, tr("Delete"), "delete")) { let _init = () => { TabLayers.delete_layer(context_raw.layer); } @@ -748,7 +748,7 @@ class TabLayers { } ui.enabled = true; - if (l.fill_layer == null && UIMenu.menu_button(ui, tr("Clear"))) { + if (l.fill_layer == null && ui_menu_button(ui, tr("Clear"))) { context_set_layer(l); let _init = () => { if (!SlotLayer.is_group(l)) { @@ -767,7 +767,7 @@ class TabLayers { } app_notify_on_init(_init); } - if (SlotLayer.is_mask(l) && l.fill_layer == null && UIMenu.menu_button(ui, tr("Invert"))) { + if (SlotLayer.is_mask(l) && l.fill_layer == null && ui_menu_button(ui, tr("Invert"))) { let _init = () => { context_set_layer(l); history_invert_mask(); @@ -775,7 +775,7 @@ class TabLayers { } app_notify_on_init(_init); } - if (SlotLayer.is_mask(l) && UIMenu.menu_button(ui, tr("Apply"))) { + if (SlotLayer.is_mask(l) && ui_menu_button(ui, tr("Apply"))) { let _init = () => { context_raw.layer = l; history_apply_mask(); @@ -786,14 +786,14 @@ class TabLayers { } app_notify_on_init(_init); } - if (SlotLayer.is_group(l) && UIMenu.menu_button(ui, tr("Merge Group"))) { + if (SlotLayer.is_group(l) && ui_menu_button(ui, tr("Merge Group"))) { let _init = () => { base_merge_group(l); } app_notify_on_init(_init); } ui.enabled = TabLayers.can_merge_down(l); - if (UIMenu.menu_button(ui, tr("Merge Down"))) { + if (ui_menu_button(ui, tr("Merge Down"))) { let _init = () => { context_set_layer(l); history_merge_layers(); @@ -803,7 +803,7 @@ class TabLayers { app_notify_on_init(_init); } ui.enabled = true; - if (UIMenu.menu_button(ui, tr("Duplicate"))) { + if (ui_menu_button(ui, tr("Duplicate"))) { let _init = () => { context_set_layer(l); history_duplicate_layer(); @@ -812,8 +812,8 @@ class TabLayers { app_notify_on_init(_init); } - UIMenu.menu_fill(ui); - UIMenu.menu_align(ui); + ui_menu_fill(ui); + ui_menu_align(ui); let layer_opac_handle: zui_handle_t = zui_nest(zui_handle("tablayers_5"), l.id); layer_opac_handle.value = l.mask_opacity; zui_slider(layer_opac_handle, tr("Opacity"), 0.0, 1.0, true); @@ -821,12 +821,12 @@ class TabLayers { if (ui.input_started) history_layer_opacity(); l.mask_opacity = layer_opac_handle.value; MakeMaterial.parse_mesh_material(); - UIMenu.keep_open = true; + ui_menu_keep_open = true; } if (!SlotLayer.is_group(l)) { - UIMenu.menu_fill(ui); - UIMenu.menu_align(ui); + ui_menu_fill(ui); + ui_menu_align(ui); let res_handle_changed_last: bool = base_res_handle.changed; ///if (krom_android || krom_ios) let ar: string[] = ["128", "256", "512", "1K", "2K", "4K"]; @@ -835,9 +835,9 @@ class TabLayers { ///end let _y: i32 = ui._y; base_res_handle.value = base_res_handle.position; - base_res_handle.position = Math.floor(zui_slider(base_res_handle, ar[base_res_handle.position], 0, ar.length - 1, false, 1, false, zui_align_t.LEFT, false)); + base_res_handle.position = math_floor(zui_slider(base_res_handle, ar[base_res_handle.position], 0, ar.length - 1, false, 1, false, zui_align_t.LEFT, false)); if (base_res_handle.changed) { - UIMenu.keep_open = true; + ui_menu_keep_open = true; } if (res_handle_changed_last && !base_res_handle.changed) { base_on_layers_resized(); @@ -846,8 +846,8 @@ class TabLayers { zui_draw_string(tr("Res"), null, 0, zui_align_t.RIGHT); zui_end_element(); - UIMenu.menu_fill(ui); - UIMenu.menu_align(ui); + ui_menu_fill(ui); + ui_menu_align(ui); ///if (krom_android || krom_ios) zui_inline_radio(base_bits_handle, ["8bit"]); ///else @@ -855,13 +855,13 @@ class TabLayers { ///end if (base_bits_handle.changed) { app_notify_on_init(base_set_layer_bits); - UIMenu.keep_open = true; + ui_menu_keep_open = true; } } if (l.fill_layer != null) { - UIMenu.menu_fill(ui); - UIMenu.menu_align(ui); + ui_menu_fill(ui); + ui_menu_align(ui); let scale_handle: zui_handle_t = zui_nest(zui_handle("tablayers_6"), l.id); scale_handle.value = l.scale; l.scale = zui_slider(scale_handle, tr("UV Scale"), 0.0, 5.0, true); @@ -872,11 +872,11 @@ class TabLayers { base_update_fill_layers(); } app_notify_on_init(_init); - UIMenu.keep_open = true; + ui_menu_keep_open = true; } - UIMenu.menu_fill(ui); - UIMenu.menu_align(ui); + ui_menu_fill(ui); + ui_menu_align(ui); let angle_handle: zui_handle_t = zui_nest(zui_handle("tablayers_7"), l.id); angle_handle.value = l.angle; l.angle = zui_slider(angle_handle, tr("Angle"), 0.0, 360, true, 1); @@ -888,11 +888,11 @@ class TabLayers { base_update_fill_layers(); } app_notify_on_init(_init); - UIMenu.keep_open = true; + ui_menu_keep_open = true; } - UIMenu.menu_fill(ui); - UIMenu.menu_align(ui); + ui_menu_fill(ui); + ui_menu_align(ui); let uv_type_handle: zui_handle_t = zui_nest(zui_handle("tablayers_8"), l.id); uv_type_handle.position = l.uv_type; l.uv_type = zui_inline_radio(uv_type_handle, [tr("UV Map"), tr("Triplanar"), tr("Project")], zui_align_t.LEFT); @@ -904,7 +904,7 @@ class TabLayers { base_update_fill_layers(); } app_notify_on_init(_init); - UIMenu.keep_open = true; + ui_menu_keep_open = true; } } @@ -931,27 +931,27 @@ class TabLayers { height_blend_handle.selected = l.paint_height_blend; emis_handle.selected = l.paint_emis; subs_handle.selected = l.paint_subs; - UIMenu.menu_fill(ui); + ui_menu_fill(ui); l.paint_base = zui_check(base_handle, tr("Base Color")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); l.paint_opac = zui_check(opac_handle, tr("Opacity")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); l.paint_nor = zui_check(nor_handle, tr("Normal")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); l.paint_nor_blend = zui_check(nor_blend_handle, tr("Normal Blending")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); l.paint_occ = zui_check(occ_handle, tr("Occlusion")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); l.paint_rough = zui_check(rough_handle, tr("Roughness")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); l.paint_met = zui_check(met_handle, tr("Metallic")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); l.paint_height = zui_check(height_handle, tr("Height")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); l.paint_height_blend = zui_check(height_blend_handle, tr("Height Blending")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); l.paint_emis = zui_check(emis_handle, tr("Emission")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); l.paint_subs = zui_check(subs_handle, tr("Subsurface")); if (base_handle.changed || opac_handle.changed || @@ -965,7 +965,7 @@ class TabLayers { emis_handle.changed || subs_handle.changed) { MakeMaterial.parse_mesh_material(); - UIMenu.keep_open = true; + ui_menu_keep_open = true; } } }, menu_elements); @@ -974,15 +974,15 @@ class TabLayers { static make_mask_preview_rgba32 = (l: SlotLayerRaw) => { ///if is_paint if (context_raw.mask_preview_rgba32 == null) { - context_raw.mask_preview_rgba32 = image_create_render_target(UtilRender.layer_preview_size, UtilRender.layer_preview_size); + context_raw.mask_preview_rgba32 = image_create_render_target(util_render_layer_preview_size, util_render_layer_preview_size); } // Convert from R8 to RGBA32 for tooltip display if (context_raw.mask_preview_last != l) { context_raw.mask_preview_last = l; app_notify_on_init(() => { g2_begin(context_raw.mask_preview_rgba32); - g2_set_pipeline(UIView2D.pipe); - g4_set_int(UIView2D.channel_location, 1); + g2_set_pipeline(ui_view2d_pipe); + g4_set_int(ui_view2d_channel_loc, 1); g2_draw_image(l.texpaint_preview, 0, 0); g2_end(); g2_set_pipeline(null); diff --git a/armorpaint/Sources/nodes/BrushOutputNode.ts b/armorpaint/Sources/nodes/BrushOutputNode.ts index 278c9086..19443efc 100644 --- a/armorpaint/Sources/nodes/BrushOutputNode.ts +++ b/armorpaint/Sources/nodes/BrushOutputNode.ts @@ -81,7 +81,7 @@ class BrushOutputNode extends LogicNode { let right: f32 = 1.0; if (context_raw.paint2d) { left = 1.0; - right = (context_raw.split_view ? 2.0 : 1.0) + UIView2D.ww / base_w(); + right = (context_raw.split_view ? 2.0 : 1.0) + ui_view2d_ww / base_w(); } // First time init @@ -104,7 +104,7 @@ class BrushOutputNode extends LogicNode { !fill_layer && !group_layer && (SlotLayer.is_visible(context_raw.layer) || context_raw.paint2d) && - !UIBase.ui.is_hovered && + !ui_base_ui.is_hovered && !base_is_dragging && !base_is_resizing && !base_is_scrolling() && @@ -114,7 +114,7 @@ class BrushOutputNode extends LogicNode { let down: bool = mouse_down() || pen_down(); if (down && context_raw.tool == workspace_tool_t.COLORID && project_assets.length > 0) { context_raw.colorid_picked = true; - UIToolbar.toolbar_handle.redraws = 1; + ui_toolbar_handle.redraws = 1; } // Prevent painting the same spot diff --git a/armorpaint/Sources/nodes/InputNode.ts b/armorpaint/Sources/nodes/InputNode.ts index d2cd6d20..c0ffbca1 100644 --- a/armorpaint/Sources/nodes/InputNode.ts +++ b/armorpaint/Sources/nodes/InputNode.ts @@ -72,8 +72,8 @@ class InputNode extends LogicNode { } if (InputNode.lock_begin) { - let dx: f32 = Math.abs(InputNode.lock_start_x - mouse_view_x()); - let dy: f32 = Math.abs(InputNode.lock_start_y - mouse_view_y()); + let dx: f32 = math_abs(InputNode.lock_start_x - mouse_view_x()); + let dy: f32 = math_abs(InputNode.lock_start_y - mouse_view_y()); if (dx > 1 || dy > 1) { InputNode.lock_begin = false; dx > dy ? InputNode.lock_y = true : InputNode.lock_x = true; diff --git a/armorsculpt/Assets/Scene.arm b/armorsculpt/Assets/Scene.arm index 99400c8c..f98eb448 100644 Binary files a/armorsculpt/Assets/Scene.arm and b/armorsculpt/Assets/Scene.arm differ diff --git a/armorsculpt/Sources/ExportObj.ts b/armorsculpt/Sources/ExportObj.ts index ddfda271..e92b50d9 100644 --- a/armorsculpt/Sources/ExportObj.ts +++ b/armorsculpt/Sources/ExportObj.ts @@ -20,9 +20,9 @@ class ExportObj { let posa = new Int16Array(inda.length * 4); for (let i = 0; i < inda.length; ++i) { let index = inda[i]; - posa[index * 4 ] = Math.floor(pixelsView.getFloat32(i * 16 , true) * 32767); - posa[index * 4 + 1] = Math.floor(pixelsView.getFloat32(i * 16 + 4, true) * 32767); - posa[index * 4 + 2] = Math.floor(pixelsView.getFloat32(i * 16 + 8, true) * 32767); + posa[index * 4 ] = math_floor(pixelsView.getFloat32(i * 16 , true) * 32767); + posa[index * 4 + 1] = math_floor(pixelsView.getFloat32(i * 16 + 4, true) * 32767); + posa[index * 4 + 2] = math_floor(pixelsView.getFloat32(i * 16 + 8, true) * 32767); } let poff = 0; @@ -32,12 +32,12 @@ class ExportObj { let inv = 1 / 32767; let sc = p.data.scale_pos * inv; // let posa = mesh.vertex_arrays[0].values; - let len = Math.floor(posa.length / 4); - // let len = Math.floor(inda.length); + let len = math_floor(posa.length / 4); + // let len = math_floor(inda.length); // Merge shared vertices and remap indices let posa2 = new Int16Array(len * 3); - let posmap = new Map(); + let posmap = new map_t(); let pi = 0; for (let i = 0; i < len; ++i) { @@ -75,7 +75,7 @@ class ExportObj { } // let inda = mesh.index_arrays[0].values; - for (let i = 0; i < Math.floor(inda.length / 3); ++i) { + for (let i = 0; i < math_floor(inda.length / 3); ++i) { let pi1 = posmap.get(inda[i * 3 ]) + 1 + poff; let pi2 = posmap.get(inda[i * 3 + 1]) + 1 + poff; let pi3 = posmap.get(inda[i * 3 + 2]) + 1 + poff; diff --git a/armorsculpt/Sources/ImportMesh.ts b/armorsculpt/Sources/ImportMesh.ts index 7c2bedf5..2bc8a010 100644 --- a/armorsculpt/Sources/ImportMesh.ts +++ b/armorsculpt/Sources/ImportMesh.ts @@ -51,7 +51,7 @@ class ImportMesh { // No mask by default for (let p of project_paintObjects) p.base.visible = true; - if (context_raw.mergedObject == null) UtilMesh.mergeMesh(); + if (context_raw.mergedObject == null) util_mesh_mergeMesh(); context_raw.paintObject.skip_context = "paint"; context_raw.mergedObject.base.visible = true; } @@ -62,7 +62,7 @@ class ImportMesh { MakeMaterial.parsePaintMaterial(); MakeMaterial.parseMeshMaterial(); - UIView2D.hwnd.redraws = 2; + ui_view2d_hwnd.redraws = 2; ///if arm_physics context_raw.paintBody = null; @@ -112,15 +112,15 @@ class ImportMesh { data_cached_meshes.set(md._.handle, md); context_raw.ddirty = 4; - UIBase.hwnds[TabArea.TabSidebar0].redraws = 2; - UIBase.hwnds[TabArea.TabSidebar1].redraws = 2; + ui_base_hwnds[TabArea.TabSidebar0].redraws = 2; + ui_base_hwnds[TabArea.TabSidebar1].redraws = 2; // Wait for addMesh calls to finish app_notify_on_init(ImportMesh.finishImport); base_notifyOnNextFrame(() => { let f32 = new Float32Array(config_getTextureResX() * config_getTextureResY() * 4); - for (let i = 0; i < Math.floor(mesh.inda.length); ++i) { + for (let i = 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; @@ -167,14 +167,14 @@ class ImportMesh { data_cached_meshes.set(md._.handle, md); context_raw.ddirty = 4; - UIBase.hwnds[TabArea.TabSidebar0].redraws = 2; + ui_base_hwnds[TabArea.TabSidebar0].redraws = 2; } _addMesh(); } static rawMesh = (mesh: any): mesh_data_t => { - let posa = new Int16Array(Math.floor(mesh.inda.length * 4)); + let posa = new Int16Array(math_floor(mesh.inda.length * 4)); for (let i = 0; i < posa.length; ++i) posa[i] = 32767; let inda = new Uint32Array(mesh.inda.length); for (let i = 0; i < inda.length; ++i) inda[i] = i; diff --git a/armorsculpt/Sources/MakeMaterial.ts b/armorsculpt/Sources/MakeMaterial.ts index ee895934..2ba91544 100644 --- a/armorsculpt/Sources/MakeMaterial.ts +++ b/armorsculpt/Sources/MakeMaterial.ts @@ -9,7 +9,7 @@ class MakeMaterial { static subsUsed = false; static getMOut = (): bool => { - for (let n of UINodes.getCanvasMaterial().nodes) if (n.type == "OUTPUT_MATERIAL_PBR") return true; + for (let n of ui_nodes_getCanvasMaterial().nodes) if (n.type == "OUTPUT_MATERIAL_PBR") return true; return false; } @@ -174,9 +174,10 @@ class MakeMaterial { if (bakePreviews) { let current = _g2_current; - if (current != null) g2_end(); + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); MakeMaterial.bakeNodePreviews(); - if (current != null) g2_begin(current); + if (g2_in_use) g2_begin(current); } let m = project_materials[0].data; @@ -198,7 +199,7 @@ class MakeMaterial { } } - let sdata: TMaterial = { name: "Material", canvas: UINodes.getCanvasMaterial() }; + let sdata: TMaterial = { name: "Material", canvas: ui_nodes_getCanvasMaterial() }; let mcon2: material_context_t = { name: "paint", bind_textures: [] }; let con = MakeSculpt.run(sdata, mcon2); @@ -224,8 +225,8 @@ class MakeMaterial { static bakeNodePreviews = () => { context_raw.nodePreviewsUsed = []; - if (context_raw.nodePreviews == null) context_raw.nodePreviews = new Map(); - MakeMaterial.traverseNodes(UINodes.getCanvasMaterial().nodes, null, []); + if (context_raw.nodePreviews == null) context_raw.nodePreviews = map_create(); + MakeMaterial.traverseNodes(ui_nodes_getCanvasMaterial().nodes, null, []); for (let key of context_raw.nodePreviews.keys()) { if (context_raw.nodePreviewsUsed.indexOf(key) == -1) { let image = context_raw.nodePreviews.get(key); @@ -256,8 +257,8 @@ class MakeMaterial { let id = ParserMaterial.node_name(node, parents); let image = context_raw.nodePreviews.get(id); context_raw.nodePreviewsUsed.push(id); - let resX = Math.floor(config_getTextureResX() / 4); - let resY = Math.floor(config_getTextureResY() / 4); + let resX = math_floor(config_getTextureResX() / 4); + let resY = math_floor(config_getTextureResY() / 4); if (image == null || image.width != resX || image.height != resY) { if (image != null) image_unload(image); image = image_create_render_target(resX, resY); @@ -265,15 +266,15 @@ class MakeMaterial { } ParserMaterial.blur_passthrough = true; - UtilRender.makeNodePreview(UINodes.getCanvasMaterial(), node, image, group, parents); + UtilRender.makeNodePreview(ui_nodes_getCanvasMaterial(), node, image, group, parents); ParserMaterial.blur_passthrough = false; } else if (node.type == "DIRECT_WARP") { let id = ParserMaterial.node_name(node, parents); let image = context_raw.nodePreviews.get(id); context_raw.nodePreviewsUsed.push(id); - let resX = Math.floor(config_getTextureResX()); - let resY = Math.floor(config_getTextureResY()); + let resX = math_floor(config_getTextureResX()); + let resY = math_floor(config_getTextureResY()); if (image == null || image.width != resX || image.height != resY) { if (image != null) image_unload(image); image = image_create_render_target(resX, resY); @@ -281,14 +282,14 @@ class MakeMaterial { } ParserMaterial.warp_passthrough = true; - UtilRender.makeNodePreview(UINodes.getCanvasMaterial(), node, image, group, parents); + UtilRender.makeNodePreview(ui_nodes_getCanvasMaterial(), node, image, group, parents); ParserMaterial.warp_passthrough = false; } } static parseNodePreviewMaterial = (node: zui_node_t, group: zui_node_canvas_t = null, parents: zui_node_t[] = null): { scon: shader_context_t, mcon: material_context_t } => { if (node.outputs.length == 0) return null; - let sdata: TMaterial = { name: "Material", canvas: UINodes.getCanvasMaterial() }; + let sdata: TMaterial = { name: "Material", canvas: ui_nodes_getCanvasMaterial() }; let mcon_raw: material_context_t = { name: "mesh", bind_textures: [] }; let con = MakeNodePreview.run(sdata, mcon_raw, node, group, parents); let compileError = false; diff --git a/armorsculpt/Sources/MakeMesh.ts b/armorsculpt/Sources/MakeMesh.ts index b4988c1c..49c92d37 100644 --- a/armorsculpt/Sources/MakeMesh.ts +++ b/armorsculpt/Sources/MakeMesh.ts @@ -53,9 +53,9 @@ class MakeMesh { NodeShader.write_attrib(vert, 'wnormal = mul(meshnor, N);'); NodeShader.write_attrib(frag, 'vec3 n = normalize(wnormal);'); - NodeShader.add_function(frag, ShaderFunctions.str_packFloatInt16); - NodeShader.add_function(frag, ShaderFunctions.str_octahedronWrap); - NodeShader.add_function(frag, ShaderFunctions.str_cotangentFrame); + NodeShader.add_function(frag, str_packFloatInt16); + NodeShader.add_function(frag, str_octahedronWrap); + NodeShader.add_function(frag, str_cotangentFrame); if (layerPass > 0) { NodeShader.add_uniform(frag, 'sampler2D gbuffer0'); NodeShader.add_uniform(frag, 'sampler2D gbuffer1'); @@ -255,13 +255,13 @@ class MakeMesh { NodeShader.add_uniform(frag, 'vec4 envmapData', '_envmapData'); // angle, sin(angle), cos(angle), strength NodeShader.write(frag, 'vec3 wreflect = reflect(-vVec, n);'); NodeShader.write(frag, 'float envlod = roughness * float(envmapNumMipmaps);'); - NodeShader.add_function(frag, ShaderFunctions.str_envMapEquirect); + NodeShader.add_function(frag, str_envMapEquirect); NodeShader.write(frag, 'vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(wreflect, envmapData.x), envlod).rgb;'); NodeShader.add_uniform(frag, 'vec3 lightArea0', '_light_area0'); NodeShader.add_uniform(frag, 'vec3 lightArea1', '_light_area1'); NodeShader.add_uniform(frag, 'vec3 lightArea2', '_light_area2'); NodeShader.add_uniform(frag, 'vec3 lightArea3', '_light_area3'); - NodeShader.add_function(frag, ShaderFunctions.str_ltcEvaluate); + NodeShader.add_function(frag, str_ltcEvaluate); NodeShader.add_uniform(frag, 'vec3 lightPos', '_point_pos'); NodeShader.add_uniform(frag, 'vec3 lightColor', '_point_color'); NodeShader.write(frag, 'float ldist = distance(wposition, lightPos);'); @@ -281,7 +281,7 @@ class MakeMesh { NodeShader.write(frag, 'direct *= lightColor * (1.0 / (ldist * ldist));'); NodeShader.add_uniform(frag, 'vec4 shirr[7]', '_envmap_irradiance'); - NodeShader.add_function(frag, ShaderFunctions.str_shIrradiance); + NodeShader.add_function(frag, str_shIrradiance); NodeShader.write(frag, 'vec3 indirect = albedo * (shIrradiance(vec3(n.x * envmapData.z - n.y * envmapData.y, n.x * envmapData.y + n.y * envmapData.z, n.z), shirr) / 3.14159265);'); NodeShader.write(frag, 'indirect += prefilteredColor * (f0 * envBRDF.x + envBRDF.y) * 1.5;'); NodeShader.write(frag, 'indirect *= envmapData.w * occlusion;'); diff --git a/armorsculpt/Sources/MakeMeshPreview.ts b/armorsculpt/Sources/MakeMeshPreview.ts index 84be232f..4590e2f3 100644 --- a/armorsculpt/Sources/MakeMeshPreview.ts +++ b/armorsculpt/Sources/MakeMeshPreview.ts @@ -26,7 +26,7 @@ class MakeMeshPreview { pos = "spos"; NodeShadercontext_add_elem(con_mesh, "bone", 'short4norm'); NodeShadercontext_add_elem(con_mesh, "weight", 'short4norm'); - NodeShader.add_function(vert, ShaderFunctions.str_getSkinningDualQuat); + NodeShader.add_function(vert, str_getSkinningDualQuat); NodeShader.add_uniform(vert, 'vec4 skinBones[128 * 2]', '_skin_bones'); NodeShader.add_uniform(vert, 'float posUnpack', '_pos_unpack'); NodeShader.write_attrib(vert, 'vec4 skinA;'); @@ -52,7 +52,7 @@ class MakeMeshPreview { ParserMaterial.sample_uv_scale = brushScale; ParserMaterial.parse_height = MakeMaterial.heightUsed; ParserMaterial.parse_height_as_channel = true; - // let sout = ParserMaterial.parse(UINodes.getCanvasMaterial(), con_mesh, vert, frag, matcon); + // let sout = ParserMaterial.parse(ui_nodes_getCanvasMaterial(), con_mesh, vert, frag, matcon); ParserMaterial.parse_height = false; ParserMaterial.parse_height_as_channel = false; ParserMaterial.sample_keep_aspect = false; @@ -95,9 +95,9 @@ class MakeMeshPreview { NodeShader.add_out(frag, 'vec4 fragColor[3]'); frag.n = true; - NodeShader.add_function(frag, ShaderFunctions.str_packFloatInt16); - NodeShader.add_function(frag, ShaderFunctions.str_cotangentFrame); - NodeShader.add_function(frag, ShaderFunctions.str_octahedronWrap); + NodeShader.add_function(frag, str_packFloatInt16); + NodeShader.add_function(frag, str_cotangentFrame); + NodeShader.add_function(frag, str_octahedronWrap); if (MakeMaterial.heightUsed) { NodeShader.write(frag, 'if (height > 0.0) {'); diff --git a/armorsculpt/Sources/MakeSculpt.ts b/armorsculpt/Sources/MakeSculpt.ts index 544aa346..d7a79bca 100644 --- a/armorsculpt/Sources/MakeSculpt.ts +++ b/armorsculpt/Sources/MakeSculpt.ts @@ -69,7 +69,7 @@ class MakeSculpt { NodeShader.write(frag, 'if (sample_undo.r == 0 && sample_undo.g == 0 && sample_undo.b == 0) discard;'); - NodeShader.add_function(frag, ShaderFunctions.str_octahedronWrap); + NodeShader.add_function(frag, str_octahedronWrap); NodeShader.add_uniform(frag, 'sampler2D gbuffer0_undo'); NodeShader.write(frag, 'vec2 g0_undo = textureLod(gbuffer0_undo, inp.xy, 0.0).rg;'); NodeShader.write(frag, 'vec3 wn;'); diff --git a/armorsculpt/Sources/TabLayers.ts b/armorsculpt/Sources/TabLayers.ts index f43d03b8..328abb04 100644 --- a/armorsculpt/Sources/TabLayers.ts +++ b/armorsculpt/Sources/TabLayers.ts @@ -6,16 +6,16 @@ class TabLayers { static showContextMenu = false; static draw = (htab: zui_handle_t) => { - let mini = config_config_raw.layout[layout_size_t.SIDEBAR_W] <= UIBase.sidebar_mini_w; + let mini = config_config_raw.layout[layout_size_t.SIDEBAR_W] <= ui_base_ui_base_sidebar_mini_w; mini ? TabLayers.draw_mini(htab) : TabLayers.draw_full(htab); } static drawMini = (htab: zui_handle_t) => { - let ui = UIBase.ui; + let ui = ui_base_ui_base_ui; zui_set_hovered_tab_name(tr("Layers")); let _ELEMENT_H = ui.t.ELEMENT_H; - ui.t.ELEMENT_H = Math.floor(UIBase.sidebar_mini_w / 2 / zui_SCALE(ui)); + ui.t.ELEMENT_H = math_floor(ui_base_ui_base_sidebar_mini_w / 2 / zui_SCALE(ui)); zui_begin_sticky(); zui_separator(5); @@ -33,7 +33,7 @@ class TabLayers { } static drawFull = (htab: zui_handle_t) => { - let ui = UIBase.ui; + let ui = ui_base_ui_base_ui; if (zui_tab(htab, tr("Layers"))) { zui_begin_sticky(); zui_row([1 / 4, 3 / 4]); @@ -59,10 +59,10 @@ class TabLayers { } static highlightOddLines = () => { - let ui = UIBase.ui; + let ui = ui_base_ui_base_ui; let step = ui.t.ELEMENT_H * 2; - let fullH = ui._window_h - UIBase.hwnds[0].scroll_offset; - for (let i = 0; i < Math.floor(fullH / step); ++i) { + let fullH = ui._window_h - ui_base_ui_base_hwnds[0].scroll_offset; + for (let i = 0; i < math_floor(fullH / step); ++i) { if (i % 2 == 0) { zui_fill(0, i * step, (ui._w / zui_SCALE(ui) - 2), step, ui.t.WINDOW_BG_COL - 0x00040404); } @@ -70,11 +70,11 @@ class TabLayers { } static buttonNew = (text: string) => { - let ui = UIBase.ui; + let ui = ui_base_ui_base_ui; if (zui_button(text)) { - UIMenu.draw((ui: zui_t) => { + ui_menu_draw((ui: zui_t) => { let l = context_context_raw.layer; - if (UIMenu.menu_button(ui, tr("Paint Layer"))) { + if (ui_menu_button(ui, tr("Paint Layer"))) { base_base_new_layer(); history_new_layer(); } @@ -83,14 +83,14 @@ class TabLayers { } static comboFilter = () => { - let ui = UIBase.ui; + let ui = ui_base_ui_base_ui; let ar = [tr("All")]; let filterHandle = zui_handle("tablayers_0"); filterHandle.position = context_context_raw.layer_filter; context_context_raw.layer_filter = zui_combo(filterHandle, ar, tr("Filter"), false, zui_align_t.LEFT); } - static remapLayerPointers = (nodes: zui_node_t[], pointerMap: Map) => { + static remapLayerPointers = (nodes: zui_node_t[], pointerMap: map_t) => { for (let n of nodes) { if (n.type == "LAYER" || n.type == "LAYER_MASK") { let i = n.buttons[0].default_value; @@ -101,14 +101,14 @@ class TabLayers { } } - static initLayerMap = (): Map => { - let res: Map = new Map(); + static initLayerMap = (): map_t => { + let res: map_t = map_create(); for (let i = 0; i < project_project_layers.length; ++i) res.set(project_project_layers[i], i); return res; } - static fillLayerMap = (map: Map): Map => { - let res: Map = new Map(); + static fillLayerMap = (map: map_t): map_t => { + let res: map_t = map_create(); for (let l of map.keys()) res.set(map.get(l), project_project_layers.indexOf(l) > -1 ? project_project_layers.indexOf(l) : 9999); return res; } @@ -121,7 +121,7 @@ class TabLayers { } static drawLayerSlot = (l: SlotLayerRaw, i: i32, mini: bool) => { - let ui = UIBase.ui; + let ui = ui_base_ui_base_ui; if (context_context_raw.layer_filter > 0 && SlotLayer.get_object_mask(l) > 0 && @@ -186,7 +186,7 @@ class TabLayers { } static drawLayerSlotMini = (l: SlotLayerRaw, i: i32) => { - let ui = UIBase.ui; + let ui = ui_base_ui_base_ui; zui_row([1, 1]); let uix = ui._x; @@ -199,7 +199,7 @@ class TabLayers { } static drawLayerSlotFull = (l: SlotLayerRaw, i: i32) => { - let ui = UIBase.ui; + let ui = ui_base_ui_base_ui; let step = ui.t.ELEMENT_H; @@ -345,12 +345,12 @@ class TabLayers { static layerToggleVisible = (l: SlotLayerRaw) => { l.visible = !l.visible; - UIView2D.hwnd.redraws = 2; + ui_view2d_ui_view2d_hwnd.redraws = 2; MakeMaterial.parse_mesh_material(); } static drawLayerHighlight = (l: SlotLayerRaw, mini: bool) => { - let ui = UIBase.ui; + let ui = ui_base_ui_base_ui; let step = ui.t.ELEMENT_H; // Separator line diff --git a/armorsculpt/Sources/nodes/BrushOutputNode.ts b/armorsculpt/Sources/nodes/BrushOutputNode.ts index b0c5ca34..f1e4c873 100644 --- a/armorsculpt/Sources/nodes/BrushOutputNode.ts +++ b/armorsculpt/Sources/nodes/BrushOutputNode.ts @@ -75,7 +75,7 @@ class BrushOutputNode extends LogicNode { let right = 1.0; if (context_raw.paint2d) { left = 1.0; - right = (context_raw.splitView ? 2.0 : 1.0) + UIView2D.ww / base_w(); + right = (context_raw.splitView ? 2.0 : 1.0) + ui_view2d_ww / base_w(); } // First time init @@ -98,7 +98,7 @@ class BrushOutputNode extends LogicNode { !fillLayer && !groupLayer && (SlotLayer.isVisible(context_raw.layer) || context_raw.paint2d) && - !UIBase.ui.is_hovered && + !ui_base_ui.is_hovered && !base_isDragging && !base_isResizing && !base_isScrolling() && diff --git a/base/Sources/BoxExport.ts b/base/Sources/BoxExport.ts index 7ff3ccbd..2b99be4e 100644 --- a/base/Sources/BoxExport.ts +++ b/base/Sources/BoxExport.ts @@ -14,7 +14,7 @@ class BoxExport { ///if (is_paint || is_lab) static show_textures = () => { - UIBox.show_custom((ui: zui_t) => { + ui_box_show_custom((ui: zui_t) => { if (BoxExport.files == null) { BoxExport.fetch_presets(); @@ -41,7 +41,7 @@ class BoxExport { ///if is_paint static show_bake_material = () => { - UIBox.show_custom((ui: zui_t) => { + ui_box_show_custom((ui: zui_t) => { if (BoxExport.files == null) { BoxExport.fetch_presets(); @@ -130,10 +130,10 @@ class BoxExport { zui_row([0.5, 0.5]); if (zui_button(tr("Cancel"))) { - UIBox.hide(); + ui_box_hide(); } if (zui_button(tr("Export"))) { - UIBox.hide(); + ui_box_hide(); if (context_raw.layers_destination == export_destination_t.PACKED) { context_raw.texture_export_path = "/"; let _init = () => { @@ -148,7 +148,7 @@ class BoxExport { } else { let filters = base_bits_handle.position != texture_bits_t.BITS8 ? "exr" : context_raw.format_type == texture_ldr_format_t.PNG ? "png" : "jpg"; - UIFiles.show(filters, true, false, (path: string) => { + ui_files_show(filters, true, false, (path: string) => { context_raw.texture_export_path = path; let doExport = () => { let _init = () => { @@ -185,7 +185,7 @@ class BoxExport { if (BoxExport.hpreset.changed) BoxExport.preset = null; if (zui_button(tr("New"))) { - UIBox.show_custom((ui: zui_t) => { + ui_box_show_custom((ui: zui_t) => { let tab_vertical: bool = config_raw.touch_ui; if (zui_tab(zui_handle("boxexport_5"), tr("New Preset"), tab_vertical)) { zui_row([0.5, 0.5]); @@ -195,7 +195,7 @@ class BoxExport { BoxExport.fetch_presets(); BoxExport.preset = null; BoxExport.hpreset.position = BoxExport.files.indexOf(preset_name); - UIBox.hide(); + ui_box_hide(); BoxExport.htab.position = 1; // Presets BoxExport.show_textures(); } @@ -204,7 +204,7 @@ class BoxExport { } if (zui_button(tr("Import"))) { - UIFiles.show("json", false, false, (path: string) => { + ui_files_show("json", false, false, (path: string) => { path = path.toLowerCase(); if (path.endsWith(".json")) { let filename: string = path.substr(path.lastIndexOf(path_sep) + 1); @@ -242,8 +242,8 @@ class BoxExport { t.name = zui_text_input(htex); if (ui.is_hovered && ui.input_released_r) { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Delete"))) { + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Delete"))) { array_remove(BoxExport.preset.textures, t); BoxExport.save_preset(); } @@ -313,7 +313,7 @@ class BoxExport { static show_mesh = () => { BoxExport.export_mesh_handle.position = context_raw.export_mesh_index; - UIBox.show_custom((ui: zui_t) => { + ui_box_show_custom((ui: zui_t) => { let htab: zui_handle_t = zui_handle("boxexport_8"); BoxExport.tab_export_mesh(ui, htab); }); @@ -338,22 +338,22 @@ class BoxExport { let paint_objects: mesh_object_t[] = pos == 0 ? project_paint_objects : [project_paint_objects[pos - 1]]; for (let po of paint_objects) { for (let inda of po.data.index_arrays) { - tris += Math.floor(inda.values.length / 3); + tris += math_floor(inda.values.length / 3); } } zui_text(tris + " " + tr("triangles")); zui_row([0.5, 0.5]); if (zui_button(tr("Cancel"))) { - UIBox.hide(); + ui_box_hide(); } if (zui_button(tr("Export"))) { - UIBox.hide(); - UIFiles.show(context_raw.export_mesh_format == mesh_format_t.OBJ ? "obj" : "arm", true, false, (path: string) => { + ui_box_hide(); + ui_files_show(context_raw.export_mesh_format == mesh_format_t.OBJ ? "obj" : "arm", true, false, (path: string) => { ///if (krom_android || krom_ios) let f: string = sys_title(); ///else - let f: string = UIFiles.filename; + let f: string = ui_files_filename; ///end if (f == "") f = tr("untitled"); let doExport = () => { @@ -374,7 +374,7 @@ class BoxExport { ///if (is_paint || is_sculpt) static show_material = () => { - UIBox.show_custom((ui: zui_t) => { + ui_box_show_custom((ui: zui_t) => { let htab: zui_handle_t = zui_handle("boxexport_11"); let tab_vertical: bool = config_raw.touch_ui; if (zui_tab(htab, tr("Export Material"), tab_vertical)) { @@ -386,12 +386,12 @@ class BoxExport { context_raw.write_icon_on_export = zui_check(h2, tr("Export Icon")); zui_row([0.5, 0.5]); if (zui_button(tr("Cancel"))) { - UIBox.hide(); + ui_box_hide(); } if (zui_button(tr("Export"))) { - UIBox.hide(); - UIFiles.show("arm", true, false, (path: string) => { - let f: string = UIFiles.filename; + ui_box_hide(); + ui_files_show("arm", true, false, (path: string) => { + let f: string = ui_files_filename; if (f == "") f = tr("untitled"); app_notify_on_init(() => { ExportArm.run_material(path + path_sep + f); @@ -403,7 +403,7 @@ class BoxExport { } static show_brush = () => { - UIBox.show_custom((ui: zui_t) => { + ui_box_show_custom((ui: zui_t) => { let htab: zui_handle_t = zui_handle("boxexport_14"); let tab_vertical: bool = config_raw.touch_ui; if (zui_tab(htab, tr("Export Brush"), tab_vertical)) { @@ -415,12 +415,12 @@ class BoxExport { context_raw.write_icon_on_export = zui_check(h2, tr("Export Icon")); zui_row([0.5, 0.5]); if (zui_button(tr("Cancel"))) { - UIBox.hide(); + ui_box_hide(); } if (zui_button(tr("Export"))) { - UIBox.hide(); - UIFiles.show("arm", true, false, (path: string) => { - let f: string = UIFiles.filename; + ui_box_hide(); + ui_files_show("arm", true, false, (path: string) => { + let f: string = ui_files_filename; if (f == "") f = tr("untitled"); app_notify_on_init(() => { ExportArm.run_brush(path + path_sep + f); @@ -443,7 +443,7 @@ class BoxExport { static parse_preset = () => { let file: string = "export_presets/" + BoxExport.files[BoxExport.hpreset.position] + ".json"; let blob: ArrayBuffer = data_get_blob(file); - BoxExport.preset = JSON.parse(sys_buffer_to_string(blob)); + BoxExport.preset = json_parse(sys_buffer_to_string(blob)); data_delete_blob("export_presets/" + file); } @@ -464,7 +464,7 @@ class BoxExport { let name: string = BoxExport.files[BoxExport.hpreset.position]; if (name == "generic") return; // generic is const let path: string = path_data() + path_sep + "export_presets" + path_sep + name + ".json"; - krom_file_save_bytes(path, sys_string_to_buffer(JSON.stringify(BoxExport.preset))); + krom_file_save_bytes(path, sys_string_to_buffer(json_stringify(BoxExport.preset))); } ///end } diff --git a/base/Sources/BoxPreferences.ts b/base/Sources/BoxPreferences.ts index 2e09adb5..f8dcfd99 100644 --- a/base/Sources/BoxPreferences.ts +++ b/base/Sources/BoxPreferences.ts @@ -12,7 +12,7 @@ class BoxPreferences { static show = () => { - UIBox.show_custom((ui: zui_t) => { + ui_box_show_custom((ui: zui_t) => { if (zui_tab(BoxPreferences.htab, tr("Interface"), true)) { if (BoxPreferences.locales == null) { @@ -25,7 +25,7 @@ class BoxPreferences { let locale_code: string = BoxPreferences.locales[locale_handle.position]; config_raw.locale = locale_code; translator_load_translations(locale_code); - UIBase.tag_ui_redraw(); + ui_base_tag_ui_redraw(); } let hscale: zui_handle_t = zui_handle("boxpreferences_1", { value: config_raw.window_scale }); @@ -61,7 +61,7 @@ class BoxPreferences { ui.changed = false; config_raw.show_asset_names = zui_check(zui_handle("boxpreferences_8", { selected: config_raw.show_asset_names }), tr("Show Asset Names")); if (ui.changed) { - UIBase.tag_ui_redraw(); + ui_base_tag_ui_redraw(); } ///if !(krom_android || krom_ios) @@ -73,7 +73,7 @@ class BoxPreferences { zui_set_touch_tooltip(config_raw.touch_ui); config_load_theme(config_raw.theme); BoxPreferences.set_scale(); - UIBase.tag_ui_redraw(); + ui_base_tag_ui_redraw(); } ///end @@ -84,9 +84,9 @@ class BoxPreferences { zui_end_element(); zui_row([0.5, 0.5]); - if (zui_button(tr("Restore")) && !UIMenu.show) { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Confirm"))) { + if (zui_button(tr("Restore")) && !ui_menu_show) { + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Confirm"))) { app_notify_on_init(() => { ui.t.ELEMENT_H = base_default_element_h; config_restore(); @@ -98,10 +98,10 @@ class BoxPreferences { MakeMaterial.parse_paint_material(); }); } - if (UIMenu.menu_button(ui, tr("Import..."))) { - UIFiles.show("json", false, false, (path: string) => { + if (ui_menu_button(ui, tr("Import..."))) { + ui_files_show("json", false, false, (path: string) => { let b: ArrayBuffer = data_get_blob(path); - let raw: config_t = JSON.parse(sys_buffer_to_string(b)); + let raw: config_t = json_parse(sys_buffer_to_string(b)); app_notify_on_init(() => { ui.t.ELEMENT_H = base_default_element_h; config_import_from(raw); @@ -113,9 +113,9 @@ class BoxPreferences { } }, 2); } - if (zui_button(tr("Reset Layout")) && !UIMenu.show) { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Confirm"))) { + if (zui_button(tr("Reset Layout")) && !ui_menu_show) { + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Confirm"))) { base_init_layout(); config_save(); } @@ -140,19 +140,19 @@ class BoxPreferences { } if (zui_button(tr("New"))) { - UIBox.show_custom((ui: zui_t) => { + ui_box_show_custom((ui: zui_t) => { if (zui_tab(zui_handle("boxpreferences_13"), tr("New Theme"))) { zui_row([0.5, 0.5]); let theme_name: string = zui_text_input(zui_handle("boxpreferences_14", { text: "new_theme" }), tr("Name")); if (zui_button(tr("OK")) || ui.is_return_down) { - let template: string = JSON.stringify(base_theme); + let template: string = json_stringify(base_theme); if (!theme_name.endsWith(".json")) theme_name += ".json"; let path: string = path_data() + path_sep + "themes" + path_sep + theme_name; krom_file_save_bytes(path, sys_string_to_buffer(template)); BoxPreferences.fetch_themes(); // Refresh file list config_raw.theme = theme_name; BoxPreferences.theme_handle.position = BoxPreferences.get_theme_index(); - UIBox.hide(); + ui_box_hide(); BoxPreferences.htab.position = 1; // Themes BoxPreferences.show(); } @@ -161,16 +161,16 @@ class BoxPreferences { } if (zui_button(tr("Import"))) { - UIFiles.show("json", false, false, (path: string) => { + ui_files_show("json", false, false, (path: string) => { ImportTheme.run(path); }); } if (zui_button(tr("Export"))) { - UIFiles.show("json", true, false, (path: string) => { - path += path_sep + UIFiles.filename; + ui_files_show("json", true, false, (path: string) => { + path += path_sep + ui_files_filename; if (!path.endsWith(".json")) path += ".json"; - krom_file_save_bytes(path, sys_string_to_buffer(JSON.stringify(base_theme))); + krom_file_save_bytes(path, sys_string_to_buffer(json_stringify(base_theme))); }); } @@ -185,10 +185,10 @@ class BoxPreferences { zui_row([1 / 8, 7 / 8]); zui_text("", 0, h.color); if (ui.is_hovered && ui.input_released) { - UIMenu.draw((ui) => { + ui_menu_draw((ui) => { ui.changed = false; zui_color_wheel(h, false, null, 11 * ui.t.ELEMENT_H * zui_SCALE(ui), true); - if (ui.changed) UIMenu.keep_open = true; + if (ui.changed) ui_menu_keep_open = true; }, 11); } let val: i32 = h.color; @@ -226,11 +226,11 @@ class BoxPreferences { zui_text("", 0, val); if (ui.is_hovered && ui.input_released) { h.color = theme[key]; - UIMenu.draw((ui) => { + ui_menu_draw((ui) => { ui.changed = false; let color: i32 = zui_color_wheel(h, false, null, 11 * ui.t.ELEMENT_H * zui_SCALE(ui), true); theme[key] = color; - if (ui.changed) UIMenu.keep_open = true; + if (ui.changed) ui_menu_keep_open = true; }, 11); } } @@ -265,9 +265,9 @@ class BoxPreferences { if (zui_tab(BoxPreferences.htab, tr("Usage"), true)) { context_raw.undo_handle = zui_handle("boxpreferences_16", { value: config_raw.undo_steps }); - config_raw.undo_steps = Math.floor(zui_slider(context_raw.undo_handle, tr("Undo Steps"), 1, 64, false, 1)); + config_raw.undo_steps = math_floor(zui_slider(context_raw.undo_handle, tr("Undo Steps"), 1, 64, false, 1)); if (config_raw.undo_steps < 1) { - config_raw.undo_steps = Math.floor(context_raw.undo_handle.value = 1); + config_raw.undo_steps = math_floor(context_raw.undo_handle.value = 1); } if (context_raw.undo_handle.changed) { let current: image_t = _g2_current; @@ -289,7 +289,7 @@ class BoxPreferences { } ///if is_paint - config_raw.dilate_radius = Math.floor(zui_slider(zui_handle("boxpreferences_17", { value: config_raw.dilate_radius }), tr("Dilate Radius"), 0.0, 16.0, true, 1)); + config_raw.dilate_radius = math_floor(zui_slider(zui_handle("boxpreferences_17", { value: config_raw.dilate_radius }), tr("Dilate Radius"), 0.0, 16.0, true, 1)); if (ui.is_hovered) zui_tooltip(tr("Dilate painted textures to prevent seams")); let dilate_handle: zui_handle_t = zui_handle("boxpreferences_18", { position: config_raw.dilate }); @@ -474,8 +474,8 @@ class BoxPreferences { let cam_raw: camera_data_t = cam.data; let near_handle: zui_handle_t = zui_handle("boxpreferences_47"); let far_handle: zui_handle_t = zui_handle("boxpreferences_48"); - near_handle.value = Math.floor(cam_raw.near_plane * 1000) / 1000; - far_handle.value = Math.floor(cam_raw.far_plane * 100) / 100; + near_handle.value = math_floor(cam_raw.near_plane * 1000) / 1000; + far_handle.value = math_floor(cam_raw.far_plane * 100) / 100; cam_raw.near_plane = zui_slider(near_handle, tr("Clip Start"), 0.001, 1.0, true); cam_raw.far_plane = zui_slider(far_handle, tr("Clip End"), 50.0, 100.0, true); if (near_handle.changed || far_handle.changed) { @@ -507,19 +507,19 @@ class BoxPreferences { } if (zui_button(tr("New"))) { - UIBox.show_custom((ui: zui_t) => { + ui_box_show_custom((ui: zui_t) => { if (zui_tab(zui_handle("boxpreferences_51"), tr("New Keymap"))) { zui_row([0.5, 0.5]); let keymap_name: string = zui_text_input(zui_handle("boxpreferences_52", { text: "new_keymap" }), tr("Name")); if (zui_button(tr("OK")) || ui.is_return_down) { - let template: string = JSON.stringify(base_default_keymap); + let template: string = json_stringify(base_default_keymap); if (!keymap_name.endsWith(".json")) keymap_name += ".json"; let path: string = path_data() + path_sep + "keymap_presets" + path_sep + keymap_name; krom_file_save_bytes(path, sys_string_to_buffer(template)); BoxPreferences.fetch_keymaps(); // Refresh file list config_raw.keymap = keymap_name; BoxPreferences.preset_handle.position = BoxPreferences.get_preset_index(); - UIBox.hide(); + ui_box_hide(); BoxPreferences.htab.position = 5; // Keymap BoxPreferences.show(); } @@ -528,15 +528,15 @@ class BoxPreferences { } if (zui_button(tr("Import"))) { - UIFiles.show("json", false, false, (path: string) => { + ui_files_show("json", false, false, (path: string) => { ImportKeymap.run(path); }); } if (zui_button(tr("Export"))) { - UIFiles.show("json", true, false, (dest: string) => { - if (!UIFiles.filename.endsWith(".json")) UIFiles.filename += ".json"; + ui_files_show("json", true, false, (dest: string) => { + if (!ui_files_filename.endsWith(".json")) ui_files_filename += ".json"; let path: string = path_data() + path_sep + "keymap_presets" + path_sep + config_raw.keymap; - file_copy(path, dest + path_sep + UIFiles.filename); + file_copy(path, dest + path_sep + ui_files_filename); }); } @@ -561,7 +561,7 @@ class BoxPreferences { zui_begin_sticky(); zui_row([1 / 4, 1 / 4]); if (zui_button(tr("New"))) { - UIBox.show_custom((ui: zui_t) => { + ui_box_show_custom((ui: zui_t) => { if (zui_tab(zui_handle("boxpreferences_54"), tr("New Plugin"))) { zui_row([0.5, 0.5]); let plugin_name: string = zui_text_input(zui_handle("boxpreferences_55", { text: "new_plugin" }), tr("Name")); @@ -581,7 +581,7 @@ plugin.drawUI = (ui) { => let path: string = path_data() + path_sep + "plugins" + path_sep + plugin_name; krom_file_save_bytes(path, sys_string_to_buffer(template)); BoxPreferences.files_plugin = null; // Refresh file list - UIBox.hide(); + ui_box_hide(); BoxPreferences.htab.position = 6; // Plugins BoxPreferences.show(); } @@ -589,7 +589,7 @@ plugin.drawUI = (ui) { => }); } if (zui_button(tr("Import"))) { - UIFiles.show("js,zip", false, false, (path: string) => { + ui_files_show("js,zip", false, false, (path: string) => { ImportPlugin.run(path); }); } @@ -613,24 +613,24 @@ plugin.drawUI = (ui) { => base_redraw_ui(); } if (ui.is_hovered && ui.input_released_r) { - UIMenu.draw((ui: zui_t) => { + ui_menu_draw((ui: zui_t) => { let path: string = path_data() + path_sep + "plugins" + path_sep + f; - if (UIMenu.menu_button(ui, tr("Edit in Text Editor"))) { + if (ui_menu_button(ui, tr("Edit in Text Editor"))) { file_start(path); } - if (UIMenu.menu_button(ui, tr("Edit in Script Tab"))) { + if (ui_menu_button(ui, tr("Edit in Script Tab"))) { let blob: ArrayBuffer = data_get_blob("plugins/" + f); TabScript.hscript.text = sys_buffer_to_string(blob); data_delete_blob("plugins/" + f); console_info(tr("Script opened")); } - if (UIMenu.menu_button(ui, tr("Export"))) { - UIFiles.show("js", true, false, (dest: string) => { - if (!UIFiles.filename.endsWith(".js")) UIFiles.filename += ".js"; - file_copy(path, dest + path_sep + UIFiles.filename); + if (ui_menu_button(ui, tr("Export"))) { + ui_files_show("js", true, false, (dest: string) => { + if (!ui_files_filename.endsWith(".js")) ui_files_filename += ".js"; + file_copy(path, dest + path_sep + ui_files_filename); }); } - if (UIMenu.menu_button(ui, tr("Delete"))) { + if (ui_menu_button(ui, tr("Delete"))) { if (config_raw.plugins.indexOf(f) >= 0) { array_remove(config_raw.plugins, f); plugin_stop(f); @@ -674,19 +674,19 @@ plugin.drawUI = (ui) { => static set_scale = () => { let scale: f32 = config_raw.window_scale; - zui_set_scale(UIBase.ui, scale); - UIHeader.headerh = Math.floor(UIHeader.default_header_h * scale); - config_raw.layout[layout_size_t.STATUS_H] = Math.floor(UIStatus.default_status_h * scale); - UIMenubar.menubarw = Math.floor(UIMenubar.default_menubar_w * scale); - UIBase.set_icon_scale(); - zui_set_scale(UINodes.ui, scale); - zui_set_scale(UIView2D.ui, scale); + zui_set_scale(ui_base_ui, scale); + ui_header_h = math_floor(ui_header_default_h * scale); + config_raw.layout[layout_size_t.STATUS_H] = math_floor(ui_status_default_status_h * scale); + ui_menubar_w = math_floor(ui_menubar_default_w * scale); + ui_base_set_icon_scale(); + zui_set_scale(ui_nodes_ui, scale); + zui_set_scale(ui_view2d_ui, scale); zui_set_scale(base_ui_box, scale); zui_set_scale(base_ui_menu, scale); base_resize(); ///if (is_paint || is_sculpt) - config_raw.layout[layout_size_t.SIDEBAR_W] = Math.floor(UIBase.default_sidebar_w * scale); - UIToolbar.toolbar_w = Math.floor(UIToolbar.default_toolbar_w * scale); + config_raw.layout[layout_size_t.SIDEBAR_W] = math_floor(ui_base_default_sidebar_w * scale); + ui_toolbar_w = math_floor(ui_toolbar_default_w * scale); ///end } } diff --git a/base/Sources/BoxProjects.ts b/base/Sources/BoxProjects.ts index 227d141e..6f61d771 100644 --- a/base/Sources/BoxProjects.ts +++ b/base/Sources/BoxProjects.ts @@ -3,7 +3,7 @@ class BoxProjects { static htab: zui_handle_t = zui_handle_create(); static hsearch: zui_handle_t = zui_handle_create(); - static icon_map: Map = null; + static icon_map: map_t = null; static show = () => { if (BoxProjects.icon_map != null) { @@ -20,7 +20,7 @@ class BoxProjects { draggable = true; ///end - UIBox.show_custom((ui: zui_t) => { + ui_box_show_custom((ui: zui_t) => { ///if (krom_android || krom_ios) BoxProjects.align_to_fullscreen(); ///end @@ -44,7 +44,7 @@ class BoxProjects { if (zui_button(tr("New"))) { project_new(); viewport_scale_to_bounds(); - UIBox.hide(); + ui_box_hide(); // Pick unique name let i: i32 = 0; let j: i32 = 0; @@ -64,12 +64,12 @@ class BoxProjects { zui_end_sticky(); zui_separator(3, false); - let slotw: i32 = Math.floor(150 * zui_SCALE(ui)); - let num: i32 = Math.floor(sys_width() / slotw); + let slotw: i32 = math_floor(150 * zui_SCALE(ui)); + let num: i32 = math_floor(sys_width() / slotw); let recent_projects: string[] = config_raw.recent_projects; let show_asset_names: bool = true; - for (let row: i32 = 0; row < Math.ceil(recent_projects.length / num); ++row) { + for (let row: i32 = 0; row < math_ceil(recent_projects.length / num); ++row) { let mult = show_asset_names ? 2 : 1; let ar: f32[] = []; for (let i: i32 = 0; i < num * mult; ++i) ar.push(1 / num); @@ -80,7 +80,7 @@ class BoxProjects { if (row > 0) ui._y += off; for (let j: i32 = 0; j < num; ++j) { - let imgw: i32 = Math.floor(128 * zui_SCALE(ui)); + let imgw: i32 = math_floor(128 * zui_SCALE(ui)); let i: i32 = j + row * num; if (i >= recent_projects.length) { zui_end_element(imgw); @@ -97,7 +97,7 @@ class BoxProjects { ///end let icon_path: string = path.substr(0, path.length - 4) + "_icon.png"; - if (BoxProjects.icon_map == null) BoxProjects.icon_map = new Map(); + if (BoxProjects.icon_map == null) BoxProjects.icon_map = map_create(); let icon: image_t = BoxProjects.icon_map.get(icon_path); if (icon == null) { let image: image_t = data_get_image(icon_path); @@ -117,7 +117,7 @@ class BoxProjects { ui._x = _uix; let doImport = () => { app_notify_on_init(() => { - UIBox.hide(); + ui_box_hide(); ImportArm.run_project(path); }); } @@ -134,9 +134,9 @@ class BoxProjects { let name: string = path.substring(path.lastIndexOf(path_sep) + 1, path.lastIndexOf(".")); if (ui.is_hovered && ui.input_released_r) { - UIMenu.draw((ui: zui_t) => { - // if (UIMenu.menuButton(ui, tr("Duplicate"))) {} - if (UIMenu.menu_button(ui, tr("Delete"))) { + ui_menu_draw((ui: zui_t) => { + // if (menuButton(ui, tr("Duplicate"))) {} + if (ui_menu_button(ui, tr("Delete"))) { app_notify_on_init(() => { file_delete(path); file_delete(icon_path); @@ -193,12 +193,13 @@ class BoxProjects { if (zui_button(file, zui_align_t.LEFT) && file_exists(path)) { let current: image_t = _g2_current; - if (current != null) g2_end(); + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); ImportArm.run_project(path); - if (current != null) g2_begin(current); - UIBox.hide(); + if (g2_in_use) g2_begin(current); + ui_box_hide(); } if (ui.is_hovered) zui_tooltip(path); } @@ -237,13 +238,13 @@ class BoxProjects { } static align_to_fullscreen = () => { - UIBox.modalw = Math.floor(sys_width() / zui_SCALE(base_ui_box)); - UIBox.modalh = Math.floor(sys_height() / zui_SCALE(base_ui_box)); + ui_box_modalw = math_floor(sys_width() / zui_SCALE(base_ui_box)); + ui_box_modalh = math_floor(sys_height() / zui_SCALE(base_ui_box)); let appw: i32 = sys_width(); let apph: i32 = sys_height(); let mw: i32 = appw; let mh: i32 = apph; - UIBox.hwnd.drag_x = Math.floor(-appw / 2 + mw / 2); - UIBox.hwnd.drag_y = Math.floor(-apph / 2 + mh / 2); + ui_box_hwnd.drag_x = math_floor(-appw / 2 + mw / 2); + ui_box_hwnd.drag_y = math_floor(-apph / 2 + mh / 2); } } diff --git a/base/Sources/ContextFormat.ts b/base/Sources/ContextFormat.ts index de4bac4d..38bf3a22 100644 --- a/base/Sources/ContextFormat.ts +++ b/base/Sources/ContextFormat.ts @@ -127,7 +127,7 @@ class context_t { layers_preview_dirty?: bool = false; node_preview_dirty?: bool = false; node_preview?: image_t = null; - node_previews?: Map = null; + node_previews?: map_t = null; node_previews_used?: string[] = null; node_preview_name?: string = ""; mask_preview_rgba32?: image_t = null; diff --git a/base/Sources/ExportArm.ts b/base/Sources/ExportArm.ts index 26b5113b..8684ac78 100644 --- a/base/Sources/ExportArm.ts +++ b/base/Sources/ExportArm.ts @@ -14,7 +14,7 @@ class ExportArm { ///if (is_paint || is_sculpt) let mnodes: zui_node_canvas_t[] = []; for (let m of project_materials) { - let c: zui_node_canvas_t = JSON.parse(JSON.stringify(m.canvas)); + let c: zui_node_canvas_t = json_parse(json_stringify(m.canvas)); for (let n of c.nodes) ExportArm.export_node(n); mnodes.push(c); } @@ -24,7 +24,7 @@ class ExportArm { ///end ///if is_lab - let c: zui_node_canvas_t = JSON.parse(JSON.stringify(project_canvas)); + let c: zui_node_canvas_t = json_parse(json_stringify(project_canvas)); for (let n of c.nodes) ExportArm.export_node(n); ///end @@ -32,7 +32,7 @@ class ExportArm { if (project_material_groups.length > 0) { mgroups = []; for (let g of project_material_groups) { - let c: zui_node_canvas_t = JSON.parse(JSON.stringify(g.canvas)); + let c: zui_node_canvas_t = json_parse(json_stringify(g.canvas)); for (let n of c.nodes) ExportArm.export_node(n); mgroups.push(c); } @@ -156,7 +156,7 @@ class ExportArm { let mesh_icon_pixels: buffer_t = image_get_pixels(mesh_icon); let u8a: Uint8Array = new Uint8Array(mesh_icon_pixels); for (let i: i32 = 0; i < 256 * 256 * 4; ++i) { - u8a[i] = Math.floor(Math.pow(u8a[i] / 255, 1.0 / 2.2) * 255); + u8a[i] = math_floor(math_pow(u8a[i] / 255, 1.0 / 2.2) * 255); } ///if (krom_metal || krom_vulkan) ExportArm.bgra_swap(mesh_icon_pixels); @@ -229,11 +229,11 @@ class ExportArm { let mnodes: zui_node_canvas_t[] = []; let mgroups: zui_node_canvas_t[] = null; let m: SlotMaterialRaw = context_raw.material; - let c: zui_node_canvas_t = JSON.parse(JSON.stringify(m.canvas)); + let c: zui_node_canvas_t = json_parse(json_stringify(m.canvas)); let assets: asset_t[] = []; - if (UINodes.has_group(c)) { + if (ui_nodes_has_group(c)) { mgroups = []; - UINodes.traverse_group(mgroups, c); + ui_nodes_traverse_group(mgroups, c); for (let gc of mgroups) for (let n of gc.nodes) ExportArm.export_node(n, assets); } for (let n of c.nodes) ExportArm.export_node(n, assets); @@ -280,7 +280,7 @@ class ExportArm { ///if (krom_metal || krom_vulkan) static bgra_swap = (buffer: ArrayBuffer) => { let view: DataView = new DataView(buffer); - for (let i: i32 = 0; i < Math.floor(buffer.byteLength / 4); ++i) { + for (let i: i32 = 0; i < math_floor(buffer.byteLength / 4); ++i) { let r: i32 = view.getUint8(i * 4); view.setUint8(i * 4, view.getUint8(i * 4 + 2)); view.setUint8(i * 4 + 2, r); @@ -294,7 +294,7 @@ class ExportArm { if (!path.endsWith(".arm")) path += ".arm"; let bnodes: zui_node_canvas_t[] = []; let b: SlotBrushRaw = context_raw.brush; - let c: zui_node_canvas_t = JSON.parse(JSON.stringify(b.canvas)); + let c: zui_node_canvas_t = json_parse(json_stringify(b.canvas)); let assets: asset_t[] = []; for (let n of c.nodes) ExportArm.export_node(n, assets); bnodes.push(c); diff --git a/base/Sources/ExportObj.ts b/base/Sources/ExportObj.ts index 2a726daf..338862ee 100644 --- a/base/Sources/ExportObj.ts +++ b/base/Sources/ExportObj.ts @@ -21,15 +21,15 @@ class ExportObj { let posa: i16_array_t = mesh.vertex_arrays[0].values; let nora: i16_array_t = mesh.vertex_arrays[1].values; let texa: i16_array_t = mesh.vertex_arrays[2].values; - let len: i32 = Math.floor(posa.length / 4); + let len: i32 = math_floor(posa.length / 4); // Merge shared vertices and remap indices let posa2: Int16Array = new Int16Array(len * 3); let nora2: Int16Array = new Int16Array(len * 3); let texa2: Int16Array = new Int16Array(len * 2); - let posmap: Map = new Map(); - let normap: Map = new Map(); - let texmap: Map = new Map(); + let posmap: map_t = map_create(); + let normap: map_t = map_create(); + let texmap: map_t = map_create(); let pi: i32 = 0; let ni: i32 = 0; @@ -93,12 +93,12 @@ class ExportObj { // let res: i32 = layers[0].texpaint_pack.width; // let strength: f32 = 0.1; // for (let i: i32 = 0; i < len; ++i) { - // let x: i32 = Math.floor(texa2[i * 2 ] / 32767 * res); - // let y: i32 = Math.floor((1.0 - texa2[i * 2 + 1] / 32767) * res); + // let x: i32 = math_floor(texa2[i * 2 ] / 32767 * res); + // let y: i32 = math_floor((1.0 - texa2[i * 2 + 1] / 32767) * res); // let h: f32 = (1.0 - height.get((y * res + x) * 4 + 3) / 255) * strength; - // posa2[i * 3 ] -= Math.floor(nora2[i * 3 ] * inv * h / sc); - // posa2[i * 3 + 1] -= Math.floor(nora2[i * 3 + 1] * inv * h / sc); - // posa2[i * 3 + 2] -= Math.floor(nora2[i * 3 + 2] * inv * h / sc); + // posa2[i * 3 ] -= math_floor(nora2[i * 3 ] * inv * h / sc); + // posa2[i * 3 + 1] -= math_floor(nora2[i * 3 + 1] * inv * h / sc); + // posa2[i * 3 + 2] -= math_floor(nora2[i * 3 + 2] * inv * h / sc); // } } @@ -130,7 +130,7 @@ class ExportObj { } let inda: u32_array_t = mesh.index_arrays[0].values; - for (let i: i32 = 0; i < Math.floor(inda.length / 3); ++i) { + for (let i: i32 = 0; i < math_floor(inda.length / 3); ++i) { let pi1: i32 = posmap.get(inda[i * 3 ]) + 1 + poff; let pi2: i32 = posmap.get(inda[i * 3 + 1]) + 1 + poff; let pi3: i32 = posmap.get(inda[i * 3 + 2]) + 1 + poff; diff --git a/base/Sources/ExportTexture.ts b/base/Sources/ExportTexture.ts index 8a9f979a..62a7abd2 100644 --- a/base/Sources/ExportTexture.ts +++ b/base/Sources/ExportTexture.ts @@ -81,7 +81,7 @@ class ExportTexture { ///else console_info(tr("Textures exported")); ///end - UIFiles.last_path = ""; + ui_files_last_path = ""; } ///if is_paint @@ -124,7 +124,7 @@ class ExportTexture { ///if (krom_android || krom_ios) let f: string = sys_title(); ///else - let f: string = UIFiles.filename; + let f: string = ui_files_filename; ///end if (f == "") f = tr("untitled"); let format_type: texture_ldr_format_t = context_raw.format_type; @@ -316,7 +316,7 @@ class ExportTexture { ExportTexture.write_texture(path + path_sep + f + tex_name + ext, pixpaint, 2, 3); } else { - if (pix == null) pix = new ArrayBuffer(texture_size_x * texture_size_y * 4 * Math.floor(bits / 8)); + if (pix == null) pix = new ArrayBuffer(texture_size_x * texture_size_y * 4 * math_floor(bits / 8)); for (let i: i32 = 0; i < 4; ++i) { let c: string = t.channels[i]; if (c == "base_r") ExportTexture.copy_channel(new DataView(pixpaint), 0, new DataView(pix), i, t.color_space == "linear"); @@ -378,7 +378,7 @@ class ExportTexture { krom_write_png(file, pixels, res_x, res_y, format); } else if (bits == 8 && context_raw.format_type == texture_ldr_format_t.JPG) { - krom_write_jpg(file, pixels, res_x, res_y, format, Math.floor(context_raw.format_quality)); + krom_write_jpg(file, pixels, res_x, res_y, format, math_floor(context_raw.format_quality)); } else { // Exr let b: ArrayBuffer = ParserExr.run(res_x, res_y, pixels, bits, type, off); @@ -387,36 +387,36 @@ class ExportTexture { } static copy_channel = (from: DataView, fromChannel: i32, to: DataView, toChannel: i32, linear: bool = true) => { - for (let i: i32 = 0; i < Math.floor(to.byteLength / 4); ++i) { + for (let i: i32 = 0; i < math_floor(to.byteLength / 4); ++i) { to.setUint8(i * 4 + toChannel, from.getUint8(i * 4 + fromChannel)); } if (!linear) ExportTexture.to_srgb(to, toChannel); } static copy_channel_inv = (from: DataView, fromChannel: i32, to: DataView, toChannel: i32, linear: bool = true) => { - for (let i: i32 = 0; i < Math.floor(to.byteLength / 4); ++i) { + for (let i: i32 = 0; i < math_floor(to.byteLength / 4); ++i) { to.setUint8(i * 4 + toChannel, 255 - from.getUint8(i * 4 + fromChannel)); } if (!linear) ExportTexture.to_srgb(to, toChannel); } static extract_channel = (from: DataView, fromChannel: i32, to: DataView, toChannel: i32, step: i32, mask: i32, linear: bool = true) => { - for (let i: i32 = 0; i < Math.floor(to.byteLength / 4); ++i) { + for (let i: i32 = 0; i < math_floor(to.byteLength / 4); ++i) { to.setUint8(i * 4 + toChannel, from.getUint8(i * 4 + fromChannel) % step == mask ? 255 : 0); } if (!linear) ExportTexture.to_srgb(to, toChannel); } static set_channel = (value: i32, to: DataView, toChannel: i32, linear: bool = true) => { - for (let i: i32 = 0; i < Math.floor(to.byteLength / 4); ++i) { + for (let i: i32 = 0; i < math_floor(to.byteLength / 4); ++i) { to.setUint8(i * 4 + toChannel, value); } if (!linear) ExportTexture.to_srgb(to, toChannel); } static to_srgb = (to: DataView, toChannel: i32) => { - for (let i: i32 = 0; i < Math.floor(to.byteLength / 4); ++i) { - to.setUint8(i * 4 + toChannel, Math.floor(Math.pow(to.getUint8(i * 4 + toChannel) / 255, ExportTexture.gamma) * 255)); + for (let i: i32 = 0; i < math_floor(to.byteLength / 4); ++i) { + to.setUint8(i * 4 + toChannel, math_floor(math_pow(to.getUint8(i * 4 + toChannel) / 255, ExportTexture.gamma) * 255)); } } } diff --git a/base/Sources/ImportArm.ts b/base/Sources/ImportArm.ts index a22d042c..9ea97482 100644 --- a/base/Sources/ImportArm.ts +++ b/base/Sources/ImportArm.ts @@ -33,11 +33,11 @@ class ImportArm { project_new(import_as_mesh); project_filepath = path; - UIFiles.filename = path.substring(path.lastIndexOf(path_sep) + 1, path.lastIndexOf(".")); + ui_files_filename = path.substring(path.lastIndexOf(path_sep) + 1, path.lastIndexOf(".")); ///if (krom_android || krom_ios) - sys_title_set(UIFiles.filename); + sys_title_set(ui_files_filename); ///else - sys_title_set(UIFiles.filename + " - " + manifest_title); + sys_title_set(ui_files_filename + " - " + manifest_title); ///end ///if (is_paint || is_sculpt) @@ -66,7 +66,7 @@ class ImportArm { base_res_handle.position = config_get_texture_res_pos(l0.res); let bits_pos: texture_bits_t = l0.bpp == 8 ? texture_bits_t.BITS8 : l0.bpp == 16 ? texture_bits_t.BITS16 : texture_bits_t.BITS32; base_bits_handle.position = bits_pos; - let bytes_per_pixel: i32 = Math.floor(l0.bpp / 8); + let bytes_per_pixel: i32 = math_floor(l0.bpp / 8); let format: tex_format_t = l0.bpp == 8 ? tex_format_t.RGBA32 : l0.bpp == 16 ? tex_format_t.RGBA64 : tex_format_t.RGBA128; ///end @@ -160,7 +160,7 @@ class ImportArm { ///end // No mask by default - if (context_raw.merged_object == null) UtilMesh.merge_mesh(); + if (context_raw.merged_object == null) util_mesh_merge(); ///end context_select_paint_object(context_main_object()); @@ -306,8 +306,8 @@ class ImportArm { } ///end - UINodes.hwnd.redraws = 2; - UINodes.group_stack = []; + ui_nodes_hwnd.redraws = 2; + ui_nodes_group_stack = []; project_material_groups = []; if (project.material_groups != null) { for (let g of project.material_groups) project_material_groups.push({ canvas: g, nodes: zui_nodes_create() }); @@ -317,7 +317,7 @@ class ImportArm { for (let m of project_materials) { context_raw.material = m; MakeMaterial.parse_paint_material(); - UtilRender.make_material_preview(); + util_render_make_material_preview(); } project_brushes = []; @@ -326,7 +326,7 @@ class ImportArm { context_raw.brush = SlotBrush.create(n); project_brushes.push(context_raw.brush); MakeMaterial.parse_brush(); - UtilRender.make_brush_preview(); + util_render_make_brush_preview(); } // Fill layers @@ -339,8 +339,8 @@ class ImportArm { } } - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; ///end ///if is_lab @@ -374,7 +374,7 @@ class ImportArm { transform_build_matrix(object.base.transform); object.base.name = md.name; project_paint_objects.push(object); - UtilMesh.merge_mesh(); + util_mesh_merge(); viewport_scale_to_bounds(); } app_notify_on_init(base_init_layers); @@ -432,13 +432,13 @@ class ImportArm { for (let m of imported) { context_set_material(m); MakeMaterial.parse_paint_material(); - UtilRender.make_material_preview(); + util_render_make_material_preview(); } } app_notify_on_init(_init); - UINodes.group_stack = []; - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; + ui_nodes_group_stack = []; + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; data_delete_blob(path); } @@ -502,12 +502,12 @@ class ImportArm { let _init = () => { for (let b of imported) { context_set_brush(b); - UtilRender.make_brush_preview(); + util_render_make_brush_preview(); } } app_notify_on_init(_init); - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; data_delete_blob(path); } ///end @@ -533,7 +533,7 @@ class ImportArm { project_raw.swatches.push(s); } } - UIBase.hwnds[tab_area_t.STATUS].redraws = 2; + ui_base_hwnds[tab_area_t.STATUS].redraws = 2; data_delete_blob(path); } diff --git a/base/Sources/ImportAsset.ts b/base/Sources/ImportAsset.ts index ddf04ac1..46207454 100644 --- a/base/Sources/ImportAsset.ts +++ b/base/Sources/ImportAsset.ts @@ -25,14 +25,14 @@ class ImportAsset { if (path_is_mesh(path)) { showBox ? project_import_mesh_box(path) : ImportMesh.run(path); - if (dropX > 0) UIBox.click_to_hide = false; // Prevent closing when going back to window after drag and drop + if (dropX > 0) ui_box_click_to_hide = false; // Prevent closing when going back to window after drag and drop } else if (path_is_texture(path)) { ImportTexture.run(path, hdrAsEnvmap); // Place image node - let x0: i32 = UINodes.wx; - let x1: i32 = UINodes.wx + UINodes.ww; - if (UINodes.show && dropX > x0 && dropX < x1) { + let x0: i32 = ui_nodes_wx; + let x1: i32 = ui_nodes_wx + ui_nodes_ww; + if (ui_nodes_show && dropX > x0 && dropX < x1) { let asset_index: i32 = 0; for (let i: i32 = 0; i < project_assets.length; ++i) { if (project_assets[i].file == path) { @@ -40,14 +40,14 @@ class ImportAsset { break; } } - UINodes.accept_asset_drag(asset_index); - UINodes.get_nodes().nodesDrag = false; - UINodes.hwnd.redraws = 2; + ui_nodes_accept_asset_drag(asset_index); + ui_nodes_get_nodes().nodesDrag = false; + ui_nodes_hwnd.redraws = 2; } ///if is_paint if (context_raw.tool == workspace_tool_t.COLORID && project_asset_names.length == 1) { - UIHeader.header_handle.redraws = 2; + ui_header_handle.redraws = 2; context_raw.ddirty = 2; } ///end diff --git a/base/Sources/ImportBlendMaterial.ts b/base/Sources/ImportBlendMaterial.ts index 077cb75b..344c0308 100644 --- a/base/Sources/ImportBlendMaterial.ts +++ b/base/Sources/ImportBlendMaterial.ts @@ -84,7 +84,7 @@ class ImportBlendMaterial { } if (base != null) { - let n: zui_node_t = UINodes.make_node(base, nodes, canvas); + let n: zui_node_t = ui_nodes_make_node(base, nodes, canvas); n.x = BlHandle.get(node, "locx") + 400; n.y = -BlHandle.get(node, "locy") + 400; n.name = BlHandle.get(node, "name"); @@ -120,11 +120,11 @@ class ImportBlendMaterial { for (let i: i32 = 0; i < BlHandle.get(ramp, "tot"); ++i) { if (i >= elems.length) elems.push([1.0, 1.0, 1.0, 1.0, 0.0]); let cbdata: any = BlHandle.get(ramp, "data", i, "CBData"); - elems[i][0] = Math.floor(BlHandle.get(cbdata, "r") * 100) / 100; - elems[i][1] = Math.floor(BlHandle.get(cbdata, "g") * 100) / 100; - elems[i][2] = Math.floor(BlHandle.get(cbdata, "b") * 100) / 100; - elems[i][3] = Math.floor(BlHandle.get(cbdata, "a") * 100) / 100; - elems[i][4] = Math.floor(BlHandle.get(cbdata, "pos") * 100) / 100; + elems[i][0] = math_floor(BlHandle.get(cbdata, "r") * 100) / 100; + elems[i][1] = math_floor(BlHandle.get(cbdata, "g") * 100) / 100; + elems[i][2] = math_floor(BlHandle.get(cbdata, "b") * 100) / 100; + elems[i][3] = math_floor(BlHandle.get(cbdata, "a") * 100) / 100; + elems[i][4] = math_floor(BlHandle.get(cbdata, "pos") * 100) / 100; } } else if (search == "mixrgb" || search == "math") { @@ -247,12 +247,12 @@ class ImportBlendMaterial { for (let m of imported) { context_set_material(m); MakeMaterial.parse_paint_material(); - UtilRender.make_material_preview(); + util_render_make_material_preview(); } } app_notify_on_init(_init); - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; data_delete_blob(path); } @@ -260,22 +260,22 @@ class ImportBlendMaterial { let idname: any = BlHandle.get(sock, "idname"); if (idname.startsWith("NodeSocketVector")) { let v: any = BlHandle.get(BlHandle.get(sock, "default_value", 0, "bNodeSocketValueVector"), "value"); - v[0] = Math.floor(v[0] * 100) / 100; - v[1] = Math.floor(v[1] * 100) / 100; - v[2] = Math.floor(v[2] * 100) / 100; + v[0] = math_floor(v[0] * 100) / 100; + v[1] = math_floor(v[1] * 100) / 100; + v[2] = math_floor(v[2] * 100) / 100; return v; } else if (idname.startsWith("NodeSocketColor")) { let v: any = BlHandle.get(BlHandle.get(sock, "default_value", 0, "bNodeSocketValueRGBA"), "value"); - v[0] = Math.floor(v[0] * 100) / 100; - v[1] = Math.floor(v[1] * 100) / 100; - v[2] = Math.floor(v[2] * 100) / 100; - v[3] = Math.floor(v[3] * 100) / 100; + v[0] = math_floor(v[0] * 100) / 100; + v[1] = math_floor(v[1] * 100) / 100; + v[2] = math_floor(v[2] * 100) / 100; + v[3] = math_floor(v[3] * 100) / 100; return v; } else if (idname.startsWith("NodeSocketFloat")) { let v: any = BlHandle.get(BlHandle.get(sock, "default_value", 0, "bNodeSocketValueFloat"), "value"); - v = Math.floor(v * 100) / 100; + v = math_floor(v * 100) / 100; return v; } else if (idname.startsWith("NodeSocketInt")) { diff --git a/base/Sources/ImportBlendMesh.ts b/base/Sources/ImportBlendMesh.ts index e4332075..3151454b 100644 --- a/base/Sources/ImportBlendMesh.ts +++ b/base/Sources/ImportBlendMesh.ts @@ -106,12 +106,12 @@ class ImportBlendMesh { if (hasuv) { bl.pos = uvdata_pos + (loopstart + totloop - 1) * 4 * 3; // * 3 = x, y, flag uv0 = ParserBlend.read_f32array(bl, 2); - if (uv0[0] > 1.0 + ImportBlendMesh.eps) uv0[0] = uv0[0] - Math.floor(uv0[0]); - if (uv0[1] > 1.0 + ImportBlendMesh.eps) uv0[1] = uv0[1] - Math.floor(uv0[1]); + if (uv0[0] > 1.0 + ImportBlendMesh.eps) uv0[0] = uv0[0] - math_floor(uv0[0]); + if (uv0[1] > 1.0 + ImportBlendMesh.eps) uv0[1] = uv0[1] - math_floor(uv0[1]); bl.pos = uvdata_pos + (loopstart) * 4 * 3; uv1 = ParserBlend.read_f32array(bl, 2); - if (uv1[0] > 1.0 + ImportBlendMesh.eps) uv1[0] = uv1[0] - Math.floor(uv1[0]); - if (uv1[1] > 1.0 + ImportBlendMesh.eps) uv1[1] = uv1[1] - Math.floor(uv1[1]); + if (uv1[0] > 1.0 + ImportBlendMesh.eps) uv1[0] = uv1[0] - math_floor(uv1[0]); + if (uv1[1] > 1.0 + ImportBlendMesh.eps) uv1[1] = uv1[1] - math_floor(uv1[1]); } let col0r: i32 = 0; let col0g: i32 = 0; @@ -157,29 +157,29 @@ class ImportBlendMesh { posa32[tri * 9 + 6] = co2[0]; posa32[tri * 9 + 7] = co2[1]; posa32[tri * 9 + 8] = co2[2]; - posa[tri * 12 + 3] = Math.floor(vec0.z * 32767); - posa[tri * 12 + 7] = Math.floor((smooth ? vec1.z : vec0.z) * 32767); - posa[tri * 12 + 11] = Math.floor((smooth ? vec2.z : vec0.z) * 32767); - nora[tri * 6 ] = Math.floor(vec0.x * 32767); - nora[tri * 6 + 1] = Math.floor(vec0.y * 32767); - nora[tri * 6 + 2] = Math.floor((smooth ? vec1.x : vec0.x) * 32767); - nora[tri * 6 + 3] = Math.floor((smooth ? vec1.y : vec0.y) * 32767); - nora[tri * 6 + 4] = Math.floor((smooth ? vec2.x : vec0.x) * 32767); - nora[tri * 6 + 5] = Math.floor((smooth ? vec2.y : vec0.y) * 32767); + posa[tri * 12 + 3] = math_floor(vec0.z * 32767); + posa[tri * 12 + 7] = math_floor((smooth ? vec1.z : vec0.z) * 32767); + posa[tri * 12 + 11] = math_floor((smooth ? vec2.z : vec0.z) * 32767); + nora[tri * 6 ] = math_floor(vec0.x * 32767); + nora[tri * 6 + 1] = math_floor(vec0.y * 32767); + nora[tri * 6 + 2] = math_floor((smooth ? vec1.x : vec0.x) * 32767); + nora[tri * 6 + 3] = math_floor((smooth ? vec1.y : vec0.y) * 32767); + nora[tri * 6 + 4] = math_floor((smooth ? vec2.x : vec0.x) * 32767); + nora[tri * 6 + 5] = math_floor((smooth ? vec2.y : vec0.y) * 32767); co1 = co2; no1 = no2; vec4_set_from(vec1, vec2); if (hasuv) { bl.pos = uvdata_pos + (loopstart + j + 1) * 4 * 3; uv2 = ParserBlend.read_f32array(bl, 2); - if (uv2[0] > 1.0 + ImportBlendMesh.eps) uv2[0] = uv2[0] - Math.floor(uv2[0]); - if (uv2[1] > 1.0 + ImportBlendMesh.eps) uv2[1] = uv2[1] - Math.floor(uv2[1]); - texa[tri * 6 ] = Math.floor(uv0[0] * 32767); - texa[tri * 6 + 1] = Math.floor((1.0 - uv0[1]) * 32767); - texa[tri * 6 + 2] = Math.floor(uv1[0] * 32767); - texa[tri * 6 + 3] = Math.floor((1.0 - uv1[1]) * 32767); - texa[tri * 6 + 4] = Math.floor(uv2[0] * 32767); - texa[tri * 6 + 5] = Math.floor((1.0 - uv2[1]) * 32767); + if (uv2[0] > 1.0 + ImportBlendMesh.eps) uv2[0] = uv2[0] - math_floor(uv2[0]); + if (uv2[1] > 1.0 + ImportBlendMesh.eps) uv2[1] = uv2[1] - math_floor(uv2[1]); + texa[tri * 6 ] = math_floor(uv0[0] * 32767); + texa[tri * 6 + 1] = math_floor((1.0 - uv0[1]) * 32767); + texa[tri * 6 + 2] = math_floor(uv1[0] * 32767); + texa[tri * 6 + 3] = math_floor((1.0 - uv1[1]) * 32767); + texa[tri * 6 + 4] = math_floor(uv2[0] * 32767); + texa[tri * 6 + 5] = math_floor((1.0 - uv2[1]) * 32767); uv1 = uv2; } if (hascol) { @@ -223,9 +223,9 @@ class ImportBlendMesh { let nx: f32 = vec0.x; let ny: f32 = vec0.y; let nz: f32 = vec0.z; - let nxabs: f32 = Math.abs(nx); - let nyabs: f32 = Math.abs(ny); - let nzabs: f32 = Math.abs(nz); + let nxabs: f32 = math_abs(nx); + let nyabs: f32 = math_abs(ny); + let nzabs: f32 = math_abs(nz); let flip: bool = nx + ny + nz > 0; let axis: i32 = nxabs > nyabs && nxabs > nzabs ? 0 : nyabs > nxabs && nyabs > nzabs ? 1 : 2; let axis0: i32 = axis == 0 ? (flip ? 2 : 1) : axis == 1 ? (flip ? 0 : 2) : (flip ? 1 : 0); @@ -278,7 +278,7 @@ class ImportBlendMesh { let px: f32 = co[axis0]; let py: f32 = co[axis1]; - if (UtilMesh.pnpoly(v0x, v0y, v1x, v1y, v2x, v2y, px, py)) { + if (util_mesh_pnpoly(v0x, v0y, v1x, v1y, v2x, v2y, px, py)) { overlap = true; break; } @@ -310,16 +310,16 @@ class ImportBlendMesh { if (hasuv) { bl.pos = uvdata_pos + (va[i ]) * 4 * 3; uv0 = ParserBlend.read_f32array(bl, 2); - if (uv0[0] > 1.0 + ImportBlendMesh.eps) uv0[0] = uv0[0] - Math.floor(uv0[0]); - if (uv0[1] > 1.0 + ImportBlendMesh.eps) uv0[1] = uv0[1] - Math.floor(uv0[1]); + if (uv0[0] > 1.0 + ImportBlendMesh.eps) uv0[0] = uv0[0] - math_floor(uv0[0]); + if (uv0[1] > 1.0 + ImportBlendMesh.eps) uv0[1] = uv0[1] - math_floor(uv0[1]); bl.pos = uvdata_pos + (va[i1]) * 4 * 3; uv1 = ParserBlend.read_f32array(bl, 2); - if (uv1[0] > 1.0 + ImportBlendMesh.eps) uv1[0] = uv1[0] - Math.floor(uv1[0]); - if (uv1[1] > 1.0 + ImportBlendMesh.eps) uv1[1] = uv1[1] - Math.floor(uv1[1]); + if (uv1[0] > 1.0 + ImportBlendMesh.eps) uv1[0] = uv1[0] - math_floor(uv1[0]); + if (uv1[1] > 1.0 + ImportBlendMesh.eps) uv1[1] = uv1[1] - math_floor(uv1[1]); bl.pos = uvdata_pos + (va[i2]) * 4 * 3; uv2 = ParserBlend.read_f32array(bl, 2); - if (uv2[0] > 1.0 + ImportBlendMesh.eps) uv2[0] = uv2[0] - Math.floor(uv2[0]); - if (uv2[1] > 1.0 + ImportBlendMesh.eps) uv2[1] = uv2[1] - Math.floor(uv2[1]); + if (uv2[0] > 1.0 + ImportBlendMesh.eps) uv2[0] = uv2[0] - math_floor(uv2[0]); + if (uv2[1] > 1.0 + ImportBlendMesh.eps) uv2[1] = uv2[1] - math_floor(uv2[1]); } let col0r: i32 = 0; let col0g: i32 = 0; @@ -353,22 +353,22 @@ class ImportBlendMesh { posa32[tri * 9 + 6] = co2[0]; posa32[tri * 9 + 7] = co2[1]; posa32[tri * 9 + 8] = co2[2]; - posa[tri * 12 + 3] = Math.floor(vec0.z * 32767); - posa[tri * 12 + 7] = Math.floor((smooth ? vec1.z : vec0.z) * 32767); - posa[tri * 12 + 11] = Math.floor((smooth ? vec2.z : vec0.z) * 32767); - nora[tri * 6 ] = Math.floor(vec0.x * 32767); - nora[tri * 6 + 1] = Math.floor(vec0.y * 32767); - nora[tri * 6 + 2] = Math.floor((smooth ? vec1.x : vec0.x) * 32767); - nora[tri * 6 + 3] = Math.floor((smooth ? vec1.y : vec0.y) * 32767); - nora[tri * 6 + 4] = Math.floor((smooth ? vec2.x : vec0.x) * 32767); - nora[tri * 6 + 5] = Math.floor((smooth ? vec2.y : vec0.y) * 32767); + posa[tri * 12 + 3] = math_floor(vec0.z * 32767); + posa[tri * 12 + 7] = math_floor((smooth ? vec1.z : vec0.z) * 32767); + posa[tri * 12 + 11] = math_floor((smooth ? vec2.z : vec0.z) * 32767); + nora[tri * 6 ] = math_floor(vec0.x * 32767); + nora[tri * 6 + 1] = math_floor(vec0.y * 32767); + nora[tri * 6 + 2] = math_floor((smooth ? vec1.x : vec0.x) * 32767); + nora[tri * 6 + 3] = math_floor((smooth ? vec1.y : vec0.y) * 32767); + nora[tri * 6 + 4] = math_floor((smooth ? vec2.x : vec0.x) * 32767); + nora[tri * 6 + 5] = math_floor((smooth ? vec2.y : vec0.y) * 32767); if (hasuv) { - texa[tri * 6 ] = Math.floor(uv0[0] * 32767); - texa[tri * 6 + 1] = Math.floor((1.0 - uv0[1]) * 32767); - texa[tri * 6 + 2] = Math.floor(uv1[0] * 32767); - texa[tri * 6 + 3] = Math.floor((1.0 - uv1[1]) * 32767); - texa[tri * 6 + 4] = Math.floor(uv2[0] * 32767); - texa[tri * 6 + 5] = Math.floor((1.0 - uv2[1]) * 32767); + texa[tri * 6 ] = math_floor(uv0[0] * 32767); + texa[tri * 6 + 1] = math_floor((1.0 - uv0[1]) * 32767); + texa[tri * 6 + 2] = math_floor(uv1[0] * 32767); + texa[tri * 6 + 3] = math_floor((1.0 - uv1[1]) * 32767); + texa[tri * 6 + 4] = math_floor(uv2[0] * 32767); + texa[tri * 6 + 5] = math_floor((1.0 - uv2[1]) * 32767); } if (hascol) { cola[tri * 12 ] = col0r * 128; @@ -398,7 +398,7 @@ class ImportBlendMesh { let obmat: any = BlHandle.get(ob, "obmat", 0, "float", 16); let mat: mat4_t = mat4_transpose(mat4_from_f32_array(obmat)); let v: vec4_t = vec4_create(); - for (let i: i32 = 0; i < Math.floor(posa32.length / 3); ++i) { + for (let i: i32 = 0; i < math_floor(posa32.length / 3); ++i) { vec4_set(v, posa32[i * 3], posa32[i * 3 + 1], posa32[i * 3 + 2]); vec4_apply_mat4(v, mat); posa32[i * 3 ] = v.x; @@ -408,26 +408,26 @@ class ImportBlendMesh { mat4_get_inv(mat, mat); mat4_transpose3x3(mat); mat.m[12] = mat.m[13] = mat.m[14] = mat.m[15] = 0; - for (let i: i32 = 0; i < Math.floor(nora.length / 2); ++i) { + for (let i: i32 = 0; i < math_floor(nora.length / 2); ++i) { vec4_set(v, nora[i * 2] / 32767, nora[i * 2 + 1] / 32767, posa[i * 4 + 3] / 32767); vec4_apply_mat(v, mat); vec4_normalize(v); - nora[i * 2 ] = Math.floor(v.x * 32767); - nora[i * 2 + 1] = Math.floor(v.y * 32767); - posa[i * 4 + 3] = Math.floor(v.z * 32767); + nora[i * 2 ] = math_floor(v.x * 32767); + nora[i * 2 + 1] = math_floor(v.y * 32767); + posa[i * 4 + 3] = math_floor(v.z * 32767); } // Pack positions to (-1, 1) range let scale_pos: f32 = 0.0; for (let i: i32 = 0; i < posa32.length; ++i) { - let f: f32 = Math.abs(posa32[i]); + let f: f32 = math_abs(posa32[i]); if (scale_pos < f) scale_pos = f; } let inv: f32 = 1 / scale_pos; - for (let i: i32 = 0; i < Math.floor(posa32.length / 3); ++i) { - posa[i * 4 ] = Math.floor(posa32[i * 3 ] * 32767 * inv); - posa[i * 4 + 1] = Math.floor(posa32[i * 3 + 1] * 32767 * inv); - posa[i * 4 + 2] = Math.floor(posa32[i * 3 + 2] * 32767 * inv); + for (let i: i32 = 0; i < math_floor(posa32.length / 3); ++i) { + posa[i * 4 ] = math_floor(posa32[i * 3 ] * 32767 * inv); + posa[i * 4 + 1] = math_floor(posa32[i * 3 + 1] * 32767 * inv); + posa[i * 4 + 2] = math_floor(posa32[i * 3 + 2] * 32767 * inv); } let obj: any = { diff --git a/base/Sources/ImportEnvmap.ts b/base/Sources/ImportEnvmap.ts index 90597641..ae7ecfcd 100644 --- a/base/Sources/ImportEnvmap.ts +++ b/base/Sources/ImportEnvmap.ts @@ -32,8 +32,8 @@ class ImportEnvmap { ImportEnvmap.mips = []; let w: i32 = 512; for (let i: i32 = 0; i < 10; ++i) { - ImportEnvmap.mips.push(image_create_render_target(w, w > 1 ? Math.floor(w / 2) : 1, tex_format_t.RGBA128)); - w = Math.floor(w / 2); + ImportEnvmap.mips.push(image_create_render_target(w, w > 1 ? math_floor(w / 2) : 1, tex_format_t.RGBA128)); + w = math_floor(w / 2); } if (const_data_screen_aligned_vb == null) const_data_create_screen_aligned_data(); @@ -104,10 +104,10 @@ class ImportEnvmap { } static reverse_equirect = (x: f32, y: f32): vec4_t => { - let theta: f32 = x * Math.PI * 2 - Math.PI; - let phi: f32 = y * Math.PI; - // return n.set(Math.sin(phi) * Math.cos(theta), -(Math.sin(phi) * Math.sin(theta)), Math.cos(phi)); - return vec4_set(ImportEnvmap.n, -Math.cos(phi), Math.sin(phi) * Math.cos(theta), -(Math.sin(phi) * Math.sin(theta))); + let theta: f32 = x * math_pi() * 2 - math_pi(); + let phi: f32 = y * math_pi(); + // return n.set(math_sin(phi) * math_cos(theta), -(math_sin(phi) * math_sin(theta)), math_cos(phi)); + return vec4_set(ImportEnvmap.n, -math_cos(phi), math_sin(phi) * math_cos(theta), -(math_sin(phi) * math_sin(theta))); } // https://ndotl.wordpress.com/2015/03/07/pbr-cubemap-filtering @@ -129,7 +129,7 @@ class ImportEnvmap { for (let i: i32 = 0; i < 3; ++i) { let value: f32 = view.getFloat32(((x + y * sourceWidth) * 16 + i * 4), true); - value = Math.pow(value, 1.0 / 2.2); + value = math_pow(value, 1.0 / 2.2); sh[0 + i] += value * weight1; sh[3 + i] += value * weight2 * ImportEnvmap.n.x; diff --git a/base/Sources/ImportFont.ts b/base/Sources/ImportFont.ts index 94a09687..f6c74b07 100644 --- a/base/Sources/ImportFont.ts +++ b/base/Sources/ImportFont.ts @@ -27,12 +27,12 @@ class ImportFont { for (let f of font_slots) { context_raw.font = f; project_fonts.push(f); - UtilRender.make_font_preview(); + util_render_make_font_preview(); } } app_notify_on_init(_init); - UIBase.hwnds[tab_area_t.STATUS].redraws = 2; + ui_base_hwnds[tab_area_t.STATUS].redraws = 2; } } diff --git a/base/Sources/ImportMesh.ts b/base/Sources/ImportMesh.ts index 6eeb8736..fd53182e 100644 --- a/base/Sources/ImportMesh.ts +++ b/base/Sources/ImportMesh.ts @@ -78,7 +78,7 @@ class ImportMesh { // No mask by default for (let p of project_paint_objects) p.base.visible = true; - if (context_raw.merged_object == null) UtilMesh.merge_mesh(); + if (context_raw.merged_object == null) util_mesh_merge(); context_raw.paint_object.skip_context = "paint"; context_raw.merged_object.base.visible = true; } @@ -90,7 +90,7 @@ class ImportMesh { MakeMaterial.parse_mesh_material(); ///if (is_paint || is_sculpt) - UIView2D.hwnd.redraws = 2; + ui_view2d_hwnd.redraws = 2; ///end ///if (krom_direct3d12 || krom_vulkan || krom_metal) @@ -131,11 +131,11 @@ class ImportMesh { context_raw.ddirty = 4; ///if (is_paint || is_sculpt) - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; - UtilUV.uvmap_cached = false; - UtilUV.trianglemap_cached = false; - UtilUV.dilatemap_cached = false; + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; + util_uv_uvmap_cached = false; + util_uv_trianglemap_cached = false; + util_uv_dilatemap_cached = false; ///end ///if (is_paint || is_sculpt) @@ -207,10 +207,10 @@ class ImportMesh { context_raw.ddirty = 4; ///if (is_paint || is_sculpt) - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - UtilUV.uvmap_cached = false; - UtilUV.trianglemap_cached = false; - UtilUV.dilatemap_cached = false; + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + util_uv_uvmap_cached = false; + util_uv_trianglemap_cached = false; + util_uv_dilatemap_cached = false; ///end } diff --git a/base/Sources/ImportObj.ts b/base/Sources/ImportObj.ts index 504c13b2..f2c86ca3 100644 --- a/base/Sources/ImportObj.ts +++ b/base/Sources/ImportObj.ts @@ -17,7 +17,7 @@ class ImportObj { for (let i: i32 = 0; i < part.udims.length; ++i) { if (part.udims[i].length == 0) continue; let u: i32 = i % part.udims_u; - let v: i32 = Math.floor(i / part.udims_u); + let v: i32 = math_floor(i / part.udims_u); part.name = name + "." + (1000 + v * 10 + u + 1); part.inda = part.udims[i]; i == 0 ? (replace_existing ? ImportMesh.make_mesh(part, path) : ImportMesh.add_mesh(part)) : ImportMesh.add_mesh(part); @@ -57,33 +57,33 @@ class ImportObj { texa1 = parts[j].texa != null ? parts[j].texa : null; inda0 = parts[i].inda; inda1 = parts[j].inda; - let voff: i32 = Math.floor(posa0.length / 4); + let voff: i32 = math_floor(posa0.length / 4); // Repack merged positions - let posa32: Float32Array = new Float32Array(Math.floor(posa0.length / 4) * 3 + Math.floor(posa1.length / 4) * 3); - for (let k: i32 = 0; k < Math.floor(posa0.length / 4); ++k) { + let posa32: Float32Array = new Float32Array(math_floor(posa0.length / 4) * 3 + math_floor(posa1.length / 4) * 3); + for (let k: i32 = 0; k < math_floor(posa0.length / 4); ++k) { posa32[k * 3 ] = posa0[k * 4 ] / 32767 * parts[i].scale_pos; posa32[k * 3 + 1] = posa0[k * 4 + 1] / 32767 * parts[i].scale_pos; posa32[k * 3 + 2] = posa0[k * 4 + 2] / 32767 * parts[i].scale_pos; } - for (let k: i32 = 0; k < Math.floor(posa1.length / 4); ++k) { + for (let k: i32 = 0; k < math_floor(posa1.length / 4); ++k) { posa32[voff * 3 + k * 3 ] = posa1[k * 4 ] / 32767 * parts[j].scale_pos; posa32[voff * 3 + k * 3 + 1] = posa1[k * 4 + 1] / 32767 * parts[j].scale_pos; posa32[voff * 3 + k * 3 + 2] = posa1[k * 4 + 2] / 32767 * parts[j].scale_pos; } let scale_pos: f32 = 0.0; for (let k: i32 = 0; k < posa32.length; ++k) { - let f: f32 = Math.abs(posa32[k]); + let f: f32 = math_abs(posa32[k]); if (scale_pos < f) scale_pos = f; } let inv: f32 = 32767 * (1 / scale_pos); let posa: Int16Array = new Int16Array(posa0.length + posa1.length); - for (let k: i32 = 0; k < Math.floor(posa.length / 4); ++k) { - posa[k * 4 ] = Math.floor(posa32[k * 3 ] * inv); - posa[k * 4 + 1] = Math.floor(posa32[k * 3 + 1] * inv); - posa[k * 4 + 2] = Math.floor(posa32[k * 3 + 2] * inv); + for (let k: i32 = 0; k < math_floor(posa.length / 4); ++k) { + posa[k * 4 ] = math_floor(posa32[k * 3 ] * inv); + posa[k * 4 + 1] = math_floor(posa32[k * 3 + 1] * inv); + posa[k * 4 + 2] = math_floor(posa32[k * 3 + 2] * inv); } - for (let k: i32 = 0; k < Math.floor(posa0.length / 4); ++k) posa[k * 4 + 3] = posa0[k * 4 + 3]; - for (let k: i32 = 0; k < Math.floor(posa1.length / 4); ++k) posa[posa0.length + k * 4 + 3] = posa1[k * 4 + 3]; + for (let k: i32 = 0; k < math_floor(posa0.length / 4); ++k) posa[k * 4 + 3] = posa0[k * 4 + 3]; + for (let k: i32 = 0; k < math_floor(posa1.length / 4); ++k) posa[posa0.length + k * 4 + 3] = posa1[k * 4 + 3]; // Merge normals and uvs let nora: Int16Array = new Int16Array(nora0.length + nora1.length); let texa: Int16Array = (texa0 != null && texa1 != null) ? new Int16Array(texa0.length + texa1.length) : null; diff --git a/base/Sources/ImportTexture.ts b/base/Sources/ImportTexture.ts index 24988e4c..1ba09414 100644 --- a/base/Sources/ImportTexture.ts +++ b/base/Sources/ImportTexture.ts @@ -38,7 +38,7 @@ class ImportTexture { if (context_raw.texture == null) context_raw.texture = asset; project_asset_names.push(name); project_asset_map.set(asset.id, image); - UIBase.hwnds[tab_area_t.STATUS].redraws = 2; + ui_base_hwnds[tab_area_t.STATUS].redraws = 2; console_info(tr("Texture imported:") + " " + name); // Set as envmap diff --git a/base/Sources/NodeShader.ts b/base/Sources/NodeShader.ts index b7034035..9ed0801c 100644 --- a/base/Sources/NodeShader.ts +++ b/base/Sources/NodeShader.ts @@ -7,7 +7,7 @@ class NodeShaderRaw { outs: string[] = []; shared_samplers: string[] = []; uniforms: string[] = []; - functions: Map = new Map(); + functions: map_t = map_create(); main: string = ''; main_init: string = ''; main_end: string = ''; diff --git a/base/Sources/NodesMaterial.ts b/base/Sources/NodesMaterial.ts index 02e16e97..4cefb6ca 100644 --- a/base/Sources/NodesMaterial.ts +++ b/base/Sources/NodesMaterial.ts @@ -2802,7 +2802,7 @@ class NodesMaterial { if (val.length > 2) val.pop(); } let ihandle: zui_handle_t = zui_nest(zui_nest(zui_nest(nhandle, 0), 2), axis, {position: 0}); - let i: i32 = Math.floor(zui_slider(ihandle, "Index", 0, num - 1, false, 1, true, zui_align_t.LEFT)); + let i: i32 = math_floor(zui_slider(ihandle, "Index", 0, num - 1, false, 1, true, zui_align_t.LEFT)); if (i >= val.length || i < 0) ihandle.value = i = val.length - 1; // Stay in bounds zui_row([1 / 2, 1 / 2]); zui_nest(zui_nest(nhandle, 0), 3).value = val[i][0]; @@ -2847,7 +2847,7 @@ class NodesMaterial { but.data = zui_combo(zui_nest(zui_nest(nhandle, 0), 1, {position: but.data}), [tr("Linear"), tr("Constant")], tr("Interpolate")); zui_row([1 / 2, 1 / 2]); - let i: i32 = Math.floor(zui_slider(ihandle, "Index", 0, vals.length - 1, false, 1, true, zui_align_t.LEFT)); + let i: i32 = math_floor(zui_slider(ihandle, "Index", 0, vals.length - 1, false, 1, true, zui_align_t.LEFT)); if (i >= vals.length || i < 0) ihandle.value = i = vals.length - 1; // Stay in bounds let val: Float32Array = vals[i]; @@ -2862,7 +2862,7 @@ class NodesMaterial { let rx: f32 = nx + ui._w - zui_nodes_p(37); let ry: f32 = ny - zui_nodes_p(5); nodes._inputStarted = ui.input_started = false; - zui_nodes_rgba_popup(ui, chandle, val, Math.floor(rx), Math.floor(ry + zui_ELEMENT_H(ui))); + zui_nodes_rgba_popup(ui, chandle, val, math_floor(rx), math_floor(ry + zui_ELEMENT_H(ui))); } val[0] = color_get_rb(chandle.color) / 255; val[1] = color_get_gb(chandle.color) / 255; @@ -2938,7 +2938,7 @@ class NodesMaterial { } if (zui_button(tr("Nodes"))) { - UINodes.group_stack.push(group); + ui_nodes_group_stack.push(group); } } @@ -2952,18 +2952,18 @@ class NodesMaterial { static add_socket_button = (ui: zui_t, nodes: zui_nodes_t, node: zui_node_t, sockets: zui_node_socket_t[]) => { if (zui_button(tr("Add"))) { - UIMenu.draw((ui: zui_t) => { - let groupStack: node_group_t[] = UINodes.group_stack; + ui_menu_draw((ui: zui_t) => { + let groupStack: node_group_t[] = ui_nodes_group_stack; let c: zui_node_canvas_t = groupStack[groupStack.length - 1].canvas; - if (UIMenu.menu_button(ui, tr("RGBA"))) { + if (ui_menu_button(ui, tr("RGBA"))) { sockets.push(NodesMaterial.create_socket(nodes, node, null, "RGBA", c)); NodesMaterial.sync_sockets(node); } - if (UIMenu.menu_button(ui, tr("Vector"))) { + if (ui_menu_button(ui, tr("Vector"))) { sockets.push(NodesMaterial.create_socket(nodes, node, null, "VECTOR", c)); NodesMaterial.sync_sockets(node); } - if (UIMenu.menu_button(ui, tr("Value"))) { + if (ui_menu_button(ui, tr("Value"))) { sockets.push(NodesMaterial.create_socket(nodes, node, null, "VALUE", c)); NodesMaterial.sync_sockets(node); } @@ -2972,7 +2972,7 @@ class NodesMaterial { } static sync_sockets = (node: zui_node_t) => { - let groupStack: node_group_t[] = UINodes.group_stack; + let groupStack: node_group_t[] = ui_nodes_group_stack; let c: zui_node_canvas_t = groupStack[groupStack.length - 1].canvas; for (let m of project_materials) NodesMaterial.sync_group_sockets(m.canvas, c.name, node); for (let g of project_material_groups) NodesMaterial.sync_group_sockets(g.canvas, c.name, node); @@ -3032,7 +3032,7 @@ class NodesMaterial { if (n == null) return null; let canvas: zui_node_canvas_t = group != null ? group.canvas : context_raw.material.canvas; let nodes: zui_nodes_t = group != null ? group.nodes : context_raw.material.nodes; - let node: zui_node_t = UINodes.make_node(n, nodes, canvas); + let node: zui_node_t = ui_nodes_make_node(n, nodes, canvas); canvas.nodes.push(node); return node; } diff --git a/base/Sources/ParserBlend.ts b/base/Sources/ParserBlend.ts index 13b00f7f..b5cc90a7 100644 --- a/base/Sources/ParserBlend.ts +++ b/base/Sources/ParserBlend.ts @@ -19,7 +19,7 @@ class BlendRaw { // Data blocks: Block[] = []; dna: Dna = null; - map: Map = new Map(); // Map blocks by memory address + map: map_t = map_create(); // Map blocks by memory address } class ParserBlend { diff --git a/base/Sources/ParserLogic.ts b/base/Sources/ParserLogic.ts index 5db49d0d..30fe5098 100644 --- a/base/Sources/ParserLogic.ts +++ b/base/Sources/ParserLogic.ts @@ -1,14 +1,14 @@ class ParserLogic { - static custom_nodes: Map = new Map(); + static custom_nodes: map_t = map_create(); static nodes: zui_node_t[]; static links: zui_node_link_t[]; static parsed_nodes: string[] = null; - static parsed_labels: Map = null; - static node_map: Map; - static raw_map: Map; + static parsed_labels: map_t = null; + static node_map: map_t; + static raw_map: map_t; static get_logic_node = (node: zui_node_t): LogicNode => { return ParserLogic.node_map.get(ParserLogic.node_name(node)); @@ -65,9 +65,9 @@ class ParserLogic { ParserLogic.links = canvas.links; ParserLogic.parsed_nodes = []; - ParserLogic.parsed_labels = new Map(); - ParserLogic.node_map = new Map(); - ParserLogic.raw_map = new Map(); + ParserLogic.parsed_labels = map_create(); + ParserLogic.node_map = map_create(); + ParserLogic.raw_map = map_create(); let root_nodes: zui_node_t[] = ParserLogic.get_root_nodes(canvas); for (let node of root_nodes) ParserLogic.build_node(node); diff --git a/base/Sources/ParserMaterial.ts b/base/Sources/ParserMaterial.ts index 18118902..f069d376 100644 --- a/base/Sources/ParserMaterial.ts +++ b/base/Sources/ParserMaterial.ts @@ -33,7 +33,7 @@ class ParserMaterial { static tex_coord: string = "texCoord"; static eps: f32 = 0.000001; - static custom_nodes: Map = new Map(); + static custom_nodes: map_t = map_create(); static parse_surface: bool = true; static parse_opacity: bool = true; static parse_height: bool = false; @@ -59,10 +59,10 @@ class ParserMaterial { static arm_export_tangents: bool = true; static out_normaltan: string; // Raw tangent space normal parsed from normal map - static script_links: Map = null; + static script_links: map_t = null; - static parsedMap: Map = new Map(); - static textureMap: Map = new Map(); + static parsedMap: map_t = map_create(); + static textureMap: map_t = map_create(); static get_node = (id: i32): zui_node_t => { for (let n of ParserMaterial.nodes) if (n.id == id) return n; @@ -462,7 +462,7 @@ class ParserMaterial { return ParserMaterial.vec3(socket.default_value); } else if (node.type == "TEX_BRICK") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_brick); + NodeShader.add_function(ParserMaterial.curshader, str_tex_brick); let co: string = ParserMaterial.get_coord(node); let col1: string = ParserMaterial.parse_vector_input(node.inputs[1]); let col2: string = ParserMaterial.parse_vector_input(node.inputs[2]); @@ -472,7 +472,7 @@ class ParserMaterial { return res; } else if (node.type == "TEX_CHECKER") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_checker); + NodeShader.add_function(ParserMaterial.curshader, str_tex_checker); let co: string = ParserMaterial.get_coord(node); let col1: string = ParserMaterial.parse_vector_input(node.inputs[1]); let col2: string = ParserMaterial.parse_vector_input(node.inputs[2]); @@ -509,21 +509,21 @@ class ParserMaterial { } } else if (node.type == "TEX_MAGIC") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_magic); + NodeShader.add_function(ParserMaterial.curshader, str_tex_magic); let co: string = ParserMaterial.get_coord(node); let scale: string = ParserMaterial.parse_value_input(node.inputs[1]); let res: string = `tex_magic(${co} * ${scale} * 4.0)`; return res; } else if (node.type == "TEX_NOISE") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_noise); + NodeShader.add_function(ParserMaterial.curshader, str_tex_noise); let co: string = ParserMaterial.get_coord(node); let scale: string = ParserMaterial.parse_value_input(node.inputs[1]); let res: string = `vec3(tex_noise(${co} * ${scale}), tex_noise(${co} * ${scale} + 0.33), tex_noise(${co} * ${scale} + 0.66))`; return res; } else if (node.type == "TEX_VORONOI") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_voronoi); + NodeShader.add_function(ParserMaterial.curshader, str_tex_voronoi); NodeShader.add_uniform(ParserMaterial.curshader, "sampler2D snoise256", "$noise256.k"); let co: string = ParserMaterial.get_coord(node); let scale: string = ParserMaterial.parse_value_input(node.inputs[1]); @@ -540,7 +540,7 @@ class ParserMaterial { return res; } else if (node.type == "TEX_WAVE") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_wave); + NodeShader.add_function(ParserMaterial.curshader, str_tex_wave); let co: string = ParserMaterial.get_coord(node); let scale: string = ParserMaterial.parse_value_input(node.inputs[1]); let res: string = ParserMaterial.to_vec3(`tex_wave_f(${co} * ${scale})`); @@ -550,7 +550,7 @@ class ParserMaterial { let out_col: string = ParserMaterial.parse_vector_input(node.inputs[0]); let bright: string = ParserMaterial.parse_value_input(node.inputs[1]); let contr: string = ParserMaterial.parse_value_input(node.inputs[2]); - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_brightcontrast); + NodeShader.add_function(ParserMaterial.curshader, str_brightcontrast); return `brightcontrast(${out_col}, ${bright}, ${contr})`; } else if (node.type == "GAMMA") { @@ -565,7 +565,7 @@ class ParserMaterial { let tex_name: string = "texwarp_" + ParserMaterial.node_name(node); NodeShader.add_uniform(ParserMaterial.curshader, "sampler2D " + tex_name, "_" + tex_name); let store: string = ParserMaterial.store_var_name(node); - NodeShader.write(ParserMaterial.curshader, `float ${store}_rad = ${angle} * (${Math.PI} / 180);`); + NodeShader.write(ParserMaterial.curshader, `float ${store}_rad = ${angle} * (${math_pi()} / 180);`); NodeShader.write(ParserMaterial.curshader, `float ${store}_x = cos(${store}_rad);`); NodeShader.write(ParserMaterial.curshader, `float ${store}_y = sin(${store}_rad);`); return `texture(${tex_name}, texCoord + vec2(${store}_x, ${store}_y) * ${mask}).rgb;`; @@ -588,7 +588,7 @@ class ParserMaterial { return `${store}_res`; } else if (node.type == "HUE_SAT") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_hue_sat); + NodeShader.add_function(ParserMaterial.curshader, str_hue_sat); let hue: string = ParserMaterial.parse_value_input(node.inputs[0]); let sat: string = ParserMaterial.parse_value_input(node.inputs[1]); let val: string = ParserMaterial.parse_value_input(node.inputs[2]); @@ -661,19 +661,19 @@ class ParserMaterial { out_col = "(" + ParserMaterial.to_vec3(`(1.0 - ${fac_var}) * ${col1} + ${fac_var} * ${col1} / ${col2}`) + ")"; } else if (blend == "HUE") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_hue_sat); + NodeShader.add_function(ParserMaterial.curshader, str_hue_sat); out_col = `mix(${col1}, hsv_to_rgb(vec3(rgb_to_hsv(${col2}).r, rgb_to_hsv(${col1}).g, rgb_to_hsv(${col1}).b)), ${fac_var})`; } else if (blend == "SATURATION") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_hue_sat); + NodeShader.add_function(ParserMaterial.curshader, str_hue_sat); out_col = `mix(${col1}, hsv_to_rgb(vec3(rgb_to_hsv(${col1}).r, rgb_to_hsv(${col2}).g, rgb_to_hsv(${col1}).b)), ${fac_var})`; } else if (blend == "COLOR") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_hue_sat); + NodeShader.add_function(ParserMaterial.curshader, str_hue_sat); out_col = `mix(${col1}, hsv_to_rgb(vec3(rgb_to_hsv(${col2}).r, rgb_to_hsv(${col2}).g, rgb_to_hsv(${col1}).b)), ${fac_var})`; } else if (blend == "VALUE") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_hue_sat); + NodeShader.add_function(ParserMaterial.curshader, str_hue_sat); out_col = `mix(${col1}, hsv_to_rgb(vec3(rgb_to_hsv(${col1}).r, rgb_to_hsv(${col1}).g, rgb_to_hsv(${col2}).b)), ${fac_var})`; } if (use_clamp) return `clamp(${out_col}, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0))`; @@ -748,7 +748,7 @@ class ParserMaterial { return `(sqrt(vec3(${vc0}, ${vc1}, ${vc2}) * vec3(${vc3a}, ${vc3b}, ${vc3c})) * ${fac})`; } else if (node.type == "COMBHSV") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_hue_sat); + NodeShader.add_function(ParserMaterial.curshader, str_hue_sat); let h: string = ParserMaterial.parse_value_input(node.inputs[0]); let s: string = ParserMaterial.parse_value_input(node.inputs[1]); let v: string = ParserMaterial.parse_value_input(node.inputs[2]); @@ -761,9 +761,9 @@ class ParserMaterial { return `vec3(${r}, ${g}, ${b})`; } else if (node.type == "WAVELENGTH") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_wavelength_to_rgb); + NodeShader.add_function(ParserMaterial.curshader, str_wavelength_to_rgb); let wl: string = ParserMaterial.parse_value_input(node.inputs[0]); - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_wavelength_to_rgb); + NodeShader.add_function(ParserMaterial.curshader, str_wavelength_to_rgb); return `wavelength_to_rgb((${wl} - 450.0) / 150.0)`; } else if (node.type == "CAMERA") { @@ -923,10 +923,10 @@ class ParserMaterial { } // if node.rotation[1] != 0.0: // a = node.rotation[1] - // out = `vec3({0}.x * {1} - {0}.z * {2}, {0}.x * {2} + {0}.z * {1}, 0.0)`.format(out, math.cos(a), math.sin(a)) + // out = `vec3({0}.x * {1} - {0}.z * {2}, {0}.x * {2} + {0}.z * {1}, 0.0)`.format(out, math_cos(a), math_sin(a)) // if node.rotation[0] != 0.0: // a = node.rotation[0] - // out = `vec3({0}.y * {1} - {0}.z * {2}, {0}.y * {2} + {0}.z * {1}, 0.0)`.format(out, math.cos(a), math.sin(a)) + // out = `vec3({0}.y * {1} - {0}.z * {2}, {0}.y * {2} + {0}.z * {1}, 0.0)`.format(out, math_cos(a), math_sin(a)) if (node_translation != `vec3(0, 0, 0)`) { out = `(${out} + ${node_translation})`; } @@ -1093,7 +1093,7 @@ class ParserMaterial { NodeShader.write(ParserMaterial.frag, `texn.y = -texn.y;`); if (!ParserMaterial.cotangent_frame_written) { ParserMaterial.cotangent_frame_written = true; - NodeShader.add_function(ParserMaterial.frag, ShaderFunctions.str_cotangent_frame); + NodeShader.add_function(ParserMaterial.frag, str_cotangent_frame); } ParserMaterial.frag.n = true; ///if (krom_direct3d11 || krom_direct3d12 || krom_metal || krom_vulkan) @@ -1314,14 +1314,14 @@ class ParserMaterial { return ParserMaterial.vec1(node.outputs[0].default_value); } else if (node.type == "TEX_BRICK") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_brick); + NodeShader.add_function(ParserMaterial.curshader, str_tex_brick); let co: string = ParserMaterial.get_coord(node); let scale: string = ParserMaterial.parse_value_input(node.inputs[4]); let res: string = `tex_brick_f(${co} * ${scale})`; return res; } else if (node.type == "TEX_CHECKER") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_checker); + NodeShader.add_function(ParserMaterial.curshader, str_tex_checker); let co: string = ParserMaterial.get_coord(node); let scale: string = ParserMaterial.parse_value_input(node.inputs[3]); let res: string = `tex_checker_f(${co}, ${scale})`; @@ -1351,28 +1351,28 @@ class ParserMaterial { } } else if (node.type == "TEX_MAGIC") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_magic); + NodeShader.add_function(ParserMaterial.curshader, str_tex_magic); let co: string = ParserMaterial.get_coord(node); let scale: string = ParserMaterial.parse_value_input(node.inputs[1]); let res: string = `tex_magic_f(${co} * ${scale} * 4.0)`; return res; } else if (node.type == "TEX_MUSGRAVE") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_musgrave); + NodeShader.add_function(ParserMaterial.curshader, str_tex_musgrave); let co: string = ParserMaterial.get_coord(node); let scale: string = ParserMaterial.parse_value_input(node.inputs[1]); let res: string = `tex_musgrave_f(${co} * ${scale} * 0.5)`; return res; } else if (node.type == "TEX_NOISE") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_noise); + NodeShader.add_function(ParserMaterial.curshader, str_tex_noise); let co: string = ParserMaterial.get_coord(node); let scale: string = ParserMaterial.parse_value_input(node.inputs[1]); let res: string = `tex_noise(${co} * ${scale})`; return res; } else if (node.type == "TEX_VORONOI") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_voronoi); + NodeShader.add_function(ParserMaterial.curshader, str_tex_voronoi); NodeShader.add_uniform(ParserMaterial.curshader, "sampler2D snoise256", "$noise256.k"); let co: string = ParserMaterial.get_coord(node); let scale: string = ParserMaterial.parse_value_input(node.inputs[1]); @@ -1389,7 +1389,7 @@ class ParserMaterial { return res; } else if (node.type == "TEX_WAVE") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_tex_wave); + NodeShader.add_function(ParserMaterial.curshader, str_tex_wave); let co: string = ParserMaterial.get_coord(node); let scale: string = ParserMaterial.parse_value_input(node.inputs[1]); let res: string = `tex_wave_f(${co} * ${scale})`; @@ -1542,7 +1542,7 @@ class ParserMaterial { } } else if (node.type == "SCRIPT_CPU") { - if (ParserMaterial.script_links == null) ParserMaterial.script_links = new Map(); + if (ParserMaterial.script_links == null) ParserMaterial.script_links = map_create(); let script: any = node.buttons[0].default_value; let link: string = ParserMaterial.node_name(node); ParserMaterial.script_links.set(link, script); @@ -1558,7 +1558,7 @@ class ParserMaterial { return `(((${col}.r * 0.3 + ${col}.g * 0.59 + ${col}.b * 0.11) / 3.0) * 2.5)`; } else if (node.type == "SEPHSV") { - NodeShader.add_function(ParserMaterial.curshader, ShaderFunctions.str_hue_sat); + NodeShader.add_function(ParserMaterial.curshader, str_hue_sat); let col: string = ParserMaterial.parse_vector_input(node.inputs[0]); if (socket == node.outputs[0]) { return `rgb_to_hsv(${col}).r`; diff --git a/base/Sources/PhysicsBody.ts b/base/Sources/PhysicsBody.ts index aeda70c7..65ce04cb 100644 --- a/base/Sources/PhysicsBody.ts +++ b/base/Sources/PhysicsBody.ts @@ -64,9 +64,9 @@ class PhysicsBody { static trans2: Ammo.btTransform; static quat: quat_t = quat_create(); - static convex_hull_cache: Map = new Map(); - static triangle_mesh_cache: Map = new Map(); - static users_cache: Map = new Map(); + static convex_hull_cache: map_t = map_create(); + static triangle_mesh_cache: map_t = map_create(); + static users_cache: map_t = map_create(); static create(): PhysicsBodyRaw { if (PhysicsBody.first) { @@ -163,7 +163,7 @@ class PhysicsBody { for (let i: i32 = 0; i < length; ++i) { Ammo.HEAPU8[PhysicsBody.ammo_array + i] = pb.height_data[i]; } - let slice: i32 = Math.floor(Math.sqrt(length)); // Assuming square terrain data + let slice: i32 = math_floor(math_sqrt(length)); // Assuming square terrain data let axis: i32 = 2; // z let data_type: i32 = 5; // u8 pb.btshape = new Ammo.btHeightfieldTerrainShape(slice, slice, PhysicsBody.ammo_array, 1 / 255, 0, 1, axis, data_type, false); @@ -391,7 +391,7 @@ class PhysicsBody { sy *= data.scale_pos; sz *= data.scale_pos; - for (let i: i32 = 0; i < Math.floor(positions.length / 4); ++i) { + for (let i: i32 = 0; i < math_floor(positions.length / 4); ++i) { PhysicsBody.vec1.setX(positions[i * 4 ] * sx); PhysicsBody.vec1.setY(positions[i * 4 + 1] * sy); PhysicsBody.vec1.setZ(positions[i * 4 + 2] * sz); @@ -425,7 +425,7 @@ class PhysicsBody { sz *= data.scale_pos; for (let ar of indices) { - for (let i: i32 = 0; i < Math.floor(ar.length / 3); ++i) { + for (let i: i32 = 0; i < math_floor(ar.length / 3); ++i) { PhysicsBody.vec1.setX(positions[ar[i * 3 ] * 4 ] * sx); PhysicsBody.vec1.setY(positions[ar[i * 3 ] * 4 + 1] * sy); PhysicsBody.vec1.setZ(positions[ar[i * 3 ] * 4 + 2] * sz); diff --git a/base/Sources/PhysicsWorld.ts b/base/Sources/PhysicsWorld.ts index 71c5c95c..d7e18535 100644 --- a/base/Sources/PhysicsWorld.ts +++ b/base/Sources/PhysicsWorld.ts @@ -5,7 +5,7 @@ class PhysicsWorldRaw { world: Ammo.btDiscreteDynamicsWorld; dispatcher: Ammo.btCollisionDispatcher; contacts: pair_t[] = []; - body_map: Map = new Map(); + body_map: map_t = map_create(); time_scale: f32 = 1.0; time_step: f32 = 1 / 60; max_steps: i32 = 1; diff --git a/base/Sources/RenderPathBase.ts b/base/Sources/RenderPathBase.ts index 1fba4517..6698b38a 100644 --- a/base/Sources/RenderPathBase.ts +++ b/base/Sources/RenderPathBase.ts @@ -18,13 +18,13 @@ class RenderPathBase { } ///if arm_voxels - static init_voxels = (targetName: string = "voxels") => { + static init_voxels = (target_name: string = "voxels") => { if (config_raw.rp_gi != true || RenderPathBase.voxels_created) return; RenderPathBase.voxels_created = true; { let t: render_target_t = render_target_create(); - t.name = targetName; + t.name = target_name; t.format = "R8"; t.width = RenderPathBase.voxels_res; t.height = RenderPathBase.voxels_res; @@ -216,9 +216,9 @@ class RenderPathBase { } let bloom_radius: f32 = 6.5; - let min_dim: f32 = Math.min(render_path_current_w,render_path_current_h); - let log_min_dim: f32 = Math.max(1.0, Math.log2(min_dim) + (bloom_radius - 8.0)); - let num_mips: i32 = Math.floor(log_min_dim); + let min_dim: f32 = math_min(render_path_current_w, render_path_current_h); + let log_min_dim: f32 = math_max(1.0, math_log2(min_dim) + (bloom_radius - 8.0)); + let num_mips: i32 = math_floor(log_min_dim); RenderPathBase.bloom_sample_scale = 0.5 + log_min_dim - num_mips; for (let i: i32 = 0; i < num_mips; ++i) { diff --git a/base/Sources/RenderPathRaytrace.ts b/base/Sources/RenderPathRaytrace.ts index c65481c0..52c8c07a 100644 --- a/base/Sources/RenderPathRaytrace.ts +++ b/base/Sources/RenderPathRaytrace.ts @@ -148,7 +148,7 @@ class RenderPathRaytrace { } static build_data = () => { - if (context_raw.merged_object == null) UtilMesh.merge_mesh(); + if (context_raw.merged_object == null) util_mesh_merge(); ///if is_paint let mo: mesh_object_t = !context_layer_filter_used() ? context_raw.merged_object : context_raw.paint_object; ///else diff --git a/base/Sources/ShaderFunctions.ts b/base/Sources/ShaderFunctions.ts deleted file mode 100644 index 62804c19..00000000 --- a/base/Sources/ShaderFunctions.ts +++ /dev/null @@ -1,524 +0,0 @@ - -class ShaderFunctions { - - static str_tex_checker: string = ` -vec3 tex_checker(const vec3 co, const vec3 col1, const vec3 col2, const float scale) { - // Prevent precision issues on unit coordinates - vec3 p = (co + 0.000001 * 0.999999) * scale; - float xi = abs(floor(p.x)); - float yi = abs(floor(p.y)); - float zi = abs(floor(p.z)); - bool check = ((mod(xi, 2.0) == mod(yi, 2.0)) == bool(mod(zi, 2.0))); - return check ? col1 : col2; -} -float tex_checker_f(const vec3 co, const float scale) { - vec3 p = (co + 0.000001 * 0.999999) * scale; - float xi = abs(floor(p.x)); - float yi = abs(floor(p.y)); - float zi = abs(floor(p.z)); - return float((mod(xi, 2.0) == mod(yi, 2.0)) == bool(mod(zi, 2.0))); -} -`; - - // Created by inigo quilez - iq/2013 - // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License - static str_tex_voronoi: string = ` -vec4 tex_voronoi(const vec3 x, textureArg(snoise256)) { - vec3 p = floor(x); - vec3 f = fract(x); - float id = 0.0; - float res = 100.0; - for (int k = -1; k <= 1; k++) - for (int j = -1; j <= 1; j++) - for (int i = -1; i <= 1; i++) { - vec3 b = vec3(float(i), float(j), float(k)); - vec3 pb = p + b; - vec3 r = vec3(b) - f + texture(snoise256, (pb.xy + vec2(3.0, 1.0) * pb.z + 0.5) / 256.0).xyz; - float d = dot(r, r); - if (d < res) { - id = dot(p + b, vec3(1.0, 57.0, 113.0)); - res = d; - } - } - vec3 col = 0.5 + 0.5 * cos(id * 0.35 + vec3(0.0, 1.0, 2.0)); - return vec4(col, sqrt(res)); -} -`; - - // By Morgan McGuire @morgan3d, http://graphicscodex.com Reuse permitted under the BSD license. - // https://www.shadertoy.com/view/4dS3Wd - static str_tex_noise: string = ` -float hash(float n) { return fract(sin(n) * 1e4); } -float tex_noise_f(vec3 x) { - const vec3 step = vec3(110, 241, 171); - vec3 i = floor(x); - vec3 f = fract(x); - float n = dot(i, step); - vec3 u = f * f * (3.0 - 2.0 * f); - return mix(mix(mix(hash(n + dot(step, vec3(0, 0, 0))), hash(n + dot(step, vec3(1, 0, 0))), u.x), - mix(hash(n + dot(step, vec3(0, 1, 0))), hash(n + dot(step, vec3(1, 1, 0))), u.x), u.y), - mix(mix(hash(n + dot(step, vec3(0, 0, 1))), hash(n + dot(step, vec3(1, 0, 1))), u.x), - mix(hash(n + dot(step, vec3(0, 1, 1))), hash(n + dot(step, vec3(1, 1, 1))), u.x), u.y), u.z); -} -float tex_noise(vec3 p) { - p *= 1.25; - float f = 0.5 * tex_noise_f(p); p *= 2.01; - f += 0.25 * tex_noise_f(p); p *= 2.02; - f += 0.125 * tex_noise_f(p); p *= 2.03; - f += 0.0625 * tex_noise_f(p); - return 1.0 - f; -} -`; - - // Based on noise created by Nikita Miropolskiy, nikat/2013 - // Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License - static str_tex_musgrave: string = ` -vec3 random3(const vec3 c) { - float j = 4096.0 * sin(dot(c, vec3(17.0, 59.4, 15.0))); - vec3 r; - r.z = fract(512.0 * j); - j *= 0.125; - r.x = fract(512.0 * j); - j *= 0.125; - r.y = fract(512.0 * j); - return r - 0.5; -} -float tex_musgrave_f(const vec3 p) { - const float F3 = 0.3333333; - const float G3 = 0.1666667; - vec3 s = floor(p + dot(p, vec3(F3, F3, F3))); - vec3 x = p - s + dot(s, vec3(G3, G3, G3)); - vec3 e = step(vec3(0.0, 0.0, 0.0), x - x.yzx); - vec3 i1 = e*(1.0 - e.zxy); - vec3 i2 = 1.0 - e.zxy*(1.0 - e); - vec3 x1 = x - i1 + G3; - vec3 x2 = x - i2 + 2.0*G3; - vec3 x3 = x - 1.0 + 3.0*G3; - vec4 w, d; - w.x = dot(x, x); - w.y = dot(x1, x1); - w.z = dot(x2, x2); - w.w = dot(x3, x3); - w = max(0.6 - w, 0.0); - d.x = dot(random3(s), x); - d.y = dot(random3(s + i1), x1); - d.z = dot(random3(s + i2), x2); - d.w = dot(random3(s + 1.0), x3); - w *= w; - w *= w; - d *= w; - return clamp(dot(d, vec4(52.0, 52.0, 52.0, 52.0)), 0.0, 1.0); -} -`; - - static str_hue_sat: string = ` -vec3 hsv_to_rgb(const vec3 c) { - const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); - return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); -} -vec3 rgb_to_hsv(const vec3 c) { - const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); - vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); - vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); - float d = q.x - min(q.w, q.y); - float e = 1.0e-10; - return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); -} -vec3 hue_sat(const vec3 col, const vec4 shift) { - vec3 hsv = rgb_to_hsv(col); - hsv.x += shift.x; - hsv.y *= shift.y; - hsv.z *= shift.z; - return mix(hsv_to_rgb(hsv), col, shift.w); -} -`; - - // https://twitter.com/Donzanoid/status/903424376707657730 - static str_wavelength_to_rgb: string = ` -vec3 wavelength_to_rgb(const float t) { - vec3 r = t * 2.1 - vec3(1.8, 1.14, 0.3); - return 1.0 - r * r; -} -`; - - static str_tex_magic: string = ` -vec3 tex_magic(const vec3 p) { - float a = 1.0 - (sin(p.x) + sin(p.y)); - float b = 1.0 - sin(p.x - p.y); - float c = 1.0 - sin(p.x + p.y); - return vec3(a, b, c); -} -float tex_magic_f(const vec3 p) { - vec3 c = tex_magic(p); - return (c.x + c.y + c.z) / 3.0; -} -`; - - static str_tex_brick: string = ` -float tex_brick_noise(int n) { /* fast integer noise */ - int nn; - n = (n >> 13) ^ n; - nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; - return 0.5f * float(nn) / 1073741824.0; -} -vec3 tex_brick(vec3 p, const vec3 c1, const vec3 c2, const vec3 c3) { - vec3 brickSize = vec3(0.9, 0.49, 0.49); - vec3 mortarSize = vec3(0.05, 0.1, 0.1); - p /= brickSize / 2; - if (fract(p.y * 0.5) > 0.5) p.x += 0.5; - float col = floor(p.x / (brickSize.x + (mortarSize.x * 2.0))); - float row = p.y; - p = fract(p); - vec3 b = step(p, 1.0 - mortarSize); - float tint = min(max(tex_brick_noise((int(col) << 16) + (int(row) & 0xFFFF)), 0.0), 1.0); - return mix(c3, mix(c1, c2, tint), b.x * b.y * b.z); -} -float tex_brick_f(vec3 p) { - p /= vec3(0.9, 0.49, 0.49) / 2; - if (fract(p.y * 0.5) > 0.5) p.x += 0.5; - p = fract(p); - vec3 b = step(p, vec3(0.95, 0.9, 0.9)); - return mix(1.0, 0.0, b.x * b.y * b.z); -} -`; - - static str_tex_wave: string = ` -float tex_wave_f(const vec3 p) { - return 1.0 - sin((p.x + p.y) * 10.0); -} -`; - - static str_brightcontrast: string = ` -vec3 brightcontrast(const vec3 col, const float bright, const float contr) { - float a = 1.0 + contr; - float b = bright - contr * 0.5; - return max(a * col + b, 0.0); -} -`; - -// - - ///if arm_voxels - static str_trace_ao: string = ` -float traceConeAO(sampler3D voxels, const vec3 origin, vec3 dir, const float aperture, const float maxDist, const float offset) { - const ivec3 voxelgiResolution = ivec3(256, 256, 256); - const float voxelgiStep = 1.0; - const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep; - dir = normalize(dir); - float sampleCol = 0.0; - float dist = offset; - float diam = dist * aperture; - vec3 samplePos; - while (sampleCol < 1.0 && dist < maxDist) { - samplePos = dir * dist + origin; - float mip = max(log2(diam * voxelgiResolution.x), 0); - float mipSample = textureLod(voxels, samplePos * 0.5 + vec3(0.5, 0.5, 0.5), mip).r; - sampleCol += (1 - sampleCol) * mipSample; - dist += max(diam / 2, VOXEL_SIZE); - diam = dist * aperture; - } - return sampleCol; -} -vec3 tangent(const vec3 n) { - vec3 t1 = cross(n, vec3(0, 0, 1)); - vec3 t2 = cross(n, vec3(0, 1, 0)); - if (length(t1) > length(t2)) return normalize(t1); - else return normalize(t2); -} -float traceAO(const vec3 origin, const vec3 normal, const float vrange, const float voffset) { - const float angleMix = 0.5f; - const float aperture = 0.55785173935; - vec3 o1 = normalize(tangent(normal)); - vec3 o2 = normalize(cross(o1, normal)); - vec3 c1 = 0.5f * (o1 + o2); - vec3 c2 = 0.5f * (o1 - o2); - float MAX_DISTANCE = 1.73205080757 * 2.0 * vrange; - const ivec3 voxelgiResolution = ivec3(256, 256, 256); - const float voxelgiStep = 1.0; - const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep; - float offset = 1.5 * VOXEL_SIZE * 2.5 * voffset; - float col = traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE, offset); - col += traceConeAO(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE, offset); - col += traceConeAO(voxels, origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE, offset); - col += traceConeAO(voxels, origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE, offset); - col += traceConeAO(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset); - col += traceConeAO(voxels, origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset); - col += traceConeAO(voxels, origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE, offset); - col += traceConeAO(voxels, origin, mix(normal, c1, angleMix), aperture, MAX_DISTANCE, offset); - col += traceConeAO(voxels, origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset); - return col / 9.0; -} -`; - ///end - - static str_cotangent_frame: string = ` -mat3 cotangentFrame(const vec3 n, const vec3 p, const vec2 duv1, const vec2 duv2) { - vec3 dp1 = dFdx(p); - vec3 dp2 = dFdy(p); - vec3 dp2perp = cross(dp2, n); - vec3 dp1perp = cross(n, dp1); - vec3 t = dp2perp * duv1.x + dp1perp * duv2.x; - vec3 b = dp2perp * duv1.y + dp1perp * duv2.y; - float invmax = inversesqrt(max(dot(t, t), dot(b, b))); - return mat3(t * invmax, b * invmax, n); -} -mat3 cotangentFrame(const vec3 n, const vec3 p, const vec2 texCoord) { - return cotangentFrame(n, p, dFdx(texCoord), dFdy(texCoord)); -} -`; - - static str_octahedron_wrap: string = ` -vec2 octahedronWrap(const vec2 v) { - return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0)); -} -`; - - static str_pack_float_int16: string = ` -float packFloatInt16(const float f, const uint i) { - const float prec = float(1 << 16); - const float maxi = float(1 << 4); - const float precMinusOne = prec - 1.0; - const float t1 = ((prec / maxi) - 1.0) / precMinusOne; - const float t2 = (prec / maxi) / precMinusOne; - return t1 * f + t2 * float(i); -} -`; - - ///if arm_skin - static str_get_skinning_dual_quat: string = ` -void getSkinningDualQuat(const ivec4 bone, vec4 weight, out vec4 A, inout vec4 B) { - ivec4 bonei = bone * 2; - mat4 matA = mat4( - skinBones[bonei.x], - skinBones[bonei.y], - skinBones[bonei.z], - skinBones[bonei.w]); - mat4 matB = mat4( - skinBones[bonei.x + 1], - skinBones[bonei.y + 1], - skinBones[bonei.z + 1], - skinBones[bonei.w + 1]); - weight.xyz *= sign(mul(matA, matA[3])).xyz; - A = mul(weight, matA); - B = mul(weight, matB); - float invNormA = 1.0 / length(A); - A *= invNormA; - B *= invNormA; -} -`; - ///end - - static str_create_basis: string = ` -void createBasis(vec3 normal, out vec3 tangent, out vec3 binormal) { - tangent = normalize(cameraRight - normal * dot(cameraRight, normal)); - binormal = cross(tangent, normal); -} -`; - - static get str_sh_irradiance(): string { - ///if krom_metal - return `vec3 shIrradiance(const vec3 nor, constant vec4 shirr[7]) { - const float c1 = 0.429043; - const float c2 = 0.511664; - const float c3 = 0.743125; - const float c4 = 0.886227; - const float c5 = 0.247708; - vec3 cl00 = vec3(shirr[0].x, shirr[0].y, shirr[0].z); - vec3 cl1m1 = vec3(shirr[0].w, shirr[1].x, shirr[1].y); - vec3 cl10 = vec3(shirr[1].z, shirr[1].w, shirr[2].x); - vec3 cl11 = vec3(shirr[2].y, shirr[2].z, shirr[2].w); - vec3 cl2m2 = vec3(shirr[3].x, shirr[3].y, shirr[3].z); - vec3 cl2m1 = vec3(shirr[3].w, shirr[4].x, shirr[4].y); - vec3 cl20 = vec3(shirr[4].z, shirr[4].w, shirr[5].x); - vec3 cl21 = vec3(shirr[5].y, shirr[5].z, shirr[5].w); - vec3 cl22 = vec3(shirr[6].x, shirr[6].y, shirr[6].z); - return ( - c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) + - c3 * cl20 * nor.x * nor.x + - c4 * cl00 - - c5 * cl20 + - 2.0 * c1 * cl2m2 * nor.y * (-nor.z) + - 2.0 * c1 * cl21 * nor.y * nor.x + - 2.0 * c1 * cl2m1 * (-nor.z) * nor.x + - 2.0 * c2 * cl11 * nor.y + - 2.0 * c2 * cl1m1 * (-nor.z) + - 2.0 * c2 * cl10 * nor.x - ); -} -`; - ///else - return `vec3 shIrradiance(const vec3 nor, const vec4 shirr[7]) { - const float c1 = 0.429043; - const float c2 = 0.511664; - const float c3 = 0.743125; - const float c4 = 0.886227; - const float c5 = 0.247708; - vec3 cl00 = vec3(shirr[0].x, shirr[0].y, shirr[0].z); - vec3 cl1m1 = vec3(shirr[0].w, shirr[1].x, shirr[1].y); - vec3 cl10 = vec3(shirr[1].z, shirr[1].w, shirr[2].x); - vec3 cl11 = vec3(shirr[2].y, shirr[2].z, shirr[2].w); - vec3 cl2m2 = vec3(shirr[3].x, shirr[3].y, shirr[3].z); - vec3 cl2m1 = vec3(shirr[3].w, shirr[4].x, shirr[4].y); - vec3 cl20 = vec3(shirr[4].z, shirr[4].w, shirr[5].x); - vec3 cl21 = vec3(shirr[5].y, shirr[5].z, shirr[5].w); - vec3 cl22 = vec3(shirr[6].x, shirr[6].y, shirr[6].z); - return ( - c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) + - c3 * cl20 * nor.x * nor.x + - c4 * cl00 - - c5 * cl20 + - 2.0 * c1 * cl2m2 * nor.y * (-nor.z) + - 2.0 * c1 * cl21 * nor.y * nor.x + - 2.0 * c1 * cl2m1 * (-nor.z) * nor.x + - 2.0 * c2 * cl11 * nor.y + - 2.0 * c2 * cl1m1 * (-nor.z) + - 2.0 * c2 * cl10 * nor.x - ); -} -`; -///end - } - - static str_envmap_equirect: string = ` -vec2 envMapEquirect(const vec3 normal, const float angle) { - const float PI = 3.1415926535; - const float PI2 = PI * 2.0; - float phi = acos(normal.z); - float theta = atan2(-normal.y, normal.x) + PI + angle; - return vec2(theta / PI2, phi / PI); -} -`; - - // Linearly Transformed Cosines - // https://eheitzresearch.wordpress.com/415-2/ - static str_ltc_evaluate: string = ` -float integrateEdge(vec3 v1, vec3 v2) { - float cosTheta = dot(v1, v2); - float theta = acos(cosTheta); - float res = cross(v1, v2).z * ((theta > 0.001) ? theta / sin(theta) : 1.0); - return res; -} -float ltcEvaluate(vec3 N, vec3 V, float dotNV, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3) { - vec3 T1 = normalize(V - N * dotNV); - vec3 T2 = cross(N, T1); - Minv = mul(transpose(mat3(T1, T2, N)), Minv); - vec3 L0 = mul((points0 - P), Minv); - vec3 L1 = mul((points1 - P), Minv); - vec3 L2 = mul((points2 - P), Minv); - vec3 L3 = mul((points3 - P), Minv); - vec3 L4 = vec3(0.0, 0.0, 0.0); - int n = 0; - int config = 0; - if (L0.z > 0.0) config += 1; - if (L1.z > 0.0) config += 2; - if (L2.z > 0.0) config += 4; - if (L3.z > 0.0) config += 8; - if (config == 0) {} - else if (config == 1) { - n = 3; - L1 = -L1.z * L0 + L0.z * L1; - L2 = -L3.z * L0 + L0.z * L3; - } - else if (config == 2) { - n = 3; - L0 = -L0.z * L1 + L1.z * L0; - L2 = -L2.z * L1 + L1.z * L2; - } - else if (config == 3) { - n = 4; - L2 = -L2.z * L1 + L1.z * L2; - L3 = -L3.z * L0 + L0.z * L3; - } - else if (config == 4) { - n = 3; - L0 = -L3.z * L2 + L2.z * L3; - L1 = -L1.z * L2 + L2.z * L1; - } - else if (config == 5) { n = 0; } - else if (config == 6) { - n = 4; - L0 = -L0.z * L1 + L1.z * L0; - L3 = -L3.z * L2 + L2.z * L3; - } - else if (config == 7) { - n = 5; - L4 = -L3.z * L0 + L0.z * L3; - L3 = -L3.z * L2 + L2.z * L3; - } - else if (config == 8) { - n = 3; - L0 = -L0.z * L3 + L3.z * L0; - L1 = -L2.z * L3 + L3.z * L2; - L2 = L3; - } - else if (config == 9) { - n = 4; - L1 = -L1.z * L0 + L0.z * L1; - L2 = -L2.z * L3 + L3.z * L2; - } - else if (config == 10) { n = 0; } - else if (config == 11) { - n = 5; - L4 = L3; - L3 = -L2.z * L3 + L3.z * L2; - L2 = -L2.z * L1 + L1.z * L2; - } - else if (config == 12) { - n = 4; - L1 = -L1.z * L2 + L2.z * L1; - L0 = -L0.z * L3 + L3.z * L0; - } - else if (config == 13) { - n = 5; - L4 = L3; - L3 = L2; - L2 = -L1.z * L2 + L2.z * L1; - L1 = -L1.z * L0 + L0.z * L1; - } - else if (config == 14) { - n = 5; - L4 = -L0.z * L3 + L3.z * L0; - L0 = -L0.z * L1 + L1.z * L0; - } - else if (config == 15) { n = 4; } - if (n == 0) return 0.0; - if (n == 3) L3 = L0; - if (n == 4) L4 = L0; - L0 = normalize(L0); - L1 = normalize(L1); - L2 = normalize(L2); - L3 = normalize(L3); - L4 = normalize(L4); - float sum = 0.0; - sum += integrateEdge(L0, L1); - sum += integrateEdge(L1, L2); - sum += integrateEdge(L2, L3); - if (n >= 4) sum += integrateEdge(L3, L4); - if (n == 5) sum += integrateEdge(L4, L0); - return max(0.0, -sum); -} -`; - - static str_get_pos_from_depth: string = ` -vec3 get_pos_from_depth(vec2 uv, mat4 invVP, textureArg(gbufferD)) { - #if defined(HLSL) || defined(METAL) || defined(SPIRV) - float depth = textureLod(gbufferD, vec2(uv.x, 1.0 - uv.y), 0.0).r; - #else - float depth = textureLod(gbufferD, uv, 0.0).r; - #endif - vec4 wpos = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0); - wpos = mul(wpos, invVP); - return wpos.xyz / wpos.w; -} -`; - - static str_get_nor_from_depth: string = ` -vec3 get_nor_from_depth(vec3 p0, vec2 uv, mat4 invVP, vec2 texStep, textureArg(gbufferD)) { - vec3 p1 = get_pos_from_depth(uv + vec2(texStep.x * 4.0, 0.0), invVP, texturePass(gbufferD)); - vec3 p2 = get_pos_from_depth(uv + vec2(0.0, texStep.y * 4.0), invVP, texturePass(gbufferD)); - return normalize(cross(p2 - p0, p1 - p0)); -} -`; - -} diff --git a/base/Sources/TabBrowser.ts b/base/Sources/TabBrowser.ts index 6d19373a..2926224b 100644 --- a/base/Sources/TabBrowser.ts +++ b/base/Sources/TabBrowser.ts @@ -9,19 +9,19 @@ class TabBrowser { static show_directory = (directory: string) => { TabBrowser.hpath.text = directory; TabBrowser.hsearch.text = ""; - UIBase.htabs[tab_area_t.STATUS].position = 0; + ui_base_htabs[tab_area_t.STATUS].position = 0; } static draw = (htab: zui_handle_t) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; let statush: i32 = config_raw.layout[layout_size_t.STATUS_H]; - if (zui_tab(htab, tr("Browser")) && statush > UIStatus.default_status_h * zui_SCALE(ui)) { + if (zui_tab(htab, tr("Browser")) && statush > ui_status_default_status_h * zui_SCALE(ui)) { if (config_raw.bookmarks == null) { config_raw.bookmarks = []; } - let bookmarks_w: i32 = Math.floor(100 * zui_SCALE(ui)); + let bookmarks_w: i32 = math_floor(100 * zui_SCALE(ui)); if (TabBrowser.hpath.text == "" && config_raw.bookmarks.length > 0) { // Init to first bookmark TabBrowser.hpath.text = config_raw.bookmarks[0]; @@ -83,15 +83,15 @@ class TabBrowser { let _y: f32 = ui._y; ui._x = bookmarks_w; ui._w -= bookmarks_w; - UIFiles.file_browser(ui, TabBrowser.hpath, false, true, TabBrowser.hsearch.text, refresh, (file: string) => { + ui_files_file_browser(ui, TabBrowser.hpath, false, true, TabBrowser.hsearch.text, refresh, (file: string) => { let file_name: string = file.substr(file.lastIndexOf(path_sep) + 1); if (file_name != "..") { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Import"))) { + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Import"))) { ImportAsset.run(file); } if (path_is_texture(file)) { - if (UIMenu.menu_button(ui, tr("Set as Envmap"))) { + if (ui_menu_button(ui, tr("Set as Envmap"))) { ImportAsset.run(file, -1.0, -1.0, true, true, () => { base_notify_on_next_frame(() => { let asset_index: i32 = -1; @@ -109,7 +109,7 @@ class TabBrowser { } ///if (is_paint || is_sculpt) - if (UIMenu.menu_button(ui, tr("Set as Mask"))) { + if (ui_menu_button(ui, tr("Set as Mask"))) { ImportAsset.run(file, -1.0, -1.0, true, true, () => { base_notify_on_next_frame(() => { let asset_index: i32 = -1; @@ -128,7 +128,7 @@ class TabBrowser { ///end ///if is_paint - if (UIMenu.menu_button(ui, tr("Set as Color ID Map"))) { + if (ui_menu_button(ui, tr("Set as Color ID Map"))) { ImportAsset.run(file, -1.0, -1.0, true, true, () => { base_notify_on_next_frame(() => { let asset_index: i32 = -1; @@ -141,9 +141,9 @@ class TabBrowser { if (asset_index != -1) { context_raw.colorid_handle.position = asset_index; context_raw.colorid_picked = false; - UIToolbar.toolbar_handle.redraws = 1; + ui_toolbar_handle.redraws = 1; if (context_raw.tool == workspace_tool_t.COLORID) { - UIHeader.header_handle.redraws = 2; + ui_header_handle.redraws = 2; context_raw.ddirty = 2; } } @@ -152,7 +152,7 @@ class TabBrowser { } ///end } - if (UIMenu.menu_button(ui, tr("Open Externally"))) { + if (ui_menu_button(ui, tr("Open Externally"))) { file_start(file); } }, path_is_texture(file) ? 5 : 2); @@ -182,22 +182,22 @@ class TabBrowser { if (zui_button(tr("Disk"), zui_align_t.LEFT)) { ///if krom_android - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Download"))) { - TabBrowser.hpath.text = UIFiles.default_path; + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Download"))) { + TabBrowser.hpath.text = ui_files_default_path; } - if (UIMenu.menu_button(ui, tr("Pictures"))) { + if (ui_menu_button(ui, tr("Pictures"))) { TabBrowser.hpath.text = "/storage/emulated/0/Pictures"; } - if (UIMenu.menu_button(ui, tr("Camera"))) { + if (ui_menu_button(ui, tr("Camera"))) { TabBrowser.hpath.text = "/storage/emulated/0/DCIM/Camera"; } - if (UIMenu.menu_button(ui, tr("Projects"))) { + if (ui_menu_button(ui, tr("Projects"))) { TabBrowser.hpath.text = krom_save_path(); } }, 4); ///else - TabBrowser.hpath.text = UIFiles.default_path; + TabBrowser.hpath.text = ui_files_default_path; ///end } @@ -209,8 +209,8 @@ class TabBrowser { } if (ui.is_hovered && ui.input_released_r) { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Delete"))) { + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Delete"))) { array_remove(config_raw.bookmarks, b); config_save(); } diff --git a/base/Sources/TabBrushes.ts b/base/Sources/TabBrushes.ts index 49ae890c..fe6928bf 100644 --- a/base/Sources/TabBrushes.ts +++ b/base/Sources/TabBrushes.ts @@ -4,7 +4,7 @@ class TabBrushes { static draw = (htab: zui_handle_t) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; if (zui_tab(htab, tr("Brushes"))) { zui_begin_sticky(); zui_row([1 / 4, 1 / 4, 1 / 4]); @@ -12,21 +12,21 @@ class TabBrushes { context_raw.brush = SlotBrush.create(); project_brushes.push(context_raw.brush); MakeMaterial.parse_brush(); - UINodes.hwnd.redraws = 2; + ui_nodes_hwnd.redraws = 2; } if (zui_button(tr("Import"))) { project_import_brush(); } if (zui_button(tr("Nodes"))) { - UIBase.show_brush_nodes(); + ui_base_show_brush_nodes(); } zui_end_sticky(); zui_separator(3, false); - let slotw: i32 = Math.floor(51 * zui_SCALE(ui)); - let num: i32 = Math.floor(config_raw.layout[layout_size_t.SIDEBAR_W] / slotw); + let slotw: i32 = math_floor(51 * zui_SCALE(ui)); + let num: i32 = math_floor(config_raw.layout[layout_size_t.SIDEBAR_W] / slotw); - for (let row: i32 = 0; row < Math.floor(Math.ceil(project_brushes.length / num)); ++row) { + for (let row: i32 = 0; row < math_floor(math_ceil(project_brushes.length / num)); ++row) { let mult: i32 = config_raw.show_asset_names ? 2 : 1; let ar: f32[] = []; for (let i: i32 = 0; i < num * mult; ++i) ar.push(1 / num); @@ -37,7 +37,7 @@ class TabBrushes { if (row > 0) ui._y += off; for (let j: i32 = 0; j < num; ++j) { - let imgw: i32 = Math.floor(50 * zui_SCALE(ui)); + let imgw: i32 = math_floor(50 * zui_SCALE(ui)); let i: i32 = j + row * num; if (i >= project_brushes.length) { zui_end_element(imgw); @@ -51,7 +51,7 @@ class TabBrushes { // Zui.fill(1, -2, img.width + 3, img.height + 3, ui.t.HIGHLIGHT_COL); // TODO let off: i32 = row % 2 == 1 ? 1 : 0; let w: i32 = 50; - if (config_raw.window_scale > 1) w += Math.floor(config_raw.window_scale * 2); + if (config_raw.window_scale > 1) w += math_floor(config_raw.window_scale * 2); zui_fill(-1, -2, w + 3, 2, ui.t.HIGHLIGHT_COL); zui_fill(-1, w - off, w + 3, 2 + off, ui.t.HIGHLIGHT_COL); zui_fill(-1, -2, 2, w + 3, ui.t.HIGHLIGHT_COL); @@ -64,7 +64,7 @@ class TabBrushes { let state: zui_state_t = project_brushes[i].preview_ready ? zui_image(img) : zui_image(resource_get("icons.k"), -1, -1.0, tile * 5, tile, tile, tile); if (state == zui_state_t.STARTED) { if (context_raw.brush != project_brushes[i]) context_select_brush(i); - if (time_time() - context_raw.select_time < 0.25) UIBase.show_brush_nodes(); + if (time_time() - context_raw.select_time < 0.25) ui_base_show_brush_nodes(); context_raw.select_time = time_time(); // app_drag_off_x = -(mouse_x - uix - ui._windowX - 3); // app_drag_off_y = -(mouse_y - uiy - ui._windowY + 1); @@ -73,27 +73,27 @@ class TabBrushes { if (ui.is_hovered && ui.input_released_r) { context_select_brush(i); let add: i32 = project_brushes.length > 1 ? 1 : 0; - UIMenu.draw((ui: zui_t) => { + ui_menu_draw((ui: zui_t) => { //let b: SlotBrushRaw = brushes[i]; - if (UIMenu.menu_button(ui, tr("Export"))) { + if (ui_menu_button(ui, tr("Export"))) { context_select_brush(i); BoxExport.show_brush(); } - if (UIMenu.menu_button(ui, tr("Duplicate"))) { + if (ui_menu_button(ui, tr("Duplicate"))) { let _init = () => { context_raw.brush = SlotBrush.create(); project_brushes.push(context_raw.brush); let cloned: any = json_parse(json_stringify(project_brushes[i].canvas)); context_raw.brush.canvas = cloned; context_set_brush(context_raw.brush); - UtilRender.make_brush_preview(); + util_render_make_brush_preview(); } app_notify_on_init(_init); } - if (project_brushes.length > 1 && UIMenu.menu_button(ui, tr("Delete"), "delete")) { + if (project_brushes.length > 1 && ui_menu_button(ui, tr("Delete"), "delete")) { TabBrushes.delete_brush(project_brushes[i]); } }, 2 + add); @@ -105,7 +105,7 @@ class TabBrushes { let _brush: SlotBrushRaw = context_raw.brush; context_raw.brush = project_brushes[i]; MakeMaterial.parse_brush(); - UtilRender.make_brush_preview(); + util_render_make_brush_preview(); context_raw.brush = _brush; }); } @@ -143,7 +143,7 @@ class TabBrushes { let i: i32 = project_brushes.indexOf(b); context_select_brush(i == project_brushes.length - 1 ? i - 1 : i + 1); project_brushes.splice(i, 1); - UIBase.hwnds[1].redraws = 2; + ui_base_hwnds[1].redraws = 2; } } diff --git a/base/Sources/TabConsole.ts b/base/Sources/TabConsole.ts index 80f9b102..6ae43c64 100644 --- a/base/Sources/TabConsole.ts +++ b/base/Sources/TabConsole.ts @@ -2,13 +2,13 @@ class TabConsole { static draw = (htab: zui_handle_t) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; let title: string = console_message_timer > 0 ? console_message + " " : tr("Console"); let color: i32 = console_message_timer > 0 ? console_message_color : -1; let statush: i32 = config_raw.layout[layout_size_t.STATUS_H]; - if (zui_tab(htab, title, false, color) && statush > UIStatus.default_status_h * zui_SCALE(ui)) { + if (zui_tab(htab, title, false, color) && statush > ui_status_default_status_h * zui_SCALE(ui)) { zui_begin_sticky(); ///if (krom_windows || krom_linux || krom_darwin) // Copy @@ -32,8 +32,8 @@ class TabConsole { } if (zui_button(tr("Export"))) { let str: string = console_last_traces.join("\n"); - UIFiles.show("txt", true, false, (path: string) => { - let f: string = UIFiles.filename; + ui_files_show("txt", true, false, (path: string) => { + let f: string = ui_files_filename; if (f == "") f = tr("untitled"); path = path + path_sep + f; if (!path.endsWith(".txt")) path += ".txt"; @@ -53,7 +53,7 @@ class TabConsole { let _fontSize: i32 = ui.font_size; let f: g2_font_t = data_get_font("font_mono.ttf"); zui_set_font(ui, f); - ui.font_size = Math.floor(15 * zui_SCALE(ui)); + ui.font_size = math_floor(15 * zui_SCALE(ui)); for (let t of console_last_traces) { zui_text(t); } diff --git a/base/Sources/TabFonts.ts b/base/Sources/TabFonts.ts index 5777bf85..e33733cf 100644 --- a/base/Sources/TabFonts.ts +++ b/base/Sources/TabFonts.ts @@ -4,9 +4,9 @@ class TabFonts { static draw = (htab: zui_handle_t) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; let statush: i32 = config_raw.layout[layout_size_t.STATUS_H]; - if (zui_tab(htab, tr("Fonts")) && statush > UIStatus.default_status_h * zui_SCALE(ui)) { + if (zui_tab(htab, tr("Fonts")) && statush > ui_status_default_status_h * zui_SCALE(ui)) { zui_begin_sticky(); if (config_raw.touch_ui) { @@ -20,16 +20,16 @@ class TabFonts { if (ui.is_hovered) zui_tooltip(tr("Import font file")); if (zui_button(tr("2D View"))) { - UIBase.show_2d_view(view_2d_type_t.FONT); + ui_base_show_2d_view(view_2d_type_t.FONT); } zui_end_sticky(); zui_separator(3, false); - let statusw: i32 = sys_width() - UIToolbar.toolbar_w - config_raw.layout[layout_size_t.SIDEBAR_W]; - let slotw: i32 = Math.floor(51 * zui_SCALE(ui)); - let num: i32 = Math.floor(statusw / slotw); + let statusw: i32 = sys_width() - ui_toolbar_w - config_raw.layout[layout_size_t.SIDEBAR_W]; + let slotw: i32 = math_floor(51 * zui_SCALE(ui)); + let num: i32 = math_floor(statusw / slotw); - for (let row: i32 = 0; row < Math.floor(Math.ceil(project_fonts.length / num)); ++row) { + for (let row: i32 = 0; row < math_floor(math_ceil(project_fonts.length / num)); ++row) { let mult: i32 = config_raw.show_asset_names ? 2 : 1; let ar: f32[] = []; for (let i: i32 = 0; i < num * mult; ++i) ar.push(1 / num); @@ -40,7 +40,7 @@ class TabFonts { if (row > 0) ui._y += off; for (let j: i32 = 0; j < num; ++j) { - let imgw: i32 = Math.floor(50 * zui_SCALE(ui)); + let imgw: i32 = math_floor(50 * zui_SCALE(ui)); let i: i32 = j + row * num; if (i >= project_fonts.length) { zui_end_element(imgw); @@ -53,7 +53,7 @@ class TabFonts { // Zui.fill(1, -2, img.width + 3, img.height + 3, ui.t.HIGHLIGHT_COL); // TODO let off: i32 = row % 2 == 1 ? 1 : 0; let w: i32 = 50; - if (config_raw.window_scale > 1) w += Math.floor(config_raw.window_scale * 2); + if (config_raw.window_scale > 1) w += math_floor(config_raw.window_scale * 2); zui_fill(-1, -2, w + 3, 2, ui.t.HIGHLIGHT_COL); zui_fill(-1, w - off, w + 3, 2 + off, ui.t.HIGHLIGHT_COL); zui_fill(-1, -2, 2, w + 3, ui.t.HIGHLIGHT_COL); @@ -64,11 +64,11 @@ class TabFonts { let tile: i32 = zui_SCALE(ui) > 1 ? 100 : 50; let state: zui_state_t = zui_state_t.IDLE; if (project_fonts[i].preview_ready) { - // g2_set_pipeline(UIView2D.pipe); // L8 + // g2_set_pipeline(pipe); // L8 // ///if krom_opengl - // g4_set_pipeline(UIView2D.pipe); + // g4_set_pipeline(pipe); // ///end - // g4_set_int(UIView2D.channelLocation, 1); + // g4_set_int(channelLocation, 1); state = zui_image(img); // g2_set_pipeline(null); } @@ -83,14 +83,14 @@ class TabFonts { } app_notify_on_init(_init); } - if (time_time() - context_raw.select_time < 0.25) UIBase.show_2d_view(view_2d_type_t.FONT); + if (time_time() - context_raw.select_time < 0.25) ui_base_show_2d_view(view_2d_type_t.FONT); context_raw.select_time = time_time(); } if (ui.is_hovered && ui.input_released_r) { context_select_font(i); let add: i32 = project_fonts.length > 1 ? 1 : 0; - UIMenu.draw((ui: zui_t) => { - if (project_fonts.length > 1 && UIMenu.menu_button(ui, tr("Delete"), "delete") && project_fonts[i].file != "") { + ui_menu_draw((ui: zui_t) => { + if (project_fonts.length > 1 && ui_menu_button(ui, tr("Delete"), "delete") && project_fonts[i].file != "") { TabFonts.delete_font(project_fonts[i]); } }, 0 + add); @@ -100,7 +100,7 @@ class TabFonts { app_notify_on_init(() => { let _font: SlotFontRaw = context_raw.font; context_raw.font = project_fonts[i]; - UtilRender.make_font_preview(); + util_render_make_font_preview(); context_raw.font = _font; }); } @@ -142,7 +142,7 @@ class TabFonts { project_fonts.splice(i, 1); } app_notify_on_init(_init); - UIBase.hwnds[2].redraws = 2; + ui_base_hwnds[2].redraws = 2; } } diff --git a/base/Sources/TabHistory.ts b/base/Sources/TabHistory.ts index 0b3ac22d..df88bc35 100644 --- a/base/Sources/TabHistory.ts +++ b/base/Sources/TabHistory.ts @@ -4,7 +4,7 @@ class TabHistory { static draw = (htab: zui_handle_t) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; if (zui_tab(htab, tr("History"))) { for (let i: i32 = 0; i < history_steps.length; ++i) { let active: i32 = history_steps.length - 1 - history_redos; diff --git a/base/Sources/TabMaterials.ts b/base/Sources/TabMaterials.ts index 2b5d22c3..1b56457e 100644 --- a/base/Sources/TabMaterials.ts +++ b/base/Sources/TabMaterials.ts @@ -4,7 +4,7 @@ class TabMaterials { static draw = (htab: zui_handle_t) => { - let mini: bool = config_raw.layout[layout_size_t.SIDEBAR_W] <= UIBase.sidebar_mini_w; + let mini: bool = config_raw.layout[layout_size_t.SIDEBAR_W] <= ui_base_sidebar_mini_w; mini ? TabMaterials.draw_mini(htab) : TabMaterials.draw_full(htab); } @@ -40,19 +40,19 @@ class TabMaterials { } static button_nodes = () => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; if (zui_button(tr("Nodes"))) { - UIBase.show_material_nodes(); + ui_base_show_material_nodes(); } else if (ui.is_hovered) zui_tooltip(tr("Show Node Editor") + ` (${config_keymap.toggle_node_editor})`); } static draw_slots = (mini: bool) => { - let ui: zui_t = UIBase.ui; - let slotw: i32 = Math.floor(51 * zui_SCALE(ui)); - let num: i32 = Math.floor(config_raw.layout[layout_size_t.SIDEBAR_W] / slotw); + let ui: zui_t = ui_base_ui; + let slotw: i32 = math_floor(51 * zui_SCALE(ui)); + let num: i32 = math_floor(config_raw.layout[layout_size_t.SIDEBAR_W] / slotw); - for (let row: i32 = 0; row < Math.floor(Math.ceil(project_materials.length / num)); ++row) { + for (let row: i32 = 0; row < math_floor(math_ceil(project_materials.length / num)); ++row) { let mult: i32 = config_raw.show_asset_names ? 2 : 1; let ar: f32[] = []; for (let i = 0; i < num * mult; ++i) ar.push(1 / num); @@ -63,7 +63,7 @@ class TabMaterials { if (row > 0) ui._y += off; for (let j: i32 = 0; j < num; ++j) { - let imgw: i32 = Math.floor(50 * zui_SCALE(ui)); + let imgw: i32 = math_floor(50 * zui_SCALE(ui)); let i: i32 = j + row * num; if (i >= project_materials.length) { zui_end_element(imgw); @@ -82,7 +82,7 @@ class TabMaterials { else { let off: i32 = row % 2 == 1 ? 1 : 0; let w: i32 = 50; - if (config_raw.window_scale > 1) w += Math.floor(config_raw.window_scale * 2); + if (config_raw.window_scale > 1) w += math_floor(config_raw.window_scale * 2); zui_fill(-1, -2, w + 3, 2, ui.t.HIGHLIGHT_COL); zui_fill(-1, w - off, w + 3, 2 + off, ui.t.HIGHLIGHT_COL); zui_fill(-1, -2, 2, w + 3, ui.t.HIGHLIGHT_COL); @@ -98,13 +98,13 @@ class TabMaterials { let uix: f32 = ui._x; let uiy: f32 = ui._y; let tile: i32 = zui_SCALE(ui) > 1 ? 100 : 50; - let imgh: f32 = mini ? UIBase.default_sidebar_mini_w * 0.85 * zui_SCALE(ui) : -1.0; + let imgh: f32 = mini ? ui_base_default_sidebar_mini_w * 0.85 * zui_SCALE(ui) : -1.0; let state = project_materials[i].preview_ready ? zui_image(img, 0xffffffff, imgh) : zui_image(resource_get("icons.k"), 0xffffffff, -1.0, tile, tile, tile, tile); // Draw material numbers when selecting a material via keyboard shortcut - let is_typing: bool = ui.is_typing || UIView2D.ui.is_typing || UINodes.ui.is_typing; + let is_typing: bool = ui.is_typing || ui_view2d_ui.is_typing || ui_nodes_ui.is_typing; if (!is_typing) { if (i < 9 && operator_shortcut(config_keymap.select_material, shortcut_type_t.DOWN)) { let number: string = String(i + 1); @@ -135,7 +135,7 @@ class TabMaterials { base_drag_material = context_raw.material; // Double click to show nodes if (time_time() - context_raw.select_time < 0.25) { - UIBase.show_material_nodes(); + ui_base_show_material_nodes(); base_drag_material = null; base_is_dragging = false; } @@ -147,27 +147,27 @@ class TabMaterials { context_select_material(i); let add: i32 = project_materials.length > 1 ? 1 : 0; - UIMenu.draw((ui: zui_t) => { + ui_menu_draw((ui: zui_t) => { let m: SlotMaterialRaw = project_materials[i]; - if (UIMenu.menu_button(ui, tr("To Fill Layer"))) { + if (ui_menu_button(ui, tr("To Fill Layer"))) { context_select_material(i); base_create_fill_layer(); } - if (UIMenu.menu_button(ui, tr("Export"))) { + if (ui_menu_button(ui, tr("Export"))) { context_select_material(i); BoxExport.show_material(); } ///if is_paint - if (UIMenu.menu_button(ui, tr("Bake"))) { + if (ui_menu_button(ui, tr("Bake"))) { context_select_material(i); BoxExport.show_bake_material(); } ///end - if (UIMenu.menu_button(ui, tr("Duplicate"))) { + if (ui_menu_button(ui, tr("Duplicate"))) { let _init = () => { context_raw.material = SlotMaterial.create(project_materials[0].data); project_materials.push(context_raw.material); @@ -179,7 +179,7 @@ class TabMaterials { app_notify_on_init(_init); } - if (project_materials.length > 1 && UIMenu.menu_button(ui, tr("Delete"), "delete")) { + if (project_materials.length > 1 && ui_menu_button(ui, tr("Delete"), "delete")) { TabMaterials.delete_material(m); } @@ -192,23 +192,23 @@ class TabMaterials { let height_handle: zui_handle_t = zui_nest(zui_handle("tabmaterials_6"), m.id, {selected: m.paint_height}); let emis_handle: zui_handle_t = zui_nest(zui_handle("tabmaterials_7"), m.id, {selected: m.paint_emis}); let subs_handle: zui_handle_t = zui_nest(zui_handle("tabmaterials_8"), m.id, {selected: m.paint_subs}); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); m.paint_base = zui_check(base_handle, tr("Base Color")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); m.paint_opac = zui_check(opac_handle, tr("Opacity")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); m.paint_nor = zui_check(nor_handle, tr("Normal")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); m.paint_occ = zui_check(occ_handle, tr("Occlusion")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); m.paint_rough = zui_check(rough_handle, tr("Roughness")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); m.paint_met = zui_check(met_handle, tr("Metallic")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); m.paint_height = zui_check(height_handle, tr("Height")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); m.paint_emis = zui_check(emis_handle, tr("Emission")); - UIMenu.menu_fill(ui); + ui_menu_fill(ui); m.paint_subs = zui_check(subs_handle, tr("Subsurface")); if (base_handle.changed || opac_handle.changed || @@ -220,7 +220,7 @@ class TabMaterials { emis_handle.changed || subs_handle.changed) { MakeMaterial.parse_paint_material(); - UIMenu.keep_open = true; + ui_menu_keep_open = true; } }, 13 + add); } @@ -273,13 +273,13 @@ class TabMaterials { } static update_material = () => { - UIHeader.header_handle.redraws = 2; - UINodes.hwnd.redraws = 2; - UINodes.group_stack = []; + ui_header_handle.redraws = 2; + ui_nodes_hwnd.redraws = 2; + ui_nodes_group_stack = []; MakeMaterial.parse_paint_material(); - UtilRender.make_material_preview(); + util_render_make_material_preview(); let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; - if (decal) UtilRender.make_decal_preview(); + if (decal) util_render_make_decal_preview(); } static update_material_pointers = (nodes: zui_node_t[], i: i32) => { @@ -325,7 +325,7 @@ class TabMaterials { history_delete_material(); context_select_material(i == project_materials.length - 1 ? i - 1 : i + 1); project_materials.splice(i, 1); - UIBase.hwnds[1].redraws = 2; + ui_base_hwnds[1].redraws = 2; for (let m of project_materials) TabMaterials.update_material_pointers(m.canvas.nodes, i); } } diff --git a/base/Sources/TabMeshes.ts b/base/Sources/TabMeshes.ts index 25f554dc..61d85007 100644 --- a/base/Sources/TabMeshes.ts +++ b/base/Sources/TabMeshes.ts @@ -2,9 +2,9 @@ class TabMeshes { static draw = (htab: zui_handle_t) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; let statush: i32 = config_raw.layout[layout_size_t.STATUS_H]; - if (zui_tab(htab, tr("Meshes")) && statush > UIStatus.default_status_h * zui_SCALE(ui)) { + if (zui_tab(htab, tr("Meshes")) && statush > ui_status_default_status_h * zui_SCALE(ui)) { zui_begin_sticky(); @@ -27,11 +27,11 @@ class TabMeshes { ///end if (zui_button(tr("Import"))) { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Replace Existing"), `${config_keymap.file_import_assets}`)) { + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Replace Existing"), `${config_keymap.file_import_assets}`)) { project_import_mesh(true); } - if (UIMenu.menu_button(ui, tr("Append"))) { + if (ui_menu_button(ui, tr("Append"))) { project_import_mesh(false); } }, 2); @@ -40,60 +40,60 @@ class TabMeshes { ///if is_lab if (zui_button(tr("Set Default"))) { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Cube"))) TabMeshes.set_default_mesh(".Cube"); - if (UIMenu.menu_button(ui, tr("Plane"))) TabMeshes.set_default_mesh(".Plane"); - if (UIMenu.menu_button(ui, tr("Sphere"))) TabMeshes.set_default_mesh(".Sphere"); - if (UIMenu.menu_button(ui, tr("Cylinder"))) TabMeshes.set_default_mesh(".Cylinder"); + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Cube"))) TabMeshes.set_default_mesh(".Cube"); + if (ui_menu_button(ui, tr("Plane"))) TabMeshes.set_default_mesh(".Plane"); + if (ui_menu_button(ui, tr("Sphere"))) TabMeshes.set_default_mesh(".Sphere"); + if (ui_menu_button(ui, tr("Cylinder"))) TabMeshes.set_default_mesh(".Cylinder"); }, 4); } ///end if (zui_button(tr("Flip Normals"))) { - UtilMesh.flip_normals(); + util_mesh_flip_normals(); context_raw.ddirty = 2; } if (zui_button(tr("Calculate Normals"))) { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Smooth"))) { UtilMesh.calc_normals(true); context_raw.ddirty = 2; } - if (UIMenu.menu_button(ui, tr("Flat"))) { UtilMesh.calc_normals(false); context_raw.ddirty = 2; } + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Smooth"))) { util_mesh_calc_normals(true); context_raw.ddirty = 2; } + if (ui_menu_button(ui, tr("Flat"))) { util_mesh_calc_normals(false); context_raw.ddirty = 2; } }, 2); } if (zui_button(tr("Geometry to Origin"))) { - UtilMesh.to_origin(); + util_mesh_to_origin(); context_raw.ddirty = 2; } if (zui_button(tr("Apply Displacement"))) { ///if is_paint - UtilMesh.apply_displacement(project_layers[0].texpaint_pack); + util_mesh_apply_displacement(project_layers[0].texpaint_pack); ///end ///if is_lab let displace_strength: f32 = config_raw.displace_strength > 0 ? config_raw.displace_strength : 1.0; let uv_scale: f32 = scene_meshes[0].data.scale_tex * context_raw.brush_scale; - UtilMesh.apply_displacement(BrushOutputNode.inst.texpaint_pack, 0.05 * displace_strength, uv_scale); + util_mesh_apply_displacement(BrushOutputNode.inst.texpaint_pack, 0.05 * displace_strength, uv_scale); ///end - UtilMesh.calc_normals(); + util_mesh_calc_normals(); context_raw.ddirty = 2; } if (zui_button(tr("Rotate"))) { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Rotate X"))) { - UtilMesh.swap_axis(1, 2); + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Rotate X"))) { + util_mesh_swap_axis(1, 2); context_raw.ddirty = 2; } - if (UIMenu.menu_button(ui, tr("Rotate Y"))) { - UtilMesh.swap_axis(2, 0); + if (ui_menu_button(ui, tr("Rotate Y"))) { + util_mesh_swap_axis(2, 0); context_raw.ddirty = 2; } - if (UIMenu.menu_button(ui, tr("Rotate Z"))) { - UtilMesh.swap_axis(0, 1); + if (ui_menu_button(ui, tr("Rotate Z"))) { + util_mesh_swap_axis(0, 1); context_raw.ddirty = 2; } }, 3); @@ -107,12 +107,12 @@ class TabMeshes { h.selected = o.base.visible; o.base.visible = zui_check(h, o.base.name); if (ui.is_hovered && ui.input_released_r) { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Export"))) { + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Export"))) { context_raw.export_mesh_index = i + 1; BoxExport.show_mesh(); } - if (project_paint_objects.length > 1 && UIMenu.menu_button(ui, tr("Delete"))) { + if (project_paint_objects.length > 1 && ui_menu_button(ui, tr("Delete"))) { array_remove(project_paint_objects, o); while (o.base.children.length > 0) { let child: object_t = o.base.children[0]; @@ -128,7 +128,7 @@ class TabMeshes { data_delete_mesh(o.data._.handle); mesh_object_remove(o); context_raw.paint_object = context_main_object(); - UtilMesh.merge_mesh(); + util_mesh_merge(); context_raw.ddirty = 2; } }, project_paint_objects.length > 1 ? 2 : 1); @@ -136,7 +136,7 @@ class TabMeshes { if (h.changed) { let visibles: mesh_object_t[] = []; for (let p of project_paint_objects) if (p.base.visible) visibles.push(p); - UtilMesh.merge_mesh(visibles); + util_mesh_merge(visibles); context_raw.ddirty = 2; } } @@ -148,7 +148,7 @@ class TabMeshes { let mo: mesh_object_t = null; if (name == ".Plane" || name == ".Sphere") { let res: i32 = config_raw.rp_supersample > 1.0 ? 2048 : 1024; - let mesh: any = name == ".Plane" ? geom_make_plane(1, 1, res, res) : geom_make_uv_sphere(1.0, res, Math.floor(res / 2), false, 2.0); + let mesh: any = name == ".Plane" ? geom_make_plane(1, 1, res, res) : geom_make_uv_sphere(1.0, res, math_floor(res / 2), false, 2.0); let raw: any = { name: "Tessellated", vertex_arrays: [ @@ -175,7 +175,7 @@ class TabMeshes { context_raw.ddirty = 2; context_raw.paint_object = mo; project_paint_objects[0] = mo; - if (UIHeader.worktab.position == space_type_t.SPACE3D) { + if (ui_header_worktab.position == space_type_t.SPACE3D) { scene_meshes = [mo]; } diff --git a/base/Sources/TabPlugins.ts b/base/Sources/TabPlugins.ts index 2c109009..797b0838 100644 --- a/base/Sources/TabPlugins.ts +++ b/base/Sources/TabPlugins.ts @@ -2,7 +2,7 @@ class TabPlugins { static draw = (htab: zui_handle_t) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; if (zui_tab(htab, tr("Plugins"))) { zui_begin_sticky(); diff --git a/base/Sources/TabScript.ts b/base/Sources/TabScript.ts index 9fa03f84..dd2c7a9a 100644 --- a/base/Sources/TabScript.ts +++ b/base/Sources/TabScript.ts @@ -5,9 +5,9 @@ class TabScript { static text_coloring: zui_text_coloring_t = null; static draw = (htab: zui_handle_t) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; let statush: i32 = config_raw.layout[layout_size_t.STATUS_H]; - if (zui_tab(htab, tr("Script")) && statush > UIStatus.default_status_h * zui_SCALE(ui)) { + if (zui_tab(htab, tr("Script")) && statush > ui_status_default_status_h * zui_SCALE(ui)) { zui_begin_sticky(); if (config_raw.touch_ui) { @@ -28,7 +28,7 @@ class TabScript { TabScript.hscript.text = ""; } if (zui_button(tr("Import"))) { - UIFiles.show("js", false, false, (path: string) => { + ui_files_show("js", false, false, (path: string) => { let b: ArrayBuffer = data_get_blob(path); TabScript.hscript.text = sys_buffer_to_string(b); data_delete_blob(path); @@ -36,8 +36,8 @@ class TabScript { } if (zui_button(tr("Export"))) { let str: string = TabScript.hscript.text; - UIFiles.show("js", true, false, (path: string) => { - let f: string = UIFiles.filename; + ui_files_show("js", true, false, (path: string) => { + let f: string = ui_files_filename; if (f == "") f = tr("untitled"); path = path + path_sep + f; if (!path.endsWith(".js")) path += ".js"; @@ -50,7 +50,7 @@ class TabScript { let _font_size: i32 = ui.font_size; let f: g2_font_t = data_get_font("font_mono.ttf"); zui_set_font(ui, f); - ui.font_size = Math.floor(15 * zui_SCALE(ui)); + ui.font_size = math_floor(15 * zui_SCALE(ui)); zui_set_text_area_line_numbers(true); zui_set_text_area_scroll_past_end(true); zui_set_text_area_coloring(TabScript.get_text_coloring()); @@ -66,10 +66,10 @@ class TabScript { static get_text_coloring = (): zui_text_coloring_t => { if (TabScript.text_coloring == null) { let blob: ArrayBuffer = data_get_blob("text_coloring.json"); - TabScript.text_coloring = JSON.parse(sys_buffer_to_string(blob)); - TabScript.text_coloring.default_color = Math.floor(TabScript.text_coloring.default_color); + TabScript.text_coloring = json_parse(sys_buffer_to_string(blob)); + TabScript.text_coloring.default_color = math_floor(TabScript.text_coloring.default_color); for (let coloring of TabScript.text_coloring.colorings) { - coloring.color = Math.floor(coloring.color); + coloring.color = math_floor(coloring.color); } } return TabScript.text_coloring; diff --git a/base/Sources/TabSwatches.ts b/base/Sources/TabSwatches.ts index 14cfd76b..aba816a0 100644 --- a/base/Sources/TabSwatches.ts +++ b/base/Sources/TabSwatches.ts @@ -21,9 +21,9 @@ class TabSwatches { } static draw = (htab: zui_handle_t) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; let statush: i32 = config_raw.layout[layout_size_t.STATUS_H]; - if (zui_tab(htab, tr("Swatches")) && statush > UIStatus.default_status_h * zui_SCALE(ui)) { + if (zui_tab(htab, tr("Swatches")) && statush > ui_status_default_status_h * zui_SCALE(ui)) { zui_begin_sticky(); if (config_raw.touch_ui) { @@ -40,12 +40,12 @@ class TabSwatches { if (ui.is_hovered) zui_tooltip(tr("Add new swatch")); if (zui_button(tr("Import"))) { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Replace Existing"))) { + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Replace Existing"))) { project_import_swatches(true); context_set_swatch(project_raw.swatches[0]); } - if (UIMenu.menu_button(ui, tr("Append"))) { + if (ui_menu_button(ui, tr("Append"))) { project_import_swatches(false); } }, 2); @@ -69,13 +69,13 @@ class TabSwatches { zui_end_sticky(); zui_separator(3, false); - let slotw: i32 = Math.floor(26 * zui_SCALE(ui)); - let num: i32 = Math.floor(ui._w / (slotw + 3)); + let slotw: i32 = math_floor(26 * zui_SCALE(ui)); + let num: i32 = math_floor(ui._w / (slotw + 3)); let drag_pos_set: bool = false; let uix: f32 = 0.0; let uiy: f32 = 0.0; - for (let row: i32 = 0; row < Math.floor(Math.ceil(project_raw.swatches.length / num)); ++row) { + for (let row: i32 = 0; row < math_floor(math_ceil(project_raw.swatches.length / num)); ++row) { let ar: f32[] = []; for (let i: i32 = 0; i < num; ++i) ar.push(1 / num); zui_row(ar); @@ -118,7 +118,7 @@ class TabSwatches { } else if (state == zui_state_t.RELEASED) { if (time_time() - context_raw.select_time < 0.25) { - UIMenu.draw((ui: zui_t) => { + ui_menu_draw((ui: zui_t) => { ui.changed = false; let h: zui_handle_t = zui_handle("tabswatches_0"); h.color = context_raw.swatch.base; @@ -146,9 +146,9 @@ class TabSwatches { hheight.value = context_raw.swatch.height; context_raw.swatch.height = zui_slider(hheight, "Height", 0, 1, true); - if (ui.changed || ui.is_typing) UIMenu.keep_open = true; + if (ui.changed || ui.is_typing) ui_menu_keep_open = true; if (ui.input_released) context_set_swatch(context_raw.swatch); // Trigger material preview update - }, 16, Math.floor(mouse_x - 200 * zui_SCALE(ui)), Math.floor(mouse_y - 250 * zui_SCALE(ui))); + }, 16, math_floor(mouse_x - 200 * zui_SCALE(ui)), math_floor(mouse_y - 250 * zui_SCALE(ui))); } context_raw.select_time = time_time(); @@ -167,13 +167,13 @@ class TabSwatches { add += 1; ///end - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Duplicate"))) { + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Duplicate"))) { context_set_swatch(project_clone_swatch(context_raw.swatch)); project_raw.swatches.push(context_raw.swatch); } ///if (krom_windows || krom_linux || krom_darwin) - else if (UIMenu.menu_button(ui, tr("Copy Hex Code"))) { + else if (ui_menu_button(ui, tr("Copy Hex Code"))) { let color: i32 = context_raw.swatch.base; color = color_set_ab(color, context_raw.swatch.opacity * 255); let val: i32 = color; @@ -181,14 +181,14 @@ class TabSwatches { krom_copy_to_clipboard(val.toString(16)); } ///end - else if (project_raw.swatches.length > 1 && UIMenu.menu_button(ui, tr("Delete"), "delete")) { + else if (project_raw.swatches.length > 1 && ui_menu_button(ui, tr("Delete"), "delete")) { TabSwatches.delete_swatch(project_raw.swatches[i]); } ///if (is_paint || is_sculpt) - else if (UIMenu.menu_button(ui, tr("Create Material"))) { + else if (ui_menu_button(ui, tr("Create Material"))) { TabMaterials.accept_swatch_drag(project_raw.swatches[i]); } - else if (UIMenu.menu_button(ui, tr("Create Color Layer"))) { + else if (ui_menu_button(ui, tr("Create Color Layer"))) { let color: i32 = project_raw.swatches[i].base; color = color_set_ab(color, project_raw.swatches[i].opacity * 255); base_create_color_layer(color, project_raw.swatches[i].occlusion, project_raw.swatches[i].roughness, project_raw.swatches[i].metallic); @@ -236,7 +236,7 @@ class TabSwatches { if (swatch_pos == -1) { project_raw.swatches.splice(TabSwatches.drag_pos, 0, swatch); } - else if (Math.abs(swatch_pos - TabSwatches.drag_pos) > 0) { // Existing swatch is reordered + else if (math_abs(swatch_pos - TabSwatches.drag_pos) > 0) { // Existing swatch is reordered array_remove(project_raw.swatches, swatch); // If the new position is after the old one, decrease by one because the swatch has been deleted let new_pos: i32 = TabSwatches.drag_pos - swatch_pos > 0 ? TabSwatches.drag_pos -1 : TabSwatches.drag_pos; @@ -248,6 +248,6 @@ class TabSwatches { let i: i32 = project_raw.swatches.indexOf(swatch); context_set_swatch(project_raw.swatches[i == project_raw.swatches.length - 1 ? i - 1 : i + 1]); project_raw.swatches.splice(i, 1); - UIBase.hwnds[tab_area_t.STATUS].redraws = 2; + ui_base_hwnds[tab_area_t.STATUS].redraws = 2; } } diff --git a/base/Sources/TabTextures.ts b/base/Sources/TabTextures.ts index df62f48a..02a20f55 100644 --- a/base/Sources/TabTextures.ts +++ b/base/Sources/TabTextures.ts @@ -2,9 +2,9 @@ class TabTextures { static draw = (htab: zui_handle_t) => { - let ui: zui_t = UIBase.ui; + let ui: zui_t = ui_base_ui; let statush: i32 = config_raw.layout[layout_size_t.STATUS_H]; - if (zui_tab(htab, tr("Textures")) && statush > UIStatus.default_status_h * zui_SCALE(ui)) { + if (zui_tab(htab, tr("Textures")) && statush > ui_status_default_status_h * zui_SCALE(ui)) { zui_begin_sticky(); @@ -16,30 +16,30 @@ class TabTextures { } if (zui_button(tr("Import"))) { - UIFiles.show(path_texture_formats.join(","), false, true, (path: string) => { + ui_files_show(path_texture_formats.join(","), false, true, (path: string) => { ImportAsset.run(path, -1.0, -1.0, true, false); - UIBase.hwnds[tab_area_t.STATUS].redraws = 2; + ui_base_hwnds[tab_area_t.STATUS].redraws = 2; }); } if (ui.is_hovered) zui_tooltip(tr("Import texture file") + ` (${config_keymap.file_import_assets})`); - if (zui_button(tr("2D View"))) UIBase.show_2d_view(view_2d_type_t.ASSET); + if (zui_button(tr("2D View"))) ui_base_show_2d_view(view_2d_type_t.ASSET); zui_end_sticky(); if (project_assets.length > 0) { ///if (is_paint || is_sculpt) - let statusw: i32 = sys_width() - UIToolbar.toolbar_w - config_raw.layout[layout_size_t.SIDEBAR_W]; + let statusw: i32 = sys_width() - ui_toolbar_w - config_raw.layout[layout_size_t.SIDEBAR_W]; ///end ///if is_lab let statusw: i32 = sys_width(); ///end - let slotw: i32 = Math.floor(52 * zui_SCALE(ui)); - let num: i32 = Math.floor(statusw / slotw); + let slotw: i32 = math_floor(52 * zui_SCALE(ui)); + let num: i32 = math_floor(statusw / slotw); - for (let row: i32 = 0; row < Math.floor(Math.ceil(project_assets.length / num)); ++row) { + for (let row: i32 = 0; row < math_floor(math_ceil(project_assets.length / num)); ++row) { let mult: i32 = config_raw.show_asset_names ? 2 : 1; let ar: f32[] = []; for (let i: i32 = 0; i < num * mult; ++i) ar.push(1 / num); @@ -50,7 +50,7 @@ class TabTextures { if (row > 0) ui._y += off; for (let j: i32 = 0; j < num; ++j) { - let imgw: i32 = Math.floor(50 * zui_SCALE(ui)); + let imgw: i32 = math_floor(50 * zui_SCALE(ui)); let i: i32 = j + row * num; if (i >= project_assets.length) { zui_end_element(imgw); @@ -69,9 +69,9 @@ class TabTextures { base_drag_asset = asset; context_raw.texture = asset; - if (time_time() - context_raw.select_time < 0.25) UIBase.show_2d_view(view_2d_type_t.ASSET); + if (time_time() - context_raw.select_time < 0.25) ui_base_show_2d_view(view_2d_type_t.ASSET); context_raw.select_time = time_time(); - UIView2D.hwnd.redraws = 2; + ui_view2d_hwnd.redraws = 2; } if (asset == context_raw.texture) { @@ -108,9 +108,9 @@ class TabTextures { count = is_packed ? 6 : 6; ///end - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Export"))) { - UIFiles.show("png", true, false, (path: string) => { + ui_menu_draw((ui: zui_t) => { + if (ui_menu_button(ui, tr("Export"))) { + ui_files_show("png", true, false, (path: string) => { base_notify_on_next_frame(() => { ///if (is_paint || is_sculpt) if (base_pipe_merge == null) base_make_pipe(); @@ -126,7 +126,7 @@ class TabTextures { g2_set_pipeline(null); g2_end(); base_notify_on_next_frame(() => { - let f: string = UIFiles.filename; + let f: string = ui_files_filename; if (f == "") f = tr("untitled"); if (!f.endsWith(".png")) f += ".png"; krom_write_png(path + path_sep + f, image_get_pixels(target), target.width, target.height, 0); @@ -135,43 +135,43 @@ class TabTextures { }); }); } - if (UIMenu.menu_button(ui, tr("Reimport"))) { + if (ui_menu_button(ui, tr("Reimport"))) { project_reimport_texture(asset); } ///if (is_paint || is_sculpt) - if (UIMenu.menu_button(ui, tr("To Mask"))) { + if (ui_menu_button(ui, tr("To Mask"))) { base_notify_on_next_frame(() => { base_create_image_mask(asset); }); } ///end - if (UIMenu.menu_button(ui, tr("Set as Envmap"))) { + if (ui_menu_button(ui, tr("Set as Envmap"))) { base_notify_on_next_frame(() => { ImportEnvmap.run(asset.file, img); }); } ///if is_paint - if (UIMenu.menu_button(ui, tr("Set as Color ID Map"))) { + if (ui_menu_button(ui, tr("Set as Color ID Map"))) { context_raw.colorid_handle.position = i; context_raw.colorid_picked = false; - UIToolbar.toolbar_handle.redraws = 1; + ui_toolbar_handle.redraws = 1; if (context_raw.tool == workspace_tool_t.COLORID) { - UIHeader.header_handle.redraws = 2; + ui_header_handle.redraws = 2; context_raw.ddirty = 2; } } ///end - if (UIMenu.menu_button(ui, tr("Delete"), "delete")) { + if (ui_menu_button(ui, tr("Delete"), "delete")) { TabTextures.delete_texture(asset); } - if (!is_packed && UIMenu.menu_button(ui, tr("Open Containing Directory..."))) { + if (!is_packed && ui_menu_button(ui, tr("Open Containing Directory..."))) { file_start(asset.file.substr(0, asset.file.lastIndexOf(path_sep))); } - if (!is_packed && UIMenu.menu_button(ui, tr("Open in Browser"))) { + if (!is_packed && ui_menu_button(ui, tr("Open in Browser"))) { TabBrowser.show_directory(asset.file.substr(0, asset.file.lastIndexOf(path_sep))); } }, count); @@ -235,14 +235,14 @@ class TabTextures { if (project_assets.length > 1) { context_raw.texture = project_assets[i == project_assets.length - 1 ? i - 1 : i + 1]; } - UIBase.hwnds[tab_area_t.STATUS].redraws = 2; + ui_base_hwnds[tab_area_t.STATUS].redraws = 2; ///if is_paint if (context_raw.tool == workspace_tool_t.COLORID && i == context_raw.colorid_handle.position) { - UIHeader.header_handle.redraws = 2; + ui_header_handle.redraws = 2; context_raw.ddirty = 2; context_raw.colorid_picked = false; - UIToolbar.toolbar_handle.redraws = 1; + ui_toolbar_handle.redraws = 1; } ///end @@ -254,8 +254,8 @@ class TabTextures { MakeMaterial.parse_paint_material(); ///if (is_paint || is_sculpt) - UtilRender.make_material_preview(); - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; + util_render_make_material_preview(); + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; ///end } base_notify_on_next_frame(_next); diff --git a/base/Sources/UIBase.ts b/base/Sources/UIBase.ts deleted file mode 100644 index 3229c7db..00000000 --- a/base/Sources/UIBase.ts +++ /dev/null @@ -1,1533 +0,0 @@ - -///if is_paint -/// -///end -///if is_sculpt -/// -///end -///if is_forge -/// -///end -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// - -class UIBase { - - static show: bool = true; - static ui: zui_t; - static border_started: i32 = 0; - static border_handle_ptr: i32 = 0; - static action_paint_remap: string = ""; - static operator_search_offset: i32 = 0; - static undo_tap_time: f32 = 0.0; - static redo_tap_time: f32 = 0.0; - - static init_hwnds = (): zui_handle_t[] => { - ///if is_paint - return [zui_handle_create(), zui_handle_create(), zui_handle_create()]; - ///end - ///if is_sculpt - return [zui_handle_create(), zui_handle_create(), zui_handle_create()]; - ///end - ///if is_lab - return [zui_handle_create()]; - ///end - } - - static init_htabs = (): zui_handle_t[] => { - ///if is_paint - return [zui_handle_create(), zui_handle_create(), zui_handle_create()]; - ///end - ///if is_sculpt - return [zui_handle_create(), zui_handle_create(), zui_handle_create()]; - ///end - ///if is_lab - return [zui_handle_create()]; - ///end - } - - static init_hwnd_tabs = (): any[] => { - ///if is_paint - return [ - [TabLayers.draw, TabHistory.draw, TabPlugins.draw - ///if is_forge - , TabObjects.draw - ///end - ], - [TabMaterials.draw, TabBrushes.draw, TabParticles.draw], - [TabBrowser.draw, TabTextures.draw, TabMeshes.draw, TabFonts.draw, TabSwatches.draw, TabScript.draw, TabConsole.draw, UIStatus.draw_version_tab] - ]; - ///end - ///if is_sculpt - return [ - [TabLayers.draw, TabHistory.draw, TabPlugins.draw - ///if is_forge - , TabObjects.draw - ///end - ], - [TabMaterials.draw, TabBrushes.draw, TabParticles.draw], - [TabBrowser.draw, TabTextures.draw, TabMeshes.draw, TabFonts.draw, TabScript.draw, TabConsole.draw, UIStatus.draw_version_tab] - ]; - ///end - ///if is_lab - return [ - [TabBrowser.draw, TabTextures.draw, TabMeshes.draw, TabSwatches.draw, TabPlugins.draw, TabScript.draw, TabConsole.draw, UIStatus.draw_version_tab] - ]; - ///end - } - - static hwnds: zui_handle_t[] = UIBase.init_hwnds(); - static htabs: zui_handle_t[] = UIBase.init_htabs(); - static hwnd_tabs: any[] = UIBase.init_hwnd_tabs(); - - ///if (is_paint || is_sculpt) - static default_sidebar_mini_w: i32 = 56; - static default_sidebar_full_w: i32 = 280; - ///if (krom_android || krom_ios) - static default_sidebar_w: i32 = UIBase.default_sidebar_mini_w; - ///else - static default_sidebar_w: i32 = UIBase.default_sidebar_full_w; - ///end - static tabx: i32 = 0; - static hminimized: zui_handle_t = zui_handle_create(); - static sidebar_mini_w: i32 = UIBase.default_sidebar_mini_w; - ///end - - constructor() { - ///if (is_paint || is_sculpt) - new UIToolbar(); - UIToolbar.toolbar_w = Math.floor(UIToolbar.default_toolbar_w * config_raw.window_scale); - context_raw.text_tool_text = tr("Text"); - ///end - - new UIHeader(); - new UIStatus(); - new UIMenubar(); - - UIHeader.headerh = Math.floor(UIHeader.default_header_h * config_raw.window_scale); - UIMenubar.menubarw = Math.floor(UIMenubar.default_menubar_w * config_raw.window_scale); - - ///if (is_paint || is_sculpt) - if (project_materials == null) { - project_materials = []; - let m: material_data_t = data_get_material("Scene", "Material"); - project_materials.push(SlotMaterial.create(m)); - context_raw.material = project_materials[0]; - } - - if (project_brushes == null) { - project_brushes = []; - project_brushes.push(SlotBrush.create()); - context_raw.brush = project_brushes[0]; - MakeMaterial.parse_brush(); - } - - if (project_fonts == null) { - project_fonts = []; - project_fonts.push(SlotFont.create("default.ttf", base_font)); - context_raw.font = project_fonts[0]; - } - - if (project_layers == null) { - project_layers = []; - project_layers.push(SlotLayer.create()); - context_raw.layer = project_layers[0]; - } - ///end - - ///if is_lab - if (project_material_data == null) { - let m: material_data_t = data_get_material("Scene", "Material"); - project_material_data = m; - } - - if (project_default_canvas == null) { // Synchronous - let b: ArrayBuffer = data_get_blob("default_brush.arm"); - project_default_canvas = b; - } - - project_nodes = zui_nodes_create(); - project_canvas = armpack_decode(project_default_canvas); - project_canvas.name = "Brush 1"; - - context_parse_brush_inputs(); - - ParserLogic.parse(project_canvas); - ///end - - if (project_raw.swatches == null) { - project_set_default_swatches(); - context_raw.swatch = project_raw.swatches[0]; - } - - if (context_raw.empty_envmap == null) { - let b: Uint8Array = new Uint8Array(4); - b[0] = 8; - b[1] = 8; - b[2] = 8; - b[3] = 255; - context_raw.empty_envmap = image_from_bytes(b.buffer, 1, 1); - } - if (context_raw.preview_envmap == null) { - let b: Uint8Array = new Uint8Array(4); - b[0] = 0; - b[1] = 0; - b[2] = 0; - b[3] = 255; - context_raw.preview_envmap = image_from_bytes(b.buffer, 1, 1); - } - - let world: world_data_t = scene_world; - if (context_raw.saved_envmap == null) { - // raw.savedEnvmap = world._envmap; - context_raw.default_irradiance = world._.irradiance; - context_raw.default_radiance = world._.radiance; - context_raw.default_radiance_mipmaps = world._.radiance_mipmaps; - } - world._.envmap = context_raw.show_envmap ? context_raw.saved_envmap : context_raw.empty_envmap; - context_raw.ddirty = 1; - - history_reset(); - - let scale: f32 = config_raw.window_scale; - UIBase.ui = zui_create({ theme: base_theme, font: base_font, scale_factor: scale, color_wheel: base_color_wheel, black_white_gradient: base_color_wheel_gradient }); - zui_set_on_border_hover(UIBase.on_border_hover); - zui_set_on_text_hover(UIBase.on_text_hover); - zui_set_on_deselect_text(UIBase.on_deselect_text); - zui_set_on_tab_drop(UIBase.on_tab_drop); - - ///if (is_paint || is_sculpt) - let resources: string[] = ["cursor.k", "icons.k"]; - ///end - ///if is_lab - let resources: string[] = ["cursor.k", "icons.k", "placeholder.k"]; - ///end - - ///if (is_paint || is_sculpt) - context_raw.gizmo = scene_get_child(".Gizmo"); - context_raw.gizmo_translate_x = object_get_child(context_raw.gizmo, ".TranslateX"); - context_raw.gizmo_translate_y = object_get_child(context_raw.gizmo, ".TranslateY"); - context_raw.gizmo_translate_z = object_get_child(context_raw.gizmo, ".TranslateZ"); - context_raw.gizmo_scale_x = object_get_child(context_raw.gizmo, ".ScaleX"); - context_raw.gizmo_scale_y = object_get_child(context_raw.gizmo, ".ScaleY"); - context_raw.gizmo_scale_z = object_get_child(context_raw.gizmo, ".ScaleZ"); - context_raw.gizmo_rotate_x = object_get_child(context_raw.gizmo, ".RotateX"); - context_raw.gizmo_rotate_y = object_get_child(context_raw.gizmo, ".RotateY"); - context_raw.gizmo_rotate_z = object_get_child(context_raw.gizmo, ".RotateZ"); - ///end - - resource_load(resources, () => {}); - - if (zui_SCALE(UIBase.ui) > 1) UIBase.set_icon_scale(); - - context_raw.paint_object = scene_get_child(".Cube").ext; - project_paint_objects = [context_raw.paint_object]; - - if (project_filepath == "") { - app_notify_on_init(base_init_layers); - } - - context_raw.project_objects = []; - for (let m of scene_meshes) context_raw.project_objects.push(m); - - operator_register("view_top", UIBase.view_top); - } - - static update = () => { - UIBase.update_ui(); - operator_update(); - - for (let p of plugin_map.values()) if (p.update != null) p.update(); - - if (!base_ui_enabled) return; - - if (!UINodes.ui.is_typing && !UIBase.ui.is_typing) { - if (operator_shortcut(config_keymap.toggle_node_editor)) { - ///if (is_paint || is_sculpt) - UINodes.canvas_type == canvas_type_t.MATERIAL ? UIBase.show_material_nodes() : UIBase.show_brush_nodes(); - ///end - ///if is_lab - UIBase.show_material_nodes(); - ///end - } - else if (operator_shortcut(config_keymap.toggle_browser)) { - UIBase.toggle_browser(); - } - - else if (operator_shortcut(config_keymap.toggle_2d_view)) { - ///if (is_paint || is_sculpt) - UIBase.show_2d_view(view_2d_type_t.LAYER); - ///else - UIBase.show_2d_view(view_2d_type_t.ASSET); - ///end - } - } - - if (operator_shortcut(config_keymap.file_save_as)) project_save_as(); - else if (operator_shortcut(config_keymap.file_save)) project_save(); - else if (operator_shortcut(config_keymap.file_open)) project_open(); - else if (operator_shortcut(config_keymap.file_open_recent)) BoxProjects.show(); - else if (operator_shortcut(config_keymap.file_reimport_mesh)) project_reimport_mesh(); - else if (operator_shortcut(config_keymap.file_reimport_textures)) project_reimport_textures(); - else if (operator_shortcut(config_keymap.file_new)) project_new_box(); - ///if (is_paint || is_lab) - else if (operator_shortcut(config_keymap.file_export_textures)) { - if (context_raw.texture_export_path == "") { // First export, ask for path - ///if is_paint - context_raw.layers_export = export_mode_t.VISIBLE; - ///end - BoxExport.show_textures(); - } - else { - let _init = () => { - ExportTexture.run(context_raw.texture_export_path); - } - app_notify_on_init(_init); - } - } - else if (operator_shortcut(config_keymap.file_export_textures_as)) { - ///if (is_paint || is_sculpt) - context_raw.layers_export = export_mode_t.VISIBLE; - ///end - BoxExport.show_textures(); - } - ///end - else if (operator_shortcut(config_keymap.file_import_assets)) project_import_asset(); - else if (operator_shortcut(config_keymap.edit_prefs)) BoxPreferences.show(); - - if (keyboard_started(config_keymap.view_distract_free) || - (keyboard_started("escape") && !UIBase.show && !UIBox.show)) { - UIBase.toggle_distract_free(); - } - - ///if krom_linux - if (operator_shortcut("alt+enter", shortcut_type_t.STARTED)) { - base_toggle_fullscreen(); - } - ///end - - ///if (is_paint || is_sculpt) - let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; - let decal_mask: bool = decal && operator_shortcut(config_keymap.decal_mask, shortcut_type_t.DOWN); - - if ((context_raw.brush_can_lock || context_raw.brush_locked) && mouse_moved) { - if (operator_shortcut(config_keymap.brush_radius, shortcut_type_t.DOWN) || - operator_shortcut(config_keymap.brush_opacity, shortcut_type_t.DOWN) || - operator_shortcut(config_keymap.brush_angle, shortcut_type_t.DOWN) || - (decal_mask && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.brush_radius, shortcut_type_t.DOWN))) { - if (context_raw.brush_locked) { - if (operator_shortcut(config_keymap.brush_opacity, shortcut_type_t.DOWN)) { - context_raw.brush_opacity += mouse_movement_x / 500; - context_raw.brush_opacity = Math.max(0.0, Math.min(1.0, context_raw.brush_opacity)); - context_raw.brush_opacity = Math.round(context_raw.brush_opacity * 100) / 100; - context_raw.brush_opacity_handle.value = context_raw.brush_opacity; - } - else if (operator_shortcut(config_keymap.brush_angle, shortcut_type_t.DOWN)) { - context_raw.brush_angle += mouse_movement_x / 5; - context_raw.brush_angle = Math.floor(context_raw.brush_angle) % 360; - if (context_raw.brush_angle < 0) context_raw.brush_angle += 360; - context_raw.brush_angle_handle.value = context_raw.brush_angle; - MakeMaterial.parse_paint_material(); - } - else if (decal_mask && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.brush_radius, shortcut_type_t.DOWN)) { - context_raw.brush_decal_mask_radius += mouse_movement_x / 150; - context_raw.brush_decal_mask_radius = Math.max(0.01, Math.min(4.0, context_raw.brush_decal_mask_radius)); - context_raw.brush_decal_mask_radius = Math.round(context_raw.brush_decal_mask_radius * 100) / 100; - context_raw.brush_decal_mask_radius_handle.value = context_raw.brush_decal_mask_radius; - } - else { - context_raw.brush_radius += mouse_movement_x / 150; - context_raw.brush_radius = Math.max(0.01, Math.min(4.0, context_raw.brush_radius)); - context_raw.brush_radius = Math.round(context_raw.brush_radius * 100) / 100; - context_raw.brush_radius_handle.value = context_raw.brush_radius; - } - UIHeader.header_handle.redraws = 2; - } - else if (context_raw.brush_can_lock) { - context_raw.brush_can_lock = false; - context_raw.brush_locked = true; - } - } - } - ///end - - ///if is_lab - if ((context_raw.brush_can_lock || context_raw.brush_locked) && mouse_moved) { - if (operator_shortcut(config_keymap.brush_radius, shortcut_type_t.DOWN)) { - if (context_raw.brush_locked) { - context_raw.brush_radius += mouse_movement_x / 150; - context_raw.brush_radius = Math.max(0.01, Math.min(4.0, context_raw.brush_radius)); - context_raw.brush_radius = Math.round(context_raw.brush_radius * 100) / 100; - context_raw.brush_radius_handle.value = context_raw.brush_radius; - UIHeader.header_handle.redraws = 2; - } - else if (context_raw.brush_can_lock) { - context_raw.brush_can_lock = false; - context_raw.brush_locked = true; - } - } - } - ///end - - let is_typing: bool = UIBase.ui.is_typing || UIView2D.ui.is_typing || UINodes.ui.is_typing; - - ///if (is_paint || is_sculpt) - if (!is_typing) { - if (operator_shortcut(config_keymap.select_material, shortcut_type_t.DOWN)) { - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; - for (let i: i32 = 1; i < 10; ++i) if (keyboard_started(i + "")) context_select_material(i - 1); - } - else if (operator_shortcut(config_keymap.select_layer, shortcut_type_t.DOWN)) { - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - for (let i: i32 = 1; i < 10; ++i) if (keyboard_started(i + "")) context_select_layer(i - 1); - } - } - ///end - - // Viewport shortcuts - if (context_in_paint_area() && !is_typing) { - - ///if is_paint - if (!mouse_down("right")) { // Fly mode off - if (operator_shortcut(config_keymap.tool_brush)) context_select_tool(workspace_tool_t.BRUSH); - else if (operator_shortcut(config_keymap.tool_eraser)) context_select_tool(workspace_tool_t.ERASER); - else if (operator_shortcut(config_keymap.tool_fill)) context_select_tool(workspace_tool_t.FILL); - else if (operator_shortcut(config_keymap.tool_colorid)) context_select_tool(workspace_tool_t.COLORID); - else if (operator_shortcut(config_keymap.tool_decal)) context_select_tool(workspace_tool_t.DECAL); - else if (operator_shortcut(config_keymap.tool_text)) context_select_tool(workspace_tool_t.TEXT); - else if (operator_shortcut(config_keymap.tool_clone)) context_select_tool(workspace_tool_t.CLONE); - else if (operator_shortcut(config_keymap.tool_blur)) context_select_tool(workspace_tool_t.BLUR); - else if (operator_shortcut(config_keymap.tool_smudge)) context_select_tool(workspace_tool_t.SMUDGE); - else if (operator_shortcut(config_keymap.tool_particle)) context_select_tool(workspace_tool_t.PARTICLE); - else if (operator_shortcut(config_keymap.tool_picker)) context_select_tool(workspace_tool_t.PICKER); - else if (operator_shortcut(config_keymap.tool_bake)) context_select_tool(workspace_tool_t.BAKE); - else if (operator_shortcut(config_keymap.tool_gizmo)) context_select_tool(workspace_tool_t.GIZMO); - else if (operator_shortcut(config_keymap.tool_material)) context_select_tool(workspace_tool_t.MATERIAL); - else if (operator_shortcut(config_keymap.swap_brush_eraser)) context_select_tool(context_raw.tool == workspace_tool_t.BRUSH ? workspace_tool_t.ERASER : workspace_tool_t.BRUSH); - } - - // Radius - if (context_raw.tool == workspace_tool_t.BRUSH || - context_raw.tool == workspace_tool_t.ERASER || - context_raw.tool == workspace_tool_t.DECAL || - context_raw.tool == workspace_tool_t.TEXT || - context_raw.tool == workspace_tool_t.CLONE || - context_raw.tool == workspace_tool_t.BLUR || - context_raw.tool == workspace_tool_t.SMUDGE || - context_raw.tool == workspace_tool_t.PARTICLE) { - if (operator_shortcut(config_keymap.brush_radius) || - operator_shortcut(config_keymap.brush_opacity) || - operator_shortcut(config_keymap.brush_angle) || - (decal_mask && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.brush_radius))) { - context_raw.brush_can_lock = true; - if (!pen_connected) mouse_lock(); - context_raw.lock_started_x = mouse_x; - context_raw.lock_started_y = mouse_y; - } - else if (operator_shortcut(config_keymap.brush_radius_decrease, shortcut_type_t.REPEAT)) { - context_raw.brush_radius -= UIBase.get_radius_increment(); - context_raw.brush_radius = Math.max(Math.round(context_raw.brush_radius * 100) / 100, 0.01); - context_raw.brush_radius_handle.value = context_raw.brush_radius; - UIHeader.header_handle.redraws = 2; - } - else if (operator_shortcut(config_keymap.brush_radius_increase, shortcut_type_t.REPEAT)) { - context_raw.brush_radius += UIBase.get_radius_increment(); - context_raw.brush_radius = Math.round(context_raw.brush_radius * 100) / 100; - context_raw.brush_radius_handle.value = context_raw.brush_radius; - UIHeader.header_handle.redraws = 2; - } - else if (decal_mask) { - if (operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.brush_radius_decrease, shortcut_type_t.REPEAT)) { - context_raw.brush_decal_mask_radius -= UIBase.get_radius_increment(); - context_raw.brush_decal_mask_radius = Math.max(Math.round(context_raw.brush_decal_mask_radius * 100) / 100, 0.01); - context_raw.brush_decal_mask_radius_handle.value = context_raw.brush_decal_mask_radius; - UIHeader.header_handle.redraws = 2; - } - else if (operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.brush_radius_increase, shortcut_type_t.REPEAT)) { - context_raw.brush_decal_mask_radius += UIBase.get_radius_increment(); - context_raw.brush_decal_mask_radius = Math.round(context_raw.brush_decal_mask_radius * 100) / 100; - context_raw.brush_decal_mask_radius_handle.value = context_raw.brush_decal_mask_radius; - UIHeader.header_handle.redraws = 2; - } - } - } - - if (decal_mask && (operator_shortcut(config_keymap.decal_mask, shortcut_type_t.STARTED) || operator_shortcut(config_keymap.decal_mask, shortcut_type_t.RELEASED))) { - UIHeader.header_handle.redraws = 2; - } - ///end - - ///if is_lab - if (UIHeader.worktab.position == space_type_t.SPACE3D) { - // Radius - if (context_raw.tool == workspace_tool_t.ERASER || - context_raw.tool == workspace_tool_t.CLONE || - context_raw.tool == workspace_tool_t.BLUR || - context_raw.tool == workspace_tool_t.SMUDGE) { - if (operator_shortcut(config_keymap.brush_radius)) { - context_raw.brush_can_lock = true; - if (!pen_connected) mouse_lock(); - context_raw.lock_started_x = mouse_x; - context_raw.lock_started_y = mouse_y; - } - else if (operator_shortcut(config_keymap.brush_radius_decrease, shortcut_type_t.REPEAT)) { - context_raw.brush_radius -= UIBase.get_radius_increment(); - context_raw.brush_radius = Math.max(Math.round(context_raw.brush_radius * 100) / 100, 0.01); - context_raw.brush_radius_handle.value = context_raw.brush_radius; - UIHeader.header_handle.redraws = 2; - } - else if (operator_shortcut(config_keymap.brush_radius_increase, shortcut_type_t.REPEAT)) { - context_raw.brush_radius += UIBase.get_radius_increment(); - context_raw.brush_radius = Math.round(context_raw.brush_radius * 100) / 100; - context_raw.brush_radius_handle.value = context_raw.brush_radius; - UIHeader.header_handle.redraws = 2; - } - } - } - ///end - - // Viewpoint - if (mouse_view_x() < app_w()) { - if (operator_shortcut(config_keymap.view_reset)) { - viewport_reset(); - viewport_scale_to_bounds(); - } - else if (operator_shortcut(config_keymap.view_back)) viewport_set_view(0, 1, 0, Math.PI / 2, 0, Math.PI); - else if (operator_shortcut(config_keymap.view_front)) viewport_set_view(0, -1, 0, Math.PI / 2, 0, 0); - else if (operator_shortcut(config_keymap.view_left)) viewport_set_view(-1, 0, 0, Math.PI / 2, 0, -Math.PI / 2); - else if (operator_shortcut(config_keymap.view_right)) viewport_set_view(1, 0, 0, Math.PI / 2, 0, Math.PI / 2); - else if (operator_shortcut(config_keymap.view_bottom)) viewport_set_view(0, 0, -1, Math.PI, 0, Math.PI); - else if (operator_shortcut(config_keymap.view_camera_type)) { - context_raw.camera_type = context_raw.camera_type == camera_type_t.PERSPECTIVE ? camera_type_t.ORTHOGRAPHIC : camera_type_t.PERSPECTIVE; - context_raw.cam_handle.position = context_raw.camera_type; - viewport_update_camera_type(context_raw.camera_type); - } - else if (operator_shortcut(config_keymap.view_orbit_left, shortcut_type_t.REPEAT)) viewport_orbit(-Math.PI / 12, 0); - else if (operator_shortcut(config_keymap.view_orbit_right, shortcut_type_t.REPEAT)) viewport_orbit(Math.PI / 12, 0); - else if (operator_shortcut(config_keymap.view_orbit_up, shortcut_type_t.REPEAT)) viewport_orbit(0, -Math.PI / 12); - else if (operator_shortcut(config_keymap.view_orbit_down, shortcut_type_t.REPEAT)) viewport_orbit(0, Math.PI / 12); - else if (operator_shortcut(config_keymap.view_orbit_opposite)) viewport_orbit_opposite(); - else if (operator_shortcut(config_keymap.view_zoom_in, shortcut_type_t.REPEAT)) viewport_zoom(0.2); - else if (operator_shortcut(config_keymap.view_zoom_out, shortcut_type_t.REPEAT)) viewport_zoom(-0.2); - else if (operator_shortcut(config_keymap.viewport_mode)) { - - let count: i32; - - ///if (is_paint || is_sculpt) - count = 16; - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - count += 1; - ///end - ///end - - ///if is_lab - count = 9; - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - count += 1; - ///end - ///end - - UIMenu.draw((ui: zui_t) => { - let mode_handle: zui_handle_t = zui_handle("uibase_0"); - mode_handle.position = context_raw.viewport_mode; - zui_text(tr("Viewport Mode"), zui_align_t.RIGHT, ui.t.HIGHLIGHT_COL); - let modes: string[] = [ - tr("Lit"), - tr("Base Color"), - tr("Normal"), - tr("Occlusion"), - tr("Roughness"), - tr("Metallic"), - tr("Opacity"), - tr("Height"), - ///if (is_paint || is_sculpt) - tr("Emission"), - tr("Subsurface"), - tr("TexCoord"), - tr("Object Normal"), - tr("Material ID"), - tr("Object ID"), - tr("Mask") - ///end - ]; - - let shortcuts: string[] = ["l", "b", "n", "o", "r", "m", "a", "h", "e", "s", "t", "1", "2", "3", "4"]; - - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - if (krom_raytrace_supported()) { - modes.push(tr("Path Traced")); - shortcuts.push("p"); - } - ///end - - for (let i: i32 = 0; i < modes.length; ++i) { - zui_radio(mode_handle, i, modes[i], shortcuts[i]); - } - - let index: i32 = shortcuts.indexOf(keyboard_key_code(ui.key)); - if (ui.is_key_pressed && index != -1) { - mode_handle.position = index; - ui.changed = true; - context_set_viewport_mode(mode_handle.position); - } - else if (mode_handle.changed) { - context_set_viewport_mode(mode_handle.position); - ui.changed = true; - } - }, count); - } - } - - if (operator_shortcut(config_keymap.operator_search)) UIBase.operator_search(); - } - - if (context_raw.brush_can_lock || context_raw.brush_locked) { - if (mouse_moved && context_raw.brush_can_unlock) { - context_raw.brush_locked = false; - context_raw.brush_can_unlock = false; - } - - ///if (is_paint || is_sculpt) - let b: bool = (context_raw.brush_can_lock || context_raw.brush_locked) && - !operator_shortcut(config_keymap.brush_radius, shortcut_type_t.DOWN) && - !operator_shortcut(config_keymap.brush_opacity, shortcut_type_t.DOWN) && - !operator_shortcut(config_keymap.brush_angle, shortcut_type_t.DOWN) && - !(decal_mask && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.brush_radius, shortcut_type_t.DOWN)); - ///end - ///if is_lab - let b: bool = (context_raw.brush_can_lock || context_raw.brush_locked) && - !operator_shortcut(config_keymap.brush_radius, shortcut_type_t.DOWN); - ///end - - if (b) { - mouse_unlock(); - context_raw.last_paint_x = -1; - context_raw.last_paint_y = -1; - if (context_raw.brush_can_lock) { - context_raw.brush_can_lock = false; - context_raw.brush_can_unlock = false; - context_raw.brush_locked = false; - } - else { - context_raw.brush_can_unlock = true; - } - } - } - - ///if (is_paint || is_sculpt) - if (UIBase.border_handle_ptr != 0) { - if (UIBase.border_handle_ptr == UINodes.hwnd.ptr || UIBase.border_handle_ptr == UIView2D.hwnd.ptr) { - if (UIBase.border_started == border_side_t.LEFT) { - config_raw.layout[layout_size_t.NODES_W] -= Math.floor(mouse_movement_x); - if (config_raw.layout[layout_size_t.NODES_W] < 32) config_raw.layout[layout_size_t.NODES_W] = 32; - else if (config_raw.layout[layout_size_t.NODES_W] > sys_width() * 0.7) config_raw.layout[layout_size_t.NODES_W] = Math.floor(sys_width() * 0.7); - } - else { // UINodes / UIView2D ratio - config_raw.layout[layout_size_t.NODES_H] -= Math.floor(mouse_movement_y); - if (config_raw.layout[layout_size_t.NODES_H] < 32) config_raw.layout[layout_size_t.NODES_H] = 32; - else if (config_raw.layout[layout_size_t.NODES_H] > app_h() * 0.95) config_raw.layout[layout_size_t.NODES_H] = Math.floor(app_h() * 0.95); - } - } - else if (UIBase.border_handle_ptr == UIBase.hwnds[tab_area_t.STATUS].ptr) { - let my: i32 = Math.floor(mouse_movement_y); - if (config_raw.layout[layout_size_t.STATUS_H] - my >= UIStatus.default_status_h * config_raw.window_scale && config_raw.layout[layout_size_t.STATUS_H] - my < sys_height() * 0.7) { - config_raw.layout[layout_size_t.STATUS_H] -= my; - } - } - else { - if (UIBase.border_started == border_side_t.LEFT) { - config_raw.layout[layout_size_t.SIDEBAR_W] -= Math.floor(mouse_movement_x); - if (config_raw.layout[layout_size_t.SIDEBAR_W] < UIBase.sidebar_mini_w) config_raw.layout[layout_size_t.SIDEBAR_W] = UIBase.sidebar_mini_w; - else if (config_raw.layout[layout_size_t.SIDEBAR_W] > sys_width() - UIBase.sidebar_mini_w) config_raw.layout[layout_size_t.SIDEBAR_W] = sys_width() - UIBase.sidebar_mini_w; - } - else { - let my: i32 = Math.floor(mouse_movement_y); - if (UIBase.border_handle_ptr == UIBase.hwnds[tab_area_t.SIDEBAR1].ptr && UIBase.border_started == border_side_t.TOP) { - if (config_raw.layout[layout_size_t.SIDEBAR_H0] + my > 32 && config_raw.layout[layout_size_t.SIDEBAR_H1] - my > 32) { - config_raw.layout[layout_size_t.SIDEBAR_H0] += my; - config_raw.layout[layout_size_t.SIDEBAR_H1] -= my; - } - } - } - } - } - ///end - - ///if is_lab - if (UIBase.border_handle_ptr != 0) { - if (UIBase.border_handle_ptr == UINodes.hwnd.ptr || UIBase.border_handle_ptr == UIView2D.hwnd.ptr) { - if (UIBase.border_started == border_side_t.LEFT) { - config_raw.layout[layout_size_t.NODES_W] -= Math.floor(mouse_movement_x); - if (config_raw.layout[layout_size_t.NODES_W] < 32) config_raw.layout[layout_size_t.NODES_W] = 32; - else if (config_raw.layout[layout_size_t.NODES_W] > sys_width() * 0.7) config_raw.layout[layout_size_t.NODES_W] = Math.floor(sys_width() * 0.7); - } - else { // UINodes / UIView2D ratio - config_raw.layout[layout_size_t.NODES_H] -= Math.floor(mouse_movement_y); - if (config_raw.layout[layout_size_t.NODES_H] < 32) config_raw.layout[layout_size_t.NODES_H] = 32; - else if (config_raw.layout[layout_size_t.NODES_H] > app_h() * 0.95) config_raw.layout[layout_size_t.NODES_H] = Math.floor(app_h() * 0.95); - } - } - else if (UIBase.border_handle_ptr == UIBase.hwnds[tab_area_t.STATUS].ptr) { - let my: i32 = Math.floor(mouse_movement_y); - if (config_raw.layout[layout_size_t.STATUS_H] - my >= UIStatus.default_status_h * config_raw.window_scale && config_raw.layout[layout_size_t.STATUS_H] - my < sys_height() * 0.7) { - config_raw.layout[layout_size_t.STATUS_H] -= my; - } - } - } - ///end - - if (!mouse_down()) { - UIBase.border_handle_ptr = 0; - base_is_resizing = false; - } - - ///if arm_physics - if (context_raw.tool == workspace_tool_t.PARTICLE && context_raw.particle_physics && context_in_paint_area() && !context_raw.paint2d) { - UtilParticle.init_particle_physics(); - let world: PhysicsWorldRaw = PhysicsWorld.active; - PhysicsWorld.late_update(world); - context_raw.ddirty = 2; - context_raw.rdirty = 2; - if (mouse_started()) { - if (context_raw.particle_timer != null) { - tween_stop(context_raw.particle_timer); - context_raw.particle_timer.done(); - context_raw.particle_timer = null; - } - history_push_undo = true; - context_raw.particle_hit_x = context_raw.particle_hit_y = context_raw.particle_hit_z = 0; - let o: object_t = scene_spawn_object(".Sphere"); - let md: material_data_t = data_get_material("Scene", ".Gizmo"); - let mo: mesh_object_t = o.ext; - mo.base.name = ".Bullet"; - mo.materials[0] = md; - mo.base.visible = true; - - let camera: camera_object_t = scene_camera; - let ct: transform_t = camera.base.transform; - vec4_set(mo.base.transform.loc, transform_world_x(ct), transform_world_y(ct), transform_world_z(ct)); - vec4_set(mo.base.transform.scale, context_raw.brush_radius * 0.2, context_raw.brush_radius * 0.2, context_raw.brush_radius * 0.2); - transform_build_matrix(mo.base.transform); - - let body: PhysicsBodyRaw = PhysicsBody.create(); - body.shape = shape_type_t.SPHERE; - body.mass = 1.0; - body.ccd = true; - mo.base.transform.radius /= 10; // Lower ccd radius - PhysicsBody.init(body, mo.base); - (mo.base as any).physicsBody = body; - mo.base.transform.radius *= 10; - - let ray: ray_t = raycast_get_ray(mouse_view_x(), mouse_view_y(), camera); - PhysicsBody.apply_impulse(body, vec4_mult(ray.dir, 0.15)); - - context_raw.particle_timer = tween_timer(5, function() { mesh_object_remove(mo); }); - } - - let pairs: pair_t[] = PhysicsWorld.get_contact_pairs(world, context_raw.paint_body); - if (pairs != null) { - for (let p of pairs) { - context_raw.last_particle_hit_x = context_raw.particle_hit_x != 0 ? context_raw.particle_hit_x : p.pos_a.x; - context_raw.last_particle_hit_y = context_raw.particle_hit_y != 0 ? context_raw.particle_hit_y : p.pos_a.y; - context_raw.last_particle_hit_z = context_raw.particle_hit_z != 0 ? context_raw.particle_hit_z : p.pos_a.z; - context_raw.particle_hit_x = p.pos_a.x; - context_raw.particle_hit_y = p.pos_a.y; - context_raw.particle_hit_z = p.pos_a.z; - context_raw.pdirty = 1; - break; // 1 pair for now - } - } - } - ///end - } - - static view_top = () => { - let is_typing: bool = UIBase.ui.is_typing || UIView2D.ui.is_typing || UINodes.ui.is_typing; - - if (context_in_paint_area() && !is_typing) { - if (mouse_view_x() < app_w()) { - viewport_set_view(0, 0, 1, 0, 0, 0); - } - } - } - - static operator_search = () => { - let search_handle: zui_handle_t = zui_handle("uibase_1"); - let first: bool = true; - UIMenu.draw((ui: zui_t) => { - zui_fill(0, 0, ui._w / zui_SCALE(ui), ui.t.ELEMENT_H * 8, ui.t.SEPARATOR_COL); - let search: string = zui_text_input(search_handle, "", zui_align_t.LEFT, true, true); - ui.changed = false; - if (first) { - first = false; - search_handle.text = ""; - zui_start_text_edit(search_handle); // Focus search bar - } - - if (search_handle.changed) UIBase.operator_search_offset = 0; - - if (ui.is_key_pressed) { // Move selection - if (ui.key == key_code_t.DOWN && UIBase.operator_search_offset < 6) UIBase.operator_search_offset++; - if (ui.key == key_code_t.UP && UIBase.operator_search_offset > 0) UIBase.operator_search_offset--; - } - let enter: bool = keyboard_down("enter"); - let count: i32 = 0; - let BUTTON_COL: i32 = ui.t.BUTTON_COL; - - for (let n in config_keymap) { - if (n.indexOf(search) >= 0) { - ui.t.BUTTON_COL = count == UIBase.operator_search_offset ? ui.t.HIGHLIGHT_COL : ui.t.SEPARATOR_COL; - if (zui_button(n, zui_align_t.LEFT, config_keymap[n]) || (enter && count == UIBase.operator_search_offset)) { - if (enter) { - ui.changed = true; - count = 6; // Trigger break - } - operator_run(n); - } - if (++count > 6) break; - } - } - - if (enter && count == 0) { // Hide popup on enter when command is not found - ui.changed = true; - search_handle.text = ""; - } - ui.t.BUTTON_COL = BUTTON_COL; - }, 8, -1, -1); - } - - static toggle_distract_free = () => { - UIBase.show = !UIBase.show; - base_resize(); - } - - static get_radius_increment = (): f32 => { - return 0.1; - } - - static hit_rect = (mx: f32, my: f32, x: i32, y: i32, w: i32, h: i32) => { - return mx > x && mx < x + w && my > y && my < y + h; - } - - ///if (is_paint || is_sculpt) - static get_brush_stencil_rect = (): rect_t => { - let w: i32 = Math.floor(context_raw.brush_stencil_image.width * (base_h() / context_raw.brush_stencil_image.height) * context_raw.brush_stencil_scale); - let h: i32 = Math.floor(base_h() * context_raw.brush_stencil_scale); - let x: i32 = Math.floor(base_x() + context_raw.brush_stencil_x * base_w()); - let y: i32 = Math.floor(base_y() + context_raw.brush_stencil_y * base_h()); - return { w: w, h: h, x: x, y: y }; - } - ///end - - static update_ui = () => { - if (console_message_timer > 0) { - console_message_timer -= time_delta(); - if (console_message_timer <= 0) UIBase.hwnds[tab_area_t.STATUS].redraws = 2; - } - - ///if (is_paint || is_sculpt) - UIBase.sidebar_mini_w = Math.floor(UIBase.default_sidebar_mini_w * zui_SCALE(UIBase.ui)); - ///end - - if (!base_ui_enabled) return; - - ///if (is_paint || is_sculpt) - // Same mapping for paint and rotate (predefined in touch keymap) - if (context_in_viewport()) { - if (mouse_started() && config_keymap.action_paint == config_keymap.action_rotate) { - UIBase.action_paint_remap = config_keymap.action_paint; - UtilRender.pick_pos_nor_tex(); - let is_mesh: bool = Math.abs(context_raw.posx_picked) < 50 && Math.abs(context_raw.posy_picked) < 50 && Math.abs(context_raw.posz_picked) < 50; - ///if krom_android - // Allow rotating with both pen and touch, because hovering a pen prevents touch input on android - let pen_only: bool = false; - ///else - let pen_only: bool = context_raw.pen_painting_only; - ///end - let is_pen: bool = pen_only && pen_down(); - // Mesh picked - disable rotate - // Pen painting only - rotate with touch, paint with pen - if ((is_mesh && !pen_only) || is_pen) { - config_keymap.action_rotate = ""; - config_keymap.action_paint = UIBase.action_paint_remap; - } - // World sphere picked - disable paint - else { - config_keymap.action_paint = ""; - config_keymap.action_rotate = UIBase.action_paint_remap; - } - } - else if (!mouse_down() && UIBase.action_paint_remap != "") { - config_keymap.action_rotate = UIBase.action_paint_remap; - config_keymap.action_paint = UIBase.action_paint_remap; - UIBase.action_paint_remap = ""; - } - } - - if (context_raw.brush_stencil_image != null && operator_shortcut(config_keymap.stencil_transform, shortcut_type_t.DOWN)) { - let r: rect_t = UIBase.get_brush_stencil_rect(); - if (mouse_started("left")) { - context_raw.brush_stencil_scaling = - UIBase.hit_rect(mouse_x, mouse_y, r.x - 8, r.y - 8, 16, 16) || - UIBase.hit_rect(mouse_x, mouse_y, r.x - 8, r.h + r.y - 8, 16, 16) || - UIBase.hit_rect(mouse_x, mouse_y, r.w + r.x - 8, r.y - 8, 16, 16) || - UIBase.hit_rect(mouse_x, mouse_y, r.w + r.x - 8, r.h + r.y - 8, 16, 16); - let cosa: f32 = Math.cos(-context_raw.brush_stencil_angle); - let sina: f32 = Math.sin(-context_raw.brush_stencil_angle); - let ox: f32 = 0; - let oy: f32 = -r.h / 2; - let x: f32 = ox * cosa - oy * sina; - let y: f32 = ox * sina + oy * cosa; - x += r.x + r.w / 2; - y += r.y + r.h / 2; - context_raw.brush_stencil_rotating = - UIBase.hit_rect(mouse_x, mouse_y, Math.floor(x - 16), Math.floor(y - 16), 32, 32); - } - let _scale: f32 = context_raw.brush_stencil_scale; - if (mouse_down("left")) { - if (context_raw.brush_stencil_scaling) { - let mult: i32 = mouse_x > r.x + r.w / 2 ? 1 : -1; - context_raw.brush_stencil_scale += mouse_movement_x / 400 * mult; - } - else if (context_raw.brush_stencil_rotating) { - let gizmo_x: f32 = r.x + r.w / 2; - let gizmo_y: f32 = r.y + r.h / 2; - context_raw.brush_stencil_angle = -Math.atan2(mouse_y - gizmo_y, mouse_x - gizmo_x) - Math.PI / 2; - } - else { - context_raw.brush_stencil_x += mouse_movement_x / base_w(); - context_raw.brush_stencil_y += mouse_movement_y / base_h(); - } - } - else context_raw.brush_stencil_scaling = false; - if (mouse_wheel_delta != 0) { - context_raw.brush_stencil_scale -= mouse_wheel_delta / 10; - } - // Center after scale - let ratio: f32 = base_h() / context_raw.brush_stencil_image.height; - let old_w: f32 = _scale * context_raw.brush_stencil_image.width * ratio; - let new_w: f32 = context_raw.brush_stencil_scale * context_raw.brush_stencil_image.width * ratio; - let old_h: f32 = _scale * base_h(); - let new_h: f32 = context_raw.brush_stencil_scale * base_h(); - context_raw.brush_stencil_x += (old_w - new_w) / base_w() / 2; - context_raw.brush_stencil_y += (old_h - new_h) / base_h() / 2; - } - ///end - - let set_clone_source: bool = context_raw.tool == workspace_tool_t.CLONE && operator_shortcut(config_keymap.set_clone_source + "+" + config_keymap.action_paint, shortcut_type_t.DOWN); - - ///if (is_paint || is_sculpt) - let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; - let decal_mask: bool = decal && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.action_paint, shortcut_type_t.DOWN); - let down: bool = operator_shortcut(config_keymap.action_paint, shortcut_type_t.DOWN) || - decal_mask || - set_clone_source || - operator_shortcut(config_keymap.brush_ruler + "+" + config_keymap.action_paint, shortcut_type_t.DOWN) || - (pen_down() && !keyboard_down("alt")); - ///end - ///if is_lab - let down: bool = operator_shortcut(config_keymap.action_paint, shortcut_type_t.DOWN) || - set_clone_source || - operator_shortcut(config_keymap.brush_ruler + "+" + config_keymap.action_paint, shortcut_type_t.DOWN) || - (pen_down() && !keyboard_down("alt")); - ///end - - if (config_raw.touch_ui) { - if (pen_down()) { - context_raw.pen_painting_only = true; - } - else if (context_raw.pen_painting_only) { - down = false; - } - } - - ///if arm_physics - if (context_raw.tool == workspace_tool_t.PARTICLE && context_raw.particle_physics) { - down = false; - } - ///end - - ///if (is_paint || is_sculpt) - ///if krom_ios - // No hover on iPad, decals are painted by pen release - if (decal) { - down = pen_released(); - if (!context_raw.pen_painting_only) { - down = down || mouse_released(); - } - } - ///end - ///end - - if (down) { - let mx: i32 = mouse_view_x(); - let my: i32 = mouse_view_y(); - let ww: i32 = app_w(); - - ///if (is_paint || is_sculpt) - if (context_raw.paint2d) { - mx -= app_w(); - ww = UIView2D.ww; - } - ///end - - if (mx < ww && - mx > app_x() && - my < app_h() && - my > app_y()) { - - if (set_clone_source) { - context_raw.clone_start_x = mx; - context_raw.clone_start_y = my; - } - else { - if (context_raw.brush_time == 0 && - !base_is_dragging && - !base_is_resizing && - !base_is_combo_selected()) { // Paint started - - // Draw line - if (operator_shortcut(config_keymap.brush_ruler + "+" + config_keymap.action_paint, shortcut_type_t.DOWN)) { - context_raw.last_paint_vec_x = context_raw.last_paint_x; - context_raw.last_paint_vec_y = context_raw.last_paint_y; - } - - ///if (is_paint || is_sculpt) - history_push_undo = true; - - if (context_raw.tool == workspace_tool_t.CLONE && context_raw.clone_start_x >= 0.0) { // Clone delta - context_raw.clone_delta_x = (context_raw.clone_start_x - mx) / ww; - context_raw.clone_delta_y = (context_raw.clone_start_y - my) / app_h(); - context_raw.clone_start_x = -1; - } - else if (context_raw.tool == workspace_tool_t.PARTICLE) { - // Reset particles - ///if arm_particles - let emitter: mesh_object_t = scene_get_child(".ParticleEmitter").ext; - let psys: particle_sys_t = emitter.particle_systems[0]; - psys.time = 0; - // psys.time = psys.seed * psys.animtime; - // psys.seed++; - ///end - } - else if (context_raw.tool == workspace_tool_t.FILL && context_raw.fill_type_handle.position == fill_type_t.UV_ISLAND) { - UtilUV.uvislandmap_cached = false; - } - ///end - } - - context_raw.brush_time += time_delta(); - - ///if (is_paint || is_sculpt) - if (context_raw.run_brush != null) { - context_raw.run_brush(0); - } - ///end - ///if is_lab - if (context_run_brush != null) { - context_run_brush(0); - } - ///end - } - } - } - else if (context_raw.brush_time > 0) { // Brush released - context_raw.brush_time = 0; - context_raw.prev_paint_vec_x = -1; - context_raw.prev_paint_vec_y = -1; - ///if (!krom_direct3d12 && !krom_vulkan && !krom_metal) // Keep accumulated samples for D3D12 - context_raw.ddirty = 3; - ///end - context_raw.brush_blend_dirty = true; // Update brush mask - - ///if (is_paint || is_sculpt) - context_raw.layer_preview_dirty = true; // Update layer preview - ///end - - ///if is_paint - // New color id picked, update fill layer - if (context_raw.tool == workspace_tool_t.COLORID && context_raw.layer.fill_layer != null) { - base_notify_on_next_frame(() => { - base_update_fill_layer(); - MakeMaterial.parse_paint_material(false); - }); - } - ///end - } - - ///if is_paint - if (context_raw.layers_preview_dirty) { - context_raw.layers_preview_dirty = false; - context_raw.layer_preview_dirty = false; - context_raw.mask_preview_last = null; - if (base_pipe_merge == null) base_make_pipe(); - // Update all layer previews - for (let l of project_layers) { - if (SlotLayer.is_group(l)) continue; - let target: image_t = l.texpaint_preview; - let source: image_t = l.texpaint; - g2_begin(target); - g2_clear(0x00000000); - // g2_set_pipeline(l.isMask() ? base_pipe_copy8 : base_pipe_copy); - g2_set_pipeline(base_pipe_copy); // texpaint_preview is always RGBA32 for now - g2_draw_scaled_image(source, 0, 0, target.width, target.height); - g2_set_pipeline(null); - g2_end(); - } - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - } - if (context_raw.layer_preview_dirty && !SlotLayer.is_group(context_raw.layer)) { - context_raw.layer_preview_dirty = false; - context_raw.mask_preview_last = null; - if (base_pipe_merge == null) base_make_pipe(); - // Update layer preview - let l: SlotLayerRaw = context_raw.layer; - let target: image_t = l.texpaint_preview; - let source: image_t = l.texpaint; - g2_begin(target); - g2_clear(0x00000000); - // g2_set_pipeline(raw.layer.isMask() ? base_pipe_copy8 : base_pipe_copy); - g2_set_pipeline(base_pipe_copy); // texpaint_preview is always RGBA32 for now - g2_draw_scaled_image(source, 0, 0, target.width, target.height); - g2_set_pipeline(null); - g2_end(); - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - } - ///end - - let undo_pressed: bool = operator_shortcut(config_keymap.edit_undo); - let redo_pressed: bool = operator_shortcut(config_keymap.edit_redo) || - (keyboard_down("control") && keyboard_started("y")); - - // Two-finger tap to undo, three-finger tap to redo - if (context_in_viewport() && config_raw.touch_ui) { - if (mouse_started("middle")) { UIBase.redo_tap_time = time_time(); } - else if (mouse_started("right")) { UIBase.undo_tap_time = time_time(); } - else if (mouse_released("middle") && time_time() - UIBase.redo_tap_time < 0.1) { UIBase.redo_tap_time = UIBase.undo_tap_time = 0; redo_pressed = true; } - else if (mouse_released("right") && time_time() - UIBase.undo_tap_time < 0.1) { UIBase.redo_tap_time = UIBase.undo_tap_time = 0; undo_pressed = true; } - } - - if (undo_pressed) history_undo(); - else if (redo_pressed) history_redo(); - - ///if (is_paint || is_sculpt) - gizmo_update(); - ///end - } - - static render = () => { - if (!UIBase.show && config_raw.touch_ui) { - UIBase.ui.input_enabled = true; - g2_end(); - zui_begin(UIBase.ui); - if (zui_window(zui_handle("uibase_2"), 0, 0, 150, Math.floor(zui_ELEMENT_H(UIBase.ui) + zui_ELEMENT_OFFSET(UIBase.ui) + 1))) { - if (zui_button(tr("Close"))) { - UIBase.toggle_distract_free(); - } - } - zui_end(); - g2_begin(null); - } - - if (!UIBase.show || sys_width() == 0 || sys_height() == 0) return; - - UIBase.ui.input_enabled = base_ui_enabled; - - // Remember last tab positions - for (let i: i32 = 0; i < UIBase.htabs.length; ++i) { - if (UIBase.htabs[i].changed) { - config_raw.layout_tabs[i] = UIBase.htabs[i].position; - config_save(); - } - } - - // Set tab positions - for (let i: i32 = 0; i < UIBase.htabs.length; ++i) { - UIBase.htabs[i].position = config_raw.layout_tabs[i]; - } - - g2_end(); - zui_begin(UIBase.ui); - - ///if (is_paint || is_sculpt) - UIToolbar.render_ui(); - ///end - UIMenubar.render_ui(); - UIHeader.render_ui(); - UIStatus.render_ui(); - - ///if (is_paint || is_sculpt) - UIBase.draw_sidebar(); - ///end - - zui_end(); - g2_begin(null); - } - - ///if (is_paint || is_sculpt) - static draw_sidebar = () => { - // Tabs - let mini: bool = config_raw.layout[layout_size_t.SIDEBAR_W] <= UIBase.sidebar_mini_w; - let expand_button_offset: i32 = config_raw.touch_ui ? Math.floor(zui_ELEMENT_H(UIBase.ui) + zui_ELEMENT_OFFSET(UIBase.ui)) : 0; - UIBase.tabx = sys_width() - config_raw.layout[layout_size_t.SIDEBAR_W]; - - let _SCROLL_W: i32 = UIBase.ui.t.SCROLL_W; - if (mini) UIBase.ui.t.SCROLL_W = UIBase.ui.t.SCROLL_MINI_W; - - if (zui_window(UIBase.hwnds[tab_area_t.SIDEBAR0], UIBase.tabx, 0, config_raw.layout[layout_size_t.SIDEBAR_W], config_raw.layout[layout_size_t.SIDEBAR_H0])) { - for (let i: i32 = 0; i < (mini ? 1 : UIBase.hwnd_tabs[tab_area_t.SIDEBAR0].length); ++i) UIBase.hwnd_tabs[tab_area_t.SIDEBAR0][i](UIBase.htabs[tab_area_t.SIDEBAR0]); - } - if (zui_window(UIBase.hwnds[tab_area_t.SIDEBAR1], UIBase.tabx, config_raw.layout[layout_size_t.SIDEBAR_H0], config_raw.layout[layout_size_t.SIDEBAR_W], config_raw.layout[layout_size_t.SIDEBAR_H1] - expand_button_offset)) { - for (let i: i32 = 0; i < (mini ? 1 : UIBase.hwnd_tabs[tab_area_t.SIDEBAR1].length); ++i) UIBase.hwnd_tabs[tab_area_t.SIDEBAR1][i](UIBase.htabs[tab_area_t.SIDEBAR1]); - } - - zui_end_window(); - UIBase.ui.t.SCROLL_W = _SCROLL_W; - - // Collapse / expand button for mini sidebar - if (config_raw.touch_ui) { - let width: i32 = config_raw.layout[layout_size_t.SIDEBAR_W]; - let height: i32 = Math.floor(zui_ELEMENT_H(UIBase.ui) + zui_ELEMENT_OFFSET(UIBase.ui)); - if (zui_window(zui_handle("uibase_3"), sys_width() - width, sys_height() - height, width, height + 1)) { - UIBase.ui._w = width; - let _BUTTON_H: i32 = UIBase.ui.t.BUTTON_H; - let _BUTTON_COL: i32 = UIBase.ui.t.BUTTON_COL; - UIBase.ui.t.BUTTON_H = UIBase.ui.t.ELEMENT_H; - UIBase.ui.t.BUTTON_COL = UIBase.ui.t.WINDOW_BG_COL; - if (zui_button(mini ? "<<" : ">>")) { - config_raw.layout[layout_size_t.SIDEBAR_W] = mini ? UIBase.default_sidebar_full_w : UIBase.default_sidebar_mini_w; - config_raw.layout[layout_size_t.SIDEBAR_W] = Math.floor(config_raw.layout[layout_size_t.SIDEBAR_W] * zui_SCALE(UIBase.ui)); - } - UIBase.ui.t.BUTTON_H = _BUTTON_H; - UIBase.ui.t.BUTTON_COL = _BUTTON_COL; - } - } - - // Expand button - if (config_raw.layout[layout_size_t.SIDEBAR_W] == 0) { - let width: i32 = Math.floor(g2_font_width(UIBase.ui.font, UIBase.ui.font_size, "<<") + 25 * zui_SCALE(UIBase.ui)); - if (zui_window(UIBase.hminimized, sys_width() - width, 0, width, Math.floor(zui_ELEMENT_H(UIBase.ui) + zui_ELEMENT_OFFSET(UIBase.ui) + 1))) { - UIBase.ui._w = width; - let _BUTTON_H: i32 = UIBase.ui.t.BUTTON_H; - let _BUTTON_COL: i32 = UIBase.ui.t.BUTTON_COL; - UIBase.ui.t.BUTTON_H = UIBase.ui.t.ELEMENT_H; - UIBase.ui.t.BUTTON_COL = UIBase.ui.t.SEPARATOR_COL; - - if (zui_button("<<")) { - config_raw.layout[layout_size_t.SIDEBAR_W] = context_raw.maximized_sidebar_width != 0 ? context_raw.maximized_sidebar_width : Math.floor(UIBase.default_sidebar_w * config_raw.window_scale); - } - UIBase.ui.t.BUTTON_H = _BUTTON_H; - UIBase.ui.t.BUTTON_COL = _BUTTON_COL; - } - } - else if (UIBase.htabs[tab_area_t.SIDEBAR0].changed && UIBase.htabs[tab_area_t.SIDEBAR0].position == context_raw.last_htab0_pos) { - if (time_time() - context_raw.select_time < 0.25) { - context_raw.maximized_sidebar_width = config_raw.layout[layout_size_t.SIDEBAR_W]; - config_raw.layout[layout_size_t.SIDEBAR_W] = 0; - } - context_raw.select_time = time_time(); - } - context_raw.last_htab0_pos = UIBase.htabs[tab_area_t.SIDEBAR0].position; - } - - static render_cursor = () => { - if (!base_ui_enabled) return; - - ///if is_paint - if (context_raw.tool == workspace_tool_t.MATERIAL || context_raw.tool == workspace_tool_t.BAKE) return; - ///end - - g2_set_color(0xffffffff); - - context_raw.view_index = context_raw.view_index_last; - let mx: i32 = base_x() + context_raw.paint_vec.x * base_w(); - let my: i32 = base_y() + context_raw.paint_vec.y * base_h(); - context_raw.view_index = -1; - - // Radius being scaled - if (context_raw.brush_locked) { - mx += context_raw.lock_started_x - sys_width() / 2; - my += context_raw.lock_started_y - sys_height() / 2; - } - - let tool: workspace_tool_t = context_raw.tool as workspace_tool_t; - - ///if is_paint - if (context_raw.brush_stencil_image != null && - tool != workspace_tool_t.BAKE && - tool != workspace_tool_t.PICKER && - tool != workspace_tool_t.MATERIAL && - tool != workspace_tool_t.COLORID) { - let r: rect_t = UIBase.get_brush_stencil_rect(); - if (!operator_shortcut(config_keymap.stencil_hide, shortcut_type_t.DOWN)) { - g2_set_color(0x88ffffff); - let angle: f32 = context_raw.brush_stencil_angle; - let cx: f32 = r.x + r.w / 2; - let cy: f32 = r.y + r.h / 2; - g2_set_transformation(mat3_multmat(mat3_multmat(mat3_translation(cx, cy), mat3_rotation(-angle)), mat3_translation(-cx, -cy))); - g2_draw_scaled_image(context_raw.brush_stencil_image, r.x, r.y, r.w, r.h); - g2_set_transformation(null); - g2_set_color(0xffffffff); - } - let transform: bool = operator_shortcut(config_keymap.stencil_transform, shortcut_type_t.DOWN); - if (transform) { - // Outline - g2_draw_rect(r.x, r.y, r.w, r.h); - // Scale - g2_draw_rect(r.x - 8, r.y - 8, 16, 16); - g2_draw_rect(r.x - 8 + r.w, r.y - 8, 16, 16); - g2_draw_rect(r.x - 8, r.y - 8 + r.h, 16, 16); - g2_draw_rect(r.x - 8 + r.w, r.y - 8 + r.h, 16, 16); - // Rotate - let angle: f32 = context_raw.brush_stencil_angle; - let cx: f32 = r.x + r.w / 2; - let cy: f32 = r.y + r.h / 2; - g2_set_transformation(mat3_multmat(mat3_multmat(mat3_translation(cx, cy), mat3_rotation(-angle)), mat3_translation(-cx, -cy))); - g2_fill_circle(r.x + r.w / 2, r.y - 4, 8); - g2_set_transformation(null); - } - } - ///end - - // Show picked material next to cursor - if (context_raw.tool == workspace_tool_t.PICKER && context_raw.picker_select_material && context_raw.color_picker_callback == null) { - let img: image_t = context_raw.material.image_icon; - ///if krom_opengl - g2_draw_scaled_image(img, mx + 10, my + 10 + img.height, img.width, -img.height); - ///else - g2_draw_image(img, mx + 10, my + 10); - ///end - } - if (context_raw.tool == workspace_tool_t.PICKER && context_raw.color_picker_callback != null) { - let img: image_t = resource_get("icons.k"); - let rect: rect_t = resource_tile50(img, workspace_tool_t.PICKER, 0); - g2_draw_sub_image(img, mx + 10, my + 10, rect.x, rect.y, rect.w, rect.h); - } - - let cursor_img: image_t = resource_get("cursor.k"); - let psize: i32 = Math.floor(cursor_img.width * (context_raw.brush_radius * context_raw.brush_nodes_radius) * zui_SCALE(UIBase.ui)); - - // Clone source cursor - if (context_raw.tool == workspace_tool_t.CLONE && !keyboard_down("alt") && (mouse_down() || pen_down())) { - g2_set_color(0x66ffffff); - g2_draw_scaled_image(cursor_img, mx + context_raw.clone_delta_x * app_w() - psize / 2, my + context_raw.clone_delta_y * app_h() - psize / 2, psize, psize); - g2_set_color(0xffffffff); - } - - let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; - - if (!config_raw.brush_3d || context_in_2d_view() || decal) { - let decal_mask: bool = decal && operator_shortcut(config_keymap.decal_mask, shortcut_type_t.DOWN); - if (decal && !context_in_nodes()) { - let decal_alpha: f32 = 0.5; - if (!decal_mask) { - context_raw.decal_x = context_raw.paint_vec.x; - context_raw.decal_y = context_raw.paint_vec.y; - decal_alpha = context_raw.brush_opacity; - - // Radius being scaled - if (context_raw.brush_locked) { - context_raw.decal_x += (context_raw.lock_started_x - sys_width() / 2) / base_w(); - context_raw.decal_y += (context_raw.lock_started_y - sys_height() / 2) / base_h(); - } - } - - if (!config_raw.brush_live) { - let psizex: i32 = Math.floor(256 * zui_SCALE(UIBase.ui) * (context_raw.brush_radius * context_raw.brush_nodes_radius * context_raw.brush_scale_x)); - let psizey: i32 = Math.floor(256 * zui_SCALE(UIBase.ui) * (context_raw.brush_radius * context_raw.brush_nodes_radius)); - - context_raw.view_index = context_raw.view_index_last; - let decalx: f32 = base_x() + context_raw.decal_x * base_w() - psizex / 2; - let decaly: f32 = base_y() + context_raw.decal_y * base_h() - psizey / 2; - context_raw.view_index = -1; - - g2_set_color(color_from_floats(1, 1, 1, decal_alpha)); - let angle: f32 = (context_raw.brush_angle + context_raw.brush_nodes_angle) * (Math.PI / 180); - let cx: f32 = decalx + psizex / 2; - let cy: f32 = decaly + psizey / 2; - g2_set_transformation(mat3_multmat(mat3_multmat(mat3_translation(cx, cy), mat3_rotation(angle)), mat3_translation(-cx, -cy))); - ///if (krom_direct3d11 || krom_direct3d12 || krom_metal || krom_vulkan) - g2_draw_scaled_image(context_raw.decal_image, decalx, decaly, psizex, psizey); - ///else - g2_draw_scaled_image(context_raw.decal_image, decalx, decaly + psizey, psizex, -psizey); - ///end - g2_set_transformation(null); - g2_set_color(0xffffffff); - } - } - if (context_raw.tool == workspace_tool_t.BRUSH || - context_raw.tool == workspace_tool_t.ERASER || - context_raw.tool == workspace_tool_t.CLONE || - context_raw.tool == workspace_tool_t.BLUR || - context_raw.tool == workspace_tool_t.SMUDGE || - context_raw.tool == workspace_tool_t.PARTICLE || - (decal_mask && !config_raw.brush_3d) || - (decal_mask && context_in_2d_view())) { - if (decal_mask) { - psize = Math.floor(cursor_img.width * (context_raw.brush_decal_mask_radius * context_raw.brush_nodes_radius) * zui_SCALE(UIBase.ui)); - } - if (config_raw.brush_3d && context_in_2d_view()) { - psize = Math.floor(psize * UIView2D.pan_scale); - } - g2_draw_scaled_image(cursor_img, mx - psize / 2, my - psize / 2, psize, psize); - } - } - - if (context_raw.brush_lazy_radius > 0 && !context_raw.brush_locked && - (context_raw.tool == workspace_tool_t.BRUSH || - context_raw.tool == workspace_tool_t.ERASER || - context_raw.tool == workspace_tool_t.DECAL || - context_raw.tool == workspace_tool_t.TEXT || - context_raw.tool == workspace_tool_t.CLONE || - context_raw.tool == workspace_tool_t.BLUR || - context_raw.tool == workspace_tool_t.SMUDGE || - context_raw.tool == workspace_tool_t.PARTICLE)) { - g2_fill_rect(mx - 1, my - 1, 2, 2); - mx = context_raw.brush_lazy_x * base_w() + base_x(); - my = context_raw.brush_lazy_y * base_h() + base_y(); - let radius: f32 = context_raw.brush_lazy_radius * 180; - g2_set_color(0xff666666); - g2_draw_scaled_image(cursor_img, mx - radius / 2, my - radius / 2, radius, radius); - g2_set_color(0xffffffff); - } - } - ///end - - static show_material_nodes = () => { - // Clear input state as ui receives input events even when not drawn - zui_end_input(); - - ///if (is_paint || is_sculpt) - UINodes.show = !UINodes.show || UINodes.canvas_type != canvas_type_t.MATERIAL; - UINodes.canvas_type = canvas_type_t.MATERIAL; - ///end - ///if is_lab - UINodes.show = !UINodes.show; - ///end - - base_resize(); - } - - ///if (is_paint || is_sculpt) - static show_brush_nodes = () => { - // Clear input state as ui receives input events even when not drawn - zui_end_input(); - UINodes.show = !UINodes.show || UINodes.canvas_type != canvas_type_t.BRUSH; - UINodes.canvas_type = canvas_type_t.BRUSH; - base_resize(); - } - ///end - - static show_2d_view = (type: view_2d_type_t) => { - // Clear input state as ui receives input events even when not drawn - zui_end_input(); - if (UIView2D.type != type) UIView2D.show = true; - else UIView2D.show = !UIView2D.show; - UIView2D.type = type; - UIView2D.hwnd.redraws = 2; - base_resize(); - } - - static toggle_browser = () => { - let minimized: bool = config_raw.layout[layout_size_t.STATUS_H] <= (UIStatus.default_status_h * config_raw.window_scale); - config_raw.layout[layout_size_t.STATUS_H] = minimized ? 240 : UIStatus.default_status_h; - config_raw.layout[layout_size_t.STATUS_H] = Math.floor(config_raw.layout[layout_size_t.STATUS_H] * config_raw.window_scale); - } - - static set_icon_scale = () => { - if (zui_SCALE(UIBase.ui) > 1) { - resource_load(["icons2x.k"], () => { - resource_bundled.set("icons.k", resource_get("icons2x.k")); - }); - } - else { - resource_load(["icons.k"], () => {}); - } - } - - static on_border_hover = (handle_ptr: i32, side: i32) => { - if (!base_ui_enabled) return; - - ///if (is_paint || is_sculpt) - if (handle_ptr != UIBase.hwnds[tab_area_t.SIDEBAR0].ptr && - handle_ptr != UIBase.hwnds[tab_area_t.SIDEBAR1].ptr && - handle_ptr != UIBase.hwnds[tab_area_t.STATUS].ptr && - handle_ptr != UINodes.hwnd.ptr && - handle_ptr != UIView2D.hwnd.ptr) return; // Scalable handles - if (handle_ptr == UIView2D.hwnd.ptr && side != border_side_t.LEFT) return; - if (handle_ptr == UINodes.hwnd.ptr && side == border_side_t.TOP && !UIView2D.show) return; - if (handle_ptr == UIBase.hwnds[tab_area_t.SIDEBAR0].ptr && side == border_side_t.TOP) return; - ///end - - ///if is_lab - if (handle_ptr != UIBase.hwnds[tab_area_t.STATUS].ptr && - handle_ptr != UINodes.hwnd.ptr && - handle_ptr != UIView2D.hwnd.ptr) return; // Scalable handles - if (handle_ptr == UIView2D.hwnd.ptr && side != border_side_t.LEFT) return; - if (handle_ptr == UINodes.hwnd.ptr && side == border_side_t.TOP && !UIView2D.show) return; - ///end - - if (handle_ptr == UINodes.hwnd.ptr && side != border_side_t.LEFT && side != border_side_t.TOP) return; - if (handle_ptr == UIBase.hwnds[tab_area_t.STATUS].ptr && side != border_side_t.TOP) return; - if (side == border_side_t.RIGHT) return; // UI is snapped to the right side - - side == border_side_t.LEFT || side == border_side_t.RIGHT ? - krom_set_mouse_cursor(3) : // Horizontal - krom_set_mouse_cursor(4); // Vertical - - if (zui_current.input_started) { - UIBase.border_started = side; - UIBase.border_handle_ptr = handle_ptr; - base_is_resizing = true; - } - } - - static on_text_hover = () => { - krom_set_mouse_cursor(2); // I-cursor - } - - static on_deselect_text = () => { - ///if krom_ios - keyboard_up_listener(key_code_t.SHIFT); - ///end - } - - static on_tab_drop = (to_ptr: i32, toPosition: i32, from_ptr: i32, fromPosition: i32) => { - let i: i32 = -1; - let j: i32 = -1; - for (let k: i32 = 0; k < UIBase.htabs.length; ++k) { - if (UIBase.htabs[k].ptr == to_ptr) i = k; - if (UIBase.htabs[k].ptr == from_ptr) j = k; - } - if (i > -1 && j > -1) { - let element: any = UIBase.hwnd_tabs[j][fromPosition]; - UIBase.hwnd_tabs[j].splice(fromPosition, 1); - UIBase.hwnd_tabs[i].splice(toPosition, 0, element); - UIBase.hwnds[i].redraws = 2; - UIBase.hwnds[j].redraws = 2; - } - } - - static tag_ui_redraw = () => { - UIHeader.header_handle.redraws = 2; - UIBase.hwnds[tab_area_t.STATUS].redraws = 2; - UIMenubar.workspace_handle.redraws = 2; - UIMenubar.menu_handle.redraws = 2; - ///if (is_paint || is_sculpt) - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; - UIToolbar.toolbar_handle.redraws = 2; - ///end - } -} diff --git a/base/Sources/UIBox.ts b/base/Sources/UIBox.ts deleted file mode 100644 index 3df7bd60..00000000 --- a/base/Sources/UIBox.ts +++ /dev/null @@ -1,187 +0,0 @@ - -class UIBox { - - static show: bool = false; - static draggable: bool = true; - static hwnd: zui_handle_t = zui_handle_create(); - static box_title: string = ""; - static box_text: string = ""; - static box_commands: (ui: zui_t)=>void = null; - static click_to_hide: bool = true; - static modalw: i32 = 400; - static modalh: i32 = 170; - static modal_on_hide: ()=>void = null; - static draws: i32 = 0; - static copyable: bool = false; - ///if (krom_android || krom_ios) - static tween_alpha: f32 = 0.0; - ///end - - static render = () => { - if (!UIMenu.show) { - let ui: zui_t = base_ui_box; - let in_use: bool = ui.combo_selected_handle_ptr != 0; - let is_escape: bool = keyboard_started("escape"); - if (UIBox.draws > 2 && (ui.input_released || is_escape) && !in_use && !ui.is_typing) { - let appw: i32 = sys_width(); - let apph: i32 = sys_height(); - let mw: i32 = Math.floor(UIBox.modalw * zui_SCALE(ui)); - let mh: i32 = Math.floor(UIBox.modalh * zui_SCALE(ui)); - let left: f32 = (appw / 2 - mw / 2) + UIBox.hwnd.drag_x; - let right: f32 = (appw / 2 + mw / 2) + UIBox.hwnd.drag_x; - let top: f32 = (apph / 2 - mh / 2) + UIBox.hwnd.drag_y; - let bottom: f32 = (apph / 2 + mh / 2) + UIBox.hwnd.drag_y; - let mx: i32 = mouse_x; - let my: i32 = mouse_y; - if ((UIBox.click_to_hide && (mx < left || mx > right || my < top || my > bottom)) || is_escape) { - UIBox.hide(); - } - } - } - - if (config_raw.touch_ui) { // Darken bg - ///if (krom_android || krom_ios) - g2_set_color(color_from_floats(0, 0, 0, UIBox.tween_alpha)); - ///else - g2_set_color(color_from_floats(0, 0, 0, 0.5)); - ///end - g2_fill_rect(0, 0, sys_width(), sys_height()); - } - - g2_end(); - - let ui: zui_t = base_ui_box; - let appw: i32 = sys_width(); - let apph: i32 = sys_height(); - let mw: i32 = Math.floor(UIBox.modalw * zui_SCALE(ui)); - let mh: i32 = Math.floor(UIBox.modalh * zui_SCALE(ui)); - if (mw > appw) mw = appw; - if (mh > apph) mh = apph; - let left: i32 = Math.floor(appw / 2 - mw / 2); - let top: i32 = Math.floor(apph / 2 - mh / 2); - - if (UIBox.box_commands == null) { - zui_begin(ui); - if (zui_window(UIBox.hwnd, left, top, mw, mh, UIBox.draggable)) { - ui._y += 10; - let tab_vertical: bool = config_raw.touch_ui; - if (zui_tab(zui_handle("uibox_0"), UIBox.box_title, tab_vertical)) { - let htext: zui_handle_t = zui_handle("uibox_1"); - htext.text = UIBox.box_text; - UIBox.copyable ? - zui_text_area(htext, zui_align_t.LEFT, false) : - zui_text(UIBox.box_text); - zui_end_element(); - - ///if (krom_windows || krom_linux || krom_darwin) - if (UIBox.copyable) zui_row([1 / 3, 1 / 3, 1 / 3]); - else zui_row([2 / 3, 1 / 3]); - ///else - zui_row([2 / 3, 1 / 3]); - ///end - - zui_end_element(); - - ///if (krom_windows || krom_linux || krom_darwin) - if (UIBox.copyable && zui_button(tr("Copy"))) { - krom_copy_to_clipboard(UIBox.box_text); - } - ///end - if (zui_button(tr("OK"))) { - UIBox.hide(); - } - } - UIBox.window_border(ui); - } - zui_end(); - } - else { - zui_begin(ui); - if (zui_window(UIBox.hwnd, left, top, mw, mh, UIBox.draggable)) { - ui._y += 10; - UIBox.box_commands(ui); - UIBox.window_border(ui); - } - zui_end(); - } - - g2_begin(null); - - UIBox.draws++; - } - - static show_message = (title: string, text: string, copyable: bool = false) => { - UIBox.init(); - UIBox.modalw = 400; - UIBox.modalh = 210; - UIBox.box_title = title; - UIBox.box_text = text; - UIBox.box_commands = null; - UIBox.copyable = copyable; - UIBox.draggable = true; - ///if (krom_android || krom_ios) - UIBox.tween_in(); - ///end - } - - static show_custom = (commands: (ui: zui_t)=>void = null, mw: i32 = 400, mh: i32 = 200, onHide: ()=>void = null, draggable: bool = true) => { - UIBox.init(); - UIBox.modalw = mw; - UIBox.modalh = mh; - UIBox.modal_on_hide = onHide; - UIBox.box_commands = commands; - UIBox.draggable = draggable; - ///if (krom_android || krom_ios) - UIBox.tween_in(); - ///end - } - - static hide = () => { - ///if (krom_android || krom_ios) - UIBox.tween_out(); - ///else - UIBox.hide_internal(); - ///end - } - - static hide_internal = () => { - if (UIBox.modal_on_hide != null) UIBox.modal_on_hide(); - UIBox.show = false; - base_redraw_ui(); - } - - ///if (krom_android || krom_ios) - static tween_in = () => { - tween_reset(); - tween_to({target: UIBox, props: { tweenAlpha: 0.5 }, duration: 0.2, ease: ease_t.EXPO_OUT}); - UIBox.hwnd.drag_y = Math.floor(sys_height() / 2); - tween_to({target: UIBox.hwnd, props: { dragY: 0 }, duration: 0.2, ease: ease_t.EXPO_OUT, tick: () => { base_redraw_ui(); }}); - } - - static tween_out = () => { - tween_to({target: UIBox, props: { tweenAlpha: 0.0 }, duration: 0.2, ease: ease_t.EXPO_IN, done: UIBox.hide_internal}); - tween_to({target: UIBox.hwnd, props: { dragY: sys_height() / 2 }, duration: 0.2, ease: ease_t.EXPO_IN}); - } - ///end - - static init = () => { - UIBox.hwnd.redraws = 2; - UIBox.hwnd.drag_x = 0; - UIBox.hwnd.drag_y = 0; - UIBox.show = true; - UIBox.draws = 0; - UIBox.click_to_hide = true; - } - - static window_border = (ui: zui_t) => { - if (ui.scissor) { - ui.scissor = false; - g2_disable_scissor(); - } - // Border - g2_set_color(ui.t.SEPARATOR_COL); - g2_fill_rect(0, 0, 1, ui._window_h); - g2_fill_rect(0 + ui._window_w - 1, 0, 1, ui._window_h); - g2_fill_rect(0, 0 + ui._window_h - 1, ui._window_w, 1); - } -} diff --git a/base/Sources/UIFiles.ts b/base/Sources/UIFiles.ts deleted file mode 100644 index 6e8ba1b4..00000000 --- a/base/Sources/UIFiles.ts +++ /dev/null @@ -1,387 +0,0 @@ - -class UIFiles { - - static default_path: string = - ///if krom_windows - "C:\\Users" - ///elseif krom_android - "/storage/emulated/0/Download" - ///elseif krom_darwin - "/Users" - ///else - "/" - ///end - ; - - static filename: string; - static path: string = UIFiles.default_path; - static last_path: string = ""; - static last_search: string = ""; - static files: string[] = null; - static icon_map: Map = null; - static selected: i32 = -1; - static show_extensions: bool = false; - static offline: bool = false; - - static show = (filters: string, isSave: bool, openMultiple: bool, filesDone: (s: string)=>void) => { - if (isSave) { - UIFiles.path = krom_save_dialog(filters, ""); - if (UIFiles.path != null) { - while (UIFiles.path.indexOf(path_sep + path_sep) >= 0) UIFiles.path = string_replace_all(UIFiles.path, path_sep + path_sep, path_sep); - UIFiles.path = string_replace_all(UIFiles.path, "\r", ""); - UIFiles.filename = UIFiles.path.substr(UIFiles.path.lastIndexOf(path_sep) + 1); - UIFiles.path = UIFiles.path.substr(0, UIFiles.path.lastIndexOf(path_sep)); - filesDone(UIFiles.path); - } - } - else { - let paths: string[] = krom_open_dialog(filters, "", openMultiple); - if (paths != null) { - for (let path of paths) { - while (path.indexOf(path_sep + path_sep) >= 0) path = string_replace_all(path, path_sep + path_sep, path_sep); - path = string_replace_all(path, "\r", ""); - UIFiles.filename = path.substr(path.lastIndexOf(path_sep) + 1); - filesDone(path); - } - } - } - - UIFiles.release_keys(); - } - - // static show_custom = (filters: string, isSave: bool, filesDone: (s: string)=>void) => { - // let known: bool = false; - // UIBox.show_custom((ui: ZuiRaw) => { - // if (Zui.tab(Zui.handle(), tr("File Browser"))) { - // let path_handle: zui_handle_t = Zui.handle(); - // let file_handle: zui_handle_t = Zui.handle(); - // Zui.row([6 / 10, 2 / 10, 2 / 10]); - // filename = Zui.textInput(file_handle, tr("File")); - // Zui.text("*." + filters, Center); - // if (Zui.button(isSave ? tr("Save") : tr("Open")) || known || ui.isReturnDown) { - // UIBox.hide(); - // filesDone((known || isSave) ? path : path + sep + filename); - // if (known) path_handle.text = path_handle.text.substr(0, path_handle.text.lastIndexOf(sep)); - // } - // known = isTexture(path) || isMesh(path) || isProject(path); - // path = fileBrowser(ui, path_handle, false); - // if (path_handle.changed) ui.currentWindow.redraws = 3; - // } - // }, 600, 500); - // } - - static release_keys = () => { - // File dialog may prevent firing key up events - keyboard_up_listener(key_code_t.SHIFT); - keyboard_up_listener(key_code_t.CONTROL); - ///if krom_darwin - keyboard_up_listener(key_code_t.META); - ///end - } - - static file_browser = (ui: zui_t, handle: zui_handle_t, foldersOnly: bool = false, dragFiles: bool = false, search: string = "", refresh: bool = false, contextMenu: (s: string)=>void = null): string => { - - let icons: image_t = resource_get("icons.k"); - let folder: rect_t = resource_tile50(icons, 2, 1); - let file: rect_t = resource_tile50(icons, 3, 1); - let is_cloud: bool = handle.text.startsWith("cloud"); - - if (is_cloud && file_cloud == null) file_init_cloud(() => { UIBase.hwnds[tab_area_t.STATUS].redraws = 3; }); - if (is_cloud && file_read_directory("cloud", false).length == 0) return handle.text; - - ///if krom_ios - let document_directory: string = krom_save_dialog("", ""); - document_directory = document_directory.substr(0, document_directory.length - 8); // Strip /'untitled' - ///end - - if (handle.text == "") handle.text = UIFiles.default_path; - if (handle.text != UIFiles.last_path || search != UIFiles.last_search || refresh) { - UIFiles.files = []; - - // Up directory - let i1: i32 = handle.text.indexOf(path_sep); - let nested: bool = i1 > -1 && handle.text.length - 1 > i1; - ///if krom_windows - // Server addresses like \\server are not nested - nested = nested && !(handle.text.length >= 2 && handle.text.charAt(0) == path_sep && handle.text.charAt(1) == path_sep && handle.text.lastIndexOf(path_sep) == 1); - ///end - if (nested) UIFiles.files.push(".."); - - let dir_path: string = handle.text; - ///if krom_ios - if (!is_cloud) dir_path = document_directory + dir_path; - ///end - let files_all: string[] = file_read_directory(dir_path, foldersOnly); - - for (let f of files_all) { - if (f == "" || f.charAt(0) == ".") continue; // Skip hidden - if (f.indexOf(".") > 0 && !path_is_known(f)) continue; // Skip unknown extensions - if (is_cloud && f.indexOf("_icon.") >= 0) continue; // Skip thumbnails - if (f.toLowerCase().indexOf(search.toLowerCase()) < 0) continue; // Search filter - UIFiles.files.push(f); - } - } - UIFiles.last_path = handle.text; - UIFiles.last_search = search; - handle.changed = false; - - let slotw: i32 = Math.floor(70 * zui_SCALE(ui)); - let num: i32 = Math.floor(ui._w / slotw); - - ui._y += 4; // Don't cut off the border around selected materials - // Directory contents - for (let row: i32 = 0; row < Math.floor(Math.ceil(UIFiles.files.length / num)); ++row) { - let ar: f32[] = []; - for (let i: i32 = 0; i < num * 2; ++i) ar.push(1 / num); - zui_row(ar); - if (row > 0) ui._y += zui_ELEMENT_OFFSET(ui) * 14.0; - - for (let j: i32 = 0; j < num; ++j) { - let i: i32 = j + row * num; - if (i >= UIFiles.files.length) { - zui_end_element(slotw); - zui_end_element(slotw); - continue; - } - - let f: string = UIFiles.files[i]; - let _x: f32 = ui._x; - - let rect: rect_t = f.indexOf(".") > 0 ? file : folder; - let col: i32 = rect == file ? ui.t.LABEL_COL : ui.t.LABEL_COL - 0x00202020; - if (UIFiles.selected == i) col = ui.t.HIGHLIGHT_COL; - - let off: f32 = ui._w / 2 - 25 * zui_SCALE(ui); - ui._x += off; - - let uix: f32 = ui._x; - let uiy: f32 = ui._y; - let state: zui_state_t = zui_state_t.IDLE; - let generic: bool = true; - let icon: image_t = null; - - if (is_cloud && f != ".." && !UIFiles.offline) { - if (UIFiles.icon_map == null) UIFiles.icon_map = new Map(); - icon = UIFiles.icon_map.get(handle.text + path_sep + f); - if (icon == null) { - let files_all: string[] = file_read_directory(handle.text); - let icon_file: string = f.substr(0, f.lastIndexOf(".")) + "_icon.jpg"; - if (files_all.indexOf(icon_file) >= 0) { - let empty: image_t = render_path_render_targets.get("empty_black")._image; - UIFiles.icon_map.set(handle.text + path_sep + f, empty); - file_cache_cloud(handle.text + path_sep + icon_file, (abs: string) => { - if (abs != null) { - let image: image_t = data_get_image(abs); - app_notify_on_init(() => { - if (base_pipe_copy_rgb == null) base_make_pipe_copy_rgb(); - icon = image_create_render_target(image.width, image.height); - if (f.endsWith(".arm")) { // Used for material sphere alpha cutout - g2_begin(icon); - - ///if (is_paint || is_sculpt) - g2_draw_image(project_materials[0].image, 0, 0); - ///end - } - else { - g2_begin(icon); - g2_clear(0xffffffff); - } - g2_set_pipeline(base_pipe_copy_rgb); - g2_draw_image(image, 0, 0); - g2_set_pipeline(null); - g2_end(); - UIFiles.icon_map.set(handle.text + path_sep + f, icon); - UIBase.hwnds[tab_area_t.STATUS].redraws = 3; - }); - } - else UIFiles.offline = true; - }); - } - } - if (icon != null) { - let w: i32 = 50; - if (i == UIFiles.selected) { - zui_fill(-2, -2, w + 4, 2, ui.t.HIGHLIGHT_COL); - zui_fill(-2, w + 2, w + 4, 2, ui.t.HIGHLIGHT_COL); - zui_fill(-2, 0, 2, w + 4, ui.t.HIGHLIGHT_COL); - zui_fill(w + 2 , -2, 2, w + 6, ui.t.HIGHLIGHT_COL); - } - state = zui_image(icon, 0xffffffff, w * zui_SCALE(ui)); - if (ui.is_hovered) { - zui_tooltip_image(icon); - zui_tooltip(f); - } - generic = false; - } - } - if (f.endsWith(".arm") && !is_cloud) { - if (UIFiles.icon_map == null) UIFiles.icon_map = new Map(); - let key: string = handle.text + path_sep + f; - icon = UIFiles.icon_map.get(key); - if (!UIFiles.icon_map.has(key)) { - let blob_path: string = key; - - ///if krom_ios - blob_path = document_directory + blob_path; - // TODO: implement native .arm parsing first - ///else - - let buffer: buffer_t = krom_load_blob(blob_path); - let raw: any = armpack_decode(buffer); - if (raw.material_icons != null) { - let bytes_icon: any = raw.material_icons[0]; - icon = image_from_bytes(lz4_decode(bytes_icon, 256 * 256 * 4), 256, 256); - } - - ///if (is_paint || is_sculpt) - else if (raw.mesh_icons != null) { - let bytes_icon: any = raw.mesh_icons[0]; - icon = image_from_bytes(lz4_decode(bytes_icon, 256 * 256 * 4), 256, 256); - } - else if (raw.brush_icons != null) { - let bytes_icon: any = raw.brush_icons[0]; - icon = image_from_bytes(lz4_decode(bytes_icon, 256 * 256 * 4), 256, 256); - } - ///end - - ///if is_lab - if (raw.mesh_icon != null) { - let bytes_icon: any = raw.mesh_icon; - icon = image_from_bytes(lz4_decode(bytes_icon, 256 * 256 * 4), 256, 256); - } - ///end - - UIFiles.icon_map.set(key, icon); - ///end - } - if (icon != null) { - let w: i32 = 50; - if (i == UIFiles.selected) { - zui_fill(-2, -2, w + 4, 2, ui.t.HIGHLIGHT_COL); - zui_fill(-2, w + 2, w + 4, 2, ui.t.HIGHLIGHT_COL); - zui_fill(-2, 0, 2, w + 4, ui.t.HIGHLIGHT_COL); - zui_fill(w + 2 , -2, 2, w + 6, ui.t.HIGHLIGHT_COL); - } - state = zui_image(icon, 0xffffffff, w * zui_SCALE(ui)); - if (ui.is_hovered) { - zui_tooltip_image(icon); - zui_tooltip(f); - } - generic = false; - } - } - - if (path_is_texture(f) && !is_cloud) { - let w: i32 = 50; - if (UIFiles.icon_map == null) UIFiles.icon_map = new Map(); - let shandle: string = handle.text + path_sep + f; - icon = UIFiles.icon_map.get(shandle); - if (icon == null) { - let empty: image_t = render_path_render_targets.get("empty_black")._image; - UIFiles.icon_map.set(shandle, empty); - let image: image_t = data_get_image(shandle); - app_notify_on_init(() => { - if (base_pipe_copy_rgb == null) base_make_pipe_copy_rgb(); - let sw: i32 = image.width > image.height ? w : Math.floor(1.0 * image.width / image.height * w); - let sh: i32 = image.width > image.height ? Math.floor(1.0 * image.height / image.width * w) : w; - icon = image_create_render_target(sw, sh); - g2_begin(icon); - g2_clear(0xffffffff); - g2_set_pipeline(base_pipe_copy_rgb); - g2_draw_scaled_image(image, 0, 0, sw, sh); - g2_set_pipeline(null); - g2_end(); - UIFiles.icon_map.set(shandle, icon); - UIBase.hwnds[tab_area_t.STATUS].redraws = 3; - data_delete_image(shandle); // The big image is not needed anymore - }); - } - if (icon != null) { - if (i == UIFiles.selected) { - zui_fill(-2, -2, w + 4, 2, ui.t.HIGHLIGHT_COL); - zui_fill(-2, w + 2, w + 4, 2, ui.t.HIGHLIGHT_COL); - zui_fill(-2, 0, 2, w + 4, ui.t.HIGHLIGHT_COL); - zui_fill(w + 2 , -2, 2, w + 6, ui.t.HIGHLIGHT_COL); - } - state = zui_image(icon, 0xffffffff, icon.height * zui_SCALE(ui)); - generic = false; - } - } - - if (generic) { - state = zui_image(icons, col, 50 * zui_SCALE(ui), rect.x, rect.y, rect.w, rect.h); - } - - if (ui.is_hovered && ui.input_released_r && contextMenu != null) { - contextMenu(handle.text + path_sep + f); - } - - if (state == zui_state_t.STARTED) { - if (f != ".." && dragFiles) { - base_drag_off_x = -(mouse_x - uix - ui._window_x - 3); - base_drag_off_y = -(mouse_y - uiy - ui._window_y + 1); - base_drag_file = handle.text; - ///if krom_ios - if (!is_cloud) base_drag_file = document_directory + base_drag_file; - ///end - if (base_drag_file.charAt(base_drag_file.length - 1) != path_sep) { - base_drag_file += path_sep; - } - base_drag_file += f; - base_drag_file_icon = icon; - } - - UIFiles.selected = i; - if (time_time() - context_raw.select_time < 0.25) { - base_drag_file = null; - base_drag_file_icon = null; - base_is_dragging = false; - handle.changed = ui.changed = true; - if (f == "..") { // Up - handle.text = handle.text.substring(0, handle.text.lastIndexOf(path_sep)); - // Drive root - if (handle.text.length == 2 && handle.text.charAt(1) == ":") handle.text += path_sep; - } - else { - if (handle.text.charAt(handle.text.length - 1) != path_sep) { - handle.text += path_sep; - } - handle.text += f; - } - UIFiles.selected = -1; - } - context_raw.select_time = time_time(); - } - - // Label - ui._x = _x; - ui._y += slotw * 0.75; - let label0: string = (UIFiles.show_extensions || f.indexOf(".") <= 0) ? f : f.substr(0, f.lastIndexOf(".")); - let label1: string = ""; - while (label0.length > 0 && g2_font_width(ui.font, ui.font_size, label0) > ui._w - 6) { // 2 line split - label1 = label0.charAt(label0.length - 1) + label1; - label0 = label0.substr(0, label0.length - 1); - } - if (label1 != "") ui.cur_ratio--; - zui_text(label0, zui_align_t.CENTER); - if (ui.is_hovered) zui_tooltip(label0 + label1); - if (label1 != "") { // Second line - ui._x = _x; - ui._y += g2_font_height(ui.font, ui.font_size); - zui_text(label1, zui_align_t.CENTER); - if (ui.is_hovered) zui_tooltip(label0 + label1); - ui._y -= g2_font_height(ui.font, ui.font_size); - } - - ui._y -= slotw * 0.75; - - if (handle.changed) break; - } - - if (handle.changed) break; - } - ui._y += slotw * 0.8; - - return handle.text; - } -} diff --git a/base/Sources/UIHeader.ts b/base/Sources/UIHeader.ts deleted file mode 100644 index bca7d23d..00000000 --- a/base/Sources/UIHeader.ts +++ /dev/null @@ -1,502 +0,0 @@ - -class UIHeader { - - static default_header_h: i32 = 28; - static headerh: i32 = UIHeader.default_header_h; - static header_handle: zui_handle_t = zui_handle_create({ layout: zui_layout_t.HORIZONTAL }); - static worktab: zui_handle_t = zui_handle_create(); - - constructor() { - } - - static render_ui = () => { - let ui: zui_t = UIBase.ui; - if (config_raw.touch_ui) { - UIHeader.headerh = UIHeader.default_header_h + 6; - } - else { - UIHeader.headerh = UIHeader.default_header_h; - } - UIHeader.headerh = Math.floor(UIHeader.headerh * zui_SCALE(ui)); - - if (config_raw.layout[layout_size_t.HEADER] == 0) return; - - let nodesw: i32 = (UINodes.show || UIView2D.show) ? config_raw.layout[layout_size_t.NODES_W] : 0; - ///if is_lab - let ww: i32 = sys_width() - nodesw; - ///else - let ww: i32 = sys_width() - UIToolbar.toolbar_w - config_raw.layout[layout_size_t.SIDEBAR_W] - nodesw; - ///end - - if (zui_window(UIHeader.header_handle, app_x(), UIHeader.headerh, ww, UIHeader.headerh)) { - ui._y += 2; - UIHeader.draw_tool_properties(ui); - } - } - - ///if is_paint - - static draw_tool_properties = (ui: zui_t) => { - if (context_raw.tool == workspace_tool_t.COLORID) { - zui_text(tr("Picked Color")); - if (context_raw.colorid_picked) { - zui_image(render_path_render_targets.get("texpaint_colorid")._image, 0xffffffff, 64); - } - ui.enabled = context_raw.colorid_picked; - if (zui_button(tr("Clear"))) { - context_raw.colorid_picked = false; - UIToolbar.toolbar_handle.redraws = 1; - } - ui.enabled = true; - zui_text(tr("Color ID Map")); - if (project_asset_names.length > 0) { - let cid: i32 = zui_combo(context_raw.colorid_handle, base_enum_texts("TEX_IMAGE"), tr("Color ID")); - if (context_raw.colorid_handle.changed) { - context_raw.ddirty = 2; - context_raw.colorid_picked = false; - UIToolbar.toolbar_handle.redraws = 1; - } - zui_image(project_get_image(project_assets[cid])); - if (ui.is_hovered) zui_tooltip_image(project_get_image(project_assets[cid]), 256); - } - if (zui_button(tr("Import"))) { - UIFiles.show(path_texture_formats.join(","), false, true, (path: string) => { - ImportAsset.run(path, -1.0, -1.0, true, false); - - context_raw.colorid_handle.position = project_asset_names.length - 1; - for (let a of project_assets) { - // Already imported - if (a.file == path) context_raw.colorid_handle.position = project_assets.indexOf(a); - } - context_raw.ddirty = 2; - context_raw.colorid_picked = false; - UIToolbar.toolbar_handle.redraws = 1; - UIBase.hwnds[2].redraws = 2; - }); - } - ui.enabled = context_raw.colorid_picked; - if (zui_button(tr("To Mask"))) { - if (SlotLayer.is_mask(context_raw.layer)) context_set_layer(context_raw.layer.parent); - let m: SlotLayerRaw = base_new_mask(false, context_raw.layer); - let _next = () => { - if (base_pipe_merge == null) base_make_pipe(); - if (const_data_screen_aligned_vb == null) const_data_create_screen_aligned_data(); - g4_begin(m.texpaint); - g4_set_pipeline(base_pipe_colorid_to_mask); - g4_set_tex(base_texpaint_colorid,render_path_render_targets.get("texpaint_colorid")._image); - g4_set_tex(base_tex_colorid, project_get_image(project_assets[context_raw.colorid_handle.position])); - g4_set_vertex_buffer(const_data_screen_aligned_vb); - g4_set_index_buffer(const_data_screen_aligned_ib); - g4_draw(); - g4_end(); - context_raw.colorid_picked = false; - UIToolbar.toolbar_handle.redraws = 1; - UIHeader.header_handle.redraws = 1; - context_raw.layer_preview_dirty = true; - base_update_fill_layers(); - } - base_notify_on_next_frame(_next); - history_new_white_mask(); - } - ui.enabled = true; - } - else if (context_raw.tool == workspace_tool_t.PICKER || context_raw.tool == workspace_tool_t.MATERIAL) { - let base_r_picked: f32 = Math.round(color_get_rb(context_raw.picked_color.base) / 255 * 10) / 10; - let base_g_picked: f32 = Math.round(color_get_gb(context_raw.picked_color.base) / 255 * 10) / 10; - let base_b_picked: f32 = Math.round(color_get_bb(context_raw.picked_color.base) / 255 * 10) / 10; - let normal_r_picked: f32 = Math.round(color_get_rb(context_raw.picked_color.normal) / 255 * 10) / 10; - let normal_g_picked: f32 = Math.round(color_get_gb(context_raw.picked_color.normal) / 255 * 10) / 10; - let normal_b_picked: f32 = Math.round(color_get_bb(context_raw.picked_color.normal) / 255 * 10) / 10; - let occlusion_picked: f32 = Math.round(context_raw.picked_color.occlusion * 100) / 100; - let roughness_picked: f32 = Math.round(context_raw.picked_color.roughness * 100) / 100; - let metallic_picked: f32 = Math.round(context_raw.picked_color.metallic * 100) / 100; - let height_picked: f32 = Math.round(context_raw.picked_color.height * 100) / 100; - let opacity_picked: f32 = Math.round(context_raw.picked_color.opacity * 100) / 100; - - let h: zui_handle_t = zui_handle("uiheader_0"); - let color: color_t = 0xffffffff; - color = color_set_rb(color, base_r_picked * 255); - color = color_set_gb(color, base_g_picked * 255); - color = color_set_bb(color, base_b_picked * 255); - h.color = color; - let state: zui_state_t = zui_text("", 0, h.color); - if (state == zui_state_t.STARTED) { - let uix: i32 = ui._x; - let uiy: i32 = ui._y; - base_drag_off_x = -(mouse_x - uix - ui._window_x - 3); - base_drag_off_y = -(mouse_y - uiy - ui._window_y + 1); - base_drag_swatch = project_clone_swatch(context_raw.picked_color); - } - if (ui.is_hovered) zui_tooltip(tr("Drag and drop picked color to swatches, materials, layers or to the node editor")); - if (ui.is_hovered && ui.input_released) { - UIMenu.draw((ui: zui_t) => { - zui_fill(0, 0, ui._w / zui_SCALE(ui), ui.t.ELEMENT_H * 9, ui.t.SEPARATOR_COL); - ui.changed = false; - zui_color_wheel(h, false, null, 10 * ui.t.ELEMENT_H * zui_SCALE(ui), false); - if (ui.changed) UIMenu.keep_open = true; - }, 10); - } - if (zui_button(tr("Add Swatch"))) { - let new_swatch: swatch_color_t = project_clone_swatch(context_raw.picked_color); - context_set_swatch(new_swatch); - project_raw.swatches.push(new_swatch); - UIBase.hwnds[2].redraws = 1; - } - if (ui.is_hovered) zui_tooltip(tr("Add picked color to swatches")); - - zui_text(tr("Base") + ` (${base_r_picked},${base_g_picked},${base_b_picked})`); - zui_text(tr("Normal") + ` (${normal_r_picked},${normal_g_picked},${normal_b_picked})`); - zui_text(tr("Occlusion") + ` (${occlusion_picked})`); - zui_text(tr("Roughness") + ` (${roughness_picked})`); - zui_text(tr("Metallic") + ` (${metallic_picked})`); - zui_text(tr("Height") + ` (${height_picked})`); - zui_text(tr("Opacity") + ` (${opacity_picked})`); - context_raw.picker_select_material = zui_check(zui_handle("uiheader_1", { selected: context_raw.picker_select_material }), tr("Select Material")); - zui_combo(context_raw.picker_mask_handle, [tr("None"), tr("Material")], tr("Mask"), true); - if (context_raw.picker_mask_handle.changed) { - MakeMaterial.parse_paint_material(); - } - } - else if (context_raw.tool == workspace_tool_t.BAKE) { - ui.changed = false; - - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - let baking: bool = context_raw.pdirty > 0; - let rt_bake: bool = context_raw.bake_type == bake_type_t.AO || context_raw.bake_type == bake_type_t.LIGHTMAP || context_raw.bake_type == bake_type_t.BENT_NORMAL || context_raw.bake_type == bake_type_t.THICKNESS; - if (baking && zui_button(tr("Stop"))) { - context_raw.pdirty = 0; - context_raw.rdirty = 2; - } - ///else - let baking: bool = false; - let rt_bake: bool = false; - ///end - - if (!baking && zui_button(tr("Bake"))) { - context_raw.pdirty = rt_bake ? context_raw.bake_samples : 1; - context_raw.rdirty = 3; - base_notify_on_next_frame(() => { - context_raw.layer_preview_dirty = true; - }); - UIBase.hwnds[0].redraws = 2; - history_push_undo = true; - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - RenderPathRaytraceBake.current_sample = 0; - ///end - } - - let bake_handle: zui_handle_t = zui_handle("uiheader_2", { position: context_raw.bake_type }); - let bakes: string[] = [ - tr("AO"), - tr("Curvature"), - tr("Normal"), - tr("Object Normal"), - tr("Height"), - tr("Derivative"), - tr("Position"), - tr("TexCoord"), - tr("Material ID"), - tr("Object ID"), - tr("Vertex Color"), - ]; - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - if (krom_raytrace_supported()) { - bakes.push(tr("Lightmap")); - bakes.push(tr("Bent Normal")); - bakes.push(tr("Thickness")); - } - else { - bakes.shift(); // Remove AO - } - ///end - - context_raw.bake_type = zui_combo(bake_handle, bakes, tr("Bake")); - - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - if (!krom_raytrace_supported()) { - context_raw.bake_type += 1; // Offset for removed AO - } - ///end - - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - if (rt_bake) { - let samples_handle: zui_handle_t = zui_handle("uiheader_3", { value: context_raw.bake_samples }); - context_raw.bake_samples = Math.floor(zui_slider(samples_handle, tr("Samples"), 1, 512, true, 1)); - } - ///end - - if (context_raw.bake_type == bake_type_t.NORMAL_OBJECT || context_raw.bake_type == bake_type_t.POSITION || context_raw.bake_type == bake_type_t.BENT_NORMAL) { - let bake_up_axis_handle: zui_handle_t = zui_handle("uiheader_4", { 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); - } - 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("uiheader_5", { 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); - } - if (context_raw.bake_type == bake_type_t.AO) { - let strength_handle: zui_handle_t = zui_handle("uiheader_6", { value: context_raw.bake_ao_strength }); - context_raw.bake_ao_strength = zui_slider(strength_handle, tr("Strength"), 0.0, 2.0, true); - let radius_handle: zui_handle_t = zui_handle("uiheader_7", { value: context_raw.bake_ao_radius }); - context_raw.bake_ao_radius = zui_slider(radius_handle, tr("Radius"), 0.0, 2.0, true); - let offset_handle: zui_handle_t = zui_handle("uiheader_8", { value: context_raw.bake_ao_offset }); - context_raw.bake_ao_offset = zui_slider(offset_handle, tr("Offset"), 0.0, 2.0, true); - } - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - if (rt_bake) { - let progress: f32 = RenderPathRaytraceBake.current_sample / context_raw.bake_samples; - if (progress > 1.0) progress = 1.0; - // Progress bar - g2_set_color(ui.t.SEPARATOR_COL); - zui_draw_rect(true, ui._x + 1, ui._y, ui._w - 2, zui_ELEMENT_H(ui)); - g2_set_color(ui.t.HIGHLIGHT_COL); - zui_draw_rect(true, ui._x + 1, ui._y, (ui._w - 2) * progress, zui_ELEMENT_H(ui)); - g2_set_color(0xffffffff); - zui_text(tr("Samples") + ": " + RenderPathRaytraceBake.current_sample); - zui_text(tr("Rays/pixel" + ": ") + RenderPathRaytraceBake.rays_pix); - zui_text(tr("Rays/second" + ": ") + RenderPathRaytraceBake.rays_sec); - } - ///end - if (context_raw.bake_type == bake_type_t.CURVATURE) { - let strength_handle: zui_handle_t = zui_handle("uiheader_9", { value: context_raw.bake_curv_strength }); - context_raw.bake_curv_strength = zui_slider(strength_handle, tr("Strength"), 0.0, 2.0, true); - let radius_handle: zui_handle_t = zui_handle("uiheader_10", { value: context_raw.bake_curv_radius }); - context_raw.bake_curv_radius = zui_slider(radius_handle, tr("Radius"), 0.0, 2.0, true); - let offset_handle: zui_handle_t = zui_handle("uiheader_11", { value: context_raw.bake_curv_offset }); - context_raw.bake_curv_offset = zui_slider(offset_handle, tr("Offset"), -2.0, 2.0, true); - let smooth_handle: zui_handle_t = zui_handle("uiheader_12", { value: context_raw.bake_curv_smooth }); - context_raw.bake_curv_smooth = Math.floor(zui_slider(smooth_handle, tr("Smooth"), 0, 5, false, 1)); - } - if (context_raw.bake_type == bake_type_t.NORMAL || context_raw.bake_type == bake_type_t.HEIGHT || context_raw.bake_type == bake_type_t.DERIVATIVE) { - let ar: string[] = []; - for (let p of project_paint_objects) ar.push(p.base.name); - let poly_handle: zui_handle_t = zui_handle("uiheader_13", { position: context_raw.bake_high_poly }); - context_raw.bake_high_poly = zui_combo(poly_handle, ar, tr("High Poly")); - } - if (ui.changed) { - MakeMaterial.parse_paint_material(); - } - } - else if (context_raw.tool == workspace_tool_t.BRUSH || - context_raw.tool == workspace_tool_t.ERASER || - context_raw.tool == workspace_tool_t.FILL || - context_raw.tool == workspace_tool_t.DECAL || - context_raw.tool == workspace_tool_t.TEXT || - context_raw.tool == workspace_tool_t.CLONE || - context_raw.tool == workspace_tool_t.BLUR || - context_raw.tool == workspace_tool_t.SMUDGE || - context_raw.tool == workspace_tool_t.PARTICLE) { - - let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; - let decal_mask: bool = decal && operator_shortcut(config_keymap.decal_mask, shortcut_type_t.DOWN); - if (context_raw.tool != workspace_tool_t.FILL) { - if (decal_mask) { - context_raw.brush_decal_mask_radius = zui_slider(context_raw.brush_decal_mask_radius_handle, tr("Radius"), 0.01, 2.0, true); - if (ui.is_hovered) zui_tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", new Map([["brush_radius", config_keymap.brush_radius], ["brush_radius_decrease", config_keymap.brush_radius_decrease], ["brush_radius_increase", config_keymap.brush_radius_increase]]))); - } - else { - context_raw.brush_radius = zui_slider(context_raw.brush_radius_handle, tr("Radius"), 0.01, 2.0, true); - if (ui.is_hovered) zui_tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", new Map([["brush_radius", config_keymap.brush_radius], ["brush_radius_decrease", config_keymap.brush_radius_decrease], ["brush_radius_increase", config_keymap.brush_radius_increase]]))); - } - } - - if (context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT) { - context_raw.brush_scale_x = zui_slider(context_raw.brush_scale_x_handle, tr("Scale X"), 0.01, 2.0, true); - } - - if (context_raw.tool == workspace_tool_t.BRUSH || - context_raw.tool == workspace_tool_t.FILL || - context_raw.tool == workspace_tool_t.DECAL || - context_raw.tool == workspace_tool_t.TEXT) { - let brush_scale_handle: zui_handle_t = zui_handle("uiheader_14", { value: context_raw.brush_scale }); - context_raw.brush_scale = zui_slider(brush_scale_handle, tr("UV Scale"), 0.01, 5.0, true); - if (brush_scale_handle.changed) { - if (context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT) { - let current: image_t = _g2_current; - g2_end(); - UtilRender.make_decal_preview(); - g2_begin(current); - } - } - - context_raw.brush_angle = zui_slider(context_raw.brush_angle_handle, tr("Angle"), 0.0, 360.0, true, 1); - if (ui.is_hovered) zui_tooltip(tr("Hold {brush_angle} and move mouse to the left to decrease the angle\nHold {brush_angle} and move mouse to the right to increase the angle", new Map([["brush_angle", config_keymap.brush_angle]]))); - - if (context_raw.brush_angle_handle.changed) { - MakeMaterial.parse_paint_material(); - } - } - - context_raw.brush_opacity = zui_slider(context_raw.brush_opacity_handle, tr("Opacity"), 0.0, 1.0, true); - if (ui.is_hovered) zui_tooltip(tr("Hold {brush_opacity} and move mouse to the left to decrease the opacity\nHold {brush_opacity} and move mouse to the right to increase the opacity", new Map([["brush_opacity", config_keymap.brush_opacity]]))); - - if (context_raw.tool == workspace_tool_t.BRUSH || context_raw.tool == workspace_tool_t.ERASER || context_raw.tool == workspace_tool_t.CLONE || decal_mask) { - context_raw.brush_hardness = zui_slider(zui_handle("uiheader_15", { value: context_raw.brush_hardness }), tr("Hardness"), 0.0, 1.0, true); - } - - if (context_raw.tool != workspace_tool_t.ERASER) { - let brush_blending_handle: zui_handle_t = zui_handle("uiheader_16", { value: context_raw.brush_blending }); - context_raw.brush_blending = zui_combo(brush_blending_handle, [ - tr("Mix"), - tr("Darken"), - tr("Multiply"), - tr("Burn"), - tr("Lighten"), - tr("Screen"), - tr("Dodge"), - tr("Add"), - tr("Overlay"), - tr("Soft Light"), - tr("Linear Light"), - tr("Difference"), - tr("Subtract"), - tr("Divide"), - tr("Hue"), - tr("Saturation"), - tr("Color"), - tr("Value"), - ], tr("Blending")); - if (brush_blending_handle.changed) { - MakeMaterial.parse_paint_material(); - } - } - - if (context_raw.tool == workspace_tool_t.BRUSH || context_raw.tool == workspace_tool_t.FILL) { - let paint_handle: zui_handle_t = zui_handle("uiheader_17"); - context_raw.brush_paint = zui_combo(paint_handle, [tr("UV Map"), tr("Triplanar"), tr("Project")], tr("TexCoord")); - if (paint_handle.changed) { - MakeMaterial.parse_paint_material(); - } - } - if (context_raw.tool == workspace_tool_t.TEXT) { - let h: zui_handle_t = zui_handle("uiheader_18"); - h.text = context_raw.text_tool_text; - let w: i32 = ui._w; - if (ui.text_selected_handle_ptr == h.ptr || ui.submit_text_handle_ptr == h.ptr) { - ui._w *= 3; - } - - context_raw.text_tool_text = zui_text_input(h, "", zui_align_t.LEFT, true, true); - ui._w = w; - - if (h.changed) { - let current: image_t = _g2_current; - g2_end(); - UtilRender.make_text_preview(); - UtilRender.make_decal_preview(); - g2_begin(current); - } - } - - 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")); - if (context_raw.fill_type_handle.changed) { - if (context_raw.fill_type_handle.position == fill_type_t.FACE) { - let current: image_t = _g2_current; - g2_end(); - // UtilUV.cacheUVMap(); - UtilUV.cache_triangle_map(); - g2_begin(current); - // wireframeHandle.selected = drawWireframe = true; - } - MakeMaterial.parse_paint_material(); - MakeMaterial.parse_mesh_material(); - } - } - else { - let _w: i32 = ui._w; - let sc: f32 = zui_SCALE(ui); - let touch_header: bool = (config_raw.touch_ui && config_raw.layout[layout_size_t.HEADER] == 1); - if (touch_header) ui._x -= 4 * sc; - ui._w = Math.floor((touch_header ? 54 : 60) * sc); - - let xray_handle: zui_handle_t = zui_handle("uiheader_19", { selected: context_raw.xray }); - context_raw.xray = zui_check(xray_handle, tr("X-Ray")); - if (xray_handle.changed) { - MakeMaterial.parse_paint_material(); - } - - let sym_x_handle: zui_handle_t = zui_handle("uiheader_20", { selected: false }); - let sym_y_handle: zui_handle_t = zui_handle("uiheader_21", { selected: false }); - let sym_z_handle: zui_handle_t = zui_handle("uiheader_22", { selected: false }); - - if (config_raw.layout[layout_size_t.HEADER] == 1) { - if (config_raw.touch_ui) { - ui._w = Math.floor(19 * sc); - context_raw.sym_x = zui_check(sym_x_handle, ""); - ui._x -= 4 * sc; - context_raw.sym_y = zui_check(sym_y_handle, ""); - ui._x -= 4 * sc; - context_raw.sym_z = zui_check(sym_z_handle, ""); - ui._x -= 4 * sc; - ui._w = Math.floor(40 * sc); - zui_text(tr("X") + tr("Y") + tr("Z")); - } - else { - ui._w = Math.floor(56 * sc); - zui_text(tr("Symmetry")); - ui._w = Math.floor(25 * sc); - context_raw.sym_x = zui_check(sym_x_handle, tr("X")); - context_raw.sym_y = zui_check(sym_y_handle, tr("Y")); - context_raw.sym_z = zui_check(sym_z_handle, tr("Z")); - } - ui._w = _w; - } - else { - // Popup - ui._w = _w; - context_raw.sym_x = zui_check(sym_x_handle, tr("Symmetry") + " " + tr("X")); - context_raw.sym_y = zui_check(sym_y_handle, tr("Symmetry") + " " + tr("Y")); - context_raw.sym_z = zui_check(sym_z_handle, tr("Symmetry") + " " + tr("Z")); - } - - if (sym_x_handle.changed || sym_y_handle.changed || sym_z_handle.changed) { - MakeMaterial.parse_paint_material(); - } - } - - ///if arm_physics - if (context_raw.tool == workspace_tool_t.PARTICLE) { - ui._x += 10 * zui_SCALE(ui); - let phys_handle: zui_handle_t = zui_handle("uiheader_23", { selected: false }); - context_raw.particle_physics = zui_check(phys_handle, tr("Physics")); - if (phys_handle.changed) { - UtilParticle.init_particle_physics(); - MakeMaterial.parse_paint_material(); - } - } - ///end - } - } - - ///end - - ///if is_sculpt - static draw_tool_properties = (ui: zui_t) => { - if (context_raw.tool == workspace_tool_t.BRUSH) { - context_raw.brush_radius = zui_slider(context_raw.brush_radius_handle, tr("Radius"), 0.01, 2.0, true); - if (ui.is_hovered) zui_tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", new Map([["brush_radius", config_keymap.brush_radius], ["brush_radius_decrease", config_keymap.brush_radius_decrease], ["brush_radius_increase", config_keymap.brush_radius_increase]]))); - } - } - ///end - - ///if is_lab - static draw_tool_properties = (ui: zui_t) => { - if (context_raw.tool == workspace_tool_t.PICKER) { - - } - else if (context_raw.tool == workspace_tool_t.ERASER || - context_raw.tool == workspace_tool_t.CLONE || - context_raw.tool == workspace_tool_t.BLUR || - context_raw.tool == workspace_tool_t.SMUDGE) { - - let nodes: zui_nodes_t = UINodes.get_nodes(); - let canvas: zui_node_canvas_t = UINodes.get_canvas(true); - let inpaint: bool = nodes.nodes_selected_id.length > 0 && zui_get_node(canvas.nodes, nodes.nodes_selected_id[0]).type == "InpaintNode"; - if (inpaint) { - context_raw.brush_radius = zui_slider(context_raw.brush_radius_handle, tr("Radius"), 0.01, 2.0, true); - if (ui.is_hovered) zui_tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", new Map([["brush_radius", config_keymap.brush_radius], ["brush_radius_decrease", config_keymap.brush_radius_decrease], ["brush_radius_increase", config_keymap.brush_radius_increase]]))); - } - } - } - ///end -} diff --git a/base/Sources/UIMenu.ts b/base/Sources/UIMenu.ts deleted file mode 100644 index 2a4d0df5..00000000 --- a/base/Sources/UIMenu.ts +++ /dev/null @@ -1,625 +0,0 @@ - -class UIMenu { - - static show: bool = false; - static menu_category: i32 = 0; - static menu_category_w: i32 = 0; - static menu_category_h: i32 = 0; - static menu_x: i32 = 0; - static menu_y: i32 = 0; - static menu_elements: i32 = 0; - static keep_open: bool = false; - static menu_commands: (ui: zui_t)=>void = null; - static show_menu_first: bool = true; - static hide_menu: bool = false; - - static render = () => { - let ui: zui_t = base_ui_menu; - let menu_w: i32 = UIMenu.menu_commands != null ? Math.floor(base_default_element_w * zui_SCALE(base_ui_menu) * 2.3) : Math.floor(zui_ELEMENT_W(ui) * 2.3); - let _BUTTON_COL: i32 = ui.t.BUTTON_COL; - ui.t.BUTTON_COL = ui.t.SEPARATOR_COL; - let _ELEMENT_OFFSET: i32 = ui.t.ELEMENT_OFFSET; - ui.t.ELEMENT_OFFSET = 0; - let _ELEMENT_H: i32 = ui.t.ELEMENT_H; - ui.t.ELEMENT_H = config_raw.touch_ui ? (28 + 2) : 28; - - zui_begin_region(ui, UIMenu.menu_x, UIMenu.menu_y, menu_w); - - if (UIMenu.menu_commands != null) { - g2_set_color(ui.t.ACCENT_SELECT_COL); - zui_draw_rect(true, ui._x + -1, ui._y + -1, ui._w + 2, zui_ELEMENT_H(ui) * UIMenu.menu_elements + 2); - g2_set_color(ui.t.SEPARATOR_COL); - zui_draw_rect(true, ui._x + 0, ui._y + 0, ui._w, zui_ELEMENT_H(ui) * UIMenu.menu_elements); - g2_set_color(0xffffffff); - - UIMenu.menu_commands(ui); - } - else { - UIMenu.menu_start(ui); - if (UIMenu.menu_category == menu_category_t.FILE) { - if (UIMenu.menu_button(ui, tr("New .."), config_keymap.file_new)) project_new_box(); - if (UIMenu.menu_button(ui, tr("Open..."), config_keymap.file_open)) project_open(); - if (UIMenu.menu_button(ui, tr("Open Recent..."), config_keymap.file_open_recent)) BoxProjects.show(); - if (UIMenu.menu_button(ui, tr("Save"), config_keymap.file_save)) project_save(); - if (UIMenu.menu_button(ui, tr("Save As..."), config_keymap.file_save_as)) project_save_as(); - UIMenu.menu_separator(ui); - if (UIMenu.menu_button(ui, tr("Import Texture..."), config_keymap.file_import_assets)) project_import_asset(path_texture_formats.join(","), false); - if (UIMenu.menu_button(ui, tr("Import Envmap..."))) { - UIFiles.show("hdr", false, false, (path: string) => { - if (!path.endsWith(".hdr")) { - console_error(tr("Error: .hdr file expected")); - return; - } - ImportAsset.run(path); - }); - } - - ///if (is_paint || is_sculpt) - if (UIMenu.menu_button(ui, tr("Import Font..."))) project_import_asset("ttf,ttc,otf"); - if (UIMenu.menu_button(ui, tr("Import Material..."))) project_import_material(); - if (UIMenu.menu_button(ui, tr("Import Brush..."))) project_import_brush(); - ///end - - ///if (is_paint || is_lab) - if (UIMenu.menu_button(ui, tr("Import Swatches..."))) project_import_swatches(); - ///end - if (UIMenu.menu_button(ui, tr("Import Mesh..."))) project_import_mesh(); - if (UIMenu.menu_button(ui, tr("Reimport Mesh"), config_keymap.file_reimport_mesh)) project_reimport_mesh(); - if (UIMenu.menu_button(ui, tr("Reimport Textures"), config_keymap.file_reimport_textures)) project_reimport_textures(); - UIMenu.menu_separator(ui); - ///if (is_paint || is_lab) - if (UIMenu.menu_button(ui, tr("Export Textures..."), config_keymap.file_export_textures_as)) { - ///if is_paint - context_raw.layers_export = export_mode_t.VISIBLE; - ///end - BoxExport.show_textures(); - } - if (UIMenu.menu_button(ui, tr("Export Swatches..."))) project_export_swatches(); - ///end - if (UIMenu.menu_button(ui, tr("Export Mesh..."))) { - context_raw.export_mesh_index = 0; // All - BoxExport.show_mesh(); - } - - ///if is_paint - if (UIMenu.menu_button(ui, tr("Bake Material..."))) BoxExport.show_bake_material(); - ///end - - UIMenu.menu_separator(ui); - if (UIMenu.menu_button(ui, tr("Exit"))) sys_stop(); - } - else if (UIMenu.menu_category == menu_category_t.EDIT) { - let step_undo: string = ""; - let step_redo: string = ""; - if (history_undos > 0) { - step_undo = history_steps[history_steps.length - 1 - history_redos].name; - } - if (history_redos > 0) { - step_redo = history_steps[history_steps.length - history_redos].name; - } - ui.enabled = history_undos > 0; - if (UIMenu.menu_button(ui, tr("Undo {step}", new Map([["step", step_undo]])), config_keymap.edit_undo)) history_undo(); - ui.enabled = history_redos > 0; - if (UIMenu.menu_button(ui, tr("Redo {step}", new Map([["step", step_redo]])), config_keymap.edit_redo)) history_redo(); - ui.enabled = true; - UIMenu.menu_separator(ui); - if (UIMenu.menu_button(ui, tr("Preferences..."), config_keymap.edit_prefs)) BoxPreferences.show(); - } - else if (UIMenu.menu_category == menu_category_t.VIEWPORT) { - if (UIMenu.menu_button(ui, tr("Distract Free"), config_keymap.view_distract_free)) { - UIBase.toggle_distract_free(); - UIBase.ui.is_hovered = false; - } - - ///if !(krom_android || krom_ios) - if (UIMenu.menu_button(ui, tr("Toggle Fullscreen"), "alt+enter")) { - base_toggle_fullscreen(); - } - ///end - - ui.changed = false; - - UIMenu.menu_fill(ui); - let p: world_data_t = scene_world; - let env_handle: zui_handle_t = zui_handle("uimenu_0"); - env_handle.value = p.strength; - UIMenu.menu_align(ui); - p.strength = zui_slider(env_handle, tr("Environment"), 0.0, 8.0, true); - if (env_handle.changed) context_raw.ddirty = 2; - - UIMenu.menu_fill(ui); - let enva_handle: zui_handle_t = zui_handle("uimenu_1"); - enva_handle.value = context_raw.envmap_angle / Math.PI * 180.0; - if (enva_handle.value < 0) { - enva_handle.value += (Math.floor(-enva_handle.value / 360) + 1) * 360; - } - else if (enva_handle.value > 360) { - enva_handle.value -= Math.floor(enva_handle.value / 360) * 360; - } - UIMenu.menu_align(ui); - context_raw.envmap_angle = zui_slider(enva_handle, tr("Environment Angle"), 0.0, 360.0, true, 1) / 180.0 * Math.PI; - if (ui.is_hovered) zui_tooltip(tr("{shortcut} and move mouse", new Map([["shortcut", config_keymap.rotate_envmap]]))); - if (enva_handle.changed) context_raw.ddirty = 2; - - if (scene_lights.length > 0) { - let light: light_object_t = scene_lights[0]; - - UIMenu.menu_fill(ui); - let lhandle: zui_handle_t = zui_handle("uimenu_2"); - let scale: f32 = 1333; - lhandle.value = light.data.strength / scale; - lhandle.value = Math.floor(lhandle.value * 100) / 100; - UIMenu.menu_align(ui); - light.data.strength = zui_slider(lhandle, tr("Light"), 0.0, 4.0, true) * scale; - if (lhandle.changed) context_raw.ddirty = 2; - - UIMenu.menu_fill(ui); - light = scene_lights[0]; - let lahandle: zui_handle_t = zui_handle("uimenu_3"); - lahandle.value = context_raw.light_angle / Math.PI * 180; - UIMenu.menu_align(ui); - let new_angle: f32 = zui_slider(lahandle, tr("Light Angle"), 0.0, 360.0, true, 1) / 180 * Math.PI; - if (ui.is_hovered) zui_tooltip(tr("{shortcut} and move mouse", new Map([["shortcut", config_keymap.rotate_light]]))); - let ldiff: f32 = new_angle - context_raw.light_angle; - if (Math.abs(ldiff) > 0.005) { - if (new_angle < 0) new_angle += (Math.floor(-new_angle / (2 * Math.PI)) + 1) * 2 * Math.PI; - else if (new_angle > 2 * Math.PI) new_angle -= Math.floor(new_angle / (2 * Math.PI)) * 2 * Math.PI; - context_raw.light_angle = new_angle; - let m: mat4_t = mat4_rot_z(ldiff); - mat4_mult_mat(light.base.transform.local, m); - transform_decompose(light.base.transform); - context_raw.ddirty = 2; - } - - UIMenu.menu_fill(ui); - let sxhandle: zui_handle_t = zui_handle("uimenu_4"); - sxhandle.value = light.data.size; - UIMenu.menu_align(ui); - light.data.size = zui_slider(sxhandle, tr("Light Size"), 0.0, 4.0, true); - if (sxhandle.changed) context_raw.ddirty = 2; - } - - ///if (is_paint || is_sculpt) - UIMenu.menu_fill(ui); - let split_view_handle: zui_handle_t = zui_handle("uimenu_5", { selected: context_raw.split_view }); - context_raw.split_view = zui_check(split_view_handle, " " + tr("Split View")); - if (split_view_handle.changed) { - base_resize(); - } - ///end - - ///if is_lab - UIMenu.menu_fill(ui); - let brush_scale_handle: zui_handle_t = zui_handle("uimenu_6", { value: context_raw.brush_scale }); - UIMenu.menu_align(ui); - context_raw.brush_scale = zui_slider(brush_scale_handle, tr("UV Scale"), 0.01, 5.0, true); - if (brush_scale_handle.changed) { - MakeMaterial.parse_mesh_material(); - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - RenderPathRaytrace.uv_scale = context_raw.brush_scale; - RenderPathRaytrace.ready = false; - ///end - } - ///end - - UIMenu.menu_fill(ui); - let cull_handle: zui_handle_t = zui_handle("uimenu_7", { selected: context_raw.cull_backfaces }); - context_raw.cull_backfaces = zui_check(cull_handle, " " + tr("Cull Backfaces")); - if (cull_handle.changed) { - MakeMaterial.parse_mesh_material(); - } - - UIMenu.menu_fill(ui); - let filter_handle: zui_handle_t = zui_handle("uimenu_8", { selected: context_raw.texture_filter }); - context_raw.texture_filter = zui_check(filter_handle, " " + tr("Filter Textures")); - if (filter_handle.changed) { - MakeMaterial.parse_paint_material(); - MakeMaterial.parse_mesh_material(); - } - - ///if (is_paint || is_sculpt) - UIMenu.menu_fill(ui); - context_raw.draw_wireframe = zui_check(context_raw.wireframe_handle, " " + tr("Wireframe")); - if (context_raw.wireframe_handle.changed) { - let current: image_t = _g2_current; - g2_end(); - UtilUV.cache_uv_map(); - g2_begin(current); - MakeMaterial.parse_mesh_material(); - } - ///end - - ///if is_paint - UIMenu.menu_fill(ui); - context_raw.draw_texels = zui_check(context_raw.texels_handle, " " + tr("Texels")); - if (context_raw.texels_handle.changed) { - MakeMaterial.parse_mesh_material(); - } - ///end - - UIMenu.menu_fill(ui); - let compass_handle: zui_handle_t = zui_handle("uimenu_9", { selected: context_raw.show_compass }); - context_raw.show_compass = zui_check(compass_handle, " " + tr("Compass")); - if (compass_handle.changed) context_raw.ddirty = 2; - - UIMenu.menu_fill(ui); - context_raw.show_envmap = zui_check(context_raw.show_envmap_handle, " " + tr("Envmap")); - if (context_raw.show_envmap_handle.changed) { - context_load_envmap(); - context_raw.ddirty = 2; - } - - UIMenu.menu_fill(ui); - context_raw.show_envmap_blur = zui_check(context_raw.show_envmap_blur_handle, " " + tr("Blur Envmap")); - if (context_raw.show_envmap_blur_handle.changed) context_raw.ddirty = 2; - - context_update_envmap(); - - if (ui.changed) UIMenu.keep_open = true; - } - else if (UIMenu.menu_category == menu_category_t.MODE) { - let mode_handle: zui_handle_t = zui_handle("uimenu_10"); - mode_handle.position = context_raw.viewport_mode; - let modes: string[] = [ - tr("Lit"), - tr("Base Color"), - ///if (is_paint || is_lab) - tr("Normal"), - tr("Occlusion"), - tr("Roughness"), - tr("Metallic"), - tr("Opacity"), - tr("Height"), - ///end - ///if (is_paint) - tr("Emission"), - tr("Subsurface"), - ///end - ///if (is_paint || is_sculpt) - tr("TexCoord"), - tr("Object Normal"), - tr("Material ID"), - tr("Object ID"), - tr("Mask") - ///end - ]; - let shortcuts: string[] = ["l", "b", "n", "o", "r", "m", "a", "h", "e", "s", "t", "1", "2", "3", "4"]; - - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - if (krom_raytrace_supported()) { - modes.push(tr("Path Traced")); - shortcuts.push("p"); - } - ///end - - for (let i: i32 = 0; i < modes.length; ++i) { - UIMenu.menu_fill(ui); - let shortcut: string = config_raw.touch_ui ? "" : config_keymap.viewport_mode + ", " + shortcuts[i]; - zui_radio(mode_handle, i, modes[i], shortcut); - } - - if (mode_handle.changed) { - context_set_viewport_mode(mode_handle.position); - // TODO: rotate mode is not supported for path tracing yet - if (mode_handle.position == viewport_mode_t.PATH_TRACE && context_raw.camera_controls == camera_controls_t.ROTATE) { - context_raw.camera_controls = camera_controls_t.ORBIT; - viewport_reset(); - } - } - } - else if (UIMenu.menu_category == menu_category_t.CAMERA) { - if (UIMenu.menu_button(ui, tr("Reset"), config_keymap.view_reset)) { - viewport_reset(); - viewport_scale_to_bounds(); - } - UIMenu.menu_separator(ui); - if (UIMenu.menu_button(ui, tr("Front"), config_keymap.view_front)) { - viewport_set_view(0, -1, 0, Math.PI / 2, 0, 0); - } - if (UIMenu.menu_button(ui, tr("Back"), config_keymap.view_back)) { - viewport_set_view(0, 1, 0, Math.PI / 2, 0, Math.PI); - } - if (UIMenu.menu_button(ui, tr("Right"), config_keymap.view_right)) { - viewport_set_view(1, 0, 0, Math.PI / 2, 0, Math.PI / 2); - } - if (UIMenu.menu_button(ui, tr("Left"), config_keymap.view_left)) { - viewport_set_view(-1, 0, 0, Math.PI / 2, 0, -Math.PI / 2); - } - if (UIMenu.menu_button(ui, tr("Top"), config_keymap.view_top)) { - viewport_set_view(0, 0, 1, 0, 0, 0); - } - if (UIMenu.menu_button(ui, tr("Bottom"), config_keymap.view_bottom)) { - viewport_set_view(0, 0, -1, Math.PI, 0, Math.PI); - } - UIMenu.menu_separator(ui); - - ui.changed = false; - - if (UIMenu.menu_button(ui, tr("Orbit Left"), config_keymap.view_orbit_left)) { - viewport_orbit(-Math.PI / 12, 0); - } - if (UIMenu.menu_button(ui, tr("Orbit Right"), config_keymap.view_orbit_right)) { - viewport_orbit(Math.PI / 12, 0); - } - if (UIMenu.menu_button(ui, tr("Orbit Up"), config_keymap.view_orbit_up)) { - viewport_orbit(0, -Math.PI / 12); - } - if (UIMenu.menu_button(ui, tr("Orbit Down"), config_keymap.view_orbit_down)) { - viewport_orbit(0, Math.PI / 12); - } - if (UIMenu.menu_button(ui, tr("Orbit Opposite"), config_keymap.view_orbit_opposite)) { - viewport_orbit_opposite(); - } - if (UIMenu.menu_button(ui, tr("Zoom In"), config_keymap.view_zoom_in)) { - viewport_zoom(0.2); - } - if (UIMenu.menu_button(ui, tr("Zoom Out"), config_keymap.view_zoom_out)) { - viewport_zoom(-0.2); - } - // menuSeparator(ui); - - UIMenu.menu_fill(ui); - let cam: camera_object_t = scene_camera; - context_raw.fov_handle = zui_handle("uimenu_11", { value: Math.floor(cam.data.fov * 100) / 100 }); - UIMenu.menu_align(ui); - cam.data.fov = zui_slider(context_raw.fov_handle, tr("FoV"), 0.3, 1.4, true); - if (context_raw.fov_handle.changed) { - viewport_update_camera_type(context_raw.camera_type); - } - - UIMenu.menu_fill(ui); - UIMenu.menu_align(ui); - let camera_controls_handle: zui_handle_t = zui_handle("uimenu_12"); - camera_controls_handle.position = context_raw.camera_controls; - context_raw.camera_controls = zui_inline_radio(camera_controls_handle, [tr("Orbit"), tr("Rotate"), tr("Fly")], zui_align_t.LEFT); - - let orbit_and_rotate_tooltip: string = tr("Orbit and Rotate mode:\n{rotate_shortcut} or move right mouse button to rotate.\n{zoom_shortcut} or scroll to zoom.\n{pan_shortcut} or move middle mouse to pan.", - new Map([ - ["rotate_shortcut", config_keymap.action_rotate], - ["zoom_shortcut", config_keymap.action_zoom], - ["pan_shortcut", config_keymap.action_pan] - ]) - ); - let fly_tooltip: string = tr("Fly mode:\nHold the right mouse button and one of the following commands:\nmove mouse to rotate.\nw, up or scroll up to move forward.\ns, down or scroll down to move backward.\na or left to move left.\nd or right to move right.\ne to move up.\nq to move down.\nHold shift to move faster or alt to move slower."); - if (ui.is_hovered) zui_tooltip(orbit_and_rotate_tooltip + "\n\n" + fly_tooltip); - - UIMenu.menu_fill(ui); - UIMenu.menu_align(ui); - context_raw.camera_type = zui_inline_radio(context_raw.cam_handle, [tr("Perspective"), tr("Orthographic")], zui_align_t.LEFT); - if (ui.is_hovered) zui_tooltip(tr("Camera Type") + ` (${config_keymap.view_camera_type})`); - if (context_raw.cam_handle.changed) { - viewport_update_camera_type(context_raw.camera_type); - } - - if (ui.changed) UIMenu.keep_open = true; - } - else if (UIMenu.menu_category == menu_category_t.HELP) { - if (UIMenu.menu_button(ui, tr("Manual"))) { - file_load_url(manifest_url + "/manual"); - } - if (UIMenu.menu_button(ui, tr("How To"))) { - file_load_url(manifest_url + "/howto"); - } - if (UIMenu.menu_button(ui, tr("What's New"))) { - file_load_url(manifest_url + "/notes"); - } - if (UIMenu.menu_button(ui, tr("Issue Tracker"))) { - file_load_url("https://github.com/armory3d/armortools/issues"); - } - if (UIMenu.menu_button(ui, tr("Report Bug"))) { - ///if (krom_darwin || krom_ios) // Limited url length - file_load_url("https://github.com/armory3d/armortools/issues/new?labels=bug&template=bug_report.md&body=*" + manifest_title + "%20" + manifest_version + "-" + config_get_sha() + ",%20" + sys_system_id()); - ///else - file_load_url("https://github.com/armory3d/armortools/issues/new?labels=bug&template=bug_report.md&body=*" + manifest_title + "%20" + manifest_version + "-" + config_get_sha() + ",%20" + sys_system_id() + "*%0A%0A**Issue description:**%0A%0A**Steps to reproduce:**%0A%0A"); - ///end - } - if (UIMenu.menu_button(ui, tr("Request Feature"))) { - ///if (krom_darwin || krom_ios) // Limited url length - file_load_url("https://github.com/armory3d/armortools/issues/new?labels=feature%20request&template=feature_request.md&body=*" + manifest_title + "%20" + manifest_version + "-" + config_get_sha() + ",%20" + sys_system_id()); - ///else - file_load_url("https://github.com/armory3d/armortools/issues/new?labels=feature%20request&template=feature_request.md&body=*" + manifest_title + "%20" + manifest_version + "-" + config_get_sha() + ",%20" + sys_system_id() + "*%0A%0A**Feature description:**%0A%0A"); - ///end - } - UIMenu.menu_separator(ui); - - if (UIMenu.menu_button(ui, tr("Check for Updates..."))) { - ///if krom_android - file_load_url(manifest_url_android); - ///elseif krom_ios - file_load_url(manifest_url_ios); - ///else - // Retrieve latest version number - file_download_bytes("https://server.armorpaint.org/" + manifest_title.toLowerCase() + ".html", (buffer: ArrayBuffer) => { - if (buffer != null) { - // Compare versions - let update: any = json_parse(sys_buffer_to_string(buffer)); - let update_version: i32 = Math.floor(update.version); - if (update_version > 0) { - let date: string = config_get_date().substr(2); // 2019 -> 19 - let date_int: i32 = parseInt(string_replace_all(date, "-", "")); - if (update_version > date_int) { - UIBox.show_message(tr("Update"), tr("Update is available!\nPlease visit {url}.", new Map([["url", manifest_url]]))); - } - else { - UIBox.show_message(tr("Update"), tr("You are up to date!")); - } - } - } - else { - UIBox.show_message(tr("Update"), tr("Unable to check for updates.\nPlease visit {url}.", new Map([["url", manifest_url]]))); - } - }); - ///end - } - - if (UIMenu.menu_button(ui, tr("About..."))) { - - let msg: string = manifest_title + ".org - v" + manifest_version + " (" + config_get_date() + ") - " + config_get_sha() + "\n"; - msg += sys_system_id() + " - " + strings_graphics_api(); - - ///if krom_windows - let save: string = (path_is_protected() ? krom_save_path() : path_data()) + path_sep + "tmp.txt"; - krom_sys_command('wmic path win32_VideoController get name > "' + save + '"'); - let blob: buffer_t = krom_load_blob(save); - let u8: Uint8Array = new Uint8Array(blob); - let gpu_raw: string = ""; - for (let i: i32 = 0; i < Math.floor(u8.length / 2); ++i) { - let c: string = String.fromCharCode(u8[i * 2]); - gpu_raw += c; - } - - let gpus: string[] = gpu_raw.split("\n"); - gpus = gpus.splice(1, gpus.length - 2); - let gpu: string = ""; - for (let g of gpus) { - gpu += trim_end(g) + ", "; - } - gpu = gpu.substr(0, gpu.length - 2); - msg += `\n${gpu}`; - ///else - // { lshw -C display } - ///end - - UIBox.show_custom((ui: zui_t) => { - let tab_vertical: bool = config_raw.touch_ui; - if (zui_tab(zui_handle("uimenu_13"), tr("About"), tab_vertical)) { - - let img: image_t = data_get_image("badge.k"); - zui_image(img); - zui_end_element(); - - zui_text_area(zui_handle("uimenu_14", { text: msg }), zui_align_t.LEFT, false); - - zui_row([1 / 3, 1 / 3, 1 / 3]); - - ///if (krom_windows || krom_linux || krom_darwin) - if (zui_button(tr("Copy"))) { - krom_copy_to_clipboard(msg); - } - ///else - zui_end_element(); - ///end - - if (zui_button(tr("Contributors"))) { - file_load_url("https://github.com/armory3d/armortools/graphs/contributors"); - } - if (zui_button(tr("OK"))) { - UIBox.hide(); - } - } - }, 400, 320); - } - } - } - - UIMenu.hide_menu = ui.combo_selected_handle_ptr == 0 && !UIMenu.keep_open && !UIMenu.show_menu_first && (ui.changed || ui.input_released || ui.input_released_r || ui.is_escape_down); - UIMenu.show_menu_first = false; - UIMenu.keep_open = false; - - ui.t.BUTTON_COL = _BUTTON_COL; - ui.t.ELEMENT_OFFSET = _ELEMENT_OFFSET; - ui.t.ELEMENT_H = _ELEMENT_H; - zui_end_region(); - - if (UIMenu.hide_menu) { - UIMenu.hide(); - UIMenu.show_menu_first = true; - UIMenu.menu_commands = null; - } - } - - static hide = () => { - UIMenu.show = false; - base_redraw_ui(); - } - - static draw = (commands: (ui: zui_t)=>void = null, elements: i32, x: i32 = -1, y: i32 = -1) => { - zui_end_input(); - UIMenu.show = true; - UIMenu.menu_commands = commands; - UIMenu.menu_elements = elements; - UIMenu.menu_x = x > -1 ? x : Math.floor(mouse_x + 1); - UIMenu.menu_y = y > -1 ? y : Math.floor(mouse_y + 1); - UIMenu.fit_to_screen(); - } - - static fit_to_screen = () => { - // Prevent the menu going out of screen - let menu_w: f32 = base_default_element_w * zui_SCALE(base_ui_menu) * 2.3; - if (UIMenu.menu_x + menu_w > sys_width()) { - if (UIMenu.menu_x - menu_w > 0) { - UIMenu.menu_x = Math.floor(UIMenu.menu_x - menu_w); - } - else { - UIMenu.menu_x = Math.floor(sys_width() - menu_w); - } - } - let menu_h: f32 = Math.floor(UIMenu.menu_elements * 30 * zui_SCALE(base_ui_menu)); // ui.t.ELEMENT_H - if (UIMenu.menu_y + menu_h > sys_height()) { - if (UIMenu.menu_y - menu_h > 0) { - UIMenu.menu_y = Math.floor(UIMenu.menu_y - menu_h); - } - else { - UIMenu.menu_y = sys_height() - menu_h; - } - UIMenu.menu_x += 1; // Move out of mouse focus - } - } - - static menu_fill = (ui: zui_t) => { - g2_set_color(ui.t.ACCENT_SELECT_COL); - g2_fill_rect(ui._x - 1, ui._y, ui._w + 2, zui_ELEMENT_H(ui) + 1 + 1); - g2_set_color(ui.t.SEPARATOR_COL); - g2_fill_rect(ui._x, ui._y, ui._w, zui_ELEMENT_H(ui) + 1); - g2_set_color(0xffffffff); - } - - static menu_separator = (ui: zui_t) => { - ui._y++; - if (config_raw.touch_ui) { - zui_fill(0, 0, ui._w / zui_SCALE(ui), 1, ui.t.ACCENT_SELECT_COL); - } - else { - zui_fill(26, 0, ui._w / zui_SCALE(ui) - 26, 1, ui.t.ACCENT_SELECT_COL); - } - } - - static menu_button = (ui: zui_t, text: string, label: string = ""/*, icon: i32 = -1*/): bool => { - UIMenu.menu_fill(ui); - if (config_raw.touch_ui) { - label = ""; - } - - // let icons: image_t = icon > -1 ? get("icons.k") : null; - // let r: rect_t = tile25(icons, icon, 8); - // return Zui.button(config_button_spacing + text, config_button_align, label, icons, r.x, r.y, r.w, r.h); - - return zui_button(config_button_spacing + text, config_button_align, label); - } - - static menu_align = (ui: zui_t) => { - if (!config_raw.touch_ui) { - zui_row([12 / 100, 88 / 100]); - zui_end_element(); - } - } - - static menu_start = (ui: zui_t) => { - // Draw top border - g2_set_color(ui.t.ACCENT_SELECT_COL); - if (config_raw.touch_ui) { - g2_fill_rect(ui._x + ui._w / 2 + UIMenu.menu_category_w / 2, ui._y - 1, ui._w / 2 - UIMenu.menu_category_w / 2 + 1, 1); - g2_fill_rect(ui._x - 1, ui._y - 1, ui._w / 2 - UIMenu.menu_category_w / 2 + 1, 1); - g2_fill_rect(ui._x + ui._w / 2 - UIMenu.menu_category_w / 2, ui._y - UIMenu.menu_category_h, UIMenu.menu_category_w, 1); - g2_fill_rect(ui._x + ui._w / 2 - UIMenu.menu_category_w / 2, ui._y - UIMenu.menu_category_h, 1, UIMenu.menu_category_h); - g2_fill_rect(ui._x + ui._w / 2 + UIMenu.menu_category_w / 2, ui._y - UIMenu.menu_category_h, 1, UIMenu.menu_category_h); - } - else { - g2_fill_rect(ui._x - 1 + UIMenu.menu_category_w, ui._y - 1, ui._w + 2 - UIMenu.menu_category_w, 1); - g2_fill_rect(ui._x - 1, ui._y - UIMenu.menu_category_h, UIMenu.menu_category_w, 1); - g2_fill_rect(ui._x - 1, ui._y - UIMenu.menu_category_h, 1, UIMenu.menu_category_h); - g2_fill_rect(ui._x - 1 + UIMenu.menu_category_w, ui._y - UIMenu.menu_category_h, 1, UIMenu.menu_category_h); - } - g2_set_color(0xffffffff); - } -} diff --git a/base/Sources/UIMenubar.ts b/base/Sources/UIMenubar.ts deleted file mode 100644 index 39e5d620..00000000 --- a/base/Sources/UIMenubar.ts +++ /dev/null @@ -1,187 +0,0 @@ - -class UIMenubar { - - static default_menubar_w: i32 = 330; - static workspace_handle: zui_handle_t = zui_handle_create({ layout: zui_layout_t.HORIZONTAL }); - static menu_handle: zui_handle_t = zui_handle_create({ layout: zui_layout_t.HORIZONTAL }); - static menubarw: i32 = UIMenubar.default_menubar_w; - - ///if is_lab - static _saved_camera: mat4_t = null; - static _plane: mesh_object_t = null; - ///end - - constructor() { - } - - static render_ui = () => { - let ui: zui_t = UIBase.ui; - - ///if (is_paint || is_sculpt) - let panelx: i32 = app_x() - UIToolbar.toolbar_w; - ///end - ///if is_lab - let panelx: i32 = app_x(); - ///end - - if (zui_window(UIMenubar.menu_handle, panelx, 0, UIMenubar.menubarw, UIHeader.headerh)) { - ui._x += 1; // Prevent "File" button highlight on startup - - zui_begin_menu(); - - if (config_raw.touch_ui) { - - ///if (is_paint || is_sculpt) - ui._w = UIToolbar.toolbar_w; - ///end - ///if is_lab - ui._w = 36; - ///end - - if (UIMenubar.icon_button(ui, 0, 2)) BoxPreferences.show(); - if (UIMenubar.icon_button(ui, 0, 3)) { - ///if (krom_android || krom_ios) - console_toast(tr("Saving project")); - project_save(); - ///end - base_notify_on_next_frame(() => { - BoxProjects.show(); - }); - } - if (UIMenubar.icon_button(ui, 4, 2)) project_import_asset(); - ///if (is_paint || is_lab) - if (UIMenubar.icon_button(ui, 5, 2)) BoxExport.show_textures(); - ///end - let size: i32 = Math.floor(ui._w / zui_SCALE(ui)); - if (UIMenu.show && UIMenu.menu_category == menu_category_t.VIEWPORT) zui_fill(0, -6, size, size - 4, ui.t.HIGHLIGHT_COL); - if (UIMenubar.icon_button(ui, 8, 2)) UIMenubar.show_menu(ui, menu_category_t.VIEWPORT); - if (UIMenu.show && UIMenu.menu_category == menu_category_t.MODE) zui_fill(0, -6, size, size - 4, ui.t.HIGHLIGHT_COL); - if (UIMenubar.icon_button(ui, 9, 2)) UIMenubar.show_menu(ui, menu_category_t.MODE); - if (UIMenu.show && UIMenu.menu_category == menu_category_t.CAMERA) zui_fill(0, -6, size, size - 4, ui.t.HIGHLIGHT_COL); - if (UIMenubar.icon_button(ui, 10, 2)) UIMenubar.show_menu(ui, menu_category_t.CAMERA); - if (UIMenu.show && UIMenu.menu_category == menu_category_t.HELP) zui_fill(0, -6, size, size - 4, ui.t.HIGHLIGHT_COL); - if (UIMenubar.icon_button(ui, 11, 2)) UIMenubar.show_menu(ui, menu_category_t.HELP); - ui.enabled = history_undos > 0; - if (UIMenubar.icon_button(ui, 6, 2)) history_undo(); - ui.enabled = history_redos > 0; - if (UIMenubar.icon_button(ui, 7, 2)) history_redo(); - ui.enabled = true; - } - else { - let categories: string[] = [tr("File"), tr("Edit"), tr("Viewport"), tr("Mode"), tr("Camera"), tr("Help")]; - for (let i: i32 = 0; i < categories.length; ++i) { - if (zui_menu_button(categories[i]) || (UIMenu.show && UIMenu.menu_commands == null && ui.is_hovered)) { - UIMenubar.show_menu(ui, i); - } - } - } - - if (UIMenubar.menubarw < ui._x + 10) { - UIMenubar.menubarw = Math.floor(ui._x + 10); - - ///if (is_paint || is_sculpt) - UIToolbar.toolbar_handle.redraws = 2; - ///end - } - - zui_end_menu(); - } - - let nodesw: i32 = (UINodes.show || UIView2D.show) ? config_raw.layout[layout_size_t.NODES_W] : 0; - ///if (is_paint || is_sculpt) - let ww: i32 = sys_width() - config_raw.layout[layout_size_t.SIDEBAR_W] - UIMenubar.menubarw - nodesw; - panelx = (app_x() - UIToolbar.toolbar_w) + UIMenubar.menubarw; - ///else - let ww: i32 = sys_width() - UIMenubar.menubarw - nodesw; - panelx = (app_x()) + UIMenubar.menubarw; - ///end - - if (zui_window(UIMenubar.workspace_handle, panelx, 0, ww, UIHeader.headerh)) { - - if (!config_raw.touch_ui) { - zui_tab(UIHeader.worktab, tr("3D View")); - } - else { - zui_fill(0, 0, ui._window_w, ui._window_h + 4, ui.t.SEPARATOR_COL); - } - - ///if is_lab - zui_tab(UIHeader.worktab, tr("2D View")); - if (UIHeader.worktab.changed) { - context_raw.ddirty = 2; - context_raw.brush_blend_dirty = true; - UIHeader.header_handle.redraws = 2; - context_main_object().skip_context = null; - - if (UIHeader.worktab.position == space_type_t.SPACE3D) { - if (UIMenubar._saved_camera != null) { - transform_set_matrix(scene_camera.base.transform, UIMenubar._saved_camera); - UIMenubar._saved_camera = null; - } - scene_meshes = [context_main_object()]; - } - else { // Space2D - if (UIMenubar._plane == null) { - let mesh: any = geom_make_plane(1, 1, 2, 2); - let raw: any = { - name: "2DView", - vertex_arrays: [ - { values: mesh.posa, attrib: "pos", data: "short4norm" }, - { values: mesh.nora, attrib: "nor", data: "short2norm" }, - { values: mesh.texa, attrib: "tex", data: "short2norm" } - ], - index_arrays: [ - { values: mesh.inda, material: 0 } - ], - scale_pos: mesh.scale_pos, - scale_tex: mesh.scale_tex - }; - let md: mesh_data_t = mesh_data_create(raw); - let dot_plane: mesh_object_t = scene_get_child(".Plane").ext; - UIMenubar._plane = mesh_object_create(md, dot_plane.materials); - array_remove(scene_meshes, UIMenubar._plane); - } - - if (UIMenubar._saved_camera == null) { - UIMenubar._saved_camera = mat4_clone(scene_camera.base.transform.local); - } - scene_meshes = [UIMenubar._plane]; - let m: mat4_t = mat4_identity(); - mat4_translate(m, 0, 0, 1.6); - transform_set_matrix(scene_camera.base.transform, m); - } - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - RenderPathRaytrace.ready = false; - ///end - } - ///end - } - } - - static show_menu = (ui: zui_t, category: i32) => { - UIMenu.show = true; - UIMenu.menu_commands = null; - UIMenu.menu_category = category; - UIMenu.menu_category_w = ui._w; - UIMenu.menu_category_h = Math.floor(zui_MENUBAR_H(ui)); - UIMenu.menu_x = Math.floor(ui._x - ui._w); - UIMenu.menu_y = Math.floor(zui_MENUBAR_H(ui)); - if (config_raw.touch_ui) { - let menuW: i32 = Math.floor(base_default_element_w * zui_SCALE(base_ui_menu) * 2.0); - UIMenu.menu_x -= Math.floor((menuW - ui._w) / 2) + Math.floor(UIHeader.headerh / 2); - UIMenu.menu_x += Math.floor(2 * zui_SCALE(base_ui_menu)); - UIMenu.menu_y -= Math.floor(2 * zui_SCALE(base_ui_menu)); - UIMenu.keep_open = true; - } - } - - static icon_button = (ui: zui_t, i: i32, j: i32): bool => { - let col: i32 = ui.t.WINDOW_BG_COL; - if (col < 0) col += 4294967296; - let light: bool = col > (0xff666666 + 4294967296); - let icon_accent: i32 = light ? 0xff666666 : 0xffaaaaaa; - let img: image_t = resource_get("icons.k"); - let rect: rect_t = resource_tile50(img, i, j); - return zui_image(img, icon_accent, -1.0, rect.x, rect.y, rect.w, rect.h) == zui_state_t.RELEASED; - } -} diff --git a/base/Sources/UINodes.ts b/base/Sources/UINodes.ts deleted file mode 100644 index 4047706c..00000000 --- a/base/Sources/UINodes.ts +++ /dev/null @@ -1,1291 +0,0 @@ - -class UINodes { - - ///if (is_paint || is_sculpt) - static show: bool = false; - ///end - ///if is_lab - static show: bool = true; - ///end - - static wx: i32; - static wy: i32; - static ww: i32; - static wh: i32; - - static ui: zui_t; - static canvas_type = canvas_type_t.MATERIAL; - static show_menu: bool = false; - static show_menu_first: bool = true; - static hide_menu: bool = false; - static menu_category: i32 = 0; - static popup_x: f32 = 0.0; - static popup_y: f32 = 0.0; - - static uichanged_last: bool = false; - static recompile_mat: bool = false; // Mat preview - static recompile_mat_final: bool = false; - static node_search_spawn: zui_node_t = null; - static node_search_offset: i32 = 0; - static last_canvas: zui_node_canvas_t = null; - static last_node_selected_id: i32 = -1; - static release_link: bool = false; - static is_node_menu_op: bool = false; - - static grid: image_t = null; - static hwnd: zui_handle_t = zui_handle_create(); - static group_stack: node_group_t[] = []; - static controls_down: bool = false; - - constructor() { - zui_set_on_link_drag(UINodes.on_link_drag); - zui_set_on_socket_released(UINodes.on_socket_released); - zui_set_on_canvas_released(UINodes.on_canvas_released); - zui_set_on_canvas_control(UINodes.on_canvas_control); - - let scale: f32 = config_raw.window_scale; - UINodes.ui = zui_create({ theme: base_theme, font: base_font, color_wheel: base_color_wheel, black_white_gradient: base_color_wheel_gradient, scale_factor: scale }); - UINodes.ui.scroll_enabled = false; - } - - static on_link_drag = (linkDragId: i32, isNewLink: bool) => { - if (isNewLink) { - let nodes: zui_nodes_t = UINodes.get_nodes(); - let link_drag: zui_node_link_t = zui_get_link(UINodes.get_canvas(true).links, linkDragId); - let node: zui_node_t = zui_get_node(UINodes.get_canvas(true).nodes, link_drag.from_id > -1 ? link_drag.from_id : link_drag.to_id); - let link_x: i32 = UINodes.ui._window_x + zui_nodes_NODE_X(node); - let link_y: i32 = UINodes.ui._window_y + zui_nodes_NODE_Y(node); - if (link_drag.from_id > -1) { - link_x += zui_nodes_NODE_W(node); - link_y += zui_nodes_OUTPUT_Y(node.outputs, link_drag.from_socket); - } - else { - link_y += zui_nodes_INPUT_Y(UINodes.get_canvas(true), node.inputs, link_drag.to_socket) + zui_nodes_OUTPUTS_H(node.outputs) + zui_nodes_BUTTONS_H(node); - } - if (Math.abs(mouse_x - link_x) > 5 || Math.abs(mouse_y - link_y) > 5) { // Link length - UINodes.node_search(-1, -1, () => { - let n: zui_node_t = zui_get_node(UINodes.get_canvas(true).nodes, nodes.nodes_selected_id[0]); - if (link_drag.to_id == -1 && n.inputs.length > 0) { - link_drag.to_id = n.id; - let from_type: string = node.outputs[link_drag.from_socket].type; - // Connect to the first socket - link_drag.to_socket = 0; - // Try to find the first type-matching socket and use it if present - for (let socket of n.inputs) { - if (socket.type == from_type) { - link_drag.to_socket = n.inputs.indexOf(socket); - break; - } - } - UINodes.get_canvas(true).links.push(link_drag); - } - else if (link_drag.from_id == -1 && n.outputs.length > 0) { - link_drag.from_id = n.id; - link_drag.from_socket = 0; - UINodes.get_canvas(true).links.push(link_drag); - } - ///if is_lab - ParserLogic.parse(UINodes.get_canvas(true)); - context_raw.rdirty = 5; - ///end - }); - } - // Selecting which node socket to preview - else if (node.id == nodes.nodes_selected_id[0]) { - context_raw.node_preview_socket = link_drag.from_id > -1 ? link_drag.from_socket : 0; - ///if (is_paint || is_sculpt) - context_raw.node_preview_dirty = true; - ///end - } - } - } - - static on_socket_released = (socket_id: i32) => { - let nodes: zui_nodes_t = UINodes.get_nodes(); - let canvas: zui_node_canvas_t = UINodes.get_canvas(true); - let socket: zui_node_socket_t = zui_get_socket(canvas.nodes, socket_id); - let node: zui_node_t = zui_get_node(canvas.nodes, socket.node_id); - if (UINodes.ui.input_released_r) { - if (node.type == "GROUP_INPUT" || node.type == "GROUP_OUTPUT") { - base_notify_on_next_frame(() => { - UIMenu.draw((ui: zui_t) => { - if (UIMenu.menu_button(ui, tr("Edit"))) { - let htype: zui_handle_t = zui_handle("uinodes_0"); - let hname: zui_handle_t = zui_handle("uinodes_1"); - let hmin: zui_handle_t = zui_handle("uinodes_2"); - let hmax: zui_handle_t = zui_handle("uinodes_3"); - let hval0: zui_handle_t = zui_handle("uinodes_4"); - let hval1: zui_handle_t = zui_handle("uinodes_5"); - let hval2: zui_handle_t = zui_handle("uinodes_6"); - let hval3: zui_handle_t = zui_handle("uinodes_7"); - htype.position = socket.type == "RGBA" ? 0 : socket.type == "VECTOR" ? 1 : 2; - hname.text = socket.name; - hmin.value = socket.min; - hmax.value = socket.max; - if (socket.type == "RGBA" || socket.type == "VECTOR") { - hval0.value = socket.default_value[0]; - hval1.value = socket.default_value[1]; - hval2.value = socket.default_value[2]; - if (socket.type == "RGBA") { - hval3.value = socket.default_value[3]; - } - } - else hval0.value = socket.default_value; - base_notify_on_next_frame(() => { - zui_end_input(); - UIBox.show_custom((ui: zui_t) => { - if (zui_tab(zui_handle("uinodes_8"), tr("Socket"))) { - let type: i32 = zui_combo(htype, [tr("Color"), tr("Vector"), tr("Value")], tr("Type"), true); - if (htype.changed) hname.text = type == 0 ? tr("Color") : type == 1 ? tr("Vector") : tr("Value"); - let name: string = zui_text_input(hname, tr("Name")); - let min: f32 = zui_float_input(hmin, tr("Min")); - let max: f32 = zui_float_input(hmax, tr("Max")); - let default_value: any = null; - if (type == 0) { - zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]); - zui_float_input(hval0, tr("R")); - zui_float_input(hval1, tr("G")); - zui_float_input(hval2, tr("B")); - zui_float_input(hval3, tr("A")); - default_value = new Float32Array([hval0.value, hval1.value, hval2.value, hval3.value]); - } - else if (type == 1) { - zui_row([1 / 3, 1 / 3, 1 / 3]); - hval0.value = zui_float_input(hval0, tr("X")); - hval1.value = zui_float_input(hval1, tr("Y")); - hval2.value = zui_float_input(hval2, tr("Z")); - default_value = new Float32Array([hval0.value, hval1.value, hval2.value]); - } - else { - default_value = zui_float_input(hval0, tr("default_value")); - } - if (zui_button(tr("OK"))) { // || ui.isReturnDown - socket.name = name; - socket.type = type == 0 ? "RGBA" : type == 1 ? "VECTOR" : "VALUE"; - socket.color = NodesMaterial.get_socket_color(socket.type); - socket.min = min; - socket.max = max; - socket.default_value = default_value; - UIBox.hide(); - NodesMaterial.sync_sockets(node); - UINodes.hwnd.redraws = 2; - } - } - }, 400, 250); - }); - } - if (UIMenu.menu_button(ui, tr("Delete"))) { - let i: i32 = 0; - // Remove links connected to the socket - while (i < canvas.links.length) { - let l: zui_node_link_t = canvas.links[i]; - if ((l.from_id == node.id && l.from_socket == node.outputs.indexOf(socket)) || - (l.to_id == node.id && l.to_socket == node.inputs.indexOf(socket))) { - canvas.links.splice(i, 1); - } - else i++; - } - // Remove socket - array_remove(node.inputs, socket); - array_remove(node.outputs, socket); - NodesMaterial.sync_sockets(node); - } - }, 2); - }); - } - else UINodes.on_canvas_released(); - } - // Selecting which node socket to preview - else if (node.id == nodes.nodes_selected_id[0]) { - let i: i32 = node.outputs.indexOf(socket); - if (i > -1) { - context_raw.node_preview_socket = i; - ///if (is_paint || is_sculpt) - context_raw.node_preview_dirty = true; - ///end - } - } - } - - static on_canvas_released = () => { - if (UINodes.ui.input_released_r && Math.abs(UINodes.ui.input_x - UINodes.ui.input_started_x) < 2 && Math.abs(UINodes.ui.input_y - UINodes.ui.input_started_y) < 2) { - // Node selection - let nodes: zui_nodes_t = UINodes.get_nodes(); - let canvas: zui_node_canvas_t = UINodes.get_canvas(true); - let selected: zui_node_t = null; - for (let node of canvas.nodes) { - if (zui_get_input_in_rect(UINodes.ui._window_x + zui_nodes_NODE_X(node), UINodes.ui._window_y + zui_nodes_NODE_Y(node), zui_nodes_NODE_W(node), zui_nodes_NODE_H(canvas, node))) { - selected = node; - break; - } - } - if (selected == null) nodes.nodes_selected_id = []; - else if (nodes.nodes_selected_id.indexOf(selected.id) == -1) nodes.nodes_selected_id = [selected.id]; - - // Node context menu - if (!zui_socket_released()) { - let number_of_entries: i32 = 5; - if (UINodes.canvas_type == canvas_type_t.MATERIAL) ++number_of_entries; - if (selected != null && selected.type == "RGB") ++number_of_entries; - - UIMenu.draw((uiMenu: zui_t) => { - uiMenu._y += 1; - let is_protected: bool = selected == null || - ///if (is_paint || is_sculpt) - selected.type == "OUTPUT_MATERIAL_PBR" || - ///end - selected.type == "GROUP_INPUT" || - selected.type == "GROUP_OUTPUT" || - selected.type == "BrushOutputNode"; - uiMenu.enabled = !is_protected; - if (UIMenu.menu_button(uiMenu, tr("Cut"), "ctrl+x")) { - base_notify_on_next_frame(() => { - UINodes.hwnd.redraws = 2; - zui_set_is_copy(true); - zui_set_is_cut(true); - UINodes.is_node_menu_op = true; - }); - } - if (UIMenu.menu_button(uiMenu, tr("Copy"), "ctrl+c")) { - base_notify_on_next_frame(() => { - zui_set_is_copy(true); - UINodes.is_node_menu_op = true; - }); - } - uiMenu.enabled = zui_clipboard != ""; - if (UIMenu.menu_button(uiMenu, tr("Paste"), "ctrl+v")) { - base_notify_on_next_frame(() => { - UINodes.hwnd.redraws = 2; - zui_set_is_paste(true); - UINodes.is_node_menu_op = true; - }); - } - uiMenu.enabled = !is_protected; - if (UIMenu.menu_button(uiMenu, tr("Delete"), "delete")) { - base_notify_on_next_frame(() => { - UINodes.hwnd.redraws = 2; - UINodes.ui.is_delete_down = true; - UINodes.is_node_menu_op = true; - }); - } - if (UIMenu.menu_button(uiMenu, tr("Duplicate"))) { - base_notify_on_next_frame(() => { - UINodes.hwnd.redraws = 2; - zui_set_is_copy(true); - zui_set_is_paste(true); - UINodes.is_node_menu_op = true; - }); - } - if (selected != null && selected.type == "RGB") { - if (UIMenu.menu_button(uiMenu, tr("Add Swatch"))) { - let color: any = selected.outputs[0].default_value; - let new_swatch: swatch_color_t = make_swatch(color_from_floats(color[0], color[1], color[2], color[3])); - context_set_swatch(new_swatch); - project_raw.swatches.push(new_swatch); - UIBase.hwnds[tab_area_t.STATUS].redraws = 1; - } - } - - if (UINodes.canvas_type == canvas_type_t.MATERIAL) { - UIMenu.menu_separator(uiMenu); - if (UIMenu.menu_button(uiMenu, tr("2D View"))) { - UIBase.show_2d_view(view_2d_type_t.NODE); - } - } - - uiMenu.enabled = true; - }, number_of_entries); - } - } - - if (UINodes.ui.input_released) { - let nodes: zui_nodes_t = UINodes.get_nodes(); - let canvas: zui_node_canvas_t = UINodes.get_canvas(true); - for (let node of canvas.nodes) { - if (zui_get_input_in_rect(UINodes.ui._window_x + zui_nodes_NODE_X(node), UINodes.ui._window_y + zui_nodes_NODE_Y(node), zui_nodes_NODE_W(node), zui_nodes_NODE_H(canvas, node))) { - if (node.id == nodes.nodes_selected_id[0]) { - UIView2D.hwnd.redraws = 2; - if (time_time() - context_raw.select_time < 0.25) UIBase.show_2d_view(view_2d_type_t.NODE); - context_raw.select_time = time_time(); - } - break; - } - } - } - } - - static on_canvas_control = (): zui_canvas_control_t => { - return UINodes.get_canvas_control(UINodes.ui, UINodes); - } - - static get_canvas_control = (ui: zui_t, parent: any): zui_canvas_control_t => { - if (config_raw.wrap_mouse && parent.controlsDown) { - if (ui.input_x < ui._window_x) { - ui.input_x = ui._window_x + ui._window_w; - krom_set_mouse_position(Math.floor(ui.input_x), Math.floor(ui.input_y)); - } - else if (ui.input_x > ui._window_x + ui._window_w) { - ui.input_x = ui._window_x; - krom_set_mouse_position(Math.floor(ui.input_x), Math.floor(ui.input_y)); - } - else if (ui.input_y < ui._window_y) { - ui.input_y = ui._window_y + ui._window_h; - krom_set_mouse_position(Math.floor(ui.input_x), Math.floor(ui.input_y)); - } - else if (ui.input_y > ui._window_y + ui._window_h) { - ui.input_y = ui._window_y; - krom_set_mouse_position(Math.floor(ui.input_x), Math.floor(ui.input_y)); - } - } - - if (operator_shortcut(config_keymap.action_pan, shortcut_type_t.STARTED) || - operator_shortcut(config_keymap.action_zoom, shortcut_type_t.STARTED) || - ui.input_started_r || - ui.input_wheel_delta != 0.0) { - parent.controlsDown = true; - } - else if (!operator_shortcut(config_keymap.action_pan, shortcut_type_t.DOWN) && - !operator_shortcut(config_keymap.action_zoom, shortcut_type_t.DOWN) && - !ui.input_down_r && - ui.input_wheel_delta == 0.0) { - parent.controlsDown = false; - } - if (!parent.controlsDown) { - return { - pan_x: 0, - pan_y: 0, - zoom: 0 - } - } - - let pan: bool = ui.input_down_r || operator_shortcut(config_keymap.action_pan, shortcut_type_t.DOWN); - let zoom_delta: f32 = operator_shortcut(config_keymap.action_zoom, shortcut_type_t.DOWN) ? UINodes.get_zoom_delta(ui) / 100.0 : 0.0; - let control: any = { - pan_x: pan ? ui.input_dx : 0.0, - pan_y: pan ? ui.input_dy : 0.0, - zoom: ui.input_wheel_delta != 0.0 ? -ui.input_wheel_delta / 10 : zoom_delta - }; - if (base_is_combo_selected()) control.zoom = 0.0; - return control; - } - - static get_zoom_delta = (ui: zui_t): f32 => { - return config_raw.zoom_direction == zoom_direction_t.VERTICAL ? -ui.input_dy : - config_raw.zoom_direction == zoom_direction_t.VERTICAL_INVERTED ? -ui.input_dy : - config_raw.zoom_direction == zoom_direction_t.HORIZONTAL ? ui.input_dx : - config_raw.zoom_direction == zoom_direction_t.HORIZONTAL_INVERTED ? ui.input_dx : - -(ui.input_dy - ui.input_dx); - } - - static get_canvas = (groups: bool = false): zui_node_canvas_t => { - ///if (is_paint || is_sculpt) - if (UINodes.canvas_type == canvas_type_t.MATERIAL) { - if (groups && UINodes.group_stack.length > 0) return UINodes.group_stack[UINodes.group_stack.length - 1].canvas; - else return UINodes.get_canvas_material(); - } - else return context_raw.brush.canvas; - ///end - - ///if is_lab - return project_canvas; - ///end - } - - ///if (is_paint || is_sculpt) - static get_canvas_material = (): zui_node_canvas_t => { - return context_raw.material.canvas; - } - ///end - - static get_nodes = (): zui_nodes_t => { - ///if (is_paint || is_sculpt) - if (UINodes.canvas_type == canvas_type_t.MATERIAL) { - if (UINodes.group_stack.length > 0) return UINodes.group_stack[UINodes.group_stack.length - 1].nodes; - else return context_raw.material.nodes; - } - else return context_raw.brush.nodes; - ///end - - ///if is_lab - if (UINodes.group_stack.length > 0) return UINodes.group_stack[UINodes.group_stack.length - 1].nodes; - else return project_nodes; - ///end - } - - static update = () => { - if (!UINodes.show || !base_ui_enabled) return; - - ///if (is_paint || is_sculpt) - UINodes.wx = Math.floor(app_w()) + UIToolbar.toolbar_w; - ///end - ///if is_lab - UINodes.wx = Math.floor(app_w()); - ///end - UINodes.wy = UIHeader.headerh * 2; - - if (UIView2D.show) { - UINodes.wy += app_h() - config_raw.layout[layout_size_t.NODES_H]; - } - - let ww: i32 = config_raw.layout[layout_size_t.NODES_W]; - if (!UIBase.show) { - ///if (is_paint || is_sculpt) - ww += config_raw.layout[layout_size_t.SIDEBAR_W] + UIToolbar.toolbar_w; - UINodes.wx -= UIToolbar.toolbar_w; - ///end - UINodes.wy = 0; - } - - let mx: i32 = mouse_x; - let my: i32 = mouse_y; - if (mx < UINodes.wx || mx > UINodes.wx + ww || my < UINodes.wy) return; - if (UINodes.ui.is_typing || !UINodes.ui.input_enabled) return; - - let nodes: zui_nodes_t = UINodes.get_nodes(); - if (nodes.nodes_selected_id.length > 0 && UINodes.ui.is_key_pressed) { - if (UINodes.ui.key == key_code_t.LEFT) for (let n of nodes.nodes_selected_id) zui_get_node(UINodes.get_canvas(true).nodes, n).x -= 1; - else if (UINodes.ui.key == key_code_t.RIGHT) for (let n of nodes.nodes_selected_id) zui_get_node(UINodes.get_canvas(true).nodes, n).x += 1; - if (UINodes.ui.key == key_code_t.UP) for (let n of nodes.nodes_selected_id) zui_get_node(UINodes.get_canvas(true).nodes, n).y -= 1; - else if (UINodes.ui.key == key_code_t.DOWN) for (let n of nodes.nodes_selected_id) zui_get_node(UINodes.get_canvas(true).nodes, n).y += 1; - } - - // Node search popup - if (operator_shortcut(config_keymap.node_search)) UINodes.node_search(); - if (UINodes.node_search_spawn != null) { - UINodes.ui.input_x = mouse_x; // Fix inputDX after popup removal - UINodes.ui.input_y = mouse_y; - UINodes.node_search_spawn = null; - } - - if (operator_shortcut(config_keymap.view_reset)) { - nodes.panX = 0.0; - nodes.panY = 0.0; - nodes.zoom = 1.0; - } - } - - static canvas_changed = () => { - UINodes.recompile_mat = true; - UINodes.recompile_mat_final = true; - } - - static node_search = (x: i32 = -1, y: i32 = -1, done: ()=>void = null) => { - let search_handle: zui_handle_t = zui_handle("uinodes_9"); - let first: bool = true; - UIMenu.draw((ui: zui_t) => { - g2_set_color(ui.t.SEPARATOR_COL); - zui_draw_rect(true, ui._x, ui._y, ui._w, zui_ELEMENT_H(ui) * 8); - g2_set_color(0xffffffff); - - let search: string = zui_text_input(search_handle, "", zui_align_t.LEFT, true, true).toLowerCase(); - ui.changed = false; - if (first) { - first = false; - search_handle.text = ""; - zui_start_text_edit(search_handle); // Focus search bar - } - - if (search_handle.changed) UINodes.node_search_offset = 0; - - if (ui.is_key_pressed) { // Move selection - if (ui.key == key_code_t.DOWN && UINodes.node_search_offset < 6) UINodes.node_search_offset++; - if (ui.key == key_code_t.UP && UINodes.node_search_offset > 0) UINodes.node_search_offset--; - } - let enter: bool = keyboard_down("enter"); - let count: i32 = 0; - let BUTTON_COL: i32 = ui.t.BUTTON_COL; - - ///if (is_paint || is_sculpt) - let node_list: zui_node_t[][] = UINodes.canvas_type == canvas_type_t.MATERIAL ? NodesMaterial.list : NodesBrush.list; - ///end - ///if is_lab - let node_list: zui_node_t[][] = NodesBrush.list; - ///end - - for (let list of node_list) { - for (let n of list) { - if (tr(n.name).toLowerCase().indexOf(search) >= 0) { - ui.t.BUTTON_COL = count == UINodes.node_search_offset ? ui.t.HIGHLIGHT_COL : ui.t.SEPARATOR_COL; - if (zui_button(tr(n.name), zui_align_t.LEFT) || (enter && count == UINodes.node_search_offset)) { - UINodes.push_undo(); - let nodes: zui_nodes_t = UINodes.get_nodes(); - let canvas: zui_node_canvas_t = UINodes.get_canvas(true); - UINodes.node_search_spawn = UINodes.make_node(n, nodes, canvas); // Spawn selected node - canvas.nodes.push(UINodes.node_search_spawn); - nodes.nodes_selected_id = [UINodes.node_search_spawn.id]; - nodes.nodesDrag = true; - - ///if is_lab - ParserLogic.parse(canvas); - ///end - - UINodes.hwnd.redraws = 2; - if (enter) { - ui.changed = true; - count = 6; // Trigger break - } - if (done != null) done(); - } - if (++count > 6) break; - } - } - if (count > 6) break; - } - if (enter && count == 0) { // Hide popup on enter when node is not found - ui.changed = true; - search_handle.text = ""; - } - ui.t.BUTTON_COL = BUTTON_COL; - }, 8, x, y); - } - - static get_node_x = (): i32 => { - return Math.floor((mouse_x - UINodes.wx - zui_nodes_PAN_X()) / zui_nodes_SCALE()); - } - - static get_node_y = (): i32 => { - return Math.floor((mouse_y - UINodes.wy - zui_nodes_PAN_Y()) / zui_nodes_SCALE()); - } - - static draw_grid = () => { - let ww: i32 = config_raw.layout[layout_size_t.NODES_W]; - - ///if (is_paint || is_sculpt) - if (!UIBase.show) { - ww += config_raw.layout[layout_size_t.SIDEBAR_W] + UIToolbar.toolbar_w; - } - ///end - - let wh: i32 = app_h(); - let step: f32 = 100 * zui_SCALE(UINodes.ui); - let w: i32 = Math.floor(ww + step * 3); - let h: i32 = Math.floor(wh + step * 3); - if (w < 1) w = 1; - if (h < 1) h = 1; - UINodes.grid = image_create_render_target(w, h); - g2_begin(UINodes.grid); - g2_clear(UINodes.ui.t.SEPARATOR_COL); - - g2_set_color(UINodes.ui.t.SEPARATOR_COL - 0x00050505); - step = 20 * zui_SCALE(UINodes.ui); - for (let i: i32 = 0; i < Math.floor(h / step) + 1; ++i) { - g2_draw_line(0, i * step, w, i * step); - } - for (let i: i32 = 0; i < Math.floor(w / step) + 1; ++i) { - g2_draw_line(i * step, 0, i * step, h); - } - - g2_set_color(UINodes.ui.t.SEPARATOR_COL - 0x00090909); - step = 100 * zui_SCALE(UINodes.ui); - for (let i: i32 = 0; i < Math.floor(h / step) + 1; ++i) { - g2_draw_line(0, i * step, w, i * step); - } - for (let i: i32 = 0; i < Math.floor(w / step) + 1; ++i) { - g2_draw_line(i * step, 0, i * step, h); - } - - g2_end(); - } - - static render = () => { - if (UINodes.recompile_mat) { - ///if (is_paint || is_sculpt) - if (UINodes.canvas_type == canvas_type_t.BRUSH) { - MakeMaterial.parse_brush(); - UtilRender.make_brush_preview(); - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; - } - else { - base_is_fill_material() ? base_update_fill_layers() : UtilRender.make_material_preview(); - if (UIView2D.show && UIView2D.type == view_2d_type_t.NODE) { - UIView2D.hwnd.redraws = 2; - } - } - - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; - if (context_raw.split_view) context_raw.ddirty = 2; - ///end - - ///if is_lab - ParserLogic.parse(project_canvas); - ///end - - UINodes.recompile_mat = false; - } - else if (UINodes.recompile_mat_final) { - ///if (is_paint || is_sculpt) - MakeMaterial.parse_paint_material(); - - if (UINodes.canvas_type == canvas_type_t.MATERIAL && base_is_fill_material()) { - base_update_fill_layers(); - UtilRender.make_material_preview(); - } - - let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; - if (decal) UtilRender.make_decal_preview(); - - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - context_raw.node_preview_dirty = true; - ///end - - UINodes.recompile_mat_final = false; - } - - let nodes: zui_nodes_t = UINodes.get_nodes(); - if (nodes.nodes_selected_id.length > 0 && nodes.nodes_selected_id[0] != UINodes.last_node_selected_id) { - UINodes.last_node_selected_id = nodes.nodes_selected_id[0]; - ///if (is_paint || is_sculpt) - context_raw.node_preview_dirty = true; - ///end - - ///if is_lab - context_raw.ddirty = 2; // Show selected node texture in viewport - UIHeader.header_handle.redraws = 2; - ///end - - context_raw.node_preview_socket = 0; - } - - // Remove dragged link when mouse is released out of the node viewport - let c: zui_node_canvas_t = UINodes.get_canvas(true); - if (UINodes.release_link && nodes.linkDragId != -1) { - array_remove(c.links, zui_get_link(c.links, nodes.linkDragId)); - nodes.linkDragId = -1; - } - UINodes.release_link = UINodes.ui.input_released; - - if (!UINodes.show || sys_width() == 0 || sys_height() == 0) return; - - UINodes.ui.input_enabled = base_ui_enabled; - - g2_end(); - - if (UINodes.grid == null) UINodes.draw_grid(); - - ///if (is_paint || is_sculpt) - if (config_raw.node_preview && context_raw.node_preview_dirty) { - UINodes.make_node_preview(); - } - ///end - - // Start with UI - zui_begin(UINodes.ui); - - // Make window - UINodes.ww = config_raw.layout[layout_size_t.NODES_W]; - - ///if (is_paint || is_sculpt) - UINodes.wx = Math.floor(app_w()) + UIToolbar.toolbar_w; - ///end - ///if is_lab - UINodes.wx = Math.floor(app_w()); - ///end - - UINodes.wy = 0; - - ///if (is_paint || is_sculpt) - if (!UIBase.show) { - UINodes.ww += config_raw.layout[layout_size_t.SIDEBAR_W] + UIToolbar.toolbar_w; - UINodes.wx -= UIToolbar.toolbar_w; - } - ///end - - let ew: i32 = Math.floor(zui_ELEMENT_W(UINodes.ui) * 0.7); - UINodes.wh = app_h() + UIHeader.headerh; - if (config_raw.layout[layout_size_t.HEADER] == 1) UINodes.wh += UIHeader.headerh; - - if (UIView2D.show) { - UINodes.wh = config_raw.layout[layout_size_t.NODES_H]; - UINodes.wy = app_h() - config_raw.layout[layout_size_t.NODES_H] + UIHeader.headerh; - if (config_raw.layout[layout_size_t.HEADER] == 1) UINodes.wy += UIHeader.headerh; - if (!UIBase.show) { - UINodes.wy -= UIHeader.headerh * 2; - } - } - - if (zui_window(UINodes.hwnd, UINodes.wx, UINodes.wy, UINodes.ww, UINodes.wh)) { - - zui_tab(zui_handle("uinodes_10"), tr("Nodes")); - - // Grid - g2_set_color(0xffffffff); - let step: f32 = 100 * zui_SCALE(UINodes.ui); - g2_draw_image(UINodes.grid, (nodes.panX * zui_nodes_SCALE()) % step - step, (nodes.panY * zui_nodes_SCALE()) % step - step); - - // Undo - if (UINodes.ui.input_started || UINodes.ui.is_key_pressed) { - UINodes.last_canvas = JSON.parse(JSON.stringify(UINodes.get_canvas(true))); - } - - // Nodes - let _input_enabled: bool = UINodes.ui.input_enabled; - UINodes.ui.input_enabled = _input_enabled && !UINodes.show_menu; - ///if (is_paint || is_sculpt) - UINodes.ui.window_border_right = config_raw.layout[layout_size_t.SIDEBAR_W]; - ///end - UINodes.ui.window_border_top = UIHeader.headerh * 2; - UINodes.ui.window_border_bottom = config_raw.layout[layout_size_t.STATUS_H]; - zui_node_canvas(nodes, UINodes.ui, c); - UINodes.ui.input_enabled = _input_enabled; - - if (nodes.colorPickerCallback != null) { - context_raw.color_picker_previous_tool = context_raw.tool; - context_select_tool(workspace_tool_t.PICKER); - let tmp: (col: i32)=>void = nodes.colorPickerCallback; - context_raw.color_picker_callback = (color: swatch_color_t) => { - tmp(color.base); - UINodes.hwnd.redraws = 2; - - ///if (is_paint || is_sculpt) - let material_live: bool = config_raw.material_live; - ///end - ///if is_lab - let material_live: bool = true; - ///end - - if (material_live) { - UINodes.canvas_changed(); - } - }; - nodes.colorPickerCallback = null; - } - - // Remove nodes with unknown id for this canvas type - if (zui_is_paste) { - ///if (is_paint || is_sculpt) - let node_list: zui_node_t[][] = UINodes.canvas_type == canvas_type_t.MATERIAL ? NodesMaterial.list : NodesBrush.list; - ///end - ///if is_lab - let node_list: zui_node_t[][] = NodesBrush.list; - ///end - - let i: i32 = 0; - while (i++ < c.nodes.length) { - let canvas_node: zui_node_t = c.nodes[i - 1]; - if (zui_exclude_remove.indexOf(canvas_node.type) >= 0) { - continue; - } - let found: bool = false; - for (let list of node_list) { - for (let list_node of list) { - if (canvas_node.type == list_node.type) { - found = true; - break; - } - } - if (found) break; - } - if (canvas_node.type == "GROUP" && !UINodes.can_place_group(canvas_node.name)) { - found = false; - } - if (!found) { - zui_remove_node(canvas_node, c); - array_remove(nodes.nodes_selected_id, canvas_node.id); - i--; - } - } - } - - if (UINodes.is_node_menu_op) { - zui_set_is_copy(false); - zui_set_is_cut(false); - zui_set_is_paste(false); - UINodes.ui.is_delete_down = false; - } - - // Recompile material on change - if (UINodes.ui.changed) { - ///if (is_paint || is_sculpt) - UINodes.recompile_mat = (UINodes.ui.input_dx != 0 || UINodes.ui.input_dy != 0 || !UINodes.uichanged_last) && config_raw.material_live; // Instant preview - ///end - ///if is_lab - UINodes.recompile_mat = (UINodes.ui.input_dx != 0 || UINodes.ui.input_dy != 0 || !UINodes.uichanged_last); // Instant preview - ///end - } - else if (UINodes.uichanged_last) { - UINodes.canvas_changed(); - UINodes.push_undo(UINodes.last_canvas); - } - UINodes.uichanged_last = UINodes.ui.changed; - - // Node previews - if (config_raw.node_preview && nodes.nodes_selected_id.length > 0) { - let img: image_t = null; - let sel: zui_node_t = zui_get_node(c.nodes, nodes.nodes_selected_id[0]); - - ///if (is_paint || is_sculpt) - - let single_channel: bool = sel.type == "LAYER_MASK"; - if (sel.type == "LAYER" || sel.type == "LAYER_MASK") { - let id: any = sel.buttons[0].default_value; - if (id < project_layers.length) { - ///if is_paint - img = project_layers[id].texpaint_preview; - ///end - } - } - else if (sel.type == "MATERIAL") { - let id: any = sel.buttons[0].default_value; - if (id < project_materials.length) { - img = project_materials[id].image; - } - } - else if (sel.type == "OUTPUT_MATERIAL_PBR") { - img = context_raw.material.image; - } - else if (sel.type == "BrushOutputNode") { - img = context_raw.brush.image; - } - else if (UINodes.canvas_type == canvas_type_t.MATERIAL) { - img = context_raw.node_preview; - } - - ///else - - let brush_node: LogicNode = ParserLogic.get_logic_node(sel); - if (brush_node != null) { - img = brush_node.get_cached_image(); - } - - ///end - - if (img != null) { - let tw: f32 = 128 * zui_SCALE(UINodes.ui); - let th: f32 = tw * (img.height / img.width); - let tx: f32 = UINodes.ww - tw - 8 * zui_SCALE(UINodes.ui); - let ty: f32 = UINodes.wh - th - 8 * zui_SCALE(UINodes.ui); - - ///if krom_opengl - let invert_y: bool = sel.type == "MATERIAL"; - ///else - let invert_y: bool = false; - ///end - - ///if (is_paint || is_sculpt) - if (single_channel) { - g2_set_pipeline(UIView2D.pipe); - ///if krom_opengl - krom_g4_set_pipeline(UIView2D.pipe.pipeline_); - ///end - krom_g4_set_int(UIView2D.channel_location, 1); - } - ///end - - g2_set_color(0xffffffff); - invert_y ? - g2_draw_scaled_image(img, tx, ty + th, tw, -th) : - g2_draw_scaled_image(img, tx, ty, tw, th); - - ///if (is_paint || is_sculpt) - if (single_channel) { - g2_set_pipeline(null); - } - ///end - } - } - - // Menu - g2_set_color(UINodes.ui.t.SEPARATOR_COL); - g2_fill_rect(0, zui_ELEMENT_H(UINodes.ui), UINodes.ww, zui_ELEMENT_H(UINodes.ui) + zui_ELEMENT_OFFSET(UINodes.ui) * 2); - g2_set_color(0xffffffff); - - let start_y: i32 = zui_ELEMENT_H(UINodes.ui) + zui_ELEMENT_OFFSET(UINodes.ui); - UINodes.ui._x = 0; - UINodes.ui._y = 2 + start_y; - UINodes.ui._w = ew; - - ///if (is_paint || is_sculpt) - // Editable canvas name - let h: zui_handle_t = zui_handle("uinodes_11"); - h.text = c.name; - UINodes.ui._w = Math.floor(Math.min(g2_font_width(UINodes.ui.font, UINodes.ui.font_size, h.text) + 15 * zui_SCALE(UINodes.ui), 100 * zui_SCALE(UINodes.ui))); - let new_name: string = zui_text_input(h, ""); - UINodes.ui._x += UINodes.ui._w + 3; - UINodes.ui._y = 2 + start_y; - UINodes.ui._w = ew; - - if (h.changed) { // Check whether renaming is possible and update group links - if (UINodes.group_stack.length > 0) { - let can_rename: bool = true; - for (let m of project_material_groups) { - if (m.canvas.name == new_name) can_rename = false; // Name already used - } - - if (can_rename) { - let old_name: string = c.name; - c.name = new_name; - let canvases: zui_node_canvas_t[] = []; - for (let m of project_materials) canvases.push(m.canvas); - for (let m of project_material_groups) canvases.push(m.canvas); - for (let canvas of canvases) { - for (let n of canvas.nodes) { - if (n.type == "GROUP" && n.name == old_name) { - n.name = c.name; - } - } - } - } - } - else { - c.name = new_name; - } - } - ///end - - ///if is_lab - UINodes.ui.window_border_top = 0; - UINodesExt.drawButtons(ew, start_y); - ///end - - let _BUTTON_COL: i32 = UINodes.ui.t.BUTTON_COL; - UINodes.ui.t.BUTTON_COL = UINodes.ui.t.SEPARATOR_COL; - - ///if (is_paint || is_sculpt) - let cats: string[] = UINodes.canvas_type == canvas_type_t.MATERIAL ? NodesMaterial.categories : NodesBrush.categories; - ///end - ///if is_lab - let cats: string[] = NodesBrush.categories; - ///end - - for (let i: i32 = 0; i < cats.length; ++i) { - if ((zui_menu_button(tr(cats[i]))) || (UINodes.ui.is_hovered && UINodes.show_menu)) { - UINodes.show_menu = true; - UINodes.menu_category = i; - UINodes.popup_x = UINodes.wx + UINodes.ui._x; - UINodes.popup_y = UINodes.wy + UINodes.ui._y; - if (config_raw.touch_ui) { - UINodes.show_menu_first = true; - let menuw: i32 = Math.floor(ew * 2.3); - UINodes.popup_x -= menuw / 2; - UINodes.popup_x += UINodes.ui._w / 2; - } - UIMenu.menu_category_w = UINodes.ui._w; - UIMenu.menu_category_h = Math.floor(zui_MENUBAR_H(UINodes.ui)); - } - UINodes.ui._x += UINodes.ui._w + 3; - UINodes.ui._y = 2 + start_y; - } - - if (config_raw.touch_ui) { - let _w: i32 = UINodes.ui._w; - UINodes.ui._w = Math.floor(36 * zui_SCALE(UINodes.ui)); - UINodes.ui._y = 4 * zui_SCALE(UINodes.ui) + start_y; - if (UIMenubar.icon_button(UINodes.ui, 2, 3)) { - UINodes.node_search(Math.floor(UINodes.ui._window_x + UINodes.ui._x), Math.floor(UINodes.ui._window_y + UINodes.ui._y)); - } - UINodes.ui._w = _w; - } - else { - if (zui_menu_button(tr("Search"))) { - UINodes.node_search(Math.floor(UINodes.ui._window_x + UINodes.ui._x), Math.floor(UINodes.ui._window_y + UINodes.ui._y)); - } - } - if (UINodes.ui.is_hovered) { - zui_tooltip(tr("Search for nodes") + ` (${config_keymap.node_search})`); - } - UINodes.ui._x += UINodes.ui._w + 3; - UINodes.ui._y = 2 + start_y; - - UINodes.ui.t.BUTTON_COL = _BUTTON_COL; - - // Close node group - if (UINodes.group_stack.length > 0 && zui_menu_button(tr("Close"))) { - UINodes.group_stack.pop(); - } - } - - zui_end(!UINodes.show_menu); - - g2_begin(null); - - if (UINodes.show_menu) { - ///if (is_paint || is_sculpt) - let list:zui_node_t[][] = UINodes.canvas_type == canvas_type_t.MATERIAL ? NodesMaterial.list : NodesBrush.list; - ///end - ///if is_lab - let list:zui_node_t[][] = NodesBrush.list; - ///end - - let num_nodes: i32 = list[UINodes.menu_category].length; - - ///if (is_paint || is_sculpt) - let is_group_category: bool = UINodes.canvas_type == canvas_type_t.MATERIAL && NodesMaterial.categories[UINodes.menu_category] == "Group"; - ///end - ///if is_lab - let is_group_category: bool = NodesMaterial.categories[UINodes.menu_category] == "Group"; - ///end - - if (is_group_category) num_nodes += project_material_groups.length; - - let py: i32 = UINodes.popup_y; - let menuw: i32 = Math.floor(ew * 2.3); - zui_begin_region(UINodes.ui, Math.floor(UINodes.popup_x), Math.floor(py), menuw); - let _BUTTON_COL: i32 = UINodes.ui.t.BUTTON_COL; - UINodes.ui.t.BUTTON_COL = UINodes.ui.t.SEPARATOR_COL; - let _ELEMENT_OFFSET: i32 = UINodes.ui.t.ELEMENT_OFFSET; - UINodes.ui.t.ELEMENT_OFFSET = 0; - let _ELEMENT_H: i32 = UINodes.ui.t.ELEMENT_H; - UINodes.ui.t.ELEMENT_H = config_raw.touch_ui ? (28 + 2) : 28; - - UIMenu.menu_start(UINodes.ui); - - for (let n of list[UINodes.menu_category]) { - if (UIMenu.menu_button(UINodes.ui, tr(n.name))) { - UINodes.push_undo(); - let canvas: zui_node_canvas_t = UINodes.get_canvas(true); - let nodes: zui_nodes_t = UINodes.get_nodes(); - let node: zui_node_t = UINodes.make_node(n, nodes, canvas); - canvas.nodes.push(node); - nodes.nodes_selected_id = [node.id]; - nodes.nodesDrag = true; - ///if is_lab - ParserLogic.parse(canvas); - ///end - } - // Next column - if (UINodes.ui._y - UINodes.wy + zui_ELEMENT_H(UINodes.ui) / 2 > UINodes.wh) { - UINodes.ui._x += menuw; - UINodes.ui._y = py; - } - } - if (is_group_category) { - for (let g of project_material_groups) { - zui_fill(0, 1, UINodes.ui._w / zui_SCALE(UINodes.ui), UINodes.ui.t.BUTTON_H + 2, UINodes.ui.t.ACCENT_SELECT_COL); - zui_fill(1, 1, UINodes.ui._w / zui_SCALE(UINodes.ui) - 2, UINodes.ui.t.BUTTON_H + 1, UINodes.ui.t.SEPARATOR_COL); - UINodes.ui.enabled = UINodes.can_place_group(g.canvas.name); - UIMenu.menu_fill(UINodes.ui); - zui_row([5 / 6, 1 / 6]); - if (zui_button(config_button_spacing + g.canvas.name, zui_align_t.LEFT)) { - UINodes.push_undo(); - let canvas: zui_node_canvas_t = UINodes.get_canvas(true); - let nodes: zui_nodes_t = UINodes.get_nodes(); - let node: zui_node_t = UINodes.make_group_node(g.canvas, nodes, canvas); - canvas.nodes.push(node); - nodes.nodes_selected_id = [node.id]; - nodes.nodesDrag = true; - } - - ///if (is_paint || is_sculpt) - UINodes.ui.enabled = !project_is_material_group_in_use(g); - if (zui_button("x", zui_align_t.CENTER)) { - history_delete_material_group(g); - array_remove(project_material_groups, g); - } - ///end - - UINodes.ui.enabled = true; - } - } - - UINodes.hide_menu = UINodes.ui.combo_selected_handle_ptr == 0 && !UINodes.show_menu_first && (UINodes.ui.changed || UINodes.ui.input_released || UINodes.ui.input_released_r || UINodes.ui.is_escape_down); - UINodes.show_menu_first = false; - - UINodes.ui.t.BUTTON_COL = _BUTTON_COL; - UINodes.ui.t.ELEMENT_OFFSET = _ELEMENT_OFFSET; - UINodes.ui.t.ELEMENT_H = _ELEMENT_H; - zui_end_region(); - } - - if (UINodes.hide_menu) { - UINodes.show_menu = false; - UINodes.show_menu_first = true; - } - } - - static contains_node_group_recursive = (group: node_group_t, groupName: string): bool => { - if (group.canvas.name == groupName) { - return true; - } - for (let n of group.canvas.nodes) { - if (n.type == "GROUP") { - let g: node_group_t = project_get_material_group_by_name(n.name); - if (g != null && UINodes.contains_node_group_recursive(g, groupName)) { - return true; - } - } - } - return false; - } - - static can_place_group = (groupName: string): bool => { - // Prevent Recursive node groups - // The group to place must not contain the current group or a group that contains the current group - if (UINodes.group_stack.length > 0) { - for (let g of UINodes.group_stack) { - if (UINodes.contains_node_group_recursive(project_get_material_group_by_name(groupName), g.canvas.name)) return false; - } - } - // Group was deleted / renamed - let group_exists: bool = false; - for (let group of project_material_groups) { - if (groupName == group.canvas.name) { - group_exists = true; - } - } - if (!group_exists) return false; - return true; - } - - static push_undo = (last_canvas: zui_node_canvas_t = null) => { - if (last_canvas == null) last_canvas = UINodes.get_canvas(true); - let canvas_group: i32 = UINodes.group_stack.length > 0 ? project_material_groups.indexOf(UINodes.group_stack[UINodes.group_stack.length - 1]) : null; - - ///if (is_paint || is_sculpt) - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - history_edit_nodes(last_canvas, UINodes.canvas_type, canvas_group); - ///end - ///if is_lab - history_edit_nodes(last_canvas, canvas_group); - ///end - } - - static accept_asset_drag = (index: i32) => { - UINodes.push_undo(); - let g: node_group_t = UINodes.group_stack.length > 0 ? UINodes.group_stack[UINodes.group_stack.length - 1] : null; - ///if (is_paint || is_sculpt) - let n: zui_node_t = UINodes.canvas_type == canvas_type_t.MATERIAL ? NodesMaterial.create_node("TEX_IMAGE", g) : NodesBrush.create_node("TEX_IMAGE"); - ///end - ///if is_lab - let n: zui_node_t = NodesBrush.create_node("ImageTextureNode"); - ///end - - n.buttons[0].default_value = index; - UINodes.get_nodes().nodes_selected_id = [n.id]; - - ///if is_lab - ParserLogic.parse(project_canvas); - ///end - } - - ///if (is_paint || is_sculpt) - static accept_layer_drag = (index: i32) => { - UINodes.push_undo(); - if (SlotLayer.is_group(project_layers[index])) return; - let g: node_group_t = UINodes.group_stack.length > 0 ? UINodes.group_stack[UINodes.group_stack.length - 1] : null; - let n: zui_node_t = NodesMaterial.create_node(SlotLayer.is_mask(context_raw.layer) ? "LAYER_MASK" : "LAYER", g); - n.buttons[0].default_value = index; - UINodes.get_nodes().nodes_selected_id = [n.id]; - } - - static accept_material_drag = (index: i32) => { - UINodes.push_undo(); - let g: node_group_t = UINodes.group_stack.length > 0 ? UINodes.group_stack[UINodes.group_stack.length - 1] : null; - let n: zui_node_t = NodesMaterial.create_node("MATERIAL", g); - n.buttons[0].default_value = index; - UINodes.get_nodes().nodes_selected_id = [n.id]; - } - ///end - - static accept_swatch_drag = (swatch: swatch_color_t) => { - ///if (is_paint || is_sculpt) - UINodes.push_undo(); - let g: node_group_t = UINodes.group_stack.length > 0 ? UINodes.group_stack[UINodes.group_stack.length - 1] : null; - let n: zui_node_t = NodesMaterial.create_node("RGB", g); - n.outputs[0].default_value = [ - color_get_rb(swatch.base) / 255, - color_get_gb(swatch.base) / 255, - color_get_bb(swatch.base) / 255, - color_get_ab(swatch.base) / 255 - ]; - UINodes.get_nodes().nodes_selected_id = [n.id]; - ///end - } - - static make_node = (n: zui_node_t, nodes: zui_nodes_t, canvas: zui_node_canvas_t): zui_node_t => { - let node: zui_node_t = JSON.parse(JSON.stringify(n)); - node.id = zui_get_node_id(canvas.nodes); - node.x = UINodes.get_node_x(); - node.y = UINodes.get_node_y(); - let count: i32 = 0; - for (let soc of node.inputs) { - soc.id = zui_get_socket_id(canvas.nodes) + count; - soc.node_id = node.id; - count++; - } - for (let soc of node.outputs) { - soc.id = zui_get_socket_id(canvas.nodes) + count; - soc.node_id = node.id; - count++; - } - return node; - } - - static make_group_node = (groupCanvas: zui_node_canvas_t, nodes: zui_nodes_t, canvas: zui_node_canvas_t): zui_node_t => { - let n: zui_node_t = NodesMaterial.list[5][0]; - let node: zui_node_t = JSON.parse(JSON.stringify(n)); - node.name = groupCanvas.name; - node.id = zui_get_node_id(canvas.nodes); - node.x = UINodes.get_node_x(); - node.y = UINodes.get_node_y(); - let group_input: zui_node_t = null; - let group_output: zui_node_t = null; - for (let g of project_material_groups) { - if (g.canvas.name == node.name) { - for (let n of g.canvas.nodes) { - if (n.type == "GROUP_INPUT") group_input = n; - else if (n.type == "GROUP_OUTPUT") group_output = n; - } - break; - } - } - if (group_input != null && group_output != null) { - for (let soc of group_input.outputs) { - node.inputs.push(NodesMaterial.create_socket(nodes, node, soc.name, soc.type, canvas, soc.min, soc.max, soc.default_value)); - } - for (let soc of group_output.inputs) { - node.outputs.push(NodesMaterial.create_socket(nodes, node, soc.name, soc.type, canvas, soc.min, soc.max, soc.default_value)); - } - } - return node; - } - - ///if (is_paint || is_sculpt) - static make_node_preview = () => { - let nodes: zui_nodes_t = context_raw.material.nodes; - if (nodes.nodes_selected_id.length == 0) return; - - let node: zui_node_t = zui_get_node(context_raw.material.canvas.nodes, nodes.nodes_selected_id[0]); - // if (node == null) return; - context_raw.node_preview_name = node.name; - - if (node.type == "LAYER" || - node.type == "LAYER_MASK" || - node.type == "MATERIAL" || - node.type == "OUTPUT_MATERIAL_PBR") return; - - if (context_raw.material.canvas.nodes.indexOf(node) == -1) return; - - if (context_raw.node_preview == null) { - context_raw.node_preview = image_create_render_target(UtilRender.material_preview_size, UtilRender.material_preview_size); - } - - context_raw.node_preview_dirty = false; - UINodes.hwnd.redraws = 2; - UtilRender.make_node_preview(context_raw.material.canvas, node, context_raw.node_preview); - } - ///end - - static has_group = (c: zui_node_canvas_t): bool => { - for (let n of c.nodes) if (n.type == "GROUP") return true; - return false; - } - - static traverse_group = (mgroups: zui_node_canvas_t[], c: zui_node_canvas_t) => { - for (let n of c.nodes) { - if (n.type == "GROUP") { - if (UINodes.get_group(mgroups, n.name) == null) { - let canvases: zui_node_canvas_t[] = []; - for (let g of project_material_groups) canvases.push(g.canvas); - let group: zui_node_canvas_t = UINodes.get_group(canvases, n.name); - mgroups.push(JSON.parse(JSON.stringify(group))); - UINodes.traverse_group(mgroups, group); - } - } - } - } - - static get_group = (canvases: zui_node_canvas_t[], name: string): zui_node_canvas_t => { - for (let c of canvases) if (c.name == name) return c; - return null; - } -} diff --git a/base/Sources/UIStatus.ts b/base/Sources/UIStatus.ts deleted file mode 100644 index 6b7925da..00000000 --- a/base/Sources/UIStatus.ts +++ /dev/null @@ -1,51 +0,0 @@ - -class UIStatus { - - static default_status_h: i32 = 33; - - constructor() { - } - - static get width(): i32 { - ///if (is_paint || is_sculpt) - return sys_width() - UIToolbar.toolbar_w - config_raw.layout[layout_size_t.SIDEBAR_W]; - ///end - ///if is_lab - return sys_width(); - ///end - } - - static render_ui = () => { - let ui: zui_t = UIBase.ui; - - let statush: i32 = config_raw.layout[layout_size_t.STATUS_H]; - - if (zui_window(UIBase.hwnds[tab_area_t.STATUS], app_x(), sys_height() - statush, UIStatus.width, statush)) { - ui._y += 2; - - // Border - g2_set_color(ui.t.SEPARATOR_COL); - g2_fill_rect(0, 0, 1, ui._window_h); - g2_fill_rect(ui._window_w - 1, 0, 1, ui._window_h); - - // Draw tabs - for (let draw of UIBase.hwnd_tabs[tab_area_t.STATUS]) draw(UIBase.htabs[tab_area_t.STATUS]); - - let minimized: bool = statush <= UIStatus.default_status_h * config_raw.window_scale; - if (UIBase.htabs[tab_area_t.STATUS].changed && (UIBase.htabs[tab_area_t.STATUS].position == context_raw.last_status_position || minimized)) { - UIBase.toggle_browser(); - } - context_raw.last_status_position = UIBase.htabs[tab_area_t.STATUS].position; - } - } - - static draw_version_tab = (htab: zui_handle_t) => { - // Version label - if (!config_raw.touch_ui) { - let ui: zui_t = UIBase.ui; - ui.enabled = false; - zui_tab(UIBase.htabs[tab_area_t.STATUS], manifest_version); - ui.enabled = true; - } - } -} diff --git a/base/Sources/UIToolbar.ts b/base/Sources/UIToolbar.ts deleted file mode 100644 index a90ae81c..00000000 --- a/base/Sources/UIToolbar.ts +++ /dev/null @@ -1,207 +0,0 @@ - -///if (is_paint || is_sculpt) - -class UIToolbar { - - static default_toolbar_w: i32 = 36; - - static toolbar_handle: zui_handle_t = zui_handle_create(); - static toolbar_w: i32 = UIToolbar.default_toolbar_w; - static last_tool: i32 = 0; - - static tool_names: string[] = [ - _tr("Brush"), - _tr("Eraser"), - _tr("Fill"), - _tr("Decal"), - _tr("Text"), - _tr("Clone"), - _tr("Blur"), - _tr("Smudge"), - _tr("Particle"), - _tr("ColorID"), - _tr("Picker"), - _tr("Bake"), - _tr("Gizmo"), - _tr("Material"), - ]; - - constructor() { - } - - static render_ui = () => { - let ui: zui_t = UIBase.ui; - - if (config_raw.touch_ui) { - UIToolbar.toolbar_w = UIToolbar.default_toolbar_w + 6; - } - else { - UIToolbar.toolbar_w = UIToolbar.default_toolbar_w; - } - UIToolbar.toolbar_w = Math.floor(UIToolbar.toolbar_w * zui_SCALE(ui)); - - if (zui_window(UIToolbar.toolbar_handle, 0, UIHeader.headerh, UIToolbar.toolbar_w, sys_height() - UIHeader.headerh)) { - ui._y -= 4 * zui_SCALE(ui); - - ui.image_scroll_align = false; - let img: image_t = resource_get("icons.k"); - - let col: i32 = ui.t.WINDOW_BG_COL; - if (col < 0) col += 4294967296; - let light: bool = col > (0xff666666 + 4294967296); - let icon_accent: i32 = light ? 0xff666666 : -1; - - // Properties icon - if (config_raw.layout[layout_size_t.HEADER] == 1) { - let rect: rect_t = resource_tile50(img, 7, 1); - if (zui_image(img, light ? 0xff666666 : ui.t.BUTTON_COL, -1.0, rect.x, rect.y, rect.w, rect.h) == zui_state_t.RELEASED) { - config_raw.layout[layout_size_t.HEADER] = 0; - } - } - // Draw ">>" button if header is hidden - else { - let _ELEMENT_H: i32 = ui.t.ELEMENT_H; - let _BUTTON_H: i32 = ui.t.BUTTON_H; - let _BUTTON_COL: i32 = ui.t.BUTTON_COL; - let _fontOffsetY: i32 = ui.font_offset_y; - ui.t.ELEMENT_H = Math.floor(ui.t.ELEMENT_H * 1.5); - ui.t.BUTTON_H = ui.t.ELEMENT_H; - ui.t.BUTTON_COL = ui.t.WINDOW_BG_COL; - let font_height: i32 = g2_font_height(ui.font, ui.font_size); - ui.font_offset_y = (zui_ELEMENT_H(ui) - font_height) / 2; - let _w: i32 = ui._w; - ui._w = UIToolbar.toolbar_w; - - if (zui_button(">>")) { - UIToolbar.tool_properties_menu(); - } - - ui._w = _w; - ui.t.ELEMENT_H = _ELEMENT_H; - ui.t.BUTTON_H = _BUTTON_H; - ui.t.BUTTON_COL = _BUTTON_COL; - ui.font_offset_y = _fontOffsetY; - } - if (ui.is_hovered) zui_tooltip(tr("Toggle header")); - ui._y -= 4 * zui_SCALE(ui); - - let keys: string[] = [ - "(" + config_keymap.tool_brush + ") - " + tr("Hold {action_paint} to paint\nHold {key} and press {action_paint} to paint a straight line (ruler mode)", new Map([["key", config_keymap.brush_ruler], ["action_paint", config_keymap.action_paint]])), - "(" + config_keymap.tool_eraser + ") - " + tr("Hold {action_paint} to erase\nHold {key} and press {action_paint} to erase a straight line (ruler mode)", new Map([["key", config_keymap.brush_ruler], ["action_paint", config_keymap.action_paint]])), - "(" + config_keymap.tool_fill + ")", - "(" + config_keymap.tool_decal + ") - " + tr("Hold {key} to paint on a decal mask", new Map([["key", config_keymap.decal_mask]])), - "(" + config_keymap.tool_text + ") - " + tr("Hold {key} to use the text as a mask", new Map([["key", config_keymap.decal_mask]])), - "(" + config_keymap.tool_clone + ") - " + tr("Hold {key} to set source", new Map([["key", config_keymap.set_clone_source]])), - "(" + config_keymap.tool_blur + ")", - "(" + config_keymap.tool_smudge + ")", - "(" + config_keymap.tool_particle + ")", - "(" + config_keymap.tool_colorid + ")", - "(" + config_keymap.tool_picker + ")", - "(" + config_keymap.tool_bake + ")", - "(" + config_keymap.tool_gizmo + ")", - "(" + config_keymap.tool_material + ")", - ]; - - let draw_tool = (i: i32) => { - ui._x += 2; - if (context_raw.tool == i) UIToolbar.draw_highlight(); - let tile_y: i32 = Math.floor(i / 12); - let tile_x: i32 = tile_y % 2 == 0 ? i % 12 : (11 - (i % 12)); - let rect: rect_t = resource_tile50(img, tile_x, tile_y); - let _y: i32 = ui._y; - - let image_state: zui_state_t = zui_image(img, icon_accent, -1.0, rect.x, rect.y, rect.w, rect.h); - if (image_state == zui_state_t.STARTED) { - context_select_tool(i); - } - else if (image_state == zui_state_t.RELEASED && config_raw.layout[layout_size_t.HEADER] == 0) { - if (UIToolbar.last_tool == i) { - UIToolbar.tool_properties_menu(); - } - UIToolbar.last_tool = i; - } - - ///if is_paint - if (i == workspace_tool_t.COLORID && context_raw.colorid_picked) { - g2_draw_scaled_sub_image(render_path_render_targets.get("texpaint_colorid")._image, 0, 0, 1, 1, 0, _y + 1.5 * zui_SCALE(ui), 5 * zui_SCALE(ui), 34 * zui_SCALE(ui)); - } - ///end - - if (ui.is_hovered) zui_tooltip(tr(UIToolbar.tool_names[i]) + " " + keys[i]); - ui._x -= 2; - ui._y += 2; - } - - draw_tool(workspace_tool_t.BRUSH); - ///if is_paint - draw_tool(workspace_tool_t.ERASER); - draw_tool(workspace_tool_t.FILL); - draw_tool(workspace_tool_t.DECAL); - draw_tool(workspace_tool_t.TEXT); - draw_tool(workspace_tool_t.CLONE); - draw_tool(workspace_tool_t.BLUR); - draw_tool(workspace_tool_t.SMUDGE); - draw_tool(workspace_tool_t.PARTICLE); - draw_tool(workspace_tool_t.COLORID); - draw_tool(workspace_tool_t.PICKER); - draw_tool(workspace_tool_t.BAKE); - draw_tool(workspace_tool_t.MATERIAL); - ///end - - ///if is_forge - draw_tool(workspace_tool_t.GIZMO); - ///end - - ui.image_scroll_align = true; - } - - if (config_raw.touch_ui) { - // Hide scrollbar - let _SCROLL_W: i32 = ui.t.SCROLL_W; - ui.t.SCROLL_W = 0; - zui_end_window(); - ui.t.SCROLL_W = _SCROLL_W; - } - } - - static tool_properties_menu = () => { - let ui: zui_t = UIBase.ui; - let _x: i32 = ui._x; - let _y: i32 = ui._y; - let _w: i32 = ui._w; - UIMenu.draw((ui: zui_t) => { - let start_y: i32 = ui._y; - ui.changed = false; - - UIHeader.draw_tool_properties(ui); - - if (ui.changed) { - UIMenu.keep_open = true; - } - - if (zui_button(tr("Pin to Header"), zui_align_t.LEFT)) { - config_raw.layout[layout_size_t.HEADER] = 1; - } - - let h: i32 = ui._y - start_y; - UIMenu.menu_elements = Math.floor(h / zui_ELEMENT_H(ui)); - UIMenu.menu_x = Math.floor(_x + _w + 2); - UIMenu.menu_y = Math.floor(_y - 6 * zui_SCALE(ui)); - UIMenu.fit_to_screen(); - - }, 0); - - // First draw out of screen, then align the menu based on menu height - UIMenu.menu_x = -sys_width(); - UIMenu.menu_y = -sys_height(); - } - - static draw_highlight = () => { - let ui: zui_t = UIBase.ui; - let size: i32 = UIToolbar.toolbar_w - 4; - g2_set_color(ui.t.HIGHLIGHT_COL); - zui_draw_rect(true, ui._x + -1, ui._y + 2, size + 2, size + 2); - } -} - -///end diff --git a/base/Sources/UIView2D.ts b/base/Sources/UIView2D.ts deleted file mode 100644 index 885b5265..00000000 --- a/base/Sources/UIView2D.ts +++ /dev/null @@ -1,459 +0,0 @@ - -class UIView2D { - - ///if (is_paint || is_sculpt) - static pipe: pipeline_t; - static channel_location: kinc_const_loc_t; - static text_input_hover: bool = false; - static uvmap_show: bool = false; - static tex_type: paint_tex_t = paint_tex_t.BASE; - static layer_mode: view_2d_layer_mode_t = view_2d_layer_mode_t.SELECTED; - ///end - - ///if (is_paint || is_sculpt) - static type: view_2d_type_t = view_2d_type_t.LAYER; - ///else - static type: view_2d_type_t = view_2d_type_t.ASSET; - ///end - - static show: bool = false; - static wx: i32; - static wy: i32; - static ww: i32; - static wh: i32; - static ui: zui_t; - static hwnd: zui_handle_t = zui_handle_create(); - static pan_x: f32 = 0.0; - static pan_y: f32 = 0.0; - static pan_scale: f32 = 1.0; - static tiled_show: bool = false; - static controls_down: bool = false; - - constructor() { - ///if (is_paint || is_sculpt) - UIView2D.pipe = g4_pipeline_create(); - UIView2D.pipe.vertex_shader = sys_get_shader("layer_view.vert"); - UIView2D.pipe.fragment_shader = sys_get_shader("layer_view.frag"); - let vs: vertex_struct_t = g4_vertex_struct_create(); - g4_vertex_struct_add(vs, "pos", vertex_data_t.F32_3X); - g4_vertex_struct_add(vs, "tex", vertex_data_t.F32_2X); - g4_vertex_struct_add(vs, "col", vertex_data_t.U8_4X_NORM); - UIView2D.pipe.input_layout = [vs]; - UIView2D.pipe.blend_source = blend_factor_t.BLEND_ONE; - UIView2D.pipe.blend_dest = blend_factor_t.BLEND_ZERO; - UIView2D.pipe.color_write_masks_alpha[0] = false; - g4_pipeline_compile(UIView2D.pipe); - UIView2D.channel_location = g4_pipeline_get_const_loc(UIView2D.pipe, "channel"); - ///end - - let scale: f32 = config_raw.window_scale; - UIView2D.ui = zui_create({ theme: base_theme, font: base_font, color_wheel: base_color_wheel, black_white_gradient: base_color_wheel_gradient, scale_factor: scale }); - UIView2D.ui.scroll_enabled = false; - } - - static render = () => { - - UIView2D.ww = config_raw.layout[layout_size_t.NODES_W]; - - ///if (is_paint || is_sculpt) - UIView2D.wx = Math.floor(app_w()) + UIToolbar.toolbar_w; - ///else - UIView2D.wx = Math.floor(app_w()); - ///end - - UIView2D.wy = 0; - - ///if (is_paint || is_sculpt) - if (!UIBase.show) { - UIView2D.ww += config_raw.layout[layout_size_t.SIDEBAR_W] + UIToolbar.toolbar_w; - UIView2D.wx -= UIToolbar.toolbar_w; - } - ///end - - if (!UIView2D.show) return; - if (sys_width() == 0 || sys_height() == 0) return; - - if (context_raw.pdirty >= 0) UIView2D.hwnd.redraws = 2; // Paint was active - - g2_end(); - - // Cache grid - if (UINodes.grid == null) UINodes.draw_grid(); - - // Ensure UV map is drawn - ///if (is_paint || is_sculpt) - if (UIView2D.uvmap_show) UtilUV.cache_uv_map(); - ///end - - // Ensure font image is drawn - ///if (is_paint || is_sculpt) - if (context_raw.font.image == null) UtilRender.make_font_preview(); - ///end - - zui_begin(UIView2D.ui); - - let headerh: i32 = config_raw.layout[layout_size_t.HEADER] == 1 ? UIHeader.headerh * 2 : UIHeader.headerh; - let apph: i32 = sys_height() - config_raw.layout[layout_size_t.STATUS_H] + headerh; - UIView2D.wh = sys_height() - config_raw.layout[layout_size_t.STATUS_H]; - - if (UINodes.show) { - UIView2D.wh -= config_raw.layout[layout_size_t.NODES_H]; - if (config_raw.touch_ui) UIView2D.wh += UIHeader.headerh; - } - - if (zui_window(UIView2D.hwnd, UIView2D.wx, UIView2D.wy, UIView2D.ww, UIView2D.wh)) { - - zui_tab(zui_handle("uiview2d_0"), tr("2D View")); - - // Grid - g2_set_color(0xffffffff); - g2_draw_image(UINodes.grid, (UIView2D.pan_x * UIView2D.pan_scale) % 100 - 100, (UIView2D.pan_y * UIView2D.pan_scale) % 100 - 100); - - // Texture - let tex: image_t = null; - - ///if (is_paint || is_sculpt) - let l: SlotLayerRaw = context_raw.layer; - let channel: i32 = 0; - ///end - - let tw: f32 = UIView2D.ww * 0.95 * UIView2D.pan_scale; - let tx: f32 = UIView2D.ww / 2 - tw / 2 + UIView2D.pan_x; - let ty: f32 = apph / 2 - tw / 2 + UIView2D.pan_y; - - if (UIView2D.type == view_2d_type_t.ASSET) { - tex = project_get_image(context_raw.texture); - } - else if (UIView2D.type == view_2d_type_t.NODE) { - ///if (is_paint || is_sculpt) - - tex = context_raw.node_preview; - - ///else - - let nodes: zui_nodes_t = UINodes.get_nodes(); - if (nodes.nodes_selected_id.length > 0) { - let sel: zui_node_t = zui_get_node(UINodes.get_canvas(true).nodes, nodes.nodes_selected_id[0]); - let brush_node: LogicNode = ParserLogic.get_logic_node(sel); - if (brush_node != null) { - tex = brush_node.get_cached_image(); - } - } - - ///end - } - ///if is_paint - else if (UIView2D.type == view_2d_type_t.LAYER) { - let layer: SlotLayerRaw = l; - - if (config_raw.brush_live && RenderPathPaint.live_layer_drawn > 0) { - layer = RenderPathPaint.live_layer; - } - - if (UIView2D.layer_mode == view_2d_layer_mode_t.VISIBLE) { - let current: image_t = _g2_current; - if (current != null) g2_end(); - layer = base_flatten(); - if (current != null) g2_begin(current); - } - else if (SlotLayer.is_group(layer)) { - let current: image_t = _g2_current; - if (current != null) g2_end(); - layer = base_flatten(false, SlotLayer.get_children(layer)); - if (current != null) g2_begin(current); - } - - tex = - SlotLayer.is_mask(context_raw.layer) ? layer.texpaint : - UIView2D.tex_type == paint_tex_t.BASE ? layer.texpaint : - UIView2D.tex_type == paint_tex_t.OPACITY ? layer.texpaint : - UIView2D.tex_type == paint_tex_t.NORMAL ? layer.texpaint_nor : - layer.texpaint_pack; - - channel = - SlotLayer.is_mask(context_raw.layer) ? 1 : - UIView2D.tex_type == paint_tex_t.OCCLUSION ? 1 : - UIView2D.tex_type == paint_tex_t.ROUGHNESS ? 2 : - UIView2D.tex_type == paint_tex_t.METALLIC ? 3 : - UIView2D.tex_type == paint_tex_t.OPACITY ? 4 : - UIView2D.tex_type == paint_tex_t.HEIGHT ? 4 : - UIView2D.tex_type == paint_tex_t.NORMAL ? 5 : - 0; - } - else if (UIView2D.type == view_2d_type_t.FONT) { - tex = context_raw.font.image; - } - ///end - - let th: f32 = tw; - if (tex != null) { - th = tw * (tex.height / tex.width); - ty = apph / 2 - th / 2 + UIView2D.pan_y; - - ///if (is_paint || is_sculpt) - if (UIView2D.type == view_2d_type_t.LAYER) { - ///if (!krom_opengl) - g2_set_pipeline(UIView2D.pipe); - ///end - if (!context_raw.texture_filter) { - g2_set_bilinear_filter(false); - } - ///if krom_opengl - krom_g4_set_pipeline(UIView2D.pipe.pipeline_); - ///end - krom_g4_set_int(UIView2D.channel_location, channel); - } - ///end - - g2_draw_scaled_image(tex, tx, ty, tw, th); - - if (UIView2D.tiled_show) { - g2_draw_scaled_image(tex, tx - tw, ty, tw, th); - g2_draw_scaled_image(tex, tx - tw, ty - th, tw, th); - g2_draw_scaled_image(tex, tx - tw, ty + th, tw, th); - g2_draw_scaled_image(tex, tx + tw, ty, tw, th); - g2_draw_scaled_image(tex, tx + tw, ty - th, tw, th); - g2_draw_scaled_image(tex, tx + tw, ty + th, tw, th); - g2_draw_scaled_image(tex, tx, ty - th, tw, th); - g2_draw_scaled_image(tex, tx, ty + th, tw, th); - } - - ///if (is_paint || is_sculpt) - if (UIView2D.type == view_2d_type_t.LAYER) { - g2_set_pipeline(null); - if (!context_raw.texture_filter) { - g2_set_bilinear_filter(true); - } - } - - // Texture and node preview color picking - 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 && UIView2D.ui.input_down) { - let x: f32 = UIView2D.ui.input_x - tx - UIView2D.wx; - let y: f32 = UIView2D.ui.input_y - ty - UIView2D.wy; - base_notify_on_next_frame(() => { - let texpaint_picker: image_t = render_path_render_targets.get("texpaint_picker")._image; - g2_begin(texpaint_picker); - g2_draw_scaled_image(tex, -x, -y, tw, th); - g2_end(); - let a: DataView = new DataView(image_get_pixels(texpaint_picker)); - ///if (krom_metal || krom_vulkan) - let i0: i32 = 2; - let i1: i32 = 1; - let i2: i32 = 0; - ///else - let i0: i32 = 0; - let i1: i32 = 1; - let i2: i32 = 2; - ///end - - context_raw.picked_color.base = color_set_rb(context_raw.picked_color.base, a.getUint8(i0)); - context_raw.picked_color.base = color_set_gb(context_raw.picked_color.base, a.getUint8(i1)); - context_raw.picked_color.base = color_set_bb(context_raw.picked_color.base, a.getUint8(i2)); - UIHeader.header_handle.redraws = 2; - }); - } - ///end - } - - ///if (is_paint || is_sculpt) - // UV map - if (UIView2D.type == view_2d_type_t.LAYER && UIView2D.uvmap_show) { - g2_draw_scaled_image(UtilUV.uvmap, tx, ty, tw, th); - } - ///end - - // Menu - let ew: i32 = Math.floor(zui_ELEMENT_W(UIView2D.ui)); - g2_set_color(UIView2D.ui.t.SEPARATOR_COL); - g2_fill_rect(0, zui_ELEMENT_H(UIView2D.ui), UIView2D.ww, zui_ELEMENT_H(UIView2D.ui) + zui_ELEMENT_OFFSET(UIView2D.ui) * 2); - g2_set_color(0xffffffff); - - let start_y: f32 = zui_ELEMENT_H(UIView2D.ui) + zui_ELEMENT_OFFSET(UIView2D.ui); - UIView2D.ui._x = 2; - UIView2D.ui._y = 2 + start_y; - UIView2D.ui._w = ew; - - // Editable layer name - let h: zui_handle_t = zui_handle("uiview2d_1"); - - ///if (is_paint || is_sculpt) - let text: string = UIView2D.type == view_2d_type_t.NODE ? context_raw.node_preview_name : h.text; - ///else - let text: string = h.text; - ///end - - UIView2D.ui._w = Math.floor(Math.min(g2_font_width(UIView2D.ui.font, UIView2D.ui.font_size, text) + 15 * zui_SCALE(UIView2D.ui), 100 * zui_SCALE(UIView2D.ui))); - - if (UIView2D.type == view_2d_type_t.ASSET) { - let asset: asset_t = context_raw.texture; - if (asset != null) { - let assetNames: string[] = project_asset_names; - let i: i32 = assetNames.indexOf(asset.name); - h.text = asset.name; - asset.name = zui_text_input(h, ""); - assetNames[i] = asset.name; - } - } - else if (UIView2D.type == view_2d_type_t.NODE) { - ///if (is_paint || is_sculpt) - - zui_text(context_raw.node_preview_name); - - ///else - - let nodes: zui_nodes_t = UINodes.get_nodes(); - if (nodes.nodes_selected_id.length > 0) { - zui_text(zui_get_node(UINodes.get_canvas(true).nodes, nodes.nodes_selected_id[0]).name); - } - - ///end - } - ///if (is_paint || is_sculpt) - else if (UIView2D.type == view_2d_type_t.LAYER) { - h.text = l.name; - l.name = zui_text_input(h, ""); - UIView2D.text_input_hover = UIView2D.ui.is_hovered; - } - else if (UIView2D.type == view_2d_type_t.FONT) { - h.text = context_raw.font.name; - context_raw.font.name = zui_text_input(h, ""); - } - ///end - - if (h.changed) UIBase.hwnds[0].redraws = 2; - UIView2D.ui._x += UIView2D.ui._w + 3; - UIView2D.ui._y = 2 + start_y; - UIView2D.ui._w = ew; - - ///if (is_paint || is_sculpt) - if (UIView2D.type == view_2d_type_t.LAYER) { - UIView2D.layer_mode = zui_combo(zui_handle("uiview2d_2", { position: UIView2D.layer_mode }), [ - tr("Visible"), - tr("Selected"), - ], tr("Layers")); - UIView2D.ui._x += ew + 3; - UIView2D.ui._y = 2 + start_y; - - if (!SlotLayer.is_mask(context_raw.layer)) { - UIView2D.tex_type = zui_combo(zui_handle("uiview2d_3", { position: UIView2D.tex_type }), [ - tr("Base Color"), - tr("Normal Map"), - tr("Occlusion"), - tr("Roughness"), - tr("Metallic"), - tr("Opacity"), - tr("Height"), - ], tr("Texture")); - UIView2D.ui._x += ew + 3; - UIView2D.ui._y = 2 + start_y; - } - - UIView2D.ui._w = Math.floor(ew * 0.7 + 3); - UIView2D.uvmap_show = zui_check(zui_handle("uiview2d_4", { selected: UIView2D.uvmap_show }), tr("UV Map")); - UIView2D.ui._x += ew * 0.7 + 3; - UIView2D.ui._y = 2 + start_y; - } - ///end - - UIView2D.tiled_show = zui_check(zui_handle("uiview2d_5", { selected: UIView2D.tiled_show }), tr("Tiled")); - UIView2D.ui._x += ew * 0.7 + 3; - UIView2D.ui._y = 2 + start_y; - - if (UIView2D.type == view_2d_type_t.ASSET && tex != null) { // Texture resolution - zui_text(tex.width + "x" + tex.height); - } - - // Picked position - ///if (is_paint || is_sculpt) - if (context_raw.tool == workspace_tool_t.PICKER && (UIView2D.type == view_2d_type_t.LAYER || UIView2D.type == view_2d_type_t.ASSET)) { - let cursor_img: image_t = resource_get("cursor.k"); - let hsize: f32 = 16 * zui_SCALE(UIView2D.ui); - let size: f32 = hsize * 2; - g2_draw_scaled_image(cursor_img, tx + tw * context_raw.uvx_picked - hsize, ty + th * context_raw.uvy_picked - hsize, size, size); - } - ///end - } - zui_end(); - g2_begin(null); - } - - static update = () => { - let headerh: f32 = zui_ELEMENT_H(UIView2D.ui) * 1.4; - - ///if (is_paint || is_sculpt) - context_raw.paint2d = false; - ///end - - if (!base_ui_enabled || - !UIView2D.show || - mouse_x < UIView2D.wx || - mouse_x > UIView2D.wx + UIView2D.ww || - mouse_y < UIView2D.wy + headerh || - mouse_y > UIView2D.wy + UIView2D.wh) { - if (UIView2D.controls_down) { - UINodes.get_canvas_control(UIView2D.ui, UIView2D); - } - return; - } - - let control: zui_canvas_control_t = UINodes.get_canvas_control(UIView2D.ui, UIView2D); - UIView2D.pan_x += control.pan_x; - UIView2D.pan_y += control.pan_y; - if (control.zoom != 0) { - let _pan_x: f32 = UIView2D.pan_x / UIView2D.pan_scale; - let _pan_y: f32 = UIView2D.pan_y / UIView2D.pan_scale; - UIView2D.pan_scale += control.zoom; - if (UIView2D.pan_scale < 0.1) UIView2D.pan_scale = 0.1; - if (UIView2D.pan_scale > 6.0) UIView2D.pan_scale = 6.0; - UIView2D.pan_x = _pan_x * UIView2D.pan_scale; - UIView2D.pan_y = _pan_y * UIView2D.pan_scale; - - if (zui_touch_scroll()) { - // Zoom to finger location - UIView2D.pan_x -= (UIView2D.ui.input_x - UIView2D.ui._window_x - UIView2D.ui._window_w / 2) * control.zoom; - UIView2D.pan_y -= (UIView2D.ui.input_y - UIView2D.ui._window_y - UIView2D.ui._window_h / 2) * control.zoom; - } - } - - ///if (is_paint || is_sculpt) - let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; - let decal_mask: bool = decal && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.action_paint, shortcut_type_t.DOWN); - let set_clone_source: bool = context_raw.tool == workspace_tool_t.CLONE && operator_shortcut(config_keymap.set_clone_source + "+" + config_keymap.action_paint, shortcut_type_t.DOWN); - - if (UIView2D.type == view_2d_type_t.LAYER && - !UIView2D.text_input_hover && - (operator_shortcut(config_keymap.action_paint, shortcut_type_t.DOWN) || - operator_shortcut(config_keymap.brush_ruler + "+" + config_keymap.action_paint, shortcut_type_t.DOWN) || - decal_mask || - set_clone_source || - config_raw.brush_live)) { - context_raw.paint2d = true; - } - ///end - - if (UIView2D.ui.is_typing) return; - - if (keyboard_started("left")) UIView2D.pan_x -= 5; - else if (keyboard_started("right")) UIView2D.pan_x += 5; - if (keyboard_started("up")) UIView2D.pan_y -= 5; - else if (keyboard_started("down")) UIView2D.pan_y += 5; - - // Limit panning to keep texture in viewport - let border: i32 = 32; - let tw: f32 = UIView2D.ww * 0.95 * UIView2D.pan_scale; - let tx: f32 = UIView2D.ww / 2 - tw / 2 + UIView2D.pan_x; - let hh: f32 = app_h(); - let ty: f32 = hh / 2 - tw / 2 + UIView2D.pan_y; - - if (tx + border > UIView2D.ww) UIView2D.pan_x = UIView2D.ww / 2 + tw / 2 - border; - else if (tx - border < -tw) UIView2D.pan_x = -tw / 2 - UIView2D.ww / 2 + border; - if (ty + border > hh) UIView2D.pan_y = hh / 2 + tw / 2 - border; - else if (ty - border < -tw) UIView2D.pan_y = -tw / 2 - hh / 2 + border; - - if (operator_shortcut(config_keymap.view_reset)) { - UIView2D.pan_x = 0.0; - UIView2D.pan_y = 0.0; - UIView2D.pan_scale = 1.0; - } - } -} diff --git a/base/Sources/UtilMesh.ts b/base/Sources/UtilMesh.ts deleted file mode 100644 index 0c9f1c65..00000000 --- a/base/Sources/UtilMesh.ts +++ /dev/null @@ -1,380 +0,0 @@ - -class UtilMesh { - - static unwrappers: Mapvoid)> = new Map(); - - static merge_mesh = (paint_objects: mesh_object_t[] = null) => { - if (paint_objects == null) paint_objects = project_paint_objects; - if (paint_objects.length == 0) return; - context_raw.merged_object_is_atlas = paint_objects.length < project_paint_objects.length; - let vlen: i32 = 0; - let ilen: i32 = 0; - let max_scale: f32 = 0.0; - for (let i: i32 = 0; i < paint_objects.length; ++i) { - vlen += paint_objects[i].data.vertex_arrays[0].values.length; - ilen += paint_objects[i].data.index_arrays[0].values.length; - if (paint_objects[i].data.scale_pos > max_scale) max_scale = paint_objects[i].data.scale_pos; - } - vlen = Math.floor(vlen / 4); - let va0: Int16Array = new Int16Array(vlen * 4); - let va1: Int16Array = new Int16Array(vlen * 2); - let va2: Int16Array = new Int16Array(vlen * 2); - let va3: Int16Array = paint_objects[0].data.vertex_arrays.length > 3 ? new Int16Array(vlen * 4) : null; - let ia: Uint32Array = new Uint32Array(ilen); - - let voff: i32 = 0; - let ioff: i32 = 0; - for (let i: i32 = 0; i < paint_objects.length; ++i) { - let vas: vertex_array_t[] = paint_objects[i].data.vertex_arrays; - let ias: index_array_t[] = paint_objects[i].data.index_arrays; - let scale: f32 = paint_objects[i].data.scale_pos; - - // Pos - for (let j: i32 = 0; j < vas[0].values.length; ++j) va0[j + voff * 4] = vas[0].values[j]; - - // Translate - ///if is_forge - for (let j: i32 = 0; j < Math.floor(va0.length / 4); ++j) { - va0[j * 4 + voff * 4] += Math.floor(transform_world_x(paint_objects[i].base.transform) * 32767); - va0[j * 4 + 1 + voff * 4] += Math.floor(transform_world_y(paint_objects[i].base.transform) * 32767); - va0[j * 4 + 2 + voff * 4] += Math.floor(transform_world_z(paint_objects[i].base.transform) * 32767); - } - ///end - - // Re-scale - for (let j: i32 = 0; j < Math.floor(va0.length / 4); ++j) { - va0[j * 4 + voff * 4] = Math.floor((va0[j * 4 + voff * 4] * scale) / max_scale); - va0[j * 4 + 1 + voff * 4] = Math.floor((va0[j * 4 + 1 + voff * 4] * scale) / max_scale); - va0[j * 4 + 2 + voff * 4] = Math.floor((va0[j * 4 + 2 + voff * 4] * scale) / max_scale); - } - // Nor - for (let j: i32 = 0; j < vas[1].values.length; ++j) va1[j + voff * 2] = vas[1].values[j]; - // Tex - for (let j: i32 = 0; j < vas[2].values.length; ++j) va2[j + voff * 2] = vas[2].values[j]; - // Col - if (va3 != null) for (let j: i32 = 0; j < vas[3].values.length; ++j) va3[j + voff * 4] = vas[3].values[j]; - // Indices - for (let j: i32 = 0; j < ias[0].values.length; ++j) ia[j + ioff] = ias[0].values[j] + voff; - - voff += Math.floor(vas[0].values.length / 4); - ioff += Math.floor(ias[0].values.length); - } - - let raw: mesh_data_t = { - name: context_raw.paint_object.base.name, - vertex_arrays: [ - { values: va0, attrib: "pos", data: "short4norm" }, - { values: va1, attrib: "nor", data: "short2norm" }, - { values: va2, attrib: "tex", data: "short2norm" } - ], - index_arrays: [ - { values: ia, material: 0 } - ], - scale_pos: max_scale, - scale_tex: 1.0 - }; - if (va3 != null) raw.vertex_arrays.push({ values: va3, attrib: "col", data: "short4norm" }); - - UtilMesh.remove_merged_mesh(); - let md: mesh_data_t = mesh_data_create(raw); - context_raw.merged_object = mesh_object_create(md, context_raw.paint_object.materials); - context_raw.merged_object.base.name = context_raw.paint_object.base.name + "_merged"; - context_raw.merged_object.force_context = "paint"; - object_set_parent(context_raw.merged_object.base, context_main_object().base); - - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - RenderPathRaytrace.ready = false; - ///end - } - - static remove_merged_mesh = () => { - if (context_raw.merged_object != null) { - mesh_data_delete(context_raw.merged_object.data); - mesh_object_remove(context_raw.merged_object); - context_raw.merged_object = null; - } - } - - static swap_axis = (a: i32, b: i32) => { - let objects: mesh_object_t[] = project_paint_objects; - for (let o of objects) { - // Remapping vertices, buckle up - // 0 - x, 1 - y, 2 - z - let vas: vertex_array_t[] = o.data.vertex_arrays; - let pa: i16_array_t = vas[0].values; - let na0: i16_array_t = a == 2 ? vas[0].values : vas[1].values; - let na1: i16_array_t = b == 2 ? vas[0].values : vas[1].values; - let c: i32 = a == 2 ? 3 : a; - let d: i32 = b == 2 ? 3 : b; - let e: i32 = a == 2 ? 4 : 2; - let f: i32 = b == 2 ? 4 : 2; - - for (let i: i32 = 0; i < Math.floor(pa.length / 4); ++i) { - let t: i32 = pa[i * 4 + a]; - pa[i * 4 + a] = pa[i * 4 + b]; - pa[i * 4 + b] = -t; - t = na0[i * e + c]; - na0[i * e + c] = na1[i * f + d]; - na1[i * f + d] = -t; - } - - let g: mesh_data_t = o.data; - let l: i32 = g4_vertex_struct_byte_size(g._.structure) / 2; - let vertices: buffer_view_t = g4_vertex_buffer_lock(g._.vertex_buffer); // posnortex - for (let i: i32 = 0; i < Math.floor(vertices.byteLength / 2 / l); ++i) { - vertices.setInt16((i * l ) * 2, vas[0].values[i * 4 ], true); - vertices.setInt16((i * l + 1) * 2, vas[0].values[i * 4 + 1], true); - vertices.setInt16((i * l + 2) * 2, vas[0].values[i * 4 + 2], true); - vertices.setInt16((i * l + 3) * 2, vas[0].values[i * 4 + 3], true); - vertices.setInt16((i * l + 4) * 2, vas[1].values[i * 2 ], true); - vertices.setInt16((i * l + 5) * 2, vas[1].values[i * 2 + 1], true); - } - g4_vertex_buffer_unlock(g._.vertex_buffer); - } - - UtilMesh.remove_merged_mesh(); - UtilMesh.merge_mesh(); - } - - static flip_normals = () => { - let objects: mesh_object_t[] = project_paint_objects; - for (let o of objects) { - let vas: vertex_array_t[] = o.data.vertex_arrays; - let va0: i16_array_t = vas[0].values; - let va1: i16_array_t = vas[1].values; - let g: mesh_data_t = o.data; - let l: i32 = g4_vertex_struct_byte_size(g._.structure) / 2; - let vertices: buffer_view_t = g4_vertex_buffer_lock(g._.vertex_buffer); // posnortex - for (let i: i32 = 0; i < Math.floor(vertices.byteLength / 2 / l); ++i) { - va0[i * 4 + 3] = -va0[i * 4 + 3]; - va1[i * 2] = -va1[i * 2]; - va1[i * 2 + 1] = -va1[i * 2 + 1]; - vertices.setInt16((i * l + 3) * 2, -vertices.getInt16((i * l + 3) * 2, true), true); - vertices.setInt16((i * l + 4) * 2, -vertices.getInt16((i * l + 4) * 2, true), true); - vertices.setInt16((i * l + 5) * 2, -vertices.getInt16((i * l + 5) * 2, true), true); - } - g4_vertex_buffer_unlock(g._.vertex_buffer); - } - - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - RenderPathRaytrace.ready = false; - ///end - } - - static calc_normals = (smooth: bool = false) => { - let va: vec4_t = vec4_create(); - let vb: vec4_t = vec4_create(); - let vc: vec4_t = vec4_create(); - let cb: vec4_t = vec4_create(); - let ab: vec4_t = vec4_create(); - let objects: mesh_object_t[] = project_paint_objects; - for (let o of objects) { - let g: mesh_data_t = o.data; - let l: i32 = g4_vertex_struct_byte_size(g._.structure) / 2; - let inda: u32_array_t = g._.indices[0]; - let vertices: buffer_view_t = g4_vertex_buffer_lock(g._.vertex_buffer); // posnortex - for (let i: i32 = 0; i < Math.floor(inda.length / 3); ++i) { - let i1: i32 = inda[i * 3 ]; - let i2: i32 = inda[i * 3 + 1]; - let i3: i32 = inda[i * 3 + 2]; - vec4_set(va, vertices.getInt16((i1 * l) * 2, true), vertices.getInt16((i1 * l + 1) * 2, true), vertices.getInt16((i1 * l + 2) * 2, true)); - vec4_set(vb, vertices.getInt16((i2 * l) * 2, true), vertices.getInt16((i2 * l + 1) * 2, true), vertices.getInt16((i2 * l + 2) * 2, true)); - vec4_set(vc, vertices.getInt16((i3 * l) * 2, true), vertices.getInt16((i3 * l + 1) * 2, true), vertices.getInt16((i3 * l + 2) * 2, true)); - vec4_sub_vecs(cb, vc, vb); - vec4_sub_vecs(ab, va, vb); - vec4_cross(cb, ab); - vec4_normalize(cb, ); - vertices.setInt16((i1 * l + 4) * 2, Math.floor(cb.x * 32767), true); - vertices.setInt16((i1 * l + 5) * 2, Math.floor(cb.y * 32767), true); - vertices.setInt16((i1 * l + 3) * 2, Math.floor(cb.z * 32767), true); - vertices.setInt16((i2 * l + 4) * 2, Math.floor(cb.x * 32767), true); - vertices.setInt16((i2 * l + 5) * 2, Math.floor(cb.y * 32767), true); - vertices.setInt16((i2 * l + 3) * 2, Math.floor(cb.z * 32767), true); - vertices.setInt16((i3 * l + 4) * 2, Math.floor(cb.x * 32767), true); - vertices.setInt16((i3 * l + 5) * 2, Math.floor(cb.y * 32767), true); - vertices.setInt16((i3 * l + 3) * 2, Math.floor(cb.z * 32767), true); - } - - if (smooth) { - let shared: Uint32Array = new Uint32Array(1024); - let sharedLen: i32 = 0; - let found: i32[] = []; - for (let i: i32 = 0; i < (inda.length - 1); ++i) { - if (found.indexOf(i) >= 0) continue; - let i1: i32 = inda[i]; - sharedLen = 0; - shared[sharedLen++] = i1; - for (let j: i32 = (i + 1); j < inda.length; ++j) { - let i2: i32 = inda[j]; - let i1l: i32 = i1 * l; - let i2l: i32 = i2 * l; - if (vertices.getInt16((i1l ) * 2, true) == vertices.getInt16((i2l ) * 2, true) && - vertices.getInt16((i1l + 1) * 2, true) == vertices.getInt16((i2l + 1) * 2, true) && - vertices.getInt16((i1l + 2) * 2, true) == vertices.getInt16((i2l + 2) * 2, true)) { - // if (n1.dot(n2) > 0) - shared[sharedLen++] = i2; - found.push(j); - if (sharedLen >= 1024) break; - } - } - if (sharedLen > 1) { - vec4_set(va, 0, 0, 0); - for (let j: i32 = 0; j < sharedLen; ++j) { - let i1: i32 = shared[j]; - let i1l: i32 = i1 * l; - vec4_add_f(va, vertices.getInt16((i1l + 4) * 2, true), vertices.getInt16((i1l + 5) * 2, true), vertices.getInt16((i1l + 3) * 2, true)); - } - vec4_mult(va, 1 / sharedLen); - vec4_normalize(va, ); - let vax: i32 = Math.floor(va.x * 32767); - let vay: i32 = Math.floor(va.y * 32767); - let vaz: i32 = Math.floor(va.z * 32767); - for (let j: i32 = 0; j < sharedLen; ++j) { - let i1: i32 = shared[j]; - let i1l: i32 = i1 * l; - vertices.setInt16((i1l + 4) * 2, vax, true); - vertices.setInt16((i1l + 5) * 2, vay, true); - vertices.setInt16((i1l + 3) * 2, vaz, true); - } - } - } - } - g4_vertex_buffer_unlock(g._.vertex_buffer); - - let va0: i16_array_t = o.data.vertex_arrays[0].values; - let va1: i16_array_t = o.data.vertex_arrays[1].values; - for (let i: i32 = 0; i < Math.floor(vertices.byteLength / 4 / l); ++i) { - va1[i * 2 ] = vertices.getInt16((i * l + 4) * 2, true); - va1[i * 2 + 1] = vertices.getInt16((i * l + 5) * 2, true); - va0[i * 4 + 3] = vertices.getInt16((i * l + 3) * 2, true); - } - } - - ///if (krom_direct3d12 || krom_vulkan || krom_metal) - UtilMesh.merge_mesh(); - RenderPathRaytrace.ready = false; - ///end - } - - static to_origin = () => { - let dx: f32 = 0.0; - let dy: f32 = 0.0; - let dz: f32 = 0.0; - for (let o of project_paint_objects) { - let l: i32 = 4; - let sc: f32 = o.data.scale_pos / 32767; - let va: i16_array_t = o.data.vertex_arrays[0].values; - let minx: f32 = va[0]; - let maxx: f32 = va[0]; - let miny: f32 = va[1]; - let maxy: f32 = va[1]; - let minz: f32 = va[2]; - let maxz: f32 = va[2]; - for (let i: i32 = 1; i < Math.floor(va.length / l); ++i) { - if (va[i * l] < minx) minx = va[i * l]; - else if (va[i * l] > maxx) maxx = va[i * l]; - if (va[i * l + 1] < miny) miny = va[i * l + 1]; - else if (va[i * l + 1] > maxy) maxy = va[i * l + 1]; - if (va[i * l + 2] < minz) minz = va[i * l + 2]; - else if (va[i * l + 2] > maxz) maxz = va[i * l + 2]; - } - dx += (minx + maxx) / 2 * sc; - dy += (miny + maxy) / 2 * sc; - dz += (minz + maxz) / 2 * sc; - } - dx /= project_paint_objects.length; - dy /= project_paint_objects.length; - dz /= project_paint_objects.length; - - for (let o of project_paint_objects) { - let g: mesh_data_t = o.data; - let sc: f32 = o.data.scale_pos / 32767; - let va: i16_array_t = o.data.vertex_arrays[0].values; - let max_scale: f32 = 0.0; - for (let i: i32 = 0; i < Math.floor(va.length / 4); ++i) { - if (Math.abs(va[i * 4 ] * sc - dx) > max_scale) max_scale = Math.abs(va[i * 4 ] * sc - dx); - if (Math.abs(va[i * 4 + 1] * sc - dy) > max_scale) max_scale = Math.abs(va[i * 4 + 1] * sc - dy); - if (Math.abs(va[i * 4 + 2] * sc - dz) > max_scale) max_scale = Math.abs(va[i * 4 + 2] * sc - dz); - } - o.base.transform.scale_world = o.data.scale_pos = o.data.scale_pos = max_scale; - transform_build_matrix(o.base.transform); - - for (let i: i32 = 0; i < Math.floor(va.length / 4); ++i) { - va[i * 4 ] = Math.floor((va[i * 4 ] * sc - dx) / max_scale * 32767); - va[i * 4 + 1] = Math.floor((va[i * 4 + 1] * sc - dy) / max_scale * 32767); - va[i * 4 + 2] = Math.floor((va[i * 4 + 2] * sc - dz) / max_scale * 32767); - } - - let l: i32 = g4_vertex_struct_byte_size(g._.structure) / 2; - let vertices: buffer_view_t = g4_vertex_buffer_lock(g._.vertex_buffer); // posnortex - for (let i: i32 = 0; i < Math.floor(vertices.byteLength / 2 / l); ++i) { - vertices.setInt16((i * l ) * 2, va[i * 4 ], true); - vertices.setInt16((i * l + 1) * 2, va[i * 4 + 1], true); - vertices.setInt16((i * l + 2) * 2, va[i * 4 + 2], true); - } - g4_vertex_buffer_unlock(g._.vertex_buffer); - } - - UtilMesh.merge_mesh(); - } - - static apply_displacement = (texpaint_pack: image_t, strength: f32 = 0.1, uvScale: f32 = 1.0) => { - let height: buffer_t = image_get_pixels(texpaint_pack); - let height_view: buffer_view_t = new DataView(height); - let res: i32 = texpaint_pack.width; - let o: mesh_object_t = project_paint_objects[0]; - let g: mesh_data_t = o.data; - let l: i32 = g4_vertex_struct_byte_size(g._.structure) / 2; - let vertices: buffer_view_t = g4_vertex_buffer_lock(g._.vertex_buffer); // posnortex - for (let i: i32 = 0; i < Math.floor(vertices.byteLength / 2 / l); ++i) { - let x: i32 = Math.floor(vertices.getInt16((i * l + 6) * 2, true) / 32767 * res); - let y: i32 = Math.floor(vertices.getInt16((i * l + 7) * 2, true) / 32767 * res); - let xx: i32 = Math.floor(x * uvScale) % res; - let yy: i32 = Math.floor(y * uvScale) % res; - let h: f32 = (1.0 - height_view.getUint8((yy * res + xx) * 4 + 3) / 255) * strength; - vertices.setInt16((i * l ) * 2, vertices.getInt16((i * l ) * 2, true) - Math.floor(vertices.getInt16((i * l + 4) * 2, true) * h), true); - vertices.setInt16((i * l + 1) * 2, vertices.getInt16((i * l + 1) * 2, true) - Math.floor(vertices.getInt16((i * l + 5) * 2, true) * h), true); - vertices.setInt16((i * l + 2) * 2, vertices.getInt16((i * l + 2) * 2, true) - Math.floor(vertices.getInt16((i * l + 3) * 2, true) * h), true); - } - g4_vertex_buffer_unlock(g._.vertex_buffer); - - let va0: i16_array_t = o.data.vertex_arrays[0].values; - for (let i: i32 = 0; i < Math.floor(vertices.byteLength / 4 / l); ++i) { - va0[i * 4 ] = vertices.getInt16((i * l ) * 2, true); - va0[i * 4 + 1] = vertices.getInt16((i * l + 1) * 2, true); - va0[i * 4 + 2] = vertices.getInt16((i * l + 2) * 2, true); - } - } - - static equirect_unwrap = (mesh: any) => { - let verts: i32 = Math.floor(mesh.posa.length / 4); - mesh.texa = new Int16Array(verts * 2); - let n: vec4_t = vec4_create(); - for (let i: i32 = 0; i < verts; ++i) { - vec4_normalize(vec4_set(n, mesh.posa[i * 4] / 32767, mesh.posa[i * 4 + 1] / 32767, mesh.posa[i * 4 + 2] / 32767)); - // Sphere projection - // mesh.texa[i * 2 ] = Math.atan2(n.x, n.y) / (Math.PI * 2) + 0.5; - // mesh.texa[i * 2 + 1] = n.z * 0.5 + 0.5; - // Equirect - mesh.texa[i * 2 ] = Math.floor(((Math.atan2(-n.z, n.x) + Math.PI) / (Math.PI * 2)) * 32767); - mesh.texa[i * 2 + 1] = Math.floor((Math.acos(n.y) / Math.PI) * 32767); - } - } - - static pnpoly = (v0x: f32, v0y: f32, v1x: f32, v1y: f32, v2x: f32, v2y: f32, px: f32, py: f32): bool => { - // https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html - let c: bool = false; - if (((v0y > py) != (v2y > py)) && (px < (v2x - v0x) * (py - v0y) / (v2y - v0y) + v0x)) c = !c; - if (((v1y > py) != (v0y > py)) && (px < (v0x - v1x) * (py - v1y) / (v0y - v1y) + v1x)) c = !c; - if (((v2y > py) != (v1y > py)) && (px < (v1x - v2x) * (py - v2y) / (v1y - v2y) + v2x)) c = !c; - return c; - } - - static calc_normal = (p0: vec4_t, p1: vec4_t, p2: vec4_t): vec4_t => { - let cb: vec4_t = vec4_sub_vecs(vec4_create(), p2, p1); - let ab: vec4_t = vec4_sub_vecs(vec4_create(), p0, p1); - vec4_cross(cb, ab); - vec4_normalize(cb); - return cb; - } -} diff --git a/base/Sources/UtilParticle.ts b/base/Sources/UtilParticle.ts deleted file mode 100644 index 2a7f0566..00000000 --- a/base/Sources/UtilParticle.ts +++ /dev/null @@ -1,116 +0,0 @@ - -///if (is_paint || is_sculpt) - -class UtilParticle { - - static init_particle = () => { - if (context_raw.particle_material != null) return; - - let raw: particle_data_t = { - name: "Particles", - type: 0, - loop: false, - count: 1000, - frame_start: 0, - frame_end: 1000, - lifetime: 400, - lifetime_random: 0.5, - emit_from: 1, - object_align_factor: new Float32Array([0, 0, -40]), - factor_random: 2.0, - physics_type: 0, - particle_size: 1.0, - size_random: 0, - mass: 1, - instance_object: ".Particle", - weight_gravity: 1 - }; - _scene_raw.particle_datas = [raw]; - let particle_refs: particle_ref_t[] = [ - { - name: "Particles", - particle: "Particles", - seed: 0 - } - ]; - - { - let t: render_target_t = render_target_create(); - t.name = "texparticle"; - t.width = 0; - t.height = 0; - t.format = "R8"; - t.scale = RenderPathBase.get_super_sampling(); - render_path_create_render_target(t); - } - - for (let mat of _scene_raw.material_datas) { - if (mat.name == "Material2") { - let m: material_data_t = JSON.parse(JSON.stringify(mat)); - m.name = "MaterialParticle"; - _scene_raw.material_datas.push(m); - break; - } - } - - let md: material_data_t = data_get_material("Scene", "MaterialParticle"); - context_raw.particle_material = md; - - for (let obj of _scene_raw.objects) { - if (obj.name == ".Sphere") { - let particle: obj_t = JSON.parse(JSON.stringify(obj)); - particle.name = ".Particle"; - if (particle.particles == null) { - particle.particles = {}; - } - particle.particles.is_particle = true; - particle.material_refs = ["MaterialParticle"]; - _scene_raw.objects.push(particle); - for (let i: i32 = 0; i < 16; ++i) particle.transform[i] *= 0.01; - break; - } - } - - let o: object_t = scene_spawn_object(".Sphere"); - let mo: mesh_object_t = o.ext; - mo.base.name = ".ParticleEmitter"; - mo.base.raw = JSON.parse(JSON.stringify(mo.base.raw)); - mo.base.raw.particles.refs = particle_refs; - ///if arm_particles - mesh_object_setup_particle_system(mo, "Scene", particle_refs[0]); - ///end - } - - ///if arm_physics - - static init_particle_physics = () => { - if (PhysicsWorld.active != null) { - UtilParticle.init_particle_mesh(); - return; - } - - PhysicsWorld.load(() => { - PhysicsWorld.create(); - UtilParticle.init_particle_mesh(); - }); - } - - static init_particle_mesh = () => { - if (context_raw.paint_body != null) return; - - let po: mesh_object_t = context_raw.merged_object != null ? context_raw.merged_object : context_raw.paint_object; - - po.base.transform.scale.x = po.base.parent.transform.scale.x; - po.base.transform.scale.y = po.base.parent.transform.scale.y; - po.base.transform.scale.z = po.base.parent.transform.scale.z; - - context_raw.paint_body = PhysicsBody.create(); - context_raw.paint_body.shape = shape_type_t.MESH; - PhysicsBody.init(context_raw.paint_body, po.base); - (po.base as any).physicsBody = context_raw.paint_body; - } - - ///end -} - -///end diff --git a/base/Sources/UtilRender.ts b/base/Sources/UtilRender.ts deleted file mode 100644 index e3582d12..00000000 --- a/base/Sources/UtilRender.ts +++ /dev/null @@ -1,451 +0,0 @@ - -///if (is_paint || is_sculpt) - -class UtilRender { - - static material_preview_size: i32 = 256; - static decal_preview_size: i32 = 512; - static layer_preview_size: i32 = 200; - static screen_aligned_full_vb: vertex_buffer_t = null; - static screen_aligned_full_ib: index_buffer_t = null; - - static make_material_preview = () => { - context_raw.material_preview = true; - - let sphere: mesh_object_t = scene_get_child(".Sphere").ext; - sphere.base.visible = true; - let meshes: mesh_object_t[] = scene_meshes; - scene_meshes = [sphere]; - let painto: mesh_object_t = context_raw.paint_object; - context_raw.paint_object = sphere; - - sphere.materials[0] = project_materials[0].data; - context_raw.material.preview_ready = true; - - mat4_set_from(context_raw.saved_camera, scene_camera.base.transform.local); - let m: mat4_t = mat4_create(0.9146286343879498, -0.0032648027153306235, 0.404281837254303, 0.4659988049397712, 0.404295023959927, 0.007367569133732468, -0.9145989516155143, -1.0687517188018691, 0.000007410128652369705, 0.9999675337275382, 0.008058532943908717, 0.015935682577325486, 0, 0, 0, 1); - transform_set_matrix(scene_camera.base.transform, m); - let saved_fov: f32 = scene_camera.data.fov; - scene_camera.data.fov = 0.92; - viewport_update_camera_type(camera_type_t.PERSPECTIVE); - let light: light_object_t = scene_lights[0]; - let _light_strength: f32 = light.data.strength; - let probe: world_data_t = scene_world; - let _probe_strength: f32 = probe.strength; - light.data.strength = 0; - probe.strength = 7; - let _envmap_angle: f32 = context_raw.envmap_angle; - context_raw.envmap_angle = 6.0; - let _brush_scale: f32 = context_raw.brush_scale; - context_raw.brush_scale = 1.5; - let _brush_nodes_scale: f32 = context_raw.brush_nodes_scale; - context_raw.brush_nodes_scale = 1.0; - - scene_world._.envmap = context_raw.preview_envmap; - // No resize - _render_path_last_w = UtilRender.material_preview_size; - _render_path_last_h = UtilRender.material_preview_size; - camera_object_build_proj(scene_camera); - camera_object_build_mat(scene_camera); - - MakeMaterial.parse_mesh_preview_material(); - let _commands: ()=>void = render_path_commands; - render_path_commands = RenderPathPreview.commands_preview; - render_path_render_frame(); - render_path_commands = _commands; - - context_raw.material_preview = false; - _render_path_last_w = app_w(); - _render_path_last_h = app_h(); - - // Restore - sphere.base.visible = false; - scene_meshes = meshes; - context_raw.paint_object = painto; - - transform_set_matrix(scene_camera.base.transform, context_raw.saved_camera); - viewport_update_camera_type(context_raw.camera_type); - scene_camera.data.fov = saved_fov; - camera_object_build_proj(scene_camera); - camera_object_build_mat(scene_camera); - light.data.strength = _light_strength; - probe.strength = _probe_strength; - context_raw.envmap_angle = _envmap_angle; - context_raw.brush_scale = _brush_scale; - context_raw.brush_nodes_scale = _brush_nodes_scale; - scene_world._.envmap = context_raw.show_envmap ? context_raw.saved_envmap : context_raw.empty_envmap; - MakeMaterial.parse_mesh_material(); - context_raw.ddirty = 0; - } - - static make_decal_preview = () => { - let current: image_t = _g2_current; - let g2_in_use: bool = _g2_in_use; - if (g2_in_use) g2_end(); - - if (context_raw.decal_image == null) { - context_raw.decal_image = image_create_render_target(UtilRender.decal_preview_size, UtilRender.decal_preview_size); - } - context_raw.decal_preview = true; - - let plane: mesh_object_t = scene_get_child(".Plane").ext; - vec4_set(plane.base.transform.scale, 1, 1, 1); - quat_from_euler(plane.base.transform.rot, -Math.PI / 2, 0, 0); - transform_build_matrix(plane.base.transform); - plane.base.visible = true; - let meshes: mesh_object_t[] = scene_meshes; - scene_meshes = [plane]; - let painto: mesh_object_t = context_raw.paint_object; - context_raw.paint_object = plane; - - mat4_set_from(context_raw.saved_camera, scene_camera.base.transform.local); - let m: mat4_t = mat4_identity(); - mat4_translate(m, 0, 0, 1); - transform_set_matrix(scene_camera.base.transform, m); - let saved_fov: f32 = scene_camera.data.fov; - scene_camera.data.fov = 0.92; - viewport_update_camera_type(camera_type_t.PERSPECTIVE); - let light: light_object_t = scene_lights[0]; - light.base.visible = false; - scene_world._.envmap = context_raw.preview_envmap; - - // No resize - _render_path_last_w = UtilRender.decal_preview_size; - _render_path_last_h = UtilRender.decal_preview_size; - camera_object_build_proj(scene_camera); - camera_object_build_mat(scene_camera); - - MakeMaterial.parse_mesh_preview_material(); - let _commands: ()=>void = render_path_commands; - render_path_commands = RenderPathPreview.commands_decal; - render_path_render_frame(); - render_path_commands = _commands; - - context_raw.decal_preview = false; - _render_path_last_w = app_w(); - _render_path_last_h = app_h(); - - // Restore - plane.base.visible = false; - scene_meshes = meshes; - context_raw.paint_object = painto; - - transform_set_matrix(scene_camera.base.transform, context_raw.saved_camera); - scene_camera.data.fov = saved_fov; - viewport_update_camera_type(context_raw.camera_type); - camera_object_build_proj(scene_camera); - camera_object_build_mat(scene_camera); - light = scene_lights[0]; - light.base.visible = true; - scene_world._.envmap = context_raw.show_envmap ? context_raw.saved_envmap : context_raw.empty_envmap; - - MakeMaterial.parse_mesh_material(); - context_raw.ddirty = 1; // Refresh depth for decal paint - - if (g2_in_use) g2_begin(current); - } - - static make_text_preview = () => { - let current: image_t = _g2_current; - if (current != null) g2_end(); - - let text: string = context_raw.text_tool_text; - let font: g2_font_t = context_raw.font.font; - let font_size: i32 = 200; - let text_w: i32 = Math.floor(g2_font_width(font, font_size, text)); - let text_h: i32 = Math.floor(g2_font_height(font, font_size)); - let texW: i32 = text_w + 32; - if (texW < 512) texW = 512; - if (context_raw.text_tool_image != null && context_raw.text_tool_image.width < texW) { - image_unload(context_raw.text_tool_image); - context_raw.text_tool_image = null; - } - if (context_raw.text_tool_image == null) { - ///if krom_metal - context_raw.text_tool_image = image_create_render_target(texW, texW, tex_format_t.RGBA32); - ///else - context_raw.text_tool_image = image_create_render_target(texW, texW, tex_format_t.R8); - ///end - } - g2_begin(context_raw.text_tool_image); - g2_clear(0xff000000); - g2_set_font(font); - g2_set_font_size(font_size); - g2_set_color(0xffffffff); - g2_draw_string(text, texW / 2 - text_w / 2, texW / 2 - text_h / 2); - g2_end(); - - if (current != null) g2_begin(current); - } - - static make_font_preview = () => { - let current: image_t = _g2_current; - if (current != null) g2_end(); - - let text: string = "Abg"; - let font: g2_font_t = context_raw.font.font; - let font_size: i32 = 318; - let text_w: i32 = Math.floor(g2_font_width(font, font_size, text)) + 8; - let text_h: i32 = Math.floor(g2_font_height(font, font_size)) + 8; - if (context_raw.font.image == null) { - context_raw.font.image = image_create_render_target(512, 512, tex_format_t.RGBA32); - } - g2_begin(context_raw.font.image); - g2_clear(0x00000000); - g2_set_font(font); - g2_set_font_size(font_size); - g2_set_color(0xffffffff); - g2_draw_string(text, 512 / 2 - text_w / 2, 512 / 2 - text_h / 2); - g2_end(); - context_raw.font.preview_ready = true; - - if (current != null) g2_begin(current); - } - - static make_brush_preview = () => { - if (RenderPathPaint.live_layer_locked) return; - context_raw.material_preview = true; - - let current: image_t = _g2_current; - if (current != null) g2_end(); - - // Prepare layers - if (RenderPathPaint.live_layer == null) { - RenderPathPaint.live_layer = SlotLayer.create("_live"); - } - - let l: SlotLayerRaw = RenderPathPaint.live_layer; - SlotLayer.clear(l); - - if (context_raw.brush.image == null) { - context_raw.brush.image = image_create_render_target(UtilRender.material_preview_size, UtilRender.material_preview_size); - context_raw.brush.image_icon = image_create_render_target(50, 50); - } - - let _material: SlotMaterialRaw = context_raw.material; - context_raw.material = SlotMaterial.create(); - let _tool: workspace_tool_t = context_raw.tool; - context_raw.tool = workspace_tool_t.BRUSH; - - let _layer: SlotLayerRaw = context_raw.layer; - if (SlotLayer.is_mask(context_raw.layer)) { - context_raw.layer = context_raw.layer.parent; - } - - let _fill_layer: SlotMaterialRaw = context_raw.layer.fill_layer; - context_raw.layer.fill_layer = null; - - RenderPathPaint.use_live_layer(true); - MakeMaterial.parse_paint_material(false); - - let hid: i32 = history_undo_i - 1 < 0 ? config_raw.undo_steps - 1 : history_undo_i - 1; - render_path_render_targets.set("texpaint_undo" + hid,render_path_render_targets.get("empty_black")); - - // Set plane mesh - let painto: mesh_object_t = context_raw.paint_object; - let visibles: bool[] = []; - for (let p of project_paint_objects) { - visibles.push(p.base.visible); - p.base.visible = false; - } - let merged_object_visible: bool = false; - if (context_raw.merged_object != null) { - merged_object_visible = context_raw.merged_object.base.visible; - context_raw.merged_object.base.visible = false; - } - - let cam: camera_object_t = scene_camera; - mat4_set_from(context_raw.saved_camera, cam.base.transform.local); - let saved_fov: f32 = cam.data.fov; - viewport_update_camera_type(camera_type_t.PERSPECTIVE); - let m: mat4_t = mat4_identity(); - mat4_translate(m, 0, 0, 0.5); - transform_set_matrix(cam.base.transform, m); - cam.data.fov = 0.92; - camera_object_build_proj(cam); - camera_object_build_mat(cam); - mat4_get_inv(m, scene_camera.vp); - - let planeo: mesh_object_t = scene_get_child(".Plane").ext; - planeo.base.visible = true; - context_raw.paint_object = planeo; - - let v: vec4_t = vec4_create(); - let sx: f32 = vec4_len(vec4_set(v, m.m[0], m.m[1], m.m[2])); - quat_from_euler(planeo.base.transform.rot, -Math.PI / 2, 0, 0); - vec4_set(planeo.base.transform.scale, sx, 1.0, sx); - vec4_set(planeo.base.transform.loc, m.m[12], -m.m[13], 0.0); - transform_build_matrix(planeo.base.transform); - - RenderPathPaint.live_layer_drawn = 0; - RenderPathBase.draw_gbuffer(); - - // Paint brush preview - let _brush_radius: f32 = context_raw.brush_radius; - let _brush_opacity: f32 = context_raw.brush_opacity; - let _brush_hardness: f32 = context_raw.brush_hardness; - context_raw.brush_radius = 0.33; - context_raw.brush_opacity = 1.0; - context_raw.brush_hardness = 0.8; - let _x: f32 = context_raw.paint_vec.x; - let _y: f32 = context_raw.paint_vec.y; - let _last_x: f32 = context_raw.last_paint_vec_x; - let _last_y: f32 = context_raw.last_paint_vec_y; - let _pdirty: i32 = context_raw.pdirty; - context_raw.pdirty = 2; - - let points_x: f32[] = [0.2, 0.2, 0.35, 0.5, 0.5, 0.5, 0.65, 0.8, 0.8, 0.8]; - let points_y: f32[] = [0.5, 0.5, 0.35 - 0.04, 0.2 - 0.08, 0.4 + 0.015, 0.6 + 0.03, 0.45 - 0.025, 0.3 - 0.05, 0.5 + 0.025, 0.7 + 0.05]; - for (let i: i32 = 1; i < points_x.length; ++i) { - context_raw.last_paint_vec_x = points_x[i - 1]; - context_raw.last_paint_vec_y = points_y[i - 1]; - context_raw.paint_vec.x = points_x[i]; - context_raw.paint_vec.y = points_y[i]; - RenderPathPaint.commands_paint(false); - } - - context_raw.brush_radius = _brush_radius; - context_raw.brush_opacity = _brush_opacity; - context_raw.brush_hardness = _brush_hardness; - context_raw.paint_vec.x = _x; - context_raw.paint_vec.y = _y; - context_raw.last_paint_vec_x = _last_x; - context_raw.last_paint_vec_y = _last_y; - context_raw.prev_paint_vec_x = -1; - context_raw.prev_paint_vec_y = -1; - context_raw.pdirty = _pdirty; - RenderPathPaint.use_live_layer(false); - context_raw.layer.fill_layer = _fill_layer; - context_raw.layer = _layer; - context_raw.material = _material; - context_raw.tool = _tool; - let _init = () => { - MakeMaterial.parse_paint_material(false); - } - app_notify_on_init(_init); - - // Restore paint mesh - context_raw.material_preview = false; - planeo.base.visible = false; - for (let i: i32 = 0; i < project_paint_objects.length; ++i) { - project_paint_objects[i].base.visible = visibles[i]; - } - if (context_raw.merged_object != null) { - context_raw.merged_object.base.visible = merged_object_visible; - } - context_raw.paint_object = painto; - transform_set_matrix(scene_camera.base.transform, context_raw.saved_camera); - scene_camera.data.fov = saved_fov; - viewport_update_camera_type(context_raw.camera_type); - camera_object_build_proj(scene_camera); - camera_object_build_mat(scene_camera); - - // Scale layer down to to image preview - if (base_pipe_merge == null) base_make_pipe(); - l = RenderPathPaint.live_layer; - let target: image_t = context_raw.brush.image; - g2_begin(target); - g2_clear(0x00000000); - g2_set_pipeline(base_pipe_copy); - g2_draw_scaled_image(l.texpaint, 0, 0, target.width, target.height); - g2_set_pipeline(null); - g2_end(); - - // Scale image preview down to to icon - render_path_render_targets.get("texpreview")._image = context_raw.brush.image; - render_path_render_targets.get("texpreview_icon")._image = context_raw.brush.image_icon; - render_path_set_target("texpreview_icon"); - render_path_bind_target("texpreview", "tex"); - render_path_draw_shader("shader_datas/supersample_resolve/supersample_resolve"); - - context_raw.brush.preview_ready = true; - context_raw.brush_blend_dirty = true; - - if (current != null) g2_begin(current); - } - - static make_node_preview = (canvas: zui_node_canvas_t, node: zui_node_t, image: image_t, group: zui_node_canvas_t = null, parents: zui_node_t[] = null) => { - let res: any = MakeMaterial.parse_node_preview_material(node, group, parents); - if (res == null || res.scon == null) return; - - if (UtilRender.screen_aligned_full_vb == null) { - UtilRender.create_screen_aligned_full_data(); - } - - let _scale_world: f32 = context_raw.paint_object.base.transform.scale_world; - context_raw.paint_object.base.transform.scale_world = 3.0; - transform_build_matrix(context_raw.paint_object.base.transform); - - g4_begin(image); - g4_set_pipeline(res.scon._.pipe_state); - uniforms_set_context_consts(res.scon, [""]); - uniforms_set_obj_consts(res.scon, context_raw.paint_object.base); - uniforms_set_material_consts(res.scon, res.mcon); - g4_set_vertex_buffer(UtilRender.screen_aligned_full_vb); - g4_set_index_buffer(UtilRender.screen_aligned_full_ib); - g4_draw(); - g4_end(); - - context_raw.paint_object.base.transform.scale_world = _scale_world; - transform_build_matrix(context_raw.paint_object.base.transform); - } - - static pick_pos_nor_tex = () => { - context_raw.pick_pos_nor_tex = true; - context_raw.pdirty = 1; - let _tool: workspace_tool_t = context_raw.tool; - context_raw.tool = workspace_tool_t.PICKER; - MakeMaterial.parse_paint_material(); - if (context_raw.paint2d) { - RenderPathPaint.set_plane_mesh(); - } - RenderPathPaint.commands_paint(false); - ///if krom_metal - // Flush command list - RenderPathPaint.commands_paint(false); - ///end - if (context_raw.paint2d) { - RenderPathPaint.restore_plane_mesh(); - } - context_raw.tool = _tool; - context_raw.pick_pos_nor_tex = false; - MakeMaterial.parse_paint_material(); - context_raw.pdirty = 0; - } - - static get_decal_mat = (): mat4_t => { - UtilRender.pick_pos_nor_tex(); - let decal_mat: mat4_t = mat4_identity(); - let loc: vec4_t = vec4_create(context_raw.posx_picked, context_raw.posy_picked, context_raw.posz_picked); - let rot: quat_t = quat_from_to(quat_create(), vec4_create(0.0, 0.0, -1.0), vec4_create(context_raw.norx_picked, context_raw.nory_picked, context_raw.norz_picked)); - let scale: vec4_t = vec4_create(context_raw.brush_radius * 0.5, context_raw.brush_radius * 0.5, context_raw.brush_radius * 0.5); - mat4_compose(decal_mat, loc, rot, scale); - return decal_mat; - } - - static create_screen_aligned_full_data = () => { - // Over-sized triangle - let data: f32[] = [-Math.floor(32767 / 3), -Math.floor(32767 / 3), 0, 32767, 0, 0, 0, 0, 0, 0, 0, 0, - 32767, -Math.floor(32767 / 3), 0, 32767, 0, 0, 0, 0, 0, 0, 0, 0, - -Math.floor(32767 / 3), 32767, 0, 32767, 0, 0, 0, 0, 0, 0, 0, 0]; - let indices: i32[] = [0, 1, 2]; - - // Mandatory vertex data names and sizes - let structure: vertex_struct_t = g4_vertex_struct_create(); - g4_vertex_struct_add(structure, "pos", vertex_data_t.I16_4X_NORM); - g4_vertex_struct_add(structure, "nor", vertex_data_t.I16_2X_NORM); - g4_vertex_struct_add(structure, "tex", vertex_data_t.I16_2X_NORM); - g4_vertex_struct_add(structure, "col", vertex_data_t.I16_4X_NORM); - UtilRender.screen_aligned_full_vb = g4_vertex_buffer_create(Math.floor(data.length / Math.floor(g4_vertex_struct_byte_size(structure) / 4)), structure, usage_t.STATIC); - let vertices: buffer_view_t = g4_vertex_buffer_lock(UtilRender.screen_aligned_full_vb); - for (let i: i32 = 0; i < Math.floor(vertices.byteLength / 2); ++i) vertices.setInt16(i * 2, data[i], true); - g4_vertex_buffer_unlock(UtilRender.screen_aligned_full_vb); - - UtilRender.screen_aligned_full_ib = g4_index_buffer_create(indices.length); - let id: u32_array_t = g4_index_buffer_lock(UtilRender.screen_aligned_full_ib); - for (let i: i32 = 0; i < id.length; ++i) id[i] = indices[i]; - g4_index_buffer_unlock(UtilRender.screen_aligned_full_ib); - } -} - -///end diff --git a/base/Sources/UtilUV.ts b/base/Sources/UtilUV.ts deleted file mode 100644 index 8e1cf351..00000000 --- a/base/Sources/UtilUV.ts +++ /dev/null @@ -1,190 +0,0 @@ - -///if (is_paint || is_sculpt) - -class UtilUV { - - static uvmap: image_t = null; - static uvmap_cached: bool = false; - static trianglemap: image_t = null; - static trianglemap_cached: bool = false; - static dilatemap: image_t = null; - static dilatemap_cached: bool = false; - static uvislandmap: image_t = null; - static uvislandmap_cached: bool = false; - static dilate_bytes: ArrayBuffer = null; - static pipe_dilate: pipeline_t = null; - - static cache_uv_map = () => { - if (UtilUV.uvmap != null && (UtilUV.uvmap.width != config_get_texture_res_x() || UtilUV.uvmap.height != config_get_texture_res_y())) { - image_unload(UtilUV.uvmap); - UtilUV.uvmap = null; - UtilUV.uvmap_cached = false; - } - - if (UtilUV.uvmap_cached) return; - - let res_x: i32 = config_get_texture_res_x(); - let res_y: i32 = config_get_texture_res_y(); - if (UtilUV.uvmap == null) { - UtilUV.uvmap = image_create_render_target(res_x, res_y); - } - - UtilUV.uvmap_cached = true; - let merged: mesh_object_t = context_raw.merged_object; - let mesh: mesh_data_t = (context_raw.layer_filter == 0 && merged != null) ? - merged.data : context_raw.paint_object.data; - - let texa: i16_array_t = mesh.vertex_arrays[2].values; - let inda: u32_array_t = mesh.index_arrays[0].values; - g2_begin(UtilUV.uvmap); - g2_clear(0x00000000); - g2_set_color(0xffcccccc); - let strength: f32 = res_x > 2048 ? 2.0 : 1.0; - let f: f32 = (1 / 32767) * UtilUV.uvmap.width; - for (let i: i32 = 0; i < Math.floor(inda.length / 3); ++i) { - let x1: f32 = (texa[inda[i * 3 ] * 2 ]) * f; - let x2: f32 = (texa[inda[i * 3 + 1] * 2 ]) * f; - let x3: f32 = (texa[inda[i * 3 + 2] * 2 ]) * f; - let y1: f32 = (texa[inda[i * 3 ] * 2 + 1]) * f; - let y2: f32 = (texa[inda[i * 3 + 1] * 2 + 1]) * f; - let y3: f32 = (texa[inda[i * 3 + 2] * 2 + 1]) * f; - g2_draw_line(x1, y1, x2, y2, strength); - g2_draw_line(x2, y2, x3, y3, strength); - g2_draw_line(x3, y3, x1, y1, strength); - } - g2_end(); - } - - static cache_triangle_map = () => { - if (UtilUV.trianglemap != null && (UtilUV.trianglemap.width != config_get_texture_res_x() || UtilUV.trianglemap.height != config_get_texture_res_y())) { - image_unload(UtilUV.trianglemap); - UtilUV.trianglemap = null; - UtilUV.trianglemap_cached = false; - } - - if (UtilUV.trianglemap_cached) return; - - if (UtilUV.trianglemap == null) { - UtilUV.trianglemap = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y()); - } - - UtilUV.trianglemap_cached = true; - let merged: mesh_data_t = context_raw.merged_object != null ? context_raw.merged_object.data : context_raw.paint_object.data; - let mesh: mesh_data_t = merged; - let texa: i16_array_t = mesh.vertex_arrays[2].values; - let inda: u32_array_t = mesh.index_arrays[0].values; - g2_begin(UtilUV.trianglemap); - g2_clear(0xff000000); - let f: f32 = (1 / 32767) * UtilUV.trianglemap.width; - let color: i32 = 0xff000001; - for (let i: i32 = 0; i < Math.floor(inda.length / 3); ++i) { - if (color == 0xffffffff) color = 0xff000001; - color++; - g2_set_color(color); - let x1: f32 = (texa[inda[i * 3 ] * 2 ]) * f; - let x2: f32 = (texa[inda[i * 3 + 1] * 2 ]) * f; - let x3: f32 = (texa[inda[i * 3 + 2] * 2 ]) * f; - let y1: f32 = (texa[inda[i * 3 ] * 2 + 1]) * f; - let y2: f32 = (texa[inda[i * 3 + 1] * 2 + 1]) * f; - let y3: f32 = (texa[inda[i * 3 + 2] * 2 + 1]) * f; - g2_fill_triangle(x1, y1, x2, y2, x3, y3); - } - g2_end(); - } - - static cache_dilate_map = () => { - if (UtilUV.dilatemap != null && (UtilUV.dilatemap.width != config_get_texture_res_x() || UtilUV.dilatemap.height != config_get_texture_res_y())) { - image_unload(UtilUV.dilatemap); - UtilUV.dilatemap = null; - UtilUV.dilatemap_cached = false; - } - - if (UtilUV.dilatemap_cached) return; - - if (UtilUV.dilatemap == null) { - UtilUV.dilatemap = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8); - } - - if (UtilUV.pipe_dilate == null) { - UtilUV.pipe_dilate = g4_pipeline_create(); - UtilUV.pipe_dilate.vertex_shader = sys_get_shader("dilate_map.vert"); - UtilUV.pipe_dilate.fragment_shader = sys_get_shader("dilate_map.frag"); - let vs: vertex_struct_t = g4_vertex_struct_create(); - ///if (krom_metal || krom_vulkan) - g4_vertex_struct_add(vs, "tex", vertex_data_t.I16_2X_NORM); - ///else - g4_vertex_struct_add(vs, "pos", vertex_data_t.I16_4X_NORM); - g4_vertex_struct_add(vs, "nor", vertex_data_t.I16_2X_NORM); - g4_vertex_struct_add(vs, "tex", vertex_data_t.I16_2X_NORM); - ///end - UtilUV.pipe_dilate.input_layout = [vs]; - UtilUV.pipe_dilate.depth_write = false; - UtilUV.pipe_dilate.depth_mode = compare_mode_t.ALWAYS; - UtilUV.pipe_dilate.color_attachments[0] = tex_format_t.R8; - g4_pipeline_compile(UtilUV.pipe_dilate); - // dilateTexUnpack = getConstantLocation(UtilUV.pipeDilate, "texUnpack"); - } - - let mask: i32 = context_object_mask_used() ? SlotLayer.get_object_mask(context_raw.layer) : 0; - if (context_layer_filter_used()) mask = context_raw.layer_filter; - let geom: mesh_data_t = mask == 0 && context_raw.merged_object != null ? context_raw.merged_object.data : context_raw.paint_object.data; - g4_begin(UtilUV.dilatemap); - g4_clear(0x00000000); - g4_set_pipeline(UtilUV.pipe_dilate); - ///if (krom_metal || krom_vulkan) - g4_set_vertex_buffer(mesh_data_get(geom, [{name: "tex", data: "short2norm"}])); - ///else - g4_set_vertex_buffer(geom._.vertex_buffer); - ///end - g4_set_index_buffer(geom._.index_buffers[0]); - g4_draw(); - g4_end(); - UtilUV.dilatemap_cached = true; - UtilUV.dilate_bytes = null; - } - - static cache_uv_island_map = () => { - UtilUV.cache_dilate_map(); - if (UtilUV.dilate_bytes == null) { - UtilUV.dilate_bytes = image_get_pixels(UtilUV.dilatemap); - } - UtilRender.pick_pos_nor_tex(); - let w: i32 = 2048; // config_get_texture_res_x() - let h: i32 = 2048; // config_get_texture_res_y() - let x: i32 = Math.floor(context_raw.uvx_picked * w); - let y: i32 = Math.floor(context_raw.uvy_picked * h); - let bytes: ArrayBuffer = new ArrayBuffer(w * h); - let view: DataView = new DataView(bytes); - let coords: coord_t[] = [{ x: x, y: y }]; - let r: i32 = Math.floor(UtilUV.dilatemap.width / w); - - let check = (c: coord_t) => { - if (c.x < 0 || c.x >= w || c.y < 0 || c.y >= h) return; - if (view.getUint8(c.y * w + c.x) == 255) return; - let dilate_view: DataView = new DataView(UtilUV.dilate_bytes); - if (dilate_view.getUint8(c.y * r * UtilUV.dilatemap.width + c.x * r) == 0) return; - view.setUint8(c.y * w + c.x, 255); - coords.push({ x: c.x + 1, y: c.y }); - coords.push({ x: c.x - 1, y: c.y }); - coords.push({ x: c.x, y: c.y + 1 }); - coords.push({ x: c.x, y: c.y - 1 }); - } - - while (coords.length > 0) { - check(coords.pop()); - } - - if (UtilUV.uvislandmap != null) { - image_unload(UtilUV.uvislandmap); - } - UtilUV.uvislandmap = image_from_bytes(bytes, w, h, tex_format_t.R8); - UtilUV.uvislandmap_cached = true; - } -} - -type coord_t = { - x?: i32; - y?: i32; -} - -///end diff --git a/base/Sources/args.ts b/base/Sources/args.ts index ff7e458b..864ac568 100644 --- a/base/Sources/args.ts +++ b/base/Sources/args.ts @@ -86,7 +86,7 @@ function args_run() { ImportAsset.run(args_asset_path, -1, -1, false); ///if is_paint if (path_is_texture(args_asset_path)) { - UIBase.show_2d_view(view_2d_type_t.ASSET); + ui_base_show_2d_view(view_2d_type_t.ASSET); } ///end } @@ -143,7 +143,7 @@ function args_run() { } let blob: ArrayBuffer = data_get_blob(file); - BoxExport.preset = JSON.parse(sys_buffer_to_string(blob)); + BoxExport.preset = json_parse(sys_buffer_to_string(blob)); data_delete_blob("export_presets/" + file); // Export queue @@ -164,7 +164,7 @@ function args_run() { ///if (is_paint || is_sculpt) else if (args_export_mesh) { if (path_is_folder(args_export_mesh_path)) { - let f: string = UIFiles.filename; + let f: string = ui_files_filename; if (f == "") f = tr("untitled"); ExportMesh.run(args_export_mesh_path + path_sep + f, null, false); } diff --git a/base/Sources/base.ts b/base/Sources/base.ts index 02bf6bec..61ff346d 100644 --- a/base/Sources/base.ts +++ b/base/Sources/base.ts @@ -218,7 +218,7 @@ function base_init() { base_default_element_w = base_theme.ELEMENT_W; base_default_font_size = base_theme.FONT_SIZE; translator_load_translations(config_raw.locale); - UIFiles.filename = tr("untitled"); + ui_files_filename = tr("untitled"); ///if (krom_android || krom_ios) sys_title_set(tr("untitled")); ///end @@ -248,38 +248,38 @@ function base_init() { args_parse(); camera_init(); - new UIBase(); - new UINodes(); - new UIView2D(); + ui_base_init(); + ui_nodes_init(); + ui_view2d_init(); ///if is_lab - RandomNode.setSeed(Math.floor(time_time() * 4294967295)); + RandomNode.setSeed(math_floor(time_time() * 4294967295)); ///end app_notify_on_update(base_update); - app_notify_on_render_2d(UIView2D.render); - app_notify_on_update(UIView2D.update); + app_notify_on_render_2d(ui_view2d_render); + app_notify_on_update(ui_view2d_update); ///if (is_paint || is_sculpt) - app_notify_on_render_2d(UIBase.render_cursor); + app_notify_on_render_2d(ui_base_render_cursor); ///end - app_notify_on_update(UINodes.update); - app_notify_on_render_2d(UINodes.render); - app_notify_on_update(UIBase.update); - app_notify_on_render_2d(UIBase.render); + app_notify_on_update(ui_nodes_update); + app_notify_on_render_2d(ui_nodes_render); + app_notify_on_update(ui_base_update); + app_notify_on_render_2d(ui_base_render); app_notify_on_update(camera_update); app_notify_on_render_2d(base_render); ///if (is_paint || is_sculpt) - base_appx = UIToolbar.toolbar_w; + base_appx = ui_toolbar_w; ///end ///if is_lab base_appx = 0; ///end - base_appy = UIHeader.headerh; - if (config_raw.layout[layout_size_t.HEADER] == 1) base_appy += UIHeader.headerh; + base_appy = ui_header_h; + if (config_raw.layout[layout_size_t.HEADER] == 1) base_appy += ui_header_h; let cam: camera_object_t = scene_camera; - cam.data.fov = Math.floor(cam.data.fov * 100) / 100; + cam.data.fov = math_floor(cam.data.fov * 100) / 100; camera_object_build_proj(cam); args_run(); @@ -305,33 +305,33 @@ function base_save_and_quit_callback(save: bool) { function base_w(): i32 { // Drawing material preview if (context_raw.material_preview) { - return UtilRender.material_preview_size; + return util_render_material_preview_size; } // Drawing decal preview if (context_raw.decal_preview) { - return UtilRender.decal_preview_size; + return util_render_decal_preview_size; } let res: i32 = 0; if (config_raw.layout == null) { - let sidebarw: i32 = UIBase.default_sidebar_w; - res = sys_width() - sidebarw - UIToolbar.default_toolbar_w; + let sidebarw: i32 = ui_base_default_sidebar_w; + res = sys_width() - sidebarw - ui_toolbar_default_w; } - else if (UINodes.show || UIView2D.show) { - res = sys_width() - config_raw.layout[layout_size_t.SIDEBAR_W] - config_raw.layout[layout_size_t.NODES_W] - UIToolbar.toolbar_w; + else if (ui_nodes_show || ui_view2d_show) { + res = sys_width() - config_raw.layout[layout_size_t.SIDEBAR_W] - config_raw.layout[layout_size_t.NODES_W] - ui_toolbar_w; } - else if (UIBase.show) { - res = sys_width() - config_raw.layout[layout_size_t.SIDEBAR_W] - UIToolbar.toolbar_w; + else if (ui_base_show) { + res = sys_width() - config_raw.layout[layout_size_t.SIDEBAR_W] - ui_toolbar_w; } else { // Distract free res = sys_width(); } if (context_raw.view_index > -1) { - res = Math.floor(res / 2); + res = math_floor(res / 2); } if (context_raw.paint2d_view) { - res = UIView2D.ww; + res = ui_view2d_ww; } return res > 0 ? res : 1; // App was minimized, force render path resize @@ -340,18 +340,18 @@ function base_w(): i32 { function base_h(): i32 { // Drawing material preview if (context_raw.material_preview) { - return UtilRender.material_preview_size; + return util_render_material_preview_size; } // Drawing decal preview if (context_raw.decal_preview) { - return UtilRender.decal_preview_size; + return util_render_decal_preview_size; } let res: i32 = sys_height(); if (config_raw.layout == null) { - res -= UIHeader.default_header_h * 2 + UIStatus.default_status_h; + res -= ui_header_default_h * 2 + ui_status_default_status_h; ///if (krom_android || krom_ios) let layout_header: i32 = 0; @@ -359,15 +359,15 @@ function base_h(): i32 { let layout_header: i32 = 1; ///end if (layout_header == 0) { - res += UIHeader.headerh; + res += ui_header_h; } } - else if (UIBase.show && res > 0) { + else if (ui_base_show && res > 0) { let statush: i32 = config_raw.layout[layout_size_t.STATUS_H]; - res -= Math.floor(UIHeader.default_header_h * 2 * config_raw.window_scale) + statush; + res -= math_floor(ui_header_default_h * 2 * config_raw.window_scale) + statush; if (config_raw.layout[layout_size_t.HEADER] == 0) { - res += UIHeader.headerh; + res += ui_header_h; } } @@ -381,7 +381,7 @@ function base_w(): i32 { if (UINodes == null) { res = sys_width(); } - else if (UINodes.show || UIView2D.show) { + else if (ui_nodes_show || ui_view2d_show) { res = sys_width() - config_raw.layout[layout_size_t.NODES_W]; } else { // Distract free @@ -394,11 +394,11 @@ function base_w(): i32 { function base_h(): i32 { let res: i32 = sys_height(); if (UIBase == null) { - res -= UIHeader.default_header_h * 2 + UIStatus.default_status_h; + res -= ui_header_default_h * 2 + ui_status_default_status_h; } else if (res > 0) { let statush: i32 = config_raw.layout[layout_size_t.STATUS_H]; - res -= Math.floor(UIHeader.default_header_h * 2 * config_raw.window_scale) + statush; + res -= math_floor(ui_header_default_h * 2 * config_raw.window_scale) + statush; } return res > 0 ? res : 1; // App was minimized, force render path resize @@ -426,9 +426,9 @@ function base_on_resize() { let ratio_h: f32 = sys_height() / base_last_window_height; base_last_window_height = sys_height(); - config_raw.layout[layout_size_t.NODES_W] = Math.floor(config_raw.layout[layout_size_t.NODES_W] * ratio_w); + config_raw.layout[layout_size_t.NODES_W] = math_floor(config_raw.layout[layout_size_t.NODES_W] * ratio_w); ///if (is_paint || is_sculpt) - config_raw.layout[layout_size_t.SIDEBAR_H0] = Math.floor(config_raw.layout[layout_size_t.SIDEBAR_H0] * ratio_h); + config_raw.layout[layout_size_t.SIDEBAR_H0] = math_floor(config_raw.layout[layout_size_t.SIDEBAR_H0] * ratio_h); config_raw.layout[layout_size_t.SIDEBAR_H1] = sys_height() - config_raw.layout[layout_size_t.SIDEBAR_H0]; ///end @@ -465,16 +465,16 @@ function base_resize() { context_raw.ddirty = 2; - if (UIBase.show) { + if (ui_base_show) { ///if (is_paint || is_sculpt) - base_appx = UIToolbar.toolbar_w; + base_appx = ui_toolbar_w; ///end ///if is_lab base_appx = 0; ///end - base_appy = UIHeader.headerh * 2; + base_appy = ui_header_h * 2; if (config_raw.layout[layout_size_t.HEADER] == 0) { - base_appy -= UIHeader.headerh; + base_appy -= ui_header_h; } } else { @@ -482,31 +482,31 @@ function base_resize() { base_appy = 0; } - if (UINodes.grid != null) { - let _grid: image_t = UINodes.grid; + if (ui_nodes_grid != null) { + let _grid: image_t = ui_nodes_grid; let _next = function() { image_unload(_grid); } base_notify_on_next_frame(_next); - UINodes.grid = null; + ui_nodes_grid = null; } base_redraw_ui(); } function base_redraw_ui() { - UIHeader.header_handle.redraws = 2; - UIBase.hwnds[tab_area_t.STATUS].redraws = 2; - UIMenubar.menu_handle.redraws = 2; - UIMenubar.workspace_handle.redraws = 2; - UINodes.hwnd.redraws = 2; - UIBox.hwnd.redraws = 2; - UIView2D.hwnd.redraws = 2; + ui_header_handle.redraws = 2; + ui_base_hwnds[tab_area_t.STATUS].redraws = 2; + ui_menubar_menu_handle.redraws = 2; + ui_menubar_workspace_handle.redraws = 2; + ui_nodes_hwnd.redraws = 2; + ui_box_hwnd.redraws = 2; + ui_view2d_hwnd.redraws = 2; if (context_raw.ddirty < 0) context_raw.ddirty = 0; // Redraw viewport ///if (is_paint || is_sculpt) - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; - UIToolbar.toolbar_handle.redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; + ui_toolbar_handle.redraws = 2; if (context_raw.split_view) context_raw.ddirty = 1; ///end } @@ -533,7 +533,7 @@ function base_update() { if (mouse_released()) { base_drag_start = 0; } - let moved: bool = Math.abs(mouse_movement_x) > 1 && Math.abs(mouse_movement_y) > 1; + let moved: bool = math_abs(mouse_movement_x) > 1 && math_abs(mouse_movement_y) > 1; if ((mouse_released() || moved) && !has_drag) { base_drag_asset = null; base_drag_swatch = null; @@ -555,7 +555,7 @@ function base_update() { if (mouse_released() && has_drag) { if (base_drag_asset != null) { if (context_in_nodes()) { // Create image texture - UINodes.accept_asset_drag(project_assets.indexOf(base_drag_asset)); + ui_nodes_accept_asset_drag(project_assets.indexOf(base_drag_asset)); } else if (context_in_viewport()) { if (base_drag_asset.file.toLowerCase().endsWith(".hdr")) { @@ -572,7 +572,7 @@ function base_update() { } else if (base_drag_swatch != null) { if (context_in_nodes()) { // Create RGB node - UINodes.accept_swatch_drag(base_drag_swatch); + ui_nodes_accept_swatch_drag(base_drag_swatch); } else if (context_in_swatches()) { TabSwatches.accept_swatch_drag(base_drag_swatch); @@ -624,7 +624,7 @@ function base_update() { } else if (base_drag_layer != null) { if (context_in_nodes()) { - UINodes.accept_layer_drag(project_layers.indexOf(base_drag_layer)); + ui_nodes_accept_layer_drag(project_layers.indexOf(base_drag_layer)); } else if (context_in_layers() && base_is_dragging) { SlotLayer.move(base_drag_layer, context_raw.drag_dest); @@ -649,12 +649,12 @@ function base_update() { let is_picker: bool = context_raw.tool == workspace_tool_t.PICKER || context_raw.tool == workspace_tool_t.MATERIAL; let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; zui_set_always_redraw_window(!context_raw.cache_draws || - UIMenu.show || - UIBox.show || + ui_menu_show || + ui_box_show || base_is_dragging || is_picker || decal || - UIView2D.show || + ui_view2d_show || !config_raw.brush_3d || context_raw.frame < 3); ///end @@ -668,16 +668,16 @@ function base_material_dropped() { // Material drag and dropped onto viewport or layers tab if (context_in_viewport()) { let uv_type: uv_type_t = keyboard_down("control") ? uv_type_t.PROJECT : uv_type_t.UVMAP; - let decal_mat: mat4_t = uv_type == uv_type_t.PROJECT ? UtilRender.get_decal_mat() : null; + let decal_mat: mat4_t = uv_type == uv_type_t.PROJECT ? util_render_get_decal_mat() : null; base_create_fill_layer(uv_type, decal_mat); } if (context_in_layers() && TabLayers.can_drop_new_layer(context_raw.drag_dest)) { let uv_type: uv_type_t = keyboard_down("control") ? uv_type_t.PROJECT : uv_type_t.UVMAP; - let decal_mat: mat4_t = uv_type == uv_type_t.PROJECT ? UtilRender.get_decal_mat() : null; + let decal_mat: mat4_t = uv_type == uv_type_t.PROJECT ? util_render_get_decal_mat() : null; base_create_fill_layer(uv_type, decal_mat, context_raw.drag_dest); } else if (context_in_nodes()) { - UINodes.accept_material_drag(project_materials.indexOf(base_drag_material)); + ui_nodes_accept_material_drag(project_materials.indexOf(base_drag_material)); } base_drag_material = null; } @@ -725,7 +725,7 @@ function base_get_drag_image(): image_t { if (base_drag_file_icon != null) return base_drag_file_icon; let icons: image_t = resource_get("icons.k"); base_drag_rect = base_drag_file.indexOf(".") > 0 ? resource_tile50(icons, 3, 1) : resource_tile50(icons, 2, 1); - base_drag_tint = UIBase.ui.t.HIGHLIGHT_COL; + base_drag_tint = ui_base_ui.t.HIGHLIGHT_COL; return icons; } @@ -738,7 +738,7 @@ function base_get_drag_image(): image_t { let folder_closed: rect_t = resource_tile50(icons, 2, 1); let folder_open: rect_t = resource_tile50(icons, 8, 1); base_drag_rect = base_drag_layer.show_panel ? folder_open : folder_closed; - base_drag_tint = UIBase.ui.t.LABEL_COL - 0x00202020; + base_drag_tint = ui_base_ui.t.LABEL_COL - 0x00202020; return icons; } if (base_drag_layer != null && SlotLayer.is_mask(base_drag_layer) && base_drag_layer.fill_layer == null) { @@ -758,8 +758,8 @@ function base_render() { if (context_raw.frame == 2) { ///if (is_paint || is_sculpt) - UtilRender.make_material_preview(); - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; + util_render_make_material_preview(); + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; ///end MakeMaterial.parse_mesh_material(); @@ -778,9 +778,9 @@ function base_render() { // Default workspace if (config_raw.workspace != 0) { - UIHeader.worktab.position = config_raw.workspace; - UIMenubar.workspace_handle.redraws = 2; - UIHeader.worktab.changed = true; + ui_header_worktab.position = config_raw.workspace; + ui_menubar_workspace_handle.redraws = 2; + ui_header_worktab.changed = true; } // Default camera controls @@ -813,7 +813,7 @@ function base_render() { let img: image_t = base_get_drag_image(); ///if (is_paint || is_sculpt) - let scale_factor: f32 = zui_SCALE(UIBase.ui); + let scale_factor: f32 = zui_SCALE(ui_base_ui); ///end ///if is_lab let scale_factor: f32 = zui_SCALE(base_ui_box); @@ -844,10 +844,10 @@ function base_render() { g2_set_color(0xffffffff); } - let using_menu: bool = UIMenu.show && mouse_y > UIHeader.headerh; - base_ui_enabled = !UIBox.show && !using_menu && !base_is_combo_selected(); - if (UIBox.show) UIBox.render(); - if (UIMenu.show) UIMenu.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(); // Save last pos for continuos paint context_raw.last_paint_vec_x = context_raw.paint_vec.x; @@ -935,7 +935,7 @@ function base_is_combo_selected(): bool { } function base_get_uis(): zui_t[] { - return [base_ui_box, base_ui_menu, UIBase.ui, UINodes.ui, UIView2D.ui]; + return [base_ui_box, base_ui_menu, ui_base_ui, ui_nodes_ui, ui_view2d_ui]; } function base_is_decal_layer(): bool { @@ -950,37 +950,37 @@ function base_is_decal_layer(): bool { } function base_redraw_status() { - UIBase.hwnds[tab_area_t.STATUS].redraws = 2; + ui_base_hwnds[tab_area_t.STATUS].redraws = 2; } function base_redraw_console() { let statush: i32 = config_raw.layout[layout_size_t.STATUS_H]; - if (UIBase.ui != null && statush > UIStatus.default_status_h * zui_SCALE(UIBase.ui)) { - UIBase.hwnds[tab_area_t.STATUS].redraws = 2; + if (ui_base_ui != null && statush > ui_status_default_status_h * zui_SCALE(ui_base_ui)) { + ui_base_hwnds[tab_area_t.STATUS].redraws = 2; } } function base_init_layout() { - let show2d: bool = (UINodes != null && UINodes.show) || (UIView2D != null && UIView2D.show); + let show2d: bool = ui_nodes_show || ui_view2d_show; let raw: config_t = config_raw; raw.layout = [ ///if (is_paint || is_sculpt) - Math.floor(UIBase.default_sidebar_w * raw.window_scale), // LayoutSidebarW - Math.floor(sys_height() / 2), // LayoutSidebarH0 - Math.floor(sys_height() / 2), // LayoutSidebarH1 + math_floor(ui_base_default_sidebar_w * raw.window_scale), // LayoutSidebarW + math_floor(sys_height() / 2), // LayoutSidebarH0 + math_floor(sys_height() / 2), // LayoutSidebarH1 ///end ///if krom_ios - show2d ? Math.floor((app_w() + raw.layout[layout_size_t.NODES_W]) * 0.473) : Math.floor(app_w() * 0.473), // LayoutNodesW + 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), + 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 + 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(UIStatus.default_status_h * raw.window_scale), // LayoutStatusH + math_floor(app_h() / 2), // LayoutNodesH + math_floor(ui_status_default_status_h * raw.window_scale), // LayoutStatusH ///if (krom_android || krom_ios) 0, // LayoutHeader @@ -1109,7 +1109,7 @@ function base_init_layers() { ///if (is_paint || is_sculpt) function base_resize_layers() { let conf: config_t = config_raw; - if (base_res_handle.position >= Math.floor(texture_res_t.RES16384)) { // Save memory for >=16k + if (base_res_handle.position >= math_floor(texture_res_t.RES16384)) { // Save memory for >=16k conf.undo_steps = 1; if (context_raw.undo_handle != null) { context_raw.undo_handle.value = conf.undo_steps; @@ -1144,8 +1144,8 @@ function base_resize_layers() { base_notify_on_next_frame(function() { image_unload(_texpaint_blur); }); - let size_x: f32 = Math.floor(config_get_texture_res_x() * 0.95); - let size_y: f32 = Math.floor(config_get_texture_res_y() * 0.95); + let size_x: f32 = math_floor(config_get_texture_res_x() * 0.95); + let size_y: f32 = math_floor(config_get_texture_res_y() * 0.95); rts.get("texpaint_blur").width = size_x; rts.get("texpaint_blur").height = size_y; rts.get("texpaint_blur")._image = image_create_render_target(size_x, size_y); @@ -2038,7 +2038,8 @@ function base_update_fill_layers() { function base_update_fill_layer(parse_paint: bool = true) { let current: image_t = _g2_current; - if (current != null) g2_end(); + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); let _tool: workspace_tool_t = context_raw.tool; let _fill_type: i32 = context_raw.fill_type_handle.position; @@ -2055,7 +2056,7 @@ function base_update_fill_layer(parse_paint: bool = true) { context_raw.rdirty = 2; context_raw.tool = _tool; context_raw.fill_type_handle.position = _fill_type; - if (current != null) g2_begin(current); + if (g2_in_use) g2_begin(current); } function base_set_object_mask() { @@ -2085,13 +2086,13 @@ function base_set_object_mask() { let is_atlas: bool = SlotLayer.get_object_mask(context_raw.layer) > 0 && SlotLayer.get_object_mask(context_raw.layer) <= project_paint_objects.length; if (context_raw.merged_object == null || is_atlas || context_raw.merged_object_is_atlas) { let visibles: mesh_object_t[] = is_atlas ? project_get_atlas_objects(SlotLayer.get_object_mask(context_raw.layer)) : null; - UtilMesh.merge_mesh(visibles); + util_mesh_merge(visibles); } context_select_paint_object(context_main_object()); context_raw.paint_object.skip_context = "paint"; context_raw.merged_object.base.visible = true; } - UtilUV.dilatemap_cached = false; + util_uv_dilatemap_cached = false; } function base_new_layer(clear: bool = true, position: i32 = -1): SlotLayerRaw { @@ -2190,11 +2191,11 @@ function base_on_layers_resized() { context_raw.material = _material; MakeMaterial.parse_paint_material(); }); - UtilUV.uvmap = null; - UtilUV.uvmap_cached = false; - UtilUV.trianglemap = null; - UtilUV.trianglemap_cached = false; - UtilUV.dilatemap_cached = false; + util_uv_uvmap = null; + util_uv_uvmap_cached = false; + util_uv_trianglemap = null; + util_uv_trianglemap_cached = false; + util_uv_dilatemap_cached = false; ///if (krom_direct3d12 || krom_vulkan || krom_metal) RenderPathRaytrace.ready = false; ///end @@ -2207,8 +2208,8 @@ function base_flatten(heightToNormal: bool = false): any { let texpaint_nor: image_t = BrushOutputNode.inst.texpaint_nor; let texpaint_pack: image_t = BrushOutputNode.inst.texpaint_pack; - let nodes: zui_nodes_t = UINodes.get_nodes(); - let canvas: zui_node_canvas_t = UINodes.get_canvas(true); + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + let canvas: zui_node_canvas_t = ui_nodes_get_canvas(true); if (nodes.nodes_selected_id.length > 0) { let node: zui_node_t = zui_get_node(canvas.nodes, nodes.nodes_selected_id[0]); let brush_node: LogicNode = ParserLogic.get_logic_node(node); diff --git a/base/Sources/camera.ts b/base/Sources/camera.ts index 83ec671b..fe4779e9 100644 --- a/base/Sources/camera.ts +++ b/base/Sources/camera.ts @@ -21,19 +21,19 @@ function camera_update() { if (config_raw.wrap_mouse && camera_controls_down) { if (mouse_view_x() < 0) { mouse_x = mouse_last_x = app_x() + app_w(); - krom_set_mouse_position(Math.floor(mouse_x), Math.floor(mouse_y)); + krom_set_mouse_position(math_floor(mouse_x), math_floor(mouse_y)); } else if (mouse_view_x() > app_w()) { mouse_x = mouse_last_x = app_x(); - krom_set_mouse_position(Math.floor(mouse_x), Math.floor(mouse_y)); + krom_set_mouse_position(math_floor(mouse_x), math_floor(mouse_y)); } else if (mouse_view_y() < 0) { mouse_y = mouse_last_y = app_y() + app_h(); - krom_set_mouse_position(Math.floor(mouse_x), Math.floor(mouse_y)); + krom_set_mouse_position(math_floor(mouse_x), math_floor(mouse_y)); } else if (mouse_view_y() > app_h()) { mouse_y = mouse_last_y = app_y(); - krom_set_mouse_position(Math.floor(mouse_x), Math.floor(mouse_y)); + krom_set_mouse_position(math_floor(mouse_x), math_floor(mouse_y)); } } else { @@ -121,7 +121,7 @@ function camera_update() { let strafe_down: bool = keyboard_down("q"); let fast: f32 = keyboard_down("shift") ? 2.0 : (keyboard_down("alt") ? 0.5 : 1.0); if (mouse_wheel_delta != 0) { - fast *= Math.abs(mouse_wheel_delta) * 4.0; + fast *= math_abs(mouse_wheel_delta) * 4.0; } if (move_forward || move_backward || strafe_right || strafe_left || strafe_up || strafe_down) { @@ -157,7 +157,7 @@ function camera_update() { if (operator_shortcut(config_keymap.rotate_light, shortcut_type_t.DOWN)) { camera_redraws = 2; let light: light_object_t = scene_lights[0]; - context_raw.light_angle = (context_raw.light_angle + ((mouse_movement_x / 100) % (2 * Math.PI) + 2 * Math.PI)) % (2 * Math.PI); + context_raw.light_angle = (context_raw.light_angle + ((mouse_movement_x / 100) % (2 * math_pi()) + 2 * math_pi())) % (2 * math_pi()); let m: mat4_t = mat4_rot_z(mouse_movement_x / 100); mat4_mult_mat(light.base.transform.local, m); transform_decompose(light.base.transform); diff --git a/base/Sources/config.ts b/base/Sources/config.ts index 9f93ac9c..afa69f69 100644 --- a/base/Sources/config.ts +++ b/base/Sources/config.ts @@ -10,7 +10,7 @@ function config_load(done: ()=>void) { try { let blob: ArrayBuffer = data_get_blob((path_is_protected() ? krom_save_path() : "") + "config.json"); config_loaded = true; - config_raw = JSON.parse(sys_buffer_to_string(blob)); + config_raw = json_parse(sys_buffer_to_string(blob)); done(); } catch (e: any) { @@ -18,7 +18,7 @@ function config_load(done: ()=>void) { try { // Protected directory let blob: ArrayBuffer = data_get_blob(krom_save_path() + "config.json"); config_loaded = true; - config_raw = JSON.parse(sys_buffer_to_string(blob)); + config_raw = json_parse(sys_buffer_to_string(blob)); done(); } catch (e: any) { @@ -35,7 +35,7 @@ function config_save() { // Use system application data folder // when running from protected path like "Program Files" let path: string = (path_is_protected() ? krom_save_path() : path_data() + path_sep) + "config.json"; - let buffer: buffer_t = sys_string_to_buffer(JSON.stringify(config_raw)); + let buffer: buffer_t = sys_string_to_buffer(json_stringify(config_raw)); krom_file_save_bytes(path, buffer); ///if krom_linux // Protected directory @@ -107,14 +107,14 @@ function config_init() { function config_get_sha(): string { let sha: string = ""; let blob: ArrayBuffer = data_get_blob("version.json"); - sha = JSON.parse(sys_buffer_to_string(blob)).sha; + sha = json_parse(sys_buffer_to_string(blob)).sha; return sha; } function config_get_date(): string { let date: string = ""; let blob: ArrayBuffer = data_get_blob("version.json"); - date = JSON.parse(sys_buffer_to_string(blob)).date; + date = json_parse(sys_buffer_to_string(blob)).date; return date; } @@ -139,7 +139,7 @@ function config_get_options(): kinc_sys_ops_t { } function config_restore() { - zui_children = new Map(); // Reset ui handles + zui_children = map_create(); // Reset ui handles config_loaded = false; let _layout: i32[] = config_raw.layout; config_init(); @@ -156,7 +156,7 @@ function config_import_from(from: config_t) { config_raw = from; config_raw.sha = _sha; config_raw.version = _version; - zui_children = new Map(); // Reset ui handles + zui_children = map_create(); // Reset ui handles config_load_keymap(); base_init_layout(); translator_load_translations(config_raw.locale); @@ -174,9 +174,10 @@ function config_apply() { context_raw.ddirty = 2; let current: image_t = _g2_current; - if (current != null) g2_end(); + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); RenderPathBase.apply_config(); - if (current != null) g2_begin(current); + if (g2_in_use) g2_begin(current); } function config_load_keymap() { @@ -185,7 +186,7 @@ function config_load_keymap() { } else { let blob: ArrayBuffer = data_get_blob("keymap_presets/" + config_raw.keymap); - config_keymap = JSON.parse(sys_buffer_to_string(blob)); + config_keymap = json_parse(sys_buffer_to_string(blob)); // Fill in undefined keys with defaults for (let field in base_default_keymap) { if (!(field in config_keymap)) { @@ -199,7 +200,7 @@ function config_load_keymap() { function config_save_keymap() { if (config_raw.keymap == "default.json") return; let path: string = data_path() + "keymap_presets/" + config_raw.keymap; - let buffer: buffer_t = sys_string_to_buffer(JSON.stringify(config_keymap)); + let buffer: buffer_t = sys_string_to_buffer(json_stringify(config_keymap)); krom_file_save_bytes(path, buffer); } @@ -232,11 +233,11 @@ function config_get_texture_res(): i32 { } function config_get_texture_res_x(): i32 { - return context_raw.project_aspect_ratio == 2 ? Math.floor(config_get_texture_res() / 2) : config_get_texture_res(); + return context_raw.project_aspect_ratio == 2 ? math_floor(config_get_texture_res() / 2) : config_get_texture_res(); } function config_get_texture_res_y(): i32 { - return context_raw.project_aspect_ratio == 1 ? Math.floor(config_get_texture_res() / 2) : config_get_texture_res(); + return context_raw.project_aspect_ratio == 1 ? math_floor(config_get_texture_res() / 2) : config_get_texture_res(); } function config_get_texture_res_pos(i: i32): i32 { @@ -256,7 +257,7 @@ function config_load_theme(theme: string, tagRedraw: bool = true) { } else { let b: ArrayBuffer = data_get_blob("themes/" + theme); - let parsed: any = JSON.parse(sys_buffer_to_string(b)); + let parsed: any = json_parse(sys_buffer_to_string(b)); base_theme = zui_theme_create(); for (let key in base_theme) { if (key == "theme_") continue; @@ -269,7 +270,7 @@ function config_load_theme(theme: string, tagRedraw: bool = true) { base_theme.FILL_WINDOW_BG = true; if (tagRedraw) { for (let ui of base_get_uis()) ui.t = base_theme; - UIBase.tag_ui_redraw(); + ui_base_tag_ui_redraw(); } if (config_raw.touch_ui) { // Enlarge elements diff --git a/base/Sources/console.ts b/base/Sources/console.ts index 256fd87b..d2e08e02 100644 --- a/base/Sources/console.ts +++ b/base/Sources/console.ts @@ -13,7 +13,7 @@ function console_draw_toast(s: string) { let y: f32 = sys_height() - 200 * scale; g2_fill_rect(x - 200 * scale, y, 400 * scale, 80 * scale); g2_set_font(base_font); - g2_set_font_size(Math.floor(22 * scale)); + g2_set_font_size(math_floor(22 * scale)); g2_set_color(0xffffffff); g2_draw_string(s, x - g2_font_width(_g2_font, _g2_font_size, s) / 2, y + 40 * scale - g2_font_height(_g2_font, _g2_font_size) / 2); } diff --git a/base/Sources/context.ts b/base/Sources/context.ts index 89a27062..088aa4aa 100644 --- a/base/Sources/context.ts +++ b/base/Sources/context.ts @@ -22,15 +22,15 @@ function context_set_material(m: SlotMaterialRaw) { if (project_materials.indexOf(m) == -1) return; context_raw.material = m; MakeMaterial.parse_paint_material(); - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; - UIHeader.header_handle.redraws = 2; - UINodes.hwnd.redraws = 2; - UINodes.group_stack = []; + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; + ui_header_handle.redraws = 2; + ui_nodes_hwnd.redraws = 2; + ui_nodes_group_stack = []; let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; if (decal) { let _next = function() { - UtilRender.make_decal_preview(); + util_render_make_decal_preview(); } base_notify_on_next_frame(_next); } @@ -45,8 +45,8 @@ function context_set_brush(b: SlotBrushRaw) { if (project_brushes.indexOf(b) == -1) return; context_raw.brush = b; MakeMaterial.parse_brush(); - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; - UINodes.hwnd.redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; + ui_nodes_hwnd.redraws = 2; } function context_select_font(i: i32) { @@ -57,10 +57,10 @@ function context_select_font(i: i32) { function context_set_font(f: SlotFontRaw) { if (project_fonts.indexOf(f) == -1) return; context_raw.font = f; - UtilRender.make_text_preview(); - UtilRender.make_decal_preview(); - UIBase.hwnds[tab_area_t.STATUS].redraws = 2; - UIView2D.hwnd.redraws = 2; + util_render_make_text_preview(); + util_render_make_decal_preview(); + ui_base_hwnds[tab_area_t.STATUS].redraws = 2; + ui_view2d_hwnd.redraws = 2; } function context_select_layer(i: i32) { @@ -71,19 +71,20 @@ function context_select_layer(i: i32) { function context_set_layer(l: SlotLayerRaw) { if (l == context_raw.layer) return; context_raw.layer = l; - UIHeader.header_handle.redraws = 2; + ui_header_handle.redraws = 2; let current: image_t = _g2_current; - if (current != null) g2_end(); + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); base_set_object_mask(); MakeMaterial.parse_mesh_material(); MakeMaterial.parse_paint_material(); - if (current != null) g2_begin(current); + if (g2_in_use) g2_begin(current); - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - UIView2D.hwnd.redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + ui_view2d_hwnd.redraws = 2; } ///end @@ -98,8 +99,8 @@ function context_select_tool(i: i32) { ///if (is_paint || is_sculpt) context_init_tool(); - UIHeader.header_handle.redraws = 2; - UIToolbar.toolbar_handle.redraws = 2; + ui_header_handle.redraws = 2; + ui_toolbar_handle.redraws = 2; ///end } @@ -108,13 +109,13 @@ function context_init_tool() { let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; if (decal) { if (context_raw.tool == workspace_tool_t.TEXT) { - UtilRender.make_text_preview(); + util_render_make_text_preview(); } - UtilRender.make_decal_preview(); + util_render_make_decal_preview(); } else if (context_raw.tool == workspace_tool_t.PARTICLE) { - UtilParticle.init_particle(); + util_particle_init(); MakeMaterial.parse_particle_material(); } @@ -141,7 +142,7 @@ function context_init_tool() { function context_select_paint_object(o: mesh_object_t) { ///if (is_paint || is_sculpt) - UIHeader.header_handle.redraws = 2; + ui_header_handle.redraws = 2; for (let p of project_paint_objects) p.skip_context = "paint"; context_raw.paint_object = o; @@ -151,9 +152,9 @@ function context_select_paint_object(o: mesh_object_t) { if (context_raw.merged_object == null || mask > 0) { context_raw.paint_object.skip_context = ""; } - UtilUV.uvmap_cached = false; - UtilUV.trianglemap_cached = false; - UtilUV.dilatemap_cached = false; + util_uv_uvmap_cached = false; + util_uv_trianglemap_cached = false; + util_uv_dilatemap_cached = false; ///end ///if is_lab @@ -200,7 +201,7 @@ function context_in_viewport(): bool { function context_in_paint_area(): bool { ///if (is_paint || is_sculpt) let right: i32 = app_w(); - if (UIView2D.show) right += UIView2D.ww; + if (ui_view2d_show) right += ui_view2d_ww; return mouse_view_x() > 0 && mouse_view_x() < right && mouse_view_y() > 0 && mouse_view_y() < app_h(); ///end @@ -220,16 +221,16 @@ function context_in_materials(): bool { ///if (is_paint || is_sculpt) function context_in_2d_view(type: view_2d_type_t = view_2d_type_t.LAYER): bool { - return UIView2D.show && UIView2D.type == type && - mouse_x > UIView2D.wx && mouse_x < UIView2D.wx + UIView2D.ww && - mouse_y > UIView2D.wy && mouse_y < UIView2D.wy + UIView2D.wh; + return ui_view2d_show && ui_view2d_type == type && + mouse_x > ui_view2d_wx && mouse_x < ui_view2d_wx + ui_view2d_ww && + mouse_y > ui_view2d_wy && mouse_y < ui_view2d_wy + ui_view2d_wh; } ///end function context_in_nodes(): bool { - return UINodes.show && - mouse_x > UINodes.wx && mouse_x < UINodes.wx + UINodes.ww && - mouse_y > UINodes.wy && mouse_y < UINodes.wy + UINodes.wh; + return ui_nodes_show && + mouse_x > ui_nodes_wx && mouse_x < ui_nodes_wx + ui_nodes_ww && + mouse_y > ui_nodes_wy && mouse_y < ui_nodes_wy + ui_nodes_wh; } function context_in_swatches(): bool { @@ -262,10 +263,10 @@ function context_set_viewport_mode(mode: viewport_mode_t) { else { render_path_commands = RenderPathForward.commands; } - let _workspace: i32 = UIHeader.worktab.position; - UIHeader.worktab.position = 0; + let _workspace: i32 = ui_header_worktab.position; + ui_header_worktab.position = 0; MakeMaterial.parse_mesh_material(); - UIHeader.worktab.position = _workspace; + ui_header_worktab.position = _workspace; } function context_load_envmap() { @@ -335,8 +336,8 @@ function context_run_brush(from: i32) { context_raw.last_paint_vec_y = context_raw.paint_vec.y; } - let nodes: zui_nodes_t = UINodes.get_nodes(); - let canvas: zui_node_canvas_t = UINodes.get_canvas(true); + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + let canvas: zui_node_canvas_t = ui_nodes_get_canvas(true); let inpaint: bool = nodes.nodes_selected_id.length > 0 && zui_get_node(canvas.nodes, nodes.nodes_selected_id[0]).type == "InpaintNode"; // Paint bounds @@ -409,8 +410,8 @@ function context_update() { context_raw.coords.y = paint_y; if (context_raw.lock_begin) { - let dx: i32 = Math.abs(context_raw.lock_start_x - mouse_view_x()); - let dy: i32 = Math.abs(context_raw.lock_start_y - mouse_view_y()); + let dx: i32 = math_abs(context_raw.lock_start_x - mouse_view_x()); + let dy: i32 = math_abs(context_raw.lock_start_y - mouse_view_y()); if (dx > 1 || dy > 1) { context_raw.lock_begin = false; dx > dy ? context_raw.lock_y = true : context_raw.lock_x = true; diff --git a/base/Sources/file.ts b/base/Sources/file.ts index 019edfd3..d68afd43 100644 --- a/base/Sources/file.ts +++ b/base/Sources/file.ts @@ -7,11 +7,11 @@ let file_cmd_mkdir: string = "mkdir -p"; let file_cmd_copy: string = "cp"; ///end -let file_cloud: Map = null; -let file_cloud_sizes: Map = null; +let file_cloud: map_t = null; +let file_cloud_sizes: map_t = null; // ///if krom_android -// let let file_internal: Map = null; // .apk contents +// let let file_internal: map_t = null; // .apk contents // ///end function file_read_directory(path: string, folders_only: bool = false): string[] { @@ -190,7 +190,7 @@ function file_init_cloud_bytes(done: ()=>void, append: string = "") { } function file_init_cloud(done: ()=>void) { - file_cloud = new Map(); - file_cloud_sizes = new Map(); + file_cloud = map_create(); + file_cloud_sizes = map_create(); file_init_cloud_bytes(done); } diff --git a/base/Sources/geom.ts b/base/Sources/geom.ts index d40da99d..0719d9da 100644 --- a/base/Sources/geom.ts +++ b/base/Sources/geom.ts @@ -10,7 +10,7 @@ function geom_make_plane(size_x: f32 = 1.0, size_y: f32 = 1.0, verts_x: i32 = 2, // Pack positions to (-1, 1) range let half_x: f32 = size_x / 2; let half_y: f32 = size_y / 2; - mesh.scale_pos = Math.max(half_x, half_y); + mesh.scale_pos = math_max(half_x, half_y); let inv: f32 = (1 / mesh.scale_pos) * 32767; mesh.posa = new Int16Array(verts_x * verts_y * 4); @@ -21,21 +21,21 @@ function geom_make_plane(size_x: f32 = 1.0, size_y: f32 = 1.0, verts_x: i32 = 2, let step_y: f32 = size_y / (verts_y - 1); for (let i: i32 = 0; i < verts_x * verts_y; ++i) { let x: f32 = (i % verts_x) * step_x - half_x; - let y: f32 = Math.floor(i / verts_x) * step_y - half_y; - mesh.posa[i * 4 ] = Math.floor(x * inv); - mesh.posa[i * 4 + 1] = Math.floor(y * inv); + let y: f32 = math_floor(i / verts_x) * step_y - half_y; + mesh.posa[i * 4 ] = math_floor(x * inv); + mesh.posa[i * 4 + 1] = math_floor(y * inv); mesh.posa[i * 4 + 2] = 0; mesh.nora[i * 2 ] = 0; mesh.nora[i * 2 + 1] = 0; mesh.posa[i * 4 + 3] = 32767; x = (i % verts_x) / (verts_x - 1); - y = 1.0 - Math.floor(i / verts_x) / (verts_y - 1); - mesh.texa[i * 2 ] = (Math.floor(x * 32767 * uv_scale) - 1) % 32767; - mesh.texa[i * 2 + 1] = (Math.floor(y * 32767 * uv_scale) - 1) % 32767; + y = 1.0 - math_floor(i / verts_x) / (verts_y - 1); + mesh.texa[i * 2 ] = (math_floor(x * 32767 * uv_scale) - 1) % 32767; + mesh.texa[i * 2 + 1] = (math_floor(y * 32767 * uv_scale) - 1) % 32767; } for (let i: i32 = 0; i < (verts_x - 1) * (verts_y - 1); ++i) { let x: f32 = i % (verts_x - 1); - let y: f32 = Math.floor(i / (verts_y - 1)); + let y: f32 = math_floor(i / (verts_y - 1)); mesh.inda[i * 6 ] = y * verts_x + x; mesh.inda[i * 6 + 1] = y * verts_x + x + 1; mesh.inda[i * 6 + 2] = (y + 1) * verts_x + x; @@ -59,7 +59,7 @@ function geom_make_uv_sphere(radius: f32 = 1.0, widthSegments: i32 = 32, heightS mesh.scale_pos = radius; mesh.scale_tex = uvScale; let inv: f32 = (1 / mesh.scale_pos) * 32767; - let pi2: f32 = Math.PI * 2; + let pi2: f32 = math_pi() * 2; let width_verts: i32 = widthSegments + 1; let height_verts: i32 = heightSegments + 1; @@ -78,22 +78,22 @@ function geom_make_uv_sphere(radius: f32 = 1.0, widthSegments: i32 = 32, heightS for (let x: i32 = 0; x < width_verts; ++x) { let u: f32 = x / widthSegments; let u_pi2: f32 = u * pi2; - let v_pi: f32 = v * Math.PI; - let v_pi_sin: f32 = Math.sin(v_pi); - let vx: f32 = -radius * Math.cos(u_pi2) * v_pi_sin; - let vy: f32 = radius * Math.sin(u_pi2) * v_pi_sin; - let vz: f32 = -radius * Math.cos(v_pi); + let v_pi: f32 = v * math_pi(); + let v_pi_sin: f32 = math_sin(v_pi); + let vx: f32 = -radius * math_cos(u_pi2) * v_pi_sin; + let vy: f32 = radius * math_sin(u_pi2) * v_pi_sin; + let vz: f32 = -radius * math_cos(v_pi); let i4: i32 = pos * 4; let i2: i32 = pos * 2; - mesh.posa[i4 ] = Math.floor(vx * inv); - mesh.posa[i4 + 1] = Math.floor(vy * inv); - mesh.posa[i4 + 2] = Math.floor(vz * inv); + mesh.posa[i4 ] = math_floor(vx * inv); + mesh.posa[i4 + 1] = math_floor(vy * inv); + mesh.posa[i4 + 2] = math_floor(vz * inv); vec4_normalize(vec4_set(nor, vx, vy, vz)); - mesh.posa[i4 + 3] = Math.floor(nor.z * 32767); - mesh.nora[i2 ] = Math.floor(nor.x * 32767); - mesh.nora[i2 + 1] = Math.floor(nor.y * 32767); - mesh.texa[i2 ] = (Math.floor((u + u_off) * 32767) - 1) % 32767; - mesh.texa[i2 + 1] = (Math.floor(v_flip * 32767) - 1) % 32767; + mesh.posa[i4 + 3] = math_floor(nor.z * 32767); + mesh.nora[i2 ] = math_floor(nor.x * 32767); + mesh.nora[i2 + 1] = math_floor(nor.y * 32767); + mesh.texa[i2 ] = (math_floor((u + u_off) * 32767) - 1) % 32767; + mesh.texa[i2 + 1] = (math_floor(v_flip * 32767) - 1) % 32767; pos++; } } diff --git a/base/Sources/gizmo.ts b/base/Sources/gizmo.ts index 636d8bcf..7202852b 100644 --- a/base/Sources/gizmo.ts +++ b/base/Sources/gizmo.ts @@ -225,9 +225,9 @@ function gizmo_update() { if (hit != null) { if (context_raw.gizmo_started) { mat4_decompose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0); - context_raw.gizmo_offset = Math.atan2(hit.y - gizmo_v.y, hit.z - gizmo_v.z); + context_raw.gizmo_offset = math_atan2(hit.y - gizmo_v.y, hit.z - gizmo_v.z); } - context_raw.gizmo_drag = Math.atan2(hit.y - gizmo_v.y, hit.z - gizmo_v.z) - context_raw.gizmo_offset; + context_raw.gizmo_drag = math_atan2(hit.y - gizmo_v.y, hit.z - gizmo_v.z) - context_raw.gizmo_offset; } } else if (context_raw.rotate_y) { @@ -235,9 +235,9 @@ function gizmo_update() { if (hit != null) { if (context_raw.gizmo_started) { mat4_decompose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0); - context_raw.gizmo_offset = Math.atan2(hit.z - gizmo_v.z, hit.x - gizmo_v.x); + context_raw.gizmo_offset = math_atan2(hit.z - gizmo_v.z, hit.x - gizmo_v.x); } - context_raw.gizmo_drag = Math.atan2(hit.z - gizmo_v.z, hit.x - gizmo_v.x) - context_raw.gizmo_offset; + context_raw.gizmo_drag = math_atan2(hit.z - gizmo_v.z, hit.x - gizmo_v.x) - context_raw.gizmo_offset; } } else if (context_raw.rotate_z) { @@ -245,16 +245,16 @@ function gizmo_update() { if (hit != null) { if (context_raw.gizmo_started) { mat4_decompose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0); - context_raw.gizmo_offset = Math.atan2(hit.y - gizmo_v.y, hit.x - gizmo_v.x); + context_raw.gizmo_offset = math_atan2(hit.y - gizmo_v.y, hit.x - gizmo_v.x); } - context_raw.gizmo_drag = Math.atan2(hit.y - gizmo_v.y, hit.x - gizmo_v.x) - context_raw.gizmo_offset; + context_raw.gizmo_drag = math_atan2(hit.y - gizmo_v.y, hit.x - gizmo_v.x) - context_raw.gizmo_offset; } } if (context_raw.gizmo_started) context_raw.gizmo_drag_last = context_raw.gizmo_drag; ///if is_forge - UtilMesh.remove_merged_mesh(); + util_mesh_remove_merged(); RenderPathRaytrace.ready = false; ///end } diff --git a/base/Sources/history.ts b/base/Sources/history.ts index 7722ce80..fd97bd5d 100644 --- a/base/Sources/history.ts +++ b/base/Sources/history.ts @@ -193,8 +193,8 @@ function history_undo() { context_raw.material = SlotMaterial.create(project_materials[0].data); project_materials.splice(step.material, 0, context_raw.material); context_raw.material.canvas = step.canvas; - UINodes.canvas_changed(); - UINodes.hwnd.redraws = 2; + ui_nodes_canvas_changed(); + ui_nodes_hwnd.redraws = 2; } else if (step.name == tr("Duplicate Material")) { context_raw.material = project_materials[step.material]; @@ -216,15 +216,15 @@ function history_undo() { context_raw.ddirty = 2; ///if (is_paint || is_sculpt) - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; - if (UIView2D.show) { - UIView2D.hwnd.redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; + if (ui_view2d_show) { + ui_view2d_hwnd.redraws = 2; } if (config_raw.touch_ui) { // Refresh undo & redo buttons - UIMenubar.menu_handle.redraws = 2; + ui_menubar_menu_handle.redraws = 2; } ///end } @@ -378,8 +378,8 @@ function history_redo() { context_raw.material = SlotMaterial.create(project_materials[0].data); project_materials.splice(step.material, 0, context_raw.material); context_raw.material.canvas = step.canvas; - UINodes.canvas_changed(); - UINodes.hwnd.redraws = 2; + ui_nodes_canvas_changed(); + ui_nodes_hwnd.redraws = 2; } else if (step.name == tr("Delete Material")) { context_raw.material = project_materials[step.material]; @@ -390,8 +390,8 @@ function history_redo() { context_raw.material = SlotMaterial.create(project_materials[0].data); project_materials.splice(step.material, 0, context_raw.material); context_raw.material.canvas = step.canvas; - UINodes.canvas_changed(); - UINodes.hwnd.redraws = 2; + ui_nodes_canvas_changed(); + ui_nodes_hwnd.redraws = 2; } else { // Paint operation let lay: SlotLayerRaw = history_undo_layers[history_undo_i]; @@ -408,13 +408,13 @@ function history_redo() { context_raw.ddirty = 2; ///if (is_paint || is_sculpt) - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; - if (UIView2D.show) UIView2D.hwnd.redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; + if (ui_view2d_show) ui_view2d_hwnd.redraws = 2; if (config_raw.touch_ui) { // Refresh undo & redo buttons - UIMenubar.menu_handle.redraws = 2; + ui_menubar_menu_handle.redraws = 2; } ///end } @@ -444,7 +444,7 @@ function history_edit_nodes(canvas: zui_node_canvas_t, canvas_group: Null = ///if (is_paint || is_sculpt) step.canvas_type = canvas_type; ///end - step.canvas = JSON.parse(JSON.stringify(canvas)); + step.canvas = json_parse(json_stringify(canvas)); } ///if (is_paint || is_sculpt) @@ -453,7 +453,7 @@ function history_paint() { history_copy_to_undo(context_raw.layer.id, history_undo_i, is_mask); history_push_undo = false; - history_push(tr(UIToolbar.tool_names[context_raw.tool])); + history_push(tr(ui_toolbar_tool_names[context_raw.tool])); } function history_new_layer() { @@ -564,38 +564,38 @@ function history_layer_blending() { function history_new_material() { let step: step_t = history_push(tr("New Material")); step.canvas_type = 0; - step.canvas = JSON.parse(JSON.stringify(context_raw.material.canvas)); + step.canvas = json_parse(json_stringify(context_raw.material.canvas)); } function history_delete_material() { let step: step_t = history_push(tr("Delete Material")); step.canvas_type = 0; - step.canvas = JSON.parse(JSON.stringify(context_raw.material.canvas)); + step.canvas = json_parse(json_stringify(context_raw.material.canvas)); } function history_duplicate_material() { let step: step_t = history_push(tr("Duplicate Material")); step.canvas_type = 0; - step.canvas = JSON.parse(JSON.stringify(context_raw.material.canvas)); + step.canvas = json_parse(json_stringify(context_raw.material.canvas)); } function history_delete_material_group(group: node_group_t) { let step: step_t = history_push(tr("Delete Node Group")); step.canvas_type = canvas_type_t.MATERIAL; step.canvas_group = project_material_groups.indexOf(group); - step.canvas = JSON.parse(JSON.stringify(group.canvas)); + step.canvas = json_parse(json_stringify(group.canvas)); } ///end function history_push(name: string): step_t { ///if (krom_windows || krom_linux || krom_darwin) - let filename: string = project_filepath == "" ? UIFiles.filename : project_filepath.substring(project_filepath.lastIndexOf(path_sep) + 1, project_filepath.length - 4); + let filename: string = project_filepath == "" ? ui_files_filename : project_filepath.substring(project_filepath.lastIndexOf(path_sep) + 1, project_filepath.length - 4); sys_title_set(filename + "* - " + manifest_title); ///end if (config_raw.touch_ui) { // Refresh undo & redo buttons - UIMenubar.menu_handle.redraws = 2; + ui_menubar_menu_handle.redraws = 2; } if (history_undos < config_raw.undo_steps) history_undos++; @@ -716,8 +716,8 @@ function history_swap_canvas(step: step_t) { step.canvas = _canvas; ///end - UINodes.canvas_changed(); - UINodes.hwnd.redraws = 2; + ui_nodes_canvas_changed(); + ui_nodes_hwnd.redraws = 2; } type step_t = { diff --git a/base/Sources/nodes/MathNode.ts b/base/Sources/nodes/MathNode.ts index 8fd6043b..55351adf 100644 --- a/base/Sources/nodes/MathNode.ts +++ b/base/Sources/nodes/MathNode.ts @@ -20,19 +20,19 @@ class MathNode extends LogicNode { f = v1 * v2; break; case "Sine": - f = Math.sin(v1); + f = math_sin(v1); break; case "Cosine": - f = Math.cos(v1); + f = math_cos(v1); break; case "Max": - f = Math.max(v1, v2); + f = math_max(v1, v2); break; case "Min": - f = Math.min(v1, v2); + f = math_min(v1, v2); break; case "Absolute": - f = Math.abs(v1); + f = math_abs(v1); break; case "Subtract": f = v1 - v2; @@ -41,40 +41,40 @@ class MathNode extends LogicNode { f = v1 / (v2 == 0.0 ? 0.000001 : v2); break; case "Tangent": - f = Math.tan(v1); + f = math_tan(v1); break; case "Arcsine": - f = Math.asin(v1); + f = math_asin(v1); break; case "Arccosine": - f = Math.acos(v1); + f = math_acos(v1); break; case "Arctangent": - f = Math.atan(v1); + f = math_atan(v1); break; case "Arctan2": - f = Math.atan2(v2, v1); + f = math_atan2(v2, v1); break; case "Power": - f = Math.pow(v1, v2); + f = math_pow(v1, v2); break; case "Logarithm": - f = Math.log(v1); + f = math_log(v1); break; case "Round": - f = Math.round(v1); + f = math_round(v1); break; case "Floor": - f = Math.floor(v1); + f = math_floor(v1); break; case "Ceil": - f = Math.ceil(v1); + f = math_ceil(v1); break; case "Truncate": - f = Math.floor(v1); + f = math_floor(v1); break; case "Fraction": - f = v1 - Math.floor(v1); + f = v1 - math_floor(v1); break; case "Less Than": f = v1 < v2 ? 1.0 : 0.0; @@ -86,37 +86,37 @@ class MathNode extends LogicNode { f = v1 % v2; break; case "Snap": - f = Math.floor(v1 / v2) * v2; + f = math_floor(v1 / v2) * v2; break; case "Square Root": - f = Math.sqrt(v1); + f = math_sqrt(v1); break; case "Inverse Square Root": - f = 1.0 / Math.sqrt(v1); + f = 1.0 / math_sqrt(v1); break; case "Exponent": - f = Math.exp(v1); + f = math_exp(v1); break; case "Sign": f = v1 > 0 ? 1.0 : (v1 < 0 ? -1.0 : 0); break; case "Ping-Pong": - f = (v2 != 0.0) ? v2 - Math.abs((Math.abs(v1) % (2 * v2)) - v2) : 0.0; + f = (v2 != 0.0) ? v2 - math_abs((math_abs(v1) % (2 * v2)) - v2) : 0.0; break; case "Hyperbolic Sine": - f = (Math.exp(v1) - Math.exp(-v1)) / 2.0; + f = (math_exp(v1) - math_exp(-v1)) / 2.0; break; case "Hyperbolic Cosine": - f = (Math.exp(v1) + Math.exp(-v1)) / 2.0; + f = (math_exp(v1) + math_exp(-v1)) / 2.0; break; case "Hyperbolic Tangent": - f = 1.0 - (2.0 / (Math.exp(2 * v1) + 1)); + f = 1.0 - (2.0 / (math_exp(2 * v1) + 1)); break; case "To Radians": - f = v1 / 180.0 * Math.PI; + f = v1 / 180.0 * math_pi(); break; case "To Degrees": - f = v1 / Math.PI * 180.0; + f = v1 / math_pi() * 180.0; break; } diff --git a/base/Sources/nodes/VectorMathNode.ts b/base/Sources/nodes/VectorMathNode.ts index 8e257be7..e53fd3d8 100644 --- a/base/Sources/nodes/VectorMathNode.ts +++ b/base/Sources/nodes/VectorMathNode.ts @@ -71,34 +71,34 @@ class VectorMathNode extends LogicNode { this.v.z *= v2.x; break; case "Absolute": - this.v.x = Math.abs(this.v.x); - this.v.y = Math.abs(this.v.y); - this.v.z = Math.abs(this.v.z); + this.v.x = math_abs(this.v.x); + this.v.y = math_abs(this.v.y); + this.v.z = math_abs(this.v.z); break; case "Minimum": - this.v.x = Math.min(v1.x, v2.x); - this.v.y = Math.min(v1.y, v2.y); - this.v.z = Math.min(v1.z, v2.z); + this.v.x = math_min(v1.x, v2.x); + this.v.y = math_min(v1.y, v2.y); + this.v.z = math_min(v1.z, v2.z); break; case "Maximum": - this.v.x = Math.max(v1.x, v2.x); - this.v.y = Math.max(v1.y, v2.y); - this.v.z = Math.max(v1.z, v2.z); + this.v.x = math_max(v1.x, v2.x); + this.v.y = math_max(v1.y, v2.y); + this.v.z = math_max(v1.z, v2.z); break; case "Floor": - this.v.x = Math.floor(v1.x); - this.v.y = Math.floor(v1.y); - this.v.z = Math.floor(v1.z); + this.v.x = math_floor(v1.x); + this.v.y = math_floor(v1.y); + this.v.z = math_floor(v1.z); break; case "Ceil": - this.v.x = Math.ceil(v1.x); - this.v.y = Math.ceil(v1.y); - this.v.z = Math.ceil(v1.z); + this.v.x = math_ceil(v1.x); + this.v.y = math_ceil(v1.y); + this.v.z = math_ceil(v1.z); break; case "Fraction": - this.v.x = v1.x - Math.floor(v1.x); - this.v.y = v1.y - Math.floor(v1.y); - this.v.z = v1.z - Math.floor(v1.z); + this.v.x = v1.x - math_floor(v1.x); + this.v.y = v1.y - math_floor(v1.y); + this.v.z = v1.z - math_floor(v1.z); break; case "Modulo": this.v.x = v1.x % v2.x; @@ -106,24 +106,24 @@ class VectorMathNode extends LogicNode { this.v.z = v1.z % v2.z; break; case "Snap": - this.v.x = Math.floor(v1.x / v2.x) * v2.x; - this.v.y = Math.floor(v1.y / v2.y) * v2.y; - this.v.z = Math.floor(v1.z / v2.z) * v2.z; + this.v.x = math_floor(v1.x / v2.x) * v2.x; + this.v.y = math_floor(v1.y / v2.y) * v2.y; + this.v.z = math_floor(v1.z / v2.z) * v2.z; break; case "Sine": - this.v.x = Math.sin(v1.x); - this.v.y = Math.sin(v1.y); - this.v.z = Math.sin(v1.z); + this.v.x = math_sin(v1.x); + this.v.y = math_sin(v1.y); + this.v.z = math_sin(v1.z); break; case "Cosine": - this.v.x = Math.cos(v1.x); - this.v.y = Math.cos(v1.y); - this.v.z = Math.cos(v1.z); + this.v.x = math_cos(v1.x); + this.v.y = math_cos(v1.y); + this.v.z = math_cos(v1.z); break; case "Tangent": - this.v.x = Math.tan(v1.x); - this.v.y = Math.tan(v1.y); - this.v.z = Math.tan(v1.z); + this.v.x = math_tan(v1.x); + this.v.y = math_tan(v1.y); + this.v.z = math_tan(v1.z); break; } diff --git a/base/Sources/operator.ts b/base/Sources/operator.ts index 6abb74c3..98823ab2 100644 --- a/base/Sources/operator.ts +++ b/base/Sources/operator.ts @@ -1,5 +1,5 @@ -let operator_ops: Map = new Map(); +let operator_ops: map_t = map_create(); function operator_register(name: string, call: any) { operator_ops.set(name, call); diff --git a/base/Sources/path.ts b/base/Sources/path.ts index c0027a38..c2f42d3f 100644 --- a/base/Sources/path.ts +++ b/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: Mapvoid)=>void> = new Map(); -let path_texture_importers: Mapvoid)=>void> = new Map(); +let path_mesh_importers: map_tvoid)=>void> = map_create(); +let path_texture_importers: map_tvoid)=>void> = 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"]; diff --git a/base/Sources/plugin.ts b/base/Sources/plugin.ts index 1e87c7f7..c785dd2f 100644 --- a/base/Sources/plugin.ts +++ b/base/Sources/plugin.ts @@ -8,7 +8,7 @@ class PluginRaw { name: string; } -let plugin_map: Map = new Map(); +let plugin_map: map_t = map_create(); let _plugin_name: string; function plugin_create(): PluginRaw { diff --git a/base/Sources/project.ts b/base/Sources/project.ts index 86c33bba..3513802d 100644 --- a/base/Sources/project.ts +++ b/base/Sources/project.ts @@ -7,7 +7,7 @@ let project_asset_id: i32 = 0; let project_mesh_assets: string[] = []; let project_material_groups: node_group_t[] = []; let project_paint_objects: mesh_object_t[] = null; -let project_asset_map: Map = new Map(); // image_t | font_t +let project_asset_map: map_t = map_create(); // image_t | font_t let project_mesh_list: string[] = null; ///if (is_paint || is_sculpt) let project_materials: SlotMaterialRaw[] = null; @@ -26,18 +26,19 @@ let project_default_canvas: ArrayBuffer = null; ///end function project_open() { - UIFiles.show("arm", false, false, function (path: string) { + ui_files_show("arm", false, false, function (path: string) { if (!path.endsWith(".arm")) { console_error(strings_error0()); return; } let current: image_t = _g2_current; - if (current != null) g2_end(); + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); ImportArm.run_project(path); - if (current != null) g2_begin(current); + if (g2_in_use) g2_begin(current); }); } @@ -68,8 +69,8 @@ function project_save(saveAndQuit: bool = false) { } function project_save_as(saveAndQuit: bool = false) { - UIFiles.show("arm", true, false, function (path: string) { - let f: string = UIFiles.filename; + ui_files_show("arm", true, false, function (path: string) { + let f: string = ui_files_filename; if (f == "") f = tr("untitled"); project_filepath = path + path_sep + f; if (!project_filepath.endsWith(".arm")) project_filepath += ".arm"; @@ -79,7 +80,7 @@ function project_save_as(saveAndQuit: bool = false) { function project_new_box() { ///if (is_paint || is_sculpt) - UIBox.show_custom(function (ui: zui_t) { + ui_box_show_custom(function (ui: zui_t) { if (zui_tab(zui_handle("project_0"), tr("New Project"))) { if (project_mesh_list == null) { project_mesh_list = file_read_directory(path_data() + path_sep + "meshes"); @@ -96,12 +97,12 @@ function project_new_box() { zui_end_element(); zui_row([0.5, 0.5]); if (zui_button(tr("Cancel"))) { - UIBox.hide(); + ui_box_hide(); } if (zui_button(tr("OK")) || ui.is_return_down) { project_new(); viewport_scale_to_bounds(); - UIBox.hide(); + ui_box_hide(); } } }); @@ -168,7 +169,7 @@ function project_new(resetLayers: bool = true) { ///if is_sculpt base_notify_on_next_frame(function () { let f32a: Float32Array = new Float32Array(config_get_texture_res_x() * config_get_texture_res_y() * 4); - for (let i: i32 = 0; i < Math.floor(mesh.inda.length); ++i) { + for (let i: i32 = 0; i < math_floor(mesh.inda.length); ++i) { let index: i32 = mesh.inda[i]; f32a[i * 4] = mesh.posa[index * 4] / 32767; f32a[i * 4 + 1] = mesh.posa[index * 4 + 1] / 32767; @@ -203,7 +204,8 @@ function project_new(resetLayers: bool = true) { let md: mesh_data_t = data_get_mesh("Scene", n); let current: image_t = _g2_current; - if (current != null) g2_end(); + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); ///if is_paint context_raw.picker_mask_handle.position = picker_mask_t.NONE; @@ -229,8 +231,8 @@ function project_new(resetLayers: bool = true) { context_raw.material = project_materials[0]; ///end - UINodes.hwnd.redraws = 2; - UINodes.group_stack = []; + ui_nodes_hwnd.redraws = 2; + ui_nodes_group_stack = []; project_material_groups = []; ///if (is_paint || is_sculpt) @@ -251,20 +253,20 @@ function project_new(resetLayers: bool = true) { MakeMaterial.parse_paint_material(); ///if (is_paint || is_sculpt) - UtilRender.make_material_preview(); + util_render_make_material_preview(); ///end for (let a of project_assets) data_delete_image(a.file); project_assets = []; project_asset_names = []; - project_asset_map = new Map(); + project_asset_map = map_create(); project_asset_id = 0; project_raw.packed_assets = []; context_raw.ddirty = 4; ///if (is_paint || is_sculpt) - UIBase.hwnds[tab_area_t.SIDEBAR0].redraws = 2; - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; ///end if (resetLayers) { @@ -283,7 +285,7 @@ function project_new(resetLayers: bool = true) { app_notify_on_init(base_init_layers); } - if (current != null) g2_begin(current); + if (g2_in_use) g2_begin(current); context_raw.saved_envmap = null; context_raw.envmap_loaded = false; @@ -306,7 +308,7 @@ function project_new(resetLayers: bool = true) { ///if (is_paint || is_sculpt) function project_import_material() { - UIFiles.show("arm,blend", false, true, function (path: string) { + ui_files_show("arm,blend", false, true, function (path: string) { path.endsWith(".blend") ? ImportBlendMaterial.run(path) : ImportArm.run_material(path); @@ -314,7 +316,7 @@ function project_import_material() { } function project_import_brush() { - UIFiles.show("arm," + path_texture_formats.join(","), false, true, function (path: string) { + ui_files_show("arm," + path_texture_formats.join(","), false, true, function (path: string) { // Create brush from texture if (path_is_texture(path)) { // Import texture @@ -347,9 +349,9 @@ function project_import_brush() { // Parse brush MakeMaterial.parse_brush(); - UINodes.hwnd.redraws = 2; + ui_nodes_hwnd.redraws = 2; let _init = function () { - UtilRender.make_brush_preview(); + util_render_make_brush_preview(); } app_notify_on_init(_init); } @@ -362,7 +364,7 @@ function project_import_brush() { ///end function project_import_mesh(replaceExisting: bool = true, done: ()=>void = null) { - UIFiles.show(path_mesh_formats.join(","), false, false, function (path: string) { + ui_files_show(path_mesh_formats.join(","), false, false, function (path: string) { project_import_mesh_box(path, replaceExisting, true, done); }); } @@ -374,7 +376,7 @@ function project_import_mesh_box(path: string, replaceExisting: bool = true, cle // data_get_blob(path); ///end - UIBox.show_custom(function (ui: zui_t) { + ui_box_show_custom(function (ui: zui_t) { let tab_vertical: bool = config_raw.touch_ui; if (zui_tab(zui_handle("project_3"), tr("Import Mesh"), tab_vertical)) { @@ -403,10 +405,10 @@ function project_import_mesh_box(path: string, replaceExisting: bool = true, cle zui_row([0.45, 0.45, 0.1]); if (zui_button(tr("Cancel"))) { - UIBox.hide(); + ui_box_hide(); } if (zui_button(tr("Import")) || ui.is_return_down) { - UIBox.hide(); + ui_box_hide(); let do_import = function () { ///if (is_paint || is_sculpt) ImportMesh.run(path, clearLayers, replaceExisting); @@ -430,7 +432,7 @@ function project_import_mesh_box(path: string, replaceExisting: bool = true, cle } } }); - UIBox.click_to_hide = false; // Prevent closing when going back to window from file browser + ui_box_click_to_hide = false; // Prevent closing when going back to window from file browser } function project_reimport_mesh() { @@ -441,7 +443,7 @@ function project_reimport_mesh() { } function project_unwrap_mesh_box(mesh: any, done: (a: any)=>void, skipUI: bool = false) { - UIBox.show_custom(function (ui: zui_t) { + ui_box_show_custom(function (ui: zui_t) { let tab_vertical: bool = config_raw.touch_ui; if (zui_tab(zui_handle("project_7"), tr("Unwrap Mesh"), tab_vertical)) { @@ -460,13 +462,13 @@ function project_unwrap_mesh_box(mesh: any, done: (a: any)=>void, skipUI: bool = zui_row([0.5, 0.5]); if (zui_button(tr("Cancel"))) { - UIBox.hide(); + ui_box_hide(); } if (zui_button(tr("Unwrap")) || ui.is_return_down || skipUI) { - UIBox.hide(); + ui_box_hide(); let do_unwrap = function () { if (unwrap_by == unwrapPlugins.length - 1) { - UtilMesh.equirect_unwrap(mesh); + util_mesh_equirect_unwrap(mesh); } else { let f: string = unwrapPlugins[unwrap_by]; @@ -474,7 +476,7 @@ function project_unwrap_mesh_box(mesh: any, done: (a: any)=>void, skipUI: bool = config_enable_plugin(f); console_info(f + " " + tr("plugin enabled")); } - UtilMesh.unwrappers.get(f)(mesh); + util_mesh_unwrappers.get(f)(mesh); } done(mesh); } @@ -493,13 +495,13 @@ function project_unwrap_mesh_box(mesh: any, done: (a: any)=>void, skipUI: bool = function project_import_asset(filters: string = null, hdrAsEnvmap: bool = true) { if (filters == null) filters = path_texture_formats.join(",") + "," + path_mesh_formats.join(","); - UIFiles.show(filters, false, true, function (path: string) { + ui_files_show(filters, false, true, function (path: string) { ImportAsset.run(path, -1.0, -1.0, true, hdrAsEnvmap); }); } function project_import_swatches(replaceExisting: bool = false) { - UIFiles.show("arm,gpl", false, false, function (path: string) { + ui_files_show("arm,gpl", false, false, function (path: string) { if (path_is_gimp_color_palette(path)) ImportGpl.run(path, replaceExisting); else ImportArm.run_swatches(path, replaceExisting); }); @@ -532,15 +534,15 @@ function project_reimport_texture(asset: asset_t) { MakeMaterial.parse_paint_material(); ///if (is_paint || is_sculpt) - UtilRender.make_material_preview(); - UIBase.hwnds[tab_area_t.SIDEBAR1].redraws = 2; + util_render_make_material_preview(); + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; ///end } base_notify_on_next_frame(_next); } if (!file_exists(asset.file)) { let filters: string = path_texture_formats.join(","); - UIFiles.show(filters, false, false, function (path: string) { + ui_files_show(filters, false, false, function (path: string) { load(path); }); } @@ -586,8 +588,8 @@ function project_packed_asset_exists(packed_assets: packed_asset_t[], name: stri } function project_export_swatches() { - UIFiles.show("arm,gpl", true, false, function (path: string) { - let f: string = UIFiles.filename; + ui_files_show("arm,gpl", true, false, function (path: string) { + let f: string = ui_files_filename; if (f == "") f = tr("untitled"); if (path_is_gimp_color_palette(f)) ExportGpl.run(path + path_sep + f, f.substring(0, f.lastIndexOf(".")), project_raw.swatches); else ExportArm.run_swatches(path + path_sep + f); diff --git a/base/Sources/ProjectFormat.ts b/base/Sources/project_format.ts similarity index 100% rename from base/Sources/ProjectFormat.ts rename to base/Sources/project_format.ts diff --git a/base/Sources/resource.ts b/base/Sources/resource.ts index 3ae488d6..747e108b 100644 --- a/base/Sources/resource.ts +++ b/base/Sources/resource.ts @@ -1,13 +1,10 @@ -let resource_bundled: Map = new Map(); +let resource_bundled: map_t = map_create(); -function resource_load(names: string[], done: ()=>void) { - let loaded: i32 = 0; +function resource_load(names: string[]) { for (let s of names) { let image: image_t = data_get_image(s); resource_bundled.set(s, image); - loaded++; - if (loaded == names.length) done(); } } diff --git a/base/Sources/strings.ts b/base/Sources/strings.ts index 901d6d94..d6568d2e 100644 --- a/base/Sources/strings.ts +++ b/base/Sources/strings.ts @@ -36,3 +36,521 @@ function strings_graphics_api(): string { return "OpenGL"; ///end } + +let str_tex_checker: string = ` +vec3 tex_checker(const vec3 co, const vec3 col1, const vec3 col2, const float scale) { + // Prevent precision issues on unit coordinates + vec3 p = (co + 0.000001 * 0.999999) * scale; + float xi = abs(floor(p.x)); + float yi = abs(floor(p.y)); + float zi = abs(floor(p.z)); + bool check = ((mod(xi, 2.0) == mod(yi, 2.0)) == bool(mod(zi, 2.0))); + return check ? col1 : col2; +} +float tex_checker_f(const vec3 co, const float scale) { + vec3 p = (co + 0.000001 * 0.999999) * scale; + float xi = abs(floor(p.x)); + float yi = abs(floor(p.y)); + float zi = abs(floor(p.z)); + return float((mod(xi, 2.0) == mod(yi, 2.0)) == bool(mod(zi, 2.0))); +} +`; + + // Created by inigo quilez - iq/2013 + // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License +let str_tex_voronoi: string = ` +vec4 tex_voronoi(const vec3 x, textureArg(snoise256)) { + vec3 p = floor(x); + vec3 f = fract(x); + float id = 0.0; + float res = 100.0; + for (int k = -1; k <= 1; k++) + for (int j = -1; j <= 1; j++) + for (int i = -1; i <= 1; i++) { + vec3 b = vec3(float(i), float(j), float(k)); + vec3 pb = p + b; + vec3 r = vec3(b) - f + texture(snoise256, (pb.xy + vec2(3.0, 1.0) * pb.z + 0.5) / 256.0).xyz; + float d = dot(r, r); + if (d < res) { + id = dot(p + b, vec3(1.0, 57.0, 113.0)); + res = d; + } + } + vec3 col = 0.5 + 0.5 * cos(id * 0.35 + vec3(0.0, 1.0, 2.0)); + return vec4(col, sqrt(res)); +} +`; + + // By Morgan McGuire @morgan3d, http://graphicscodex.com Reuse permitted under the BSD license. + // https://www.shadertoy.com/view/4dS3Wd +let str_tex_noise: string = ` +float hash(float n) { return fract(sin(n) * 1e4); } +float tex_noise_f(vec3 x) { + const vec3 step = vec3(110, 241, 171); + vec3 i = floor(x); + vec3 f = fract(x); + float n = dot(i, step); + vec3 u = f * f * (3.0 - 2.0 * f); + return mix(mix(mix(hash(n + dot(step, vec3(0, 0, 0))), hash(n + dot(step, vec3(1, 0, 0))), u.x), + mix(hash(n + dot(step, vec3(0, 1, 0))), hash(n + dot(step, vec3(1, 1, 0))), u.x), u.y), + mix(mix(hash(n + dot(step, vec3(0, 0, 1))), hash(n + dot(step, vec3(1, 0, 1))), u.x), + mix(hash(n + dot(step, vec3(0, 1, 1))), hash(n + dot(step, vec3(1, 1, 1))), u.x), u.y), u.z); +} +float tex_noise(vec3 p) { + p *= 1.25; + float f = 0.5 * tex_noise_f(p); p *= 2.01; + f += 0.25 * tex_noise_f(p); p *= 2.02; + f += 0.125 * tex_noise_f(p); p *= 2.03; + f += 0.0625 * tex_noise_f(p); + return 1.0 - f; +} +`; + + // Based on noise created by Nikita Miropolskiy, nikat/2013 + // Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License +let str_tex_musgrave: string = ` +vec3 random3(const vec3 c) { + float j = 4096.0 * sin(dot(c, vec3(17.0, 59.4, 15.0))); + vec3 r; + r.z = fract(512.0 * j); + j *= 0.125; + r.x = fract(512.0 * j); + j *= 0.125; + r.y = fract(512.0 * j); + return r - 0.5; +} +float tex_musgrave_f(const vec3 p) { + const float F3 = 0.3333333; + const float G3 = 0.1666667; + vec3 s = floor(p + dot(p, vec3(F3, F3, F3))); + vec3 x = p - s + dot(s, vec3(G3, G3, G3)); + vec3 e = step(vec3(0.0, 0.0, 0.0), x - x.yzx); + vec3 i1 = e*(1.0 - e.zxy); + vec3 i2 = 1.0 - e.zxy*(1.0 - e); + vec3 x1 = x - i1 + G3; + vec3 x2 = x - i2 + 2.0*G3; + vec3 x3 = x - 1.0 + 3.0*G3; + vec4 w, d; + w.x = dot(x, x); + w.y = dot(x1, x1); + w.z = dot(x2, x2); + w.w = dot(x3, x3); + w = max(0.6 - w, 0.0); + d.x = dot(random3(s), x); + d.y = dot(random3(s + i1), x1); + d.z = dot(random3(s + i2), x2); + d.w = dot(random3(s + 1.0), x3); + w *= w; + w *= w; + d *= w; + return clamp(dot(d, vec4(52.0, 52.0, 52.0, 52.0)), 0.0, 1.0); +} +`; + +let str_hue_sat: string = ` +vec3 hsv_to_rgb(const vec3 c) { + const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} +vec3 rgb_to_hsv(const vec3 c) { + const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} +vec3 hue_sat(const vec3 col, const vec4 shift) { + vec3 hsv = rgb_to_hsv(col); + hsv.x += shift.x; + hsv.y *= shift.y; + hsv.z *= shift.z; + return mix(hsv_to_rgb(hsv), col, shift.w); +} +`; + +// https://twitter.com/Donzanoid/status/903424376707657730 +let str_wavelength_to_rgb: string = ` +vec3 wavelength_to_rgb(const float t) { + vec3 r = t * 2.1 - vec3(1.8, 1.14, 0.3); + return 1.0 - r * r; +} +`; + +let str_tex_magic: string = ` +vec3 tex_magic(const vec3 p) { + float a = 1.0 - (sin(p.x) + sin(p.y)); + float b = 1.0 - sin(p.x - p.y); + float c = 1.0 - sin(p.x + p.y); + return vec3(a, b, c); +} +float tex_magic_f(const vec3 p) { + vec3 c = tex_magic(p); + return (c.x + c.y + c.z) / 3.0; +} +`; + +let str_tex_brick: string = ` +float tex_brick_noise(int n) { /* fast integer noise */ + int nn; + n = (n >> 13) ^ n; + nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; + return 0.5f * float(nn) / 1073741824.0; +} +vec3 tex_brick(vec3 p, const vec3 c1, const vec3 c2, const vec3 c3) { + vec3 brickSize = vec3(0.9, 0.49, 0.49); + vec3 mortarSize = vec3(0.05, 0.1, 0.1); + p /= brickSize / 2; + if (fract(p.y * 0.5) > 0.5) p.x += 0.5; + float col = floor(p.x / (brickSize.x + (mortarSize.x * 2.0))); + float row = p.y; + p = fract(p); + vec3 b = step(p, 1.0 - mortarSize); + float tint = min(max(tex_brick_noise((int(col) << 16) + (int(row) & 0xFFFF)), 0.0), 1.0); + return mix(c3, mix(c1, c2, tint), b.x * b.y * b.z); +} +float tex_brick_f(vec3 p) { + p /= vec3(0.9, 0.49, 0.49) / 2; + if (fract(p.y * 0.5) > 0.5) p.x += 0.5; + p = fract(p); + vec3 b = step(p, vec3(0.95, 0.9, 0.9)); + return mix(1.0, 0.0, b.x * b.y * b.z); +} +`; + +let str_tex_wave: string = ` +float tex_wave_f(const vec3 p) { + return 1.0 - sin((p.x + p.y) * 10.0); +} +`; + +let str_brightcontrast: string = ` +vec3 brightcontrast(const vec3 col, const float bright, const float contr) { + float a = 1.0 + contr; + float b = bright - contr * 0.5; + return max(a * col + b, 0.0); +} +`; + +///if arm_voxels +let str_trace_ao: string = ` +float traceConeAO(sampler3D voxels, const vec3 origin, vec3 dir, const float aperture, const float maxDist, const float offset) { + const ivec3 voxelgiResolution = ivec3(256, 256, 256); + const float voxelgiStep = 1.0; + const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep; + dir = normalize(dir); + float sampleCol = 0.0; + float dist = offset; + float diam = dist * aperture; + vec3 samplePos; + while (sampleCol < 1.0 && dist < maxDist) { + samplePos = dir * dist + origin; + float mip = max(log2(diam * voxelgiResolution.x), 0); + float mipSample = textureLod(voxels, samplePos * 0.5 + vec3(0.5, 0.5, 0.5), mip).r; + sampleCol += (1 - sampleCol) * mipSample; + dist += max(diam / 2, VOXEL_SIZE); + diam = dist * aperture; + } + return sampleCol; +} +vec3 tangent(const vec3 n) { + vec3 t1 = cross(n, vec3(0, 0, 1)); + vec3 t2 = cross(n, vec3(0, 1, 0)); + if (length(t1) > length(t2)) return normalize(t1); + else return normalize(t2); +} +float traceAO(const vec3 origin, const vec3 normal, const float vrange, const float voffset) { + const float angleMix = 0.5f; + const float aperture = 0.55785173935; + vec3 o1 = normalize(tangent(normal)); + vec3 o2 = normalize(cross(o1, normal)); + vec3 c1 = 0.5f * (o1 + o2); + vec3 c2 = 0.5f * (o1 - o2); + float MAX_DISTANCE = 1.73205080757 * 2.0 * vrange; + const ivec3 voxelgiResolution = ivec3(256, 256, 256); + const float voxelgiStep = 1.0; + const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep; + float offset = 1.5 * VOXEL_SIZE * 2.5 * voffset; + float col = traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE, offset); + col += traceConeAO(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE, offset); + col += traceConeAO(voxels, origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE, offset); + col += traceConeAO(voxels, origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE, offset); + col += traceConeAO(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset); + col += traceConeAO(voxels, origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset); + col += traceConeAO(voxels, origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE, offset); + col += traceConeAO(voxels, origin, mix(normal, c1, angleMix), aperture, MAX_DISTANCE, offset); + col += traceConeAO(voxels, origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset); + return col / 9.0; +} +`; +///end + +let str_cotangent_frame: string = ` +mat3 cotangentFrame(const vec3 n, const vec3 p, const vec2 duv1, const vec2 duv2) { + vec3 dp1 = dFdx(p); + vec3 dp2 = dFdy(p); + vec3 dp2perp = cross(dp2, n); + vec3 dp1perp = cross(n, dp1); + vec3 t = dp2perp * duv1.x + dp1perp * duv2.x; + vec3 b = dp2perp * duv1.y + dp1perp * duv2.y; + float invmax = inversesqrt(max(dot(t, t), dot(b, b))); + return mat3(t * invmax, b * invmax, n); +} +mat3 cotangentFrame(const vec3 n, const vec3 p, const vec2 texCoord) { + return cotangentFrame(n, p, dFdx(texCoord), dFdy(texCoord)); +} +`; + +let str_octahedron_wrap: string = ` +vec2 octahedronWrap(const vec2 v) { + return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0)); +} +`; + +let str_pack_float_int16: string = ` +float packFloatInt16(const float f, const uint i) { + const float prec = float(1 << 16); + const float maxi = float(1 << 4); + const float precMinusOne = prec - 1.0; + const float t1 = ((prec / maxi) - 1.0) / precMinusOne; + const float t2 = (prec / maxi) / precMinusOne; + return t1 * f + t2 * float(i); +} +`; + +///if arm_skin +let str_get_skinning_dual_quat: string = ` +void getSkinningDualQuat(const ivec4 bone, vec4 weight, out vec4 A, inout vec4 B) { + ivec4 bonei = bone * 2; + mat4 matA = mat4( + skinBones[bonei.x], + skinBones[bonei.y], + skinBones[bonei.z], + skinBones[bonei.w]); + mat4 matB = mat4( + skinBones[bonei.x + 1], + skinBones[bonei.y + 1], + skinBones[bonei.z + 1], + skinBones[bonei.w + 1]); + weight.xyz *= sign(mul(matA, matA[3])).xyz; + A = mul(weight, matA); + B = mul(weight, matB); + float invNormA = 1.0 / length(A); + A *= invNormA; + B *= invNormA; +} +`; +///end + +let str_create_basis: string = ` +void createBasis(vec3 normal, out vec3 tangent, out vec3 binormal) { + tangent = normalize(cameraRight - normal * dot(cameraRight, normal)); + binormal = cross(tangent, normal); +} +`; + +function str_sh_irradiance(): string { +///if krom_metal + return `vec3 shIrradiance(const vec3 nor, constant vec4 shirr[7]) { + const float c1 = 0.429043; + const float c2 = 0.511664; + const float c3 = 0.743125; + const float c4 = 0.886227; + const float c5 = 0.247708; + vec3 cl00 = vec3(shirr[0].x, shirr[0].y, shirr[0].z); + vec3 cl1m1 = vec3(shirr[0].w, shirr[1].x, shirr[1].y); + vec3 cl10 = vec3(shirr[1].z, shirr[1].w, shirr[2].x); + vec3 cl11 = vec3(shirr[2].y, shirr[2].z, shirr[2].w); + vec3 cl2m2 = vec3(shirr[3].x, shirr[3].y, shirr[3].z); + vec3 cl2m1 = vec3(shirr[3].w, shirr[4].x, shirr[4].y); + vec3 cl20 = vec3(shirr[4].z, shirr[4].w, shirr[5].x); + vec3 cl21 = vec3(shirr[5].y, shirr[5].z, shirr[5].w); + vec3 cl22 = vec3(shirr[6].x, shirr[6].y, shirr[6].z); + return ( + c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) + + c3 * cl20 * nor.x * nor.x + + c4 * cl00 - + c5 * cl20 + + 2.0 * c1 * cl2m2 * nor.y * (-nor.z) + + 2.0 * c1 * cl21 * nor.y * nor.x + + 2.0 * c1 * cl2m1 * (-nor.z) * nor.x + + 2.0 * c2 * cl11 * nor.y + + 2.0 * c2 * cl1m1 * (-nor.z) + + 2.0 * c2 * cl10 * nor.x + ); +} +`; +///else + return `vec3 shIrradiance(const vec3 nor, const vec4 shirr[7]) { + const float c1 = 0.429043; + const float c2 = 0.511664; + const float c3 = 0.743125; + const float c4 = 0.886227; + const float c5 = 0.247708; + vec3 cl00 = vec3(shirr[0].x, shirr[0].y, shirr[0].z); + vec3 cl1m1 = vec3(shirr[0].w, shirr[1].x, shirr[1].y); + vec3 cl10 = vec3(shirr[1].z, shirr[1].w, shirr[2].x); + vec3 cl11 = vec3(shirr[2].y, shirr[2].z, shirr[2].w); + vec3 cl2m2 = vec3(shirr[3].x, shirr[3].y, shirr[3].z); + vec3 cl2m1 = vec3(shirr[3].w, shirr[4].x, shirr[4].y); + vec3 cl20 = vec3(shirr[4].z, shirr[4].w, shirr[5].x); + vec3 cl21 = vec3(shirr[5].y, shirr[5].z, shirr[5].w); + vec3 cl22 = vec3(shirr[6].x, shirr[6].y, shirr[6].z); + return ( + c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) + + c3 * cl20 * nor.x * nor.x + + c4 * cl00 - + c5 * cl20 + + 2.0 * c1 * cl2m2 * nor.y * (-nor.z) + + 2.0 * c1 * cl21 * nor.y * nor.x + + 2.0 * c1 * cl2m1 * (-nor.z) * nor.x + + 2.0 * c2 * cl11 * nor.y + + 2.0 * c2 * cl1m1 * (-nor.z) + + 2.0 * c2 * cl10 * nor.x + ); +} +`; +///end +} + +let str_envmap_equirect: string = ` +vec2 envMapEquirect(const vec3 normal, const float angle) { + const float PI = 3.1415926535; + const float PI2 = PI * 2.0; + float phi = acos(normal.z); + float theta = atan2(-normal.y, normal.x) + PI + angle; + return vec2(theta / PI2, phi / PI); +} +`; + +// Linearly Transformed Cosines +// https://eheitzresearch.wordpress.com/415-2/ +let str_ltc_evaluate: string = ` +float integrateEdge(vec3 v1, vec3 v2) { + float cosTheta = dot(v1, v2); + float theta = acos(cosTheta); + float res = cross(v1, v2).z * ((theta > 0.001) ? theta / sin(theta) : 1.0); + return res; +} +float ltcEvaluate(vec3 N, vec3 V, float dotNV, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3) { + vec3 T1 = normalize(V - N * dotNV); + vec3 T2 = cross(N, T1); + Minv = mul(transpose(mat3(T1, T2, N)), Minv); + vec3 L0 = mul((points0 - P), Minv); + vec3 L1 = mul((points1 - P), Minv); + vec3 L2 = mul((points2 - P), Minv); + vec3 L3 = mul((points3 - P), Minv); + vec3 L4 = vec3(0.0, 0.0, 0.0); + int n = 0; + int config = 0; + if (L0.z > 0.0) config += 1; + if (L1.z > 0.0) config += 2; + if (L2.z > 0.0) config += 4; + if (L3.z > 0.0) config += 8; + if (config == 0) {} + else if (config == 1) { + n = 3; + L1 = -L1.z * L0 + L0.z * L1; + L2 = -L3.z * L0 + L0.z * L3; + } + else if (config == 2) { + n = 3; + L0 = -L0.z * L1 + L1.z * L0; + L2 = -L2.z * L1 + L1.z * L2; + } + else if (config == 3) { + n = 4; + L2 = -L2.z * L1 + L1.z * L2; + L3 = -L3.z * L0 + L0.z * L3; + } + else if (config == 4) { + n = 3; + L0 = -L3.z * L2 + L2.z * L3; + L1 = -L1.z * L2 + L2.z * L1; + } + else if (config == 5) { n = 0; } + else if (config == 6) { + n = 4; + L0 = -L0.z * L1 + L1.z * L0; + L3 = -L3.z * L2 + L2.z * L3; + } + else if (config == 7) { + n = 5; + L4 = -L3.z * L0 + L0.z * L3; + L3 = -L3.z * L2 + L2.z * L3; + } + else if (config == 8) { + n = 3; + L0 = -L0.z * L3 + L3.z * L0; + L1 = -L2.z * L3 + L3.z * L2; + L2 = L3; + } + else if (config == 9) { + n = 4; + L1 = -L1.z * L0 + L0.z * L1; + L2 = -L2.z * L3 + L3.z * L2; + } + else if (config == 10) { n = 0; } + else if (config == 11) { + n = 5; + L4 = L3; + L3 = -L2.z * L3 + L3.z * L2; + L2 = -L2.z * L1 + L1.z * L2; + } + else if (config == 12) { + n = 4; + L1 = -L1.z * L2 + L2.z * L1; + L0 = -L0.z * L3 + L3.z * L0; + } + else if (config == 13) { + n = 5; + L4 = L3; + L3 = L2; + L2 = -L1.z * L2 + L2.z * L1; + L1 = -L1.z * L0 + L0.z * L1; + } + else if (config == 14) { + n = 5; + L4 = -L0.z * L3 + L3.z * L0; + L0 = -L0.z * L1 + L1.z * L0; + } + else if (config == 15) { n = 4; } + if (n == 0) return 0.0; + if (n == 3) L3 = L0; + if (n == 4) L4 = L0; + L0 = normalize(L0); + L1 = normalize(L1); + L2 = normalize(L2); + L3 = normalize(L3); + L4 = normalize(L4); + float sum = 0.0; + sum += integrateEdge(L0, L1); + sum += integrateEdge(L1, L2); + sum += integrateEdge(L2, L3); + if (n >= 4) sum += integrateEdge(L3, L4); + if (n == 5) sum += integrateEdge(L4, L0); + return max(0.0, -sum); +} +`; + +let str_get_pos_from_depth: string = ` +vec3 get_pos_from_depth(vec2 uv, mat4 invVP, textureArg(gbufferD)) { + #if defined(HLSL) || defined(METAL) || defined(SPIRV) + float depth = textureLod(gbufferD, vec2(uv.x, 1.0 - uv.y), 0.0).r; + #else + float depth = textureLod(gbufferD, uv, 0.0).r; + #endif + vec4 wpos = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0); + wpos = mul(wpos, invVP); + return wpos.xyz / wpos.w; +} +`; + +let str_get_nor_from_depth: string = ` +vec3 get_nor_from_depth(vec3 p0, vec2 uv, mat4 invVP, vec2 texStep, textureArg(gbufferD)) { + vec3 p1 = get_pos_from_depth(uv + vec2(texStep.x * 4.0, 0.0), invVP, texturePass(gbufferD)); + vec3 p2 = get_pos_from_depth(uv + vec2(0.0, texStep.y * 4.0), invVP, texturePass(gbufferD)); + return normalize(cross(p2 - p0, p1 - p0)); +} +`; diff --git a/base/Sources/translator.ts b/base/Sources/translator.ts index 401b7a5c..99400225 100644 --- a/base/Sources/translator.ts +++ b/base/Sources/translator.ts @@ -1,7 +1,7 @@ -let translator_translations: Map = new Map(); +let translator_translations: map_t = map_create(); // The font index is a value specific to font_cjk.ttc. -let translator_cjk_font_indices: Map = new Map([ +let translator_cjk_font_indices: map_t = new Map([ ["ja", 0], ["ko", 1], ["zh_cn", 2], @@ -19,7 +19,7 @@ function _tr(s: string) { // Localizes a string with the given placeholders replaced (format is `{placeholderName}`). // If the string isn't available in the translation, this method will return the source English string. -function tr(id: string, vars: Map = null): string { +function tr(id: string, vars: map_t = null): string { let translation: string = id; // English is the source language @@ -120,8 +120,8 @@ function translator_init_font(cjk: bool, fontPath: string, fontScale: f32) { } base_font = f; // Scale up the font size and elements width a bit - base_theme.FONT_SIZE = Math.floor(base_default_font_size * fontScale); - base_theme.ELEMENT_W = Math.floor(base_default_element_w * (config_raw.locale != "en" ? 1.4 : 1.0)); + base_theme.FONT_SIZE = math_floor(base_default_font_size * fontScale); + base_theme.ELEMENT_W = math_floor(base_default_element_w * (config_raw.locale != "en" ? 1.4 : 1.0)); let uis: zui_t[] = base_get_uis(); for (let ui of uis) { zui_set_font(ui, f); diff --git a/base/Sources/ui_base.ts b/base/Sources/ui_base.ts new file mode 100644 index 00000000..7932d711 --- /dev/null +++ b/base/Sources/ui_base.ts @@ -0,0 +1,1529 @@ + +///if is_paint +/// +///end +///if is_sculpt +/// +///end +///if is_forge +/// +///end +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// + +let ui_base_show: bool = true; +let ui_base_ui: zui_t; +let ui_base_border_started: i32 = 0; +let ui_base_border_handle_ptr: i32 = 0; +let ui_base_action_paint_remap: string = ""; +let ui_base_operator_search_offset: i32 = 0; +let ui_base_undo_tap_time: f32 = 0.0; +let ui_base_redo_tap_time: f32 = 0.0; + +let ui_base_hwnds: zui_handle_t[] = ui_base_init_hwnds(); +let ui_base_htabs: zui_handle_t[] = ui_base_init_htabs(); +let ui_base_hwnd_tabs: any[] = ui_base_init_hwnd_tabs(); + +///if (is_paint || is_sculpt) +let ui_base_default_sidebar_mini_w: i32 = 56; +let ui_base_default_sidebar_full_w: i32 = 280; +///if (krom_android || krom_ios) +let ui_base_default_sidebar_w: i32 = ui_base_default_sidebar_mini_w; +///else +let ui_base_default_sidebar_w: i32 = ui_base_default_sidebar_full_w; +///end +let ui_base_tabx: i32 = 0; +let ui_base_hminimized: zui_handle_t = zui_handle_create(); +let ui_base_sidebar_mini_w: i32 = ui_base_default_sidebar_mini_w; +///end + +function ui_base_init_hwnds(): zui_handle_t[] { + ///if is_paint + return [zui_handle_create(), zui_handle_create(), zui_handle_create()]; + ///end + ///if is_sculpt + return [zui_handle_create(), zui_handle_create(), zui_handle_create()]; + ///end + ///if is_lab + return [zui_handle_create()]; + ///end +} + +function ui_base_init_htabs(): zui_handle_t[] { + ///if is_paint + return [zui_handle_create(), zui_handle_create(), zui_handle_create()]; + ///end + ///if is_sculpt + return [zui_handle_create(), zui_handle_create(), zui_handle_create()]; + ///end + ///if is_lab + return [zui_handle_create()]; + ///end +} + +function ui_base_init_hwnd_tabs(): any[] { + ///if is_paint + return [ + [TabLayers.draw, TabHistory.draw, TabPlugins.draw + ///if is_forge + , TabObjects.draw + ///end + ], + [TabMaterials.draw, TabBrushes.draw, TabParticles.draw], + [TabBrowser.draw, TabTextures.draw, TabMeshes.draw, TabFonts.draw, TabSwatches.draw, TabScript.draw, TabConsole.draw, ui_status_draw_version_tab] + ]; + ///end + ///if is_sculpt + return [ + [TabLayers.draw, TabHistory.draw, TabPlugins.draw + ///if is_forge + , TabObjects.draw + ///end + ], + [TabMaterials.draw, TabBrushes.draw, TabParticles.draw], + [TabBrowser.draw, TabTextures.draw, TabMeshes.draw, TabFonts.draw, TabScript.draw, TabConsole.draw, ui_status_draw_version_tab] + ]; + ///end + ///if is_lab + return [ + [TabBrowser.draw, TabTextures.draw, TabMeshes.draw, TabSwatches.draw, TabPlugins.draw, TabScript.draw, TabConsole.draw, ui_status_draw_version_tab] + ]; + ///end +} + +function ui_base_init() { + ///if (is_paint || is_sculpt) + ui_toolbar_init(); + ui_toolbar_w = math_floor(ui_toolbar_default_w * config_raw.window_scale); + context_raw.text_tool_text = tr("Text"); + ///end + + ui_header_init(); + ui_status_init(); + ui_menubar_init(); + + ui_header_h = math_floor(ui_header_default_h * config_raw.window_scale); + ui_menubar_w = math_floor(ui_menubar_default_w * config_raw.window_scale); + + ///if (is_paint || is_sculpt) + if (project_materials == null) { + project_materials = []; + let m: material_data_t = data_get_material("Scene", "Material"); + project_materials.push(SlotMaterial.create(m)); + context_raw.material = project_materials[0]; + } + + if (project_brushes == null) { + project_brushes = []; + project_brushes.push(SlotBrush.create()); + context_raw.brush = project_brushes[0]; + MakeMaterial.parse_brush(); + } + + if (project_fonts == null) { + project_fonts = []; + project_fonts.push(SlotFont.create("default.ttf", base_font)); + context_raw.font = project_fonts[0]; + } + + if (project_layers == null) { + project_layers = []; + project_layers.push(SlotLayer.create()); + context_raw.layer = project_layers[0]; + } + ///end + + ///if is_lab + if (project_material_data == null) { + let m: material_data_t = data_get_material("Scene", "Material"); + project_material_data = m; + } + + if (project_default_canvas == null) { // Synchronous + let b: ArrayBuffer = data_get_blob("default_brush.arm"); + project_default_canvas = b; + } + + project_nodes = zui_nodes_create(); + project_canvas = armpack_decode(project_default_canvas); + project_canvas.name = "Brush 1"; + + context_parse_brush_inputs(); + + ParserLogic.parse(project_canvas); + ///end + + if (project_raw.swatches == null) { + project_set_default_swatches(); + context_raw.swatch = project_raw.swatches[0]; + } + + if (context_raw.empty_envmap == null) { + let b: Uint8Array = new Uint8Array(4); + b[0] = 8; + b[1] = 8; + b[2] = 8; + b[3] = 255; + context_raw.empty_envmap = image_from_bytes(b.buffer, 1, 1); + } + if (context_raw.preview_envmap == null) { + let b: Uint8Array = new Uint8Array(4); + b[0] = 0; + b[1] = 0; + b[2] = 0; + b[3] = 255; + context_raw.preview_envmap = image_from_bytes(b.buffer, 1, 1); + } + + let world: world_data_t = scene_world; + if (context_raw.saved_envmap == null) { + // raw.savedEnvmap = world._envmap; + context_raw.default_irradiance = world._.irradiance; + context_raw.default_radiance = world._.radiance; + context_raw.default_radiance_mipmaps = world._.radiance_mipmaps; + } + world._.envmap = context_raw.show_envmap ? context_raw.saved_envmap : context_raw.empty_envmap; + context_raw.ddirty = 1; + + 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 }); + 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); + zui_set_on_tab_drop(ui_base_on_tab_drop); + + ///if (is_paint || is_sculpt) + let resources: string[] = ["cursor.k", "icons.k"]; + ///end + ///if is_lab + let resources: string[] = ["cursor.k", "icons.k", "placeholder.k"]; + ///end + + ///if (is_paint || is_sculpt) + context_raw.gizmo = scene_get_child(".Gizmo"); + context_raw.gizmo_translate_x = object_get_child(context_raw.gizmo, ".TranslateX"); + context_raw.gizmo_translate_y = object_get_child(context_raw.gizmo, ".TranslateY"); + context_raw.gizmo_translate_z = object_get_child(context_raw.gizmo, ".TranslateZ"); + context_raw.gizmo_scale_x = object_get_child(context_raw.gizmo, ".ScaleX"); + context_raw.gizmo_scale_y = object_get_child(context_raw.gizmo, ".ScaleY"); + context_raw.gizmo_scale_z = object_get_child(context_raw.gizmo, ".ScaleZ"); + context_raw.gizmo_rotate_x = object_get_child(context_raw.gizmo, ".RotateX"); + context_raw.gizmo_rotate_y = object_get_child(context_raw.gizmo, ".RotateY"); + context_raw.gizmo_rotate_z = object_get_child(context_raw.gizmo, ".RotateZ"); + ///end + + resource_load(resources); + + if (zui_SCALE(ui_base_ui) > 1) ui_base_set_icon_scale(); + + context_raw.paint_object = scene_get_child(".Cube").ext; + project_paint_objects = [context_raw.paint_object]; + + if (project_filepath == "") { + app_notify_on_init(base_init_layers); + } + + context_raw.project_objects = []; + for (let m of scene_meshes) context_raw.project_objects.push(m); + + operator_register("view_top", ui_base_view_top); +} + +function ui_base_update() { + ui_base_update_ui(); + operator_update(); + + for (let p of plugin_map.values()) if (p.update != null) p.update(); + + if (!base_ui_enabled) return; + + if (!ui_nodes_ui.is_typing && !ui_base_ui.is_typing) { + if (operator_shortcut(config_keymap.toggle_node_editor)) { + ///if (is_paint || is_sculpt) + ui_nodes_canvas_type == canvas_type_t.MATERIAL ? ui_base_show_material_nodes() : ui_base_show_brush_nodes(); + ///end + ///if is_lab + ui_base_show_material_nodes(); + ///end + } + else if (operator_shortcut(config_keymap.toggle_browser)) { + ui_base_toggle_browser(); + } + + else if (operator_shortcut(config_keymap.toggle_2d_view)) { + ///if (is_paint || is_sculpt) + ui_base_show_2d_view(view_2d_type_t.LAYER); + ///else + ui_base_show_2d_view(view_2d_type_t.ASSET); + ///end + } + } + + if (operator_shortcut(config_keymap.file_save_as)) project_save_as(); + else if (operator_shortcut(config_keymap.file_save)) project_save(); + else if (operator_shortcut(config_keymap.file_open)) project_open(); + else if (operator_shortcut(config_keymap.file_open_recent)) BoxProjects.show(); + else if (operator_shortcut(config_keymap.file_reimport_mesh)) project_reimport_mesh(); + else if (operator_shortcut(config_keymap.file_reimport_textures)) project_reimport_textures(); + else if (operator_shortcut(config_keymap.file_new)) project_new_box(); + ///if (is_paint || is_lab) + else if (operator_shortcut(config_keymap.file_export_textures)) { + if (context_raw.texture_export_path == "") { // First export, ask for path + ///if is_paint + context_raw.layers_export = export_mode_t.VISIBLE; + ///end + BoxExport.show_textures(); + } + else { + let _init = function () { + ExportTexture.run(context_raw.texture_export_path); + } + app_notify_on_init(_init); + } + } + else if (operator_shortcut(config_keymap.file_export_textures_as)) { + ///if (is_paint || is_sculpt) + context_raw.layers_export = export_mode_t.VISIBLE; + ///end + BoxExport.show_textures(); + } + ///end + else if (operator_shortcut(config_keymap.file_import_assets)) project_import_asset(); + else if (operator_shortcut(config_keymap.edit_prefs)) BoxPreferences.show(); + + if (keyboard_started(config_keymap.view_distract_free) || + (keyboard_started("escape") && !ui_base_show && !ui_box_show)) { + ui_base_toggle_distract_free(); + } + + ///if krom_linux + if (operator_shortcut("alt+enter", shortcut_type_t.STARTED)) { + base_toggle_fullscreen(); + } + ///end + + ///if (is_paint || is_sculpt) + let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; + let decal_mask: bool = decal && operator_shortcut(config_keymap.decal_mask, shortcut_type_t.DOWN); + + if ((context_raw.brush_can_lock || context_raw.brush_locked) && mouse_moved) { + if (operator_shortcut(config_keymap.brush_radius, shortcut_type_t.DOWN) || + operator_shortcut(config_keymap.brush_opacity, shortcut_type_t.DOWN) || + operator_shortcut(config_keymap.brush_angle, shortcut_type_t.DOWN) || + (decal_mask && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.brush_radius, shortcut_type_t.DOWN))) { + if (context_raw.brush_locked) { + if (operator_shortcut(config_keymap.brush_opacity, shortcut_type_t.DOWN)) { + context_raw.brush_opacity += mouse_movement_x / 500; + context_raw.brush_opacity = math_max(0.0, math_min(1.0, context_raw.brush_opacity)); + context_raw.brush_opacity = math_round(context_raw.brush_opacity * 100) / 100; + context_raw.brush_opacity_handle.value = context_raw.brush_opacity; + } + else if (operator_shortcut(config_keymap.brush_angle, shortcut_type_t.DOWN)) { + context_raw.brush_angle += mouse_movement_x / 5; + context_raw.brush_angle = math_floor(context_raw.brush_angle) % 360; + if (context_raw.brush_angle < 0) context_raw.brush_angle += 360; + context_raw.brush_angle_handle.value = context_raw.brush_angle; + MakeMaterial.parse_paint_material(); + } + else if (decal_mask && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.brush_radius, shortcut_type_t.DOWN)) { + context_raw.brush_decal_mask_radius += mouse_movement_x / 150; + context_raw.brush_decal_mask_radius = math_max(0.01, math_min(4.0, context_raw.brush_decal_mask_radius)); + context_raw.brush_decal_mask_radius = math_round(context_raw.brush_decal_mask_radius * 100) / 100; + context_raw.brush_decal_mask_radius_handle.value = context_raw.brush_decal_mask_radius; + } + else { + context_raw.brush_radius += mouse_movement_x / 150; + context_raw.brush_radius = math_max(0.01, math_min(4.0, context_raw.brush_radius)); + context_raw.brush_radius = math_round(context_raw.brush_radius * 100) / 100; + context_raw.brush_radius_handle.value = context_raw.brush_radius; + } + ui_header_handle.redraws = 2; + } + else if (context_raw.brush_can_lock) { + context_raw.brush_can_lock = false; + context_raw.brush_locked = true; + } + } + } + ///end + + ///if is_lab + if ((context_raw.brush_can_lock || context_raw.brush_locked) && mouse_moved) { + if (operator_shortcut(config_keymap.brush_radius, shortcut_type_t.DOWN)) { + if (context_raw.brush_locked) { + context_raw.brush_radius += mouse_movement_x / 150; + context_raw.brush_radius = math_max(0.01, math_min(4.0, context_raw.brush_radius)); + context_raw.brush_radius = math_round(context_raw.brush_radius * 100) / 100; + context_raw.brush_radius_handle.value = context_raw.brush_radius; + ui_header_handle.redraws = 2; + } + else if (context_raw.brush_can_lock) { + context_raw.brush_can_lock = false; + context_raw.brush_locked = true; + } + } + } + ///end + + let is_typing: bool = ui_base_ui.is_typing || ui_view2d_ui.is_typing || ui_nodes_ui.is_typing; + + ///if (is_paint || is_sculpt) + if (!is_typing) { + if (operator_shortcut(config_keymap.select_material, shortcut_type_t.DOWN)) { + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; + for (let i: i32 = 1; i < 10; ++i) if (keyboard_started(i + "")) context_select_material(i - 1); + } + else if (operator_shortcut(config_keymap.select_layer, shortcut_type_t.DOWN)) { + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + for (let i: i32 = 1; i < 10; ++i) if (keyboard_started(i + "")) context_select_layer(i - 1); + } + } + ///end + + // Viewport shortcuts + if (context_in_paint_area() && !is_typing) { + + ///if is_paint + if (!mouse_down("right")) { // Fly mode off + if (operator_shortcut(config_keymap.tool_brush)) context_select_tool(workspace_tool_t.BRUSH); + else if (operator_shortcut(config_keymap.tool_eraser)) context_select_tool(workspace_tool_t.ERASER); + else if (operator_shortcut(config_keymap.tool_fill)) context_select_tool(workspace_tool_t.FILL); + else if (operator_shortcut(config_keymap.tool_colorid)) context_select_tool(workspace_tool_t.COLORID); + else if (operator_shortcut(config_keymap.tool_decal)) context_select_tool(workspace_tool_t.DECAL); + else if (operator_shortcut(config_keymap.tool_text)) context_select_tool(workspace_tool_t.TEXT); + else if (operator_shortcut(config_keymap.tool_clone)) context_select_tool(workspace_tool_t.CLONE); + else if (operator_shortcut(config_keymap.tool_blur)) context_select_tool(workspace_tool_t.BLUR); + else if (operator_shortcut(config_keymap.tool_smudge)) context_select_tool(workspace_tool_t.SMUDGE); + else if (operator_shortcut(config_keymap.tool_particle)) context_select_tool(workspace_tool_t.PARTICLE); + else if (operator_shortcut(config_keymap.tool_picker)) context_select_tool(workspace_tool_t.PICKER); + else if (operator_shortcut(config_keymap.tool_bake)) context_select_tool(workspace_tool_t.BAKE); + else if (operator_shortcut(config_keymap.tool_gizmo)) context_select_tool(workspace_tool_t.GIZMO); + else if (operator_shortcut(config_keymap.tool_material)) context_select_tool(workspace_tool_t.MATERIAL); + else if (operator_shortcut(config_keymap.swap_brush_eraser)) context_select_tool(context_raw.tool == workspace_tool_t.BRUSH ? workspace_tool_t.ERASER : workspace_tool_t.BRUSH); + } + + // Radius + if (context_raw.tool == workspace_tool_t.BRUSH || + context_raw.tool == workspace_tool_t.ERASER || + context_raw.tool == workspace_tool_t.DECAL || + context_raw.tool == workspace_tool_t.TEXT || + context_raw.tool == workspace_tool_t.CLONE || + context_raw.tool == workspace_tool_t.BLUR || + context_raw.tool == workspace_tool_t.SMUDGE || + context_raw.tool == workspace_tool_t.PARTICLE) { + if (operator_shortcut(config_keymap.brush_radius) || + operator_shortcut(config_keymap.brush_opacity) || + operator_shortcut(config_keymap.brush_angle) || + (decal_mask && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.brush_radius))) { + context_raw.brush_can_lock = true; + if (!pen_connected) mouse_lock(); + context_raw.lock_started_x = mouse_x; + context_raw.lock_started_y = mouse_y; + } + else if (operator_shortcut(config_keymap.brush_radius_decrease, shortcut_type_t.REPEAT)) { + context_raw.brush_radius -= ui_base_get_radius_increment(); + context_raw.brush_radius = math_max(math_round(context_raw.brush_radius * 100) / 100, 0.01); + context_raw.brush_radius_handle.value = context_raw.brush_radius; + ui_header_handle.redraws = 2; + } + else if (operator_shortcut(config_keymap.brush_radius_increase, shortcut_type_t.REPEAT)) { + context_raw.brush_radius += ui_base_get_radius_increment(); + context_raw.brush_radius = math_round(context_raw.brush_radius * 100) / 100; + context_raw.brush_radius_handle.value = context_raw.brush_radius; + ui_header_handle.redraws = 2; + } + else if (decal_mask) { + if (operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.brush_radius_decrease, shortcut_type_t.REPEAT)) { + context_raw.brush_decal_mask_radius -= ui_base_get_radius_increment(); + context_raw.brush_decal_mask_radius = math_max(math_round(context_raw.brush_decal_mask_radius * 100) / 100, 0.01); + context_raw.brush_decal_mask_radius_handle.value = context_raw.brush_decal_mask_radius; + ui_header_handle.redraws = 2; + } + else if (operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.brush_radius_increase, shortcut_type_t.REPEAT)) { + context_raw.brush_decal_mask_radius += ui_base_get_radius_increment(); + context_raw.brush_decal_mask_radius = math_round(context_raw.brush_decal_mask_radius * 100) / 100; + context_raw.brush_decal_mask_radius_handle.value = context_raw.brush_decal_mask_radius; + ui_header_handle.redraws = 2; + } + } + } + + if (decal_mask && (operator_shortcut(config_keymap.decal_mask, shortcut_type_t.STARTED) || operator_shortcut(config_keymap.decal_mask, shortcut_type_t.RELEASED))) { + ui_header_handle.redraws = 2; + } + ///end + + ///if is_lab + if (ui_header_worktab.position == space_type_t.SPACE3D) { + // Radius + if (context_raw.tool == workspace_tool_t.ERASER || + context_raw.tool == workspace_tool_t.CLONE || + context_raw.tool == workspace_tool_t.BLUR || + context_raw.tool == workspace_tool_t.SMUDGE) { + if (operator_shortcut(config_keymap.brush_radius)) { + context_raw.brush_can_lock = true; + if (!pen_connected) mouse_lock(); + context_raw.lock_started_x = mouse_x; + context_raw.lock_started_y = mouse_y; + } + else if (operator_shortcut(config_keymap.brush_radius_decrease, shortcut_type_t.REPEAT)) { + context_raw.brush_radius -= ui_base_get_radius_increment(); + context_raw.brush_radius = math_max(math_round(context_raw.brush_radius * 100) / 100, 0.01); + context_raw.brush_radius_handle.value = context_raw.brush_radius; + ui_header_handle.redraws = 2; + } + else if (operator_shortcut(config_keymap.brush_radius_increase, shortcut_type_t.REPEAT)) { + context_raw.brush_radius += ui_base_get_radius_increment(); + context_raw.brush_radius = math_round(context_raw.brush_radius * 100) / 100; + context_raw.brush_radius_handle.value = context_raw.brush_radius; + ui_header_handle.redraws = 2; + } + } + } + ///end + + // Viewpoint + if (mouse_view_x() < app_w()) { + if (operator_shortcut(config_keymap.view_reset)) { + viewport_reset(); + viewport_scale_to_bounds(); + } + else if (operator_shortcut(config_keymap.view_back)) viewport_set_view(0, 1, 0, math_pi() / 2, 0, math_pi()); + else if (operator_shortcut(config_keymap.view_front)) viewport_set_view(0, -1, 0, math_pi() / 2, 0, 0); + else if (operator_shortcut(config_keymap.view_left)) viewport_set_view(-1, 0, 0, math_pi() / 2, 0, -math_pi() / 2); + else if (operator_shortcut(config_keymap.view_right)) viewport_set_view(1, 0, 0, math_pi() / 2, 0, math_pi() / 2); + else if (operator_shortcut(config_keymap.view_bottom)) viewport_set_view(0, 0, -1, math_pi(), 0, math_pi()); + else if (operator_shortcut(config_keymap.view_camera_type)) { + context_raw.camera_type = context_raw.camera_type == camera_type_t.PERSPECTIVE ? camera_type_t.ORTHOGRAPHIC : camera_type_t.PERSPECTIVE; + context_raw.cam_handle.position = context_raw.camera_type; + viewport_update_camera_type(context_raw.camera_type); + } + else if (operator_shortcut(config_keymap.view_orbit_left, shortcut_type_t.REPEAT)) viewport_orbit(-math_pi() / 12, 0); + else if (operator_shortcut(config_keymap.view_orbit_right, shortcut_type_t.REPEAT)) viewport_orbit(math_pi() / 12, 0); + else if (operator_shortcut(config_keymap.view_orbit_up, shortcut_type_t.REPEAT)) viewport_orbit(0, -math_pi() / 12); + else if (operator_shortcut(config_keymap.view_orbit_down, shortcut_type_t.REPEAT)) viewport_orbit(0, math_pi() / 12); + else if (operator_shortcut(config_keymap.view_orbit_opposite)) viewport_orbit_opposite(); + else if (operator_shortcut(config_keymap.view_zoom_in, shortcut_type_t.REPEAT)) viewport_zoom(0.2); + else if (operator_shortcut(config_keymap.view_zoom_out, shortcut_type_t.REPEAT)) viewport_zoom(-0.2); + else if (operator_shortcut(config_keymap.viewport_mode)) { + + let count: i32; + + ///if (is_paint || is_sculpt) + count = 16; + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + count += 1; + ///end + ///end + + ///if is_lab + count = 9; + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + count += 1; + ///end + ///end + + ui_menu_draw(function (ui: zui_t) { + let mode_handle: zui_handle_t = zui_handle("uibase_0"); + mode_handle.position = context_raw.viewport_mode; + zui_text(tr("Viewport Mode"), zui_align_t.RIGHT, ui.t.HIGHLIGHT_COL); + let modes: string[] = [ + tr("Lit"), + tr("Base Color"), + tr("Normal"), + tr("Occlusion"), + tr("Roughness"), + tr("Metallic"), + tr("Opacity"), + tr("Height"), + ///if (is_paint || is_sculpt) + tr("Emission"), + tr("Subsurface"), + tr("TexCoord"), + tr("Object Normal"), + tr("Material ID"), + tr("Object ID"), + tr("Mask") + ///end + ]; + + let shortcuts: string[] = ["l", "b", "n", "o", "r", "m", "a", "h", "e", "s", "t", "1", "2", "3", "4"]; + + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + if (krom_raytrace_supported()) { + modes.push(tr("Path Traced")); + shortcuts.push("p"); + } + ///end + + for (let i: i32 = 0; i < modes.length; ++i) { + zui_radio(mode_handle, i, modes[i], shortcuts[i]); + } + + let index: i32 = shortcuts.indexOf(keyboard_key_code(ui.key)); + if (ui.is_key_pressed && index != -1) { + mode_handle.position = index; + ui.changed = true; + context_set_viewport_mode(mode_handle.position); + } + else if (mode_handle.changed) { + context_set_viewport_mode(mode_handle.position); + ui.changed = true; + } + }, count); + } + } + + if (operator_shortcut(config_keymap.operator_search)) ui_base_operator_search(); + } + + if (context_raw.brush_can_lock || context_raw.brush_locked) { + if (mouse_moved && context_raw.brush_can_unlock) { + context_raw.brush_locked = false; + context_raw.brush_can_unlock = false; + } + + ///if (is_paint || is_sculpt) + let b: bool = (context_raw.brush_can_lock || context_raw.brush_locked) && + !operator_shortcut(config_keymap.brush_radius, shortcut_type_t.DOWN) && + !operator_shortcut(config_keymap.brush_opacity, shortcut_type_t.DOWN) && + !operator_shortcut(config_keymap.brush_angle, shortcut_type_t.DOWN) && + !(decal_mask && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.brush_radius, shortcut_type_t.DOWN)); + ///end + ///if is_lab + let b: bool = (context_raw.brush_can_lock || context_raw.brush_locked) && + !operator_shortcut(config_keymap.brush_radius, shortcut_type_t.DOWN); + ///end + + if (b) { + mouse_unlock(); + context_raw.last_paint_x = -1; + context_raw.last_paint_y = -1; + if (context_raw.brush_can_lock) { + context_raw.brush_can_lock = false; + context_raw.brush_can_unlock = false; + context_raw.brush_locked = false; + } + else { + context_raw.brush_can_unlock = true; + } + } + } + + ///if (is_paint || is_sculpt) + if (ui_base_border_handle_ptr != 0) { + if (ui_base_border_handle_ptr == ui_nodes_hwnd.ptr || ui_base_border_handle_ptr == ui_view2d_hwnd.ptr) { + if (ui_base_border_started == border_side_t.LEFT) { + config_raw.layout[layout_size_t.NODES_W] -= math_floor(mouse_movement_x); + if (config_raw.layout[layout_size_t.NODES_W] < 32) config_raw.layout[layout_size_t.NODES_W] = 32; + else if (config_raw.layout[layout_size_t.NODES_W] > sys_width() * 0.7) config_raw.layout[layout_size_t.NODES_W] = math_floor(sys_width() * 0.7); + } + else { // UINodes / UIView2D ratio + config_raw.layout[layout_size_t.NODES_H] -= math_floor(mouse_movement_y); + if (config_raw.layout[layout_size_t.NODES_H] < 32) config_raw.layout[layout_size_t.NODES_H] = 32; + else if (config_raw.layout[layout_size_t.NODES_H] > app_h() * 0.95) config_raw.layout[layout_size_t.NODES_H] = math_floor(app_h() * 0.95); + } + } + else if (ui_base_border_handle_ptr == ui_base_hwnds[tab_area_t.STATUS].ptr) { + let my: i32 = math_floor(mouse_movement_y); + if (config_raw.layout[layout_size_t.STATUS_H] - my >= ui_status_default_status_h * config_raw.window_scale && config_raw.layout[layout_size_t.STATUS_H] - my < sys_height() * 0.7) { + config_raw.layout[layout_size_t.STATUS_H] -= my; + } + } + else { + if (ui_base_border_started == border_side_t.LEFT) { + config_raw.layout[layout_size_t.SIDEBAR_W] -= math_floor(mouse_movement_x); + if (config_raw.layout[layout_size_t.SIDEBAR_W] < ui_base_sidebar_mini_w) config_raw.layout[layout_size_t.SIDEBAR_W] = ui_base_sidebar_mini_w; + else if (config_raw.layout[layout_size_t.SIDEBAR_W] > sys_width() - ui_base_sidebar_mini_w) config_raw.layout[layout_size_t.SIDEBAR_W] = sys_width() - ui_base_sidebar_mini_w; + } + else { + let my: i32 = math_floor(mouse_movement_y); + if (ui_base_border_handle_ptr == ui_base_hwnds[tab_area_t.SIDEBAR1].ptr && ui_base_border_started == border_side_t.TOP) { + if (config_raw.layout[layout_size_t.SIDEBAR_H0] + my > 32 && config_raw.layout[layout_size_t.SIDEBAR_H1] - my > 32) { + config_raw.layout[layout_size_t.SIDEBAR_H0] += my; + config_raw.layout[layout_size_t.SIDEBAR_H1] -= my; + } + } + } + } + } + ///end + + ///if is_lab + if (ui_base_border_handle_ptr != 0) { + if (ui_base_border_handle_ptr == ui_nodes_hwnd.ptr || ui_base_border_handle_ptr == ui_view2d_hwnd.ptr) { + if (ui_base_border_started == border_side_t.LEFT) { + config_raw.layout[layout_size_t.NODES_W] -= math_floor(mouse_movement_x); + if (config_raw.layout[layout_size_t.NODES_W] < 32) config_raw.layout[layout_size_t.NODES_W] = 32; + else if (config_raw.layout[layout_size_t.NODES_W] > sys_width() * 0.7) config_raw.layout[layout_size_t.NODES_W] = math_floor(sys_width() * 0.7); + } + else { // UINodes / UIView2D ratio + config_raw.layout[layout_size_t.NODES_H] -= math_floor(mouse_movement_y); + if (config_raw.layout[layout_size_t.NODES_H] < 32) config_raw.layout[layout_size_t.NODES_H] = 32; + else if (config_raw.layout[layout_size_t.NODES_H] > app_h() * 0.95) config_raw.layout[layout_size_t.NODES_H] = math_floor(app_h() * 0.95); + } + } + else if (ui_base_border_handle_ptr == ui_base_hwnds[tab_area_t.STATUS].ptr) { + let my: i32 = math_floor(mouse_movement_y); + if (config_raw.layout[layout_size_t.STATUS_H] - my >= ui_status_default_status_h * config_raw.window_scale && config_raw.layout[layout_size_t.STATUS_H] - my < sys_height() * 0.7) { + config_raw.layout[layout_size_t.STATUS_H] -= my; + } + } + } + ///end + + if (!mouse_down()) { + ui_base_border_handle_ptr = 0; + base_is_resizing = false; + } + + ///if arm_physics + if (context_raw.tool == workspace_tool_t.PARTICLE && context_raw.particle_physics && context_in_paint_area() && !context_raw.paint2d) { + util_particle_init_physics(); + let world: PhysicsWorldRaw = PhysicsWorld.active; + PhysicsWorld.late_update(world); + context_raw.ddirty = 2; + context_raw.rdirty = 2; + if (mouse_started()) { + if (context_raw.particle_timer != null) { + tween_stop(context_raw.particle_timer); + context_raw.particle_timer.done(); + context_raw.particle_timer = null; + } + history_push_undo = true; + context_raw.particle_hit_x = context_raw.particle_hit_y = context_raw.particle_hit_z = 0; + let o: object_t = scene_spawn_object(".Sphere"); + let md: material_data_t = data_get_material("Scene", ".Gizmo"); + let mo: mesh_object_t = o.ext; + mo.base.name = ".Bullet"; + mo.materials[0] = md; + mo.base.visible = true; + + let camera: camera_object_t = scene_camera; + let ct: transform_t = camera.base.transform; + vec4_set(mo.base.transform.loc, transform_world_x(ct), transform_world_y(ct), transform_world_z(ct)); + vec4_set(mo.base.transform.scale, context_raw.brush_radius * 0.2, context_raw.brush_radius * 0.2, context_raw.brush_radius * 0.2); + transform_build_matrix(mo.base.transform); + + let body: PhysicsBodyRaw = PhysicsBody.create(); + body.shape = shape_type_t.SPHERE; + body.mass = 1.0; + body.ccd = true; + mo.base.transform.radius /= 10; // Lower ccd radius + PhysicsBody.init(body, mo.base); + (mo.base as any).physicsBody = body; + mo.base.transform.radius *= 10; + + let ray: ray_t = raycast_get_ray(mouse_view_x(), mouse_view_y(), camera); + PhysicsBody.apply_impulse(body, vec4_mult(ray.dir, 0.15)); + + context_raw.particle_timer = tween_timer(5, function() { mesh_object_remove(mo); }); + } + + let pairs: pair_t[] = PhysicsWorld.get_contact_pairs(world, context_raw.paint_body); + if (pairs != null) { + for (let p of pairs) { + context_raw.last_particle_hit_x = context_raw.particle_hit_x != 0 ? context_raw.particle_hit_x : p.pos_a.x; + context_raw.last_particle_hit_y = context_raw.particle_hit_y != 0 ? context_raw.particle_hit_y : p.pos_a.y; + context_raw.last_particle_hit_z = context_raw.particle_hit_z != 0 ? context_raw.particle_hit_z : p.pos_a.z; + context_raw.particle_hit_x = p.pos_a.x; + context_raw.particle_hit_y = p.pos_a.y; + context_raw.particle_hit_z = p.pos_a.z; + context_raw.pdirty = 1; + break; // 1 pair for now + } + } + } + ///end +} + +function ui_base_view_top() { + let is_typing: bool = ui_base_ui.is_typing || ui_view2d_ui.is_typing || ui_nodes_ui.is_typing; + + if (context_in_paint_area() && !is_typing) { + if (mouse_view_x() < app_w()) { + viewport_set_view(0, 0, 1, 0, 0, 0); + } + } +} + +function ui_base_operator_search() { + let search_handle: zui_handle_t = zui_handle("uibase_1"); + let first: bool = true; + ui_menu_draw(function (ui: zui_t) { + zui_fill(0, 0, ui._w / zui_SCALE(ui), ui.t.ELEMENT_H * 8, ui.t.SEPARATOR_COL); + let search: string = zui_text_input(search_handle, "", zui_align_t.LEFT, true, true); + ui.changed = false; + if (first) { + first = false; + search_handle.text = ""; + zui_start_text_edit(search_handle); // Focus search bar + } + + if (search_handle.changed) ui_base_operator_search_offset = 0; + + if (ui.is_key_pressed) { // Move selection + if (ui.key == key_code_t.DOWN && ui_base_operator_search_offset < 6) ui_base_operator_search_offset++; + if (ui.key == key_code_t.UP && ui_base_operator_search_offset > 0) ui_base_operator_search_offset--; + } + let enter: bool = keyboard_down("enter"); + let count: i32 = 0; + let BUTTON_COL: i32 = ui.t.BUTTON_COL; + + for (let n in config_keymap) { + if (n.indexOf(search) >= 0) { + ui.t.BUTTON_COL = count == ui_base_operator_search_offset ? ui.t.HIGHLIGHT_COL : ui.t.SEPARATOR_COL; + if (zui_button(n, zui_align_t.LEFT, config_keymap[n]) || (enter && count == ui_base_operator_search_offset)) { + if (enter) { + ui.changed = true; + count = 6; // Trigger break + } + operator_run(n); + } + if (++count > 6) break; + } + } + + if (enter && count == 0) { // Hide popup on enter when command is not found + ui.changed = true; + search_handle.text = ""; + } + ui.t.BUTTON_COL = BUTTON_COL; + }, 8, -1, -1); +} + +function ui_base_toggle_distract_free() { + ui_base_show = !ui_base_show; + base_resize(); +} + +function ui_base_get_radius_increment(): f32 { + return 0.1; +} + +function ui_base_hit_rect(mx: f32, my: f32, x: i32, y: i32, w: i32, h: i32) { + return mx > x && mx < x + w && my > y && my < y + h; +} + +///if (is_paint || is_sculpt) +function ui_base_get_brush_stencil_rect(): rect_t { + let w: i32 = math_floor(context_raw.brush_stencil_image.width * (base_h() / context_raw.brush_stencil_image.height) * context_raw.brush_stencil_scale); + let h: i32 = math_floor(base_h() * context_raw.brush_stencil_scale); + let x: i32 = math_floor(base_x() + context_raw.brush_stencil_x * base_w()); + let y: i32 = math_floor(base_y() + context_raw.brush_stencil_y * base_h()); + return { w: w, h: h, x: x, y: y }; +} +///end + +function ui_base_update_ui() { + if (console_message_timer > 0) { + console_message_timer -= time_delta(); + if (console_message_timer <= 0) ui_base_hwnds[tab_area_t.STATUS].redraws = 2; + } + + ///if (is_paint || is_sculpt) + ui_base_sidebar_mini_w = math_floor(ui_base_default_sidebar_mini_w * zui_SCALE(ui_base_ui)); + ///end + + if (!base_ui_enabled) return; + + ///if (is_paint || is_sculpt) + // Same mapping for paint and rotate (predefined in touch keymap) + if (context_in_viewport()) { + if (mouse_started() && config_keymap.action_paint == config_keymap.action_rotate) { + ui_base_action_paint_remap = config_keymap.action_paint; + util_render_pick_pos_nor_tex(); + let is_mesh: bool = math_abs(context_raw.posx_picked) < 50 && math_abs(context_raw.posy_picked) < 50 && math_abs(context_raw.posz_picked) < 50; + ///if krom_android + // Allow rotating with both pen and touch, because hovering a pen prevents touch input on android + let pen_only: bool = false; + ///else + let pen_only: bool = context_raw.pen_painting_only; + ///end + let is_pen: bool = pen_only && pen_down(); + // Mesh picked - disable rotate + // Pen painting only - rotate with touch, paint with pen + if ((is_mesh && !pen_only) || is_pen) { + config_keymap.action_rotate = ""; + config_keymap.action_paint = ui_base_action_paint_remap; + } + // World sphere picked - disable paint + else { + config_keymap.action_paint = ""; + config_keymap.action_rotate = ui_base_action_paint_remap; + } + } + else if (!mouse_down() && ui_base_action_paint_remap != "") { + config_keymap.action_rotate = ui_base_action_paint_remap; + config_keymap.action_paint = ui_base_action_paint_remap; + ui_base_action_paint_remap = ""; + } + } + + if (context_raw.brush_stencil_image != null && operator_shortcut(config_keymap.stencil_transform, shortcut_type_t.DOWN)) { + let r: rect_t = ui_base_get_brush_stencil_rect(); + if (mouse_started("left")) { + context_raw.brush_stencil_scaling = + ui_base_hit_rect(mouse_x, mouse_y, r.x - 8, r.y - 8, 16, 16) || + ui_base_hit_rect(mouse_x, mouse_y, r.x - 8, r.h + r.y - 8, 16, 16) || + ui_base_hit_rect(mouse_x, mouse_y, r.w + r.x - 8, r.y - 8, 16, 16) || + ui_base_hit_rect(mouse_x, mouse_y, r.w + r.x - 8, r.h + r.y - 8, 16, 16); + let cosa: f32 = math_cos(-context_raw.brush_stencil_angle); + let sina: f32 = math_sin(-context_raw.brush_stencil_angle); + let ox: f32 = 0; + let oy: f32 = -r.h / 2; + let x: f32 = ox * cosa - oy * sina; + let y: f32 = ox * sina + oy * cosa; + x += r.x + r.w / 2; + y += r.y + r.h / 2; + context_raw.brush_stencil_rotating = + ui_base_hit_rect(mouse_x, mouse_y, math_floor(x - 16), math_floor(y - 16), 32, 32); + } + let _scale: f32 = context_raw.brush_stencil_scale; + if (mouse_down("left")) { + if (context_raw.brush_stencil_scaling) { + let mult: i32 = mouse_x > r.x + r.w / 2 ? 1 : -1; + context_raw.brush_stencil_scale += mouse_movement_x / 400 * mult; + } + else if (context_raw.brush_stencil_rotating) { + let gizmo_x: f32 = r.x + r.w / 2; + let gizmo_y: f32 = r.y + r.h / 2; + context_raw.brush_stencil_angle = -math_atan2(mouse_y - gizmo_y, mouse_x - gizmo_x) - math_pi() / 2; + } + else { + context_raw.brush_stencil_x += mouse_movement_x / base_w(); + context_raw.brush_stencil_y += mouse_movement_y / base_h(); + } + } + else context_raw.brush_stencil_scaling = false; + if (mouse_wheel_delta != 0) { + context_raw.brush_stencil_scale -= mouse_wheel_delta / 10; + } + // Center after scale + let ratio: f32 = base_h() / context_raw.brush_stencil_image.height; + let old_w: f32 = _scale * context_raw.brush_stencil_image.width * ratio; + let new_w: f32 = context_raw.brush_stencil_scale * context_raw.brush_stencil_image.width * ratio; + let old_h: f32 = _scale * base_h(); + let new_h: f32 = context_raw.brush_stencil_scale * base_h(); + context_raw.brush_stencil_x += (old_w - new_w) / base_w() / 2; + context_raw.brush_stencil_y += (old_h - new_h) / base_h() / 2; + } + ///end + + let set_clone_source: bool = context_raw.tool == workspace_tool_t.CLONE && operator_shortcut(config_keymap.set_clone_source + "+" + config_keymap.action_paint, shortcut_type_t.DOWN); + + ///if (is_paint || is_sculpt) + let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; + let decal_mask: bool = decal && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.action_paint, shortcut_type_t.DOWN); + let down: bool = operator_shortcut(config_keymap.action_paint, shortcut_type_t.DOWN) || + decal_mask || + set_clone_source || + operator_shortcut(config_keymap.brush_ruler + "+" + config_keymap.action_paint, shortcut_type_t.DOWN) || + (pen_down() && !keyboard_down("alt")); + ///end + ///if is_lab + let down: bool = operator_shortcut(config_keymap.action_paint, shortcut_type_t.DOWN) || + set_clone_source || + operator_shortcut(config_keymap.brush_ruler + "+" + config_keymap.action_paint, shortcut_type_t.DOWN) || + (pen_down() && !keyboard_down("alt")); + ///end + + if (config_raw.touch_ui) { + if (pen_down()) { + context_raw.pen_painting_only = true; + } + else if (context_raw.pen_painting_only) { + down = false; + } + } + + ///if arm_physics + if (context_raw.tool == workspace_tool_t.PARTICLE && context_raw.particle_physics) { + down = false; + } + ///end + + ///if (is_paint || is_sculpt) + ///if krom_ios + // No hover on iPad, decals are painted by pen release + if (decal) { + down = pen_released(); + if (!context_raw.pen_painting_only) { + down = down || mouse_released(); + } + } + ///end + ///end + + if (down) { + let mx: i32 = mouse_view_x(); + let my: i32 = mouse_view_y(); + let ww: i32 = app_w(); + + ///if (is_paint || is_sculpt) + if (context_raw.paint2d) { + mx -= app_w(); + ww = ui_view2d_ww; + } + ///end + + if (mx < ww && + mx > app_x() && + my < app_h() && + my > app_y()) { + + if (set_clone_source) { + context_raw.clone_start_x = mx; + context_raw.clone_start_y = my; + } + else { + if (context_raw.brush_time == 0 && + !base_is_dragging && + !base_is_resizing && + !base_is_combo_selected()) { // Paint started + + // Draw line + if (operator_shortcut(config_keymap.brush_ruler + "+" + config_keymap.action_paint, shortcut_type_t.DOWN)) { + context_raw.last_paint_vec_x = context_raw.last_paint_x; + context_raw.last_paint_vec_y = context_raw.last_paint_y; + } + + ///if (is_paint || is_sculpt) + history_push_undo = true; + + if (context_raw.tool == workspace_tool_t.CLONE && context_raw.clone_start_x >= 0.0) { // Clone delta + context_raw.clone_delta_x = (context_raw.clone_start_x - mx) / ww; + context_raw.clone_delta_y = (context_raw.clone_start_y - my) / app_h(); + context_raw.clone_start_x = -1; + } + else if (context_raw.tool == workspace_tool_t.PARTICLE) { + // Reset particles + ///if arm_particles + let emitter: mesh_object_t = scene_get_child(".ParticleEmitter").ext; + let psys: particle_sys_t = emitter.particle_systems[0]; + psys.time = 0; + // psys.time = psys.seed * psys.animtime; + // psys.seed++; + ///end + } + else if (context_raw.tool == workspace_tool_t.FILL && context_raw.fill_type_handle.position == fill_type_t.UV_ISLAND) { + util_uv_uvislandmap_cached = false; + } + ///end + } + + context_raw.brush_time += time_delta(); + + ///if (is_paint || is_sculpt) + if (context_raw.run_brush != null) { + context_raw.run_brush(0); + } + ///end + ///if is_lab + if (context_run_brush != null) { + context_run_brush(0); + } + ///end + } + } + } + else if (context_raw.brush_time > 0) { // Brush released + context_raw.brush_time = 0; + context_raw.prev_paint_vec_x = -1; + context_raw.prev_paint_vec_y = -1; + ///if (!krom_direct3d12 && !krom_vulkan && !krom_metal) // Keep accumulated samples for D3D12 + context_raw.ddirty = 3; + ///end + context_raw.brush_blend_dirty = true; // Update brush mask + + ///if (is_paint || is_sculpt) + context_raw.layer_preview_dirty = true; // Update layer preview + ///end + + ///if is_paint + // New color id picked, update fill layer + if (context_raw.tool == workspace_tool_t.COLORID && context_raw.layer.fill_layer != null) { + base_notify_on_next_frame(function () { + base_update_fill_layer(); + MakeMaterial.parse_paint_material(false); + }); + } + ///end + } + + ///if is_paint + if (context_raw.layers_preview_dirty) { + context_raw.layers_preview_dirty = false; + context_raw.layer_preview_dirty = false; + context_raw.mask_preview_last = null; + if (base_pipe_merge == null) base_make_pipe(); + // Update all layer previews + for (let l of project_layers) { + if (SlotLayer.is_group(l)) continue; + let target: image_t = l.texpaint_preview; + let source: image_t = l.texpaint; + g2_begin(target); + g2_clear(0x00000000); + // g2_set_pipeline(l.isMask() ? base_pipe_copy8 : base_pipe_copy); + g2_set_pipeline(base_pipe_copy); // texpaint_preview is always RGBA32 for now + g2_draw_scaled_image(source, 0, 0, target.width, target.height); + g2_set_pipeline(null); + g2_end(); + } + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + } + if (context_raw.layer_preview_dirty && !SlotLayer.is_group(context_raw.layer)) { + context_raw.layer_preview_dirty = false; + context_raw.mask_preview_last = null; + if (base_pipe_merge == null) base_make_pipe(); + // Update layer preview + let l: SlotLayerRaw = context_raw.layer; + let target: image_t = l.texpaint_preview; + let source: image_t = l.texpaint; + g2_begin(target); + g2_clear(0x00000000); + // g2_set_pipeline(raw.layer.isMask() ? base_pipe_copy8 : base_pipe_copy); + g2_set_pipeline(base_pipe_copy); // texpaint_preview is always RGBA32 for now + g2_draw_scaled_image(source, 0, 0, target.width, target.height); + g2_set_pipeline(null); + g2_end(); + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + } + ///end + + let undo_pressed: bool = operator_shortcut(config_keymap.edit_undo); + let redo_pressed: bool = operator_shortcut(config_keymap.edit_redo) || + (keyboard_down("control") && keyboard_started("y")); + + // Two-finger tap to undo, three-finger tap to redo + if (context_in_viewport() && config_raw.touch_ui) { + if (mouse_started("middle")) { ui_base_redo_tap_time = time_time(); } + else if (mouse_started("right")) { ui_base_undo_tap_time = time_time(); } + else if (mouse_released("middle") && time_time() - ui_base_redo_tap_time < 0.1) { ui_base_redo_tap_time = ui_base_undo_tap_time = 0; redo_pressed = true; } + else if (mouse_released("right") && time_time() - ui_base_undo_tap_time < 0.1) { ui_base_redo_tap_time = ui_base_undo_tap_time = 0; undo_pressed = true; } + } + + if (undo_pressed) history_undo(); + else if (redo_pressed) history_redo(); + + ///if (is_paint || is_sculpt) + gizmo_update(); + ///end +} + +function ui_base_render() { + if (!ui_base_show && config_raw.touch_ui) { + ui_base_ui.input_enabled = true; + g2_end(); + zui_begin(ui_base_ui); + if (zui_window(zui_handle("uibase_2"), 0, 0, 150, math_floor(zui_ELEMENT_H(ui_base_ui) + zui_ELEMENT_OFFSET(ui_base_ui) + 1))) { + if (zui_button(tr("Close"))) { + ui_base_toggle_distract_free(); + } + } + zui_end(); + g2_begin(null); + } + + if (!ui_base_show || sys_width() == 0 || sys_height() == 0) return; + + ui_base_ui.input_enabled = base_ui_enabled; + + // Remember last tab positions + for (let i: i32 = 0; i < ui_base_htabs.length; ++i) { + if (ui_base_htabs[i].changed) { + config_raw.layout_tabs[i] = ui_base_htabs[i].position; + config_save(); + } + } + + // Set tab positions + for (let i: i32 = 0; i < ui_base_htabs.length; ++i) { + ui_base_htabs[i].position = config_raw.layout_tabs[i]; + } + + g2_end(); + zui_begin(ui_base_ui); + + ///if (is_paint || is_sculpt) + ui_toolbar_render_ui(); + ///end + ui_menubar_render_ui(); + ui_header_render_ui(); + ui_status_render_ui(); + + ///if (is_paint || is_sculpt) + ui_base_draw_sidebar(); + ///end + + zui_end(); + g2_begin(null); +} + +///if (is_paint || is_sculpt) +function ui_base_draw_sidebar() { + // Tabs + let mini: bool = config_raw.layout[layout_size_t.SIDEBAR_W] <= ui_base_sidebar_mini_w; + let expand_button_offset: i32 = config_raw.touch_ui ? math_floor(zui_ELEMENT_H(ui_base_ui) + zui_ELEMENT_OFFSET(ui_base_ui)) : 0; + ui_base_tabx = sys_width() - config_raw.layout[layout_size_t.SIDEBAR_W]; + + let _SCROLL_W: i32 = ui_base_ui.t.SCROLL_W; + if (mini) ui_base_ui.t.SCROLL_W = ui_base_ui.t.SCROLL_MINI_W; + + if (zui_window(ui_base_hwnds[tab_area_t.SIDEBAR0], ui_base_tabx, 0, config_raw.layout[layout_size_t.SIDEBAR_W], config_raw.layout[layout_size_t.SIDEBAR_H0])) { + for (let i: i32 = 0; i < (mini ? 1 : ui_base_hwnd_tabs[tab_area_t.SIDEBAR0].length); ++i) ui_base_hwnd_tabs[tab_area_t.SIDEBAR0][i](ui_base_htabs[tab_area_t.SIDEBAR0]); + } + if (zui_window(ui_base_hwnds[tab_area_t.SIDEBAR1], ui_base_tabx, config_raw.layout[layout_size_t.SIDEBAR_H0], config_raw.layout[layout_size_t.SIDEBAR_W], config_raw.layout[layout_size_t.SIDEBAR_H1] - expand_button_offset)) { + for (let i: i32 = 0; i < (mini ? 1 : ui_base_hwnd_tabs[tab_area_t.SIDEBAR1].length); ++i) ui_base_hwnd_tabs[tab_area_t.SIDEBAR1][i](ui_base_htabs[tab_area_t.SIDEBAR1]); + } + + zui_end_window(); + ui_base_ui.t.SCROLL_W = _SCROLL_W; + + // Collapse / expand button for mini sidebar + if (config_raw.touch_ui) { + let width: i32 = config_raw.layout[layout_size_t.SIDEBAR_W]; + let height: i32 = math_floor(zui_ELEMENT_H(ui_base_ui) + zui_ELEMENT_OFFSET(ui_base_ui)); + if (zui_window(zui_handle("uibase_3"), sys_width() - width, sys_height() - height, width, height + 1)) { + ui_base_ui._w = width; + let _BUTTON_H: i32 = ui_base_ui.t.BUTTON_H; + let _BUTTON_COL: i32 = ui_base_ui.t.BUTTON_COL; + ui_base_ui.t.BUTTON_H = ui_base_ui.t.ELEMENT_H; + ui_base_ui.t.BUTTON_COL = ui_base_ui.t.WINDOW_BG_COL; + if (zui_button(mini ? "<<" : ">>")) { + config_raw.layout[layout_size_t.SIDEBAR_W] = mini ? ui_base_default_sidebar_full_w : ui_base_default_sidebar_mini_w; + config_raw.layout[layout_size_t.SIDEBAR_W] = math_floor(config_raw.layout[layout_size_t.SIDEBAR_W] * zui_SCALE(ui_base_ui)); + } + ui_base_ui.t.BUTTON_H = _BUTTON_H; + ui_base_ui.t.BUTTON_COL = _BUTTON_COL; + } + } + + // Expand button + if (config_raw.layout[layout_size_t.SIDEBAR_W] == 0) { + let width: i32 = math_floor(g2_font_width(ui_base_ui.font, ui_base_ui.font_size, "<<") + 25 * zui_SCALE(ui_base_ui)); + if (zui_window(ui_base_hminimized, sys_width() - width, 0, width, math_floor(zui_ELEMENT_H(ui_base_ui) + zui_ELEMENT_OFFSET(ui_base_ui) + 1))) { + ui_base_ui._w = width; + let _BUTTON_H: i32 = ui_base_ui.t.BUTTON_H; + let _BUTTON_COL: i32 = ui_base_ui.t.BUTTON_COL; + ui_base_ui.t.BUTTON_H = ui_base_ui.t.ELEMENT_H; + ui_base_ui.t.BUTTON_COL = ui_base_ui.t.SEPARATOR_COL; + + if (zui_button("<<")) { + config_raw.layout[layout_size_t.SIDEBAR_W] = context_raw.maximized_sidebar_width != 0 ? context_raw.maximized_sidebar_width : math_floor(ui_base_default_sidebar_w * config_raw.window_scale); + } + ui_base_ui.t.BUTTON_H = _BUTTON_H; + ui_base_ui.t.BUTTON_COL = _BUTTON_COL; + } + } + else if (ui_base_htabs[tab_area_t.SIDEBAR0].changed && ui_base_htabs[tab_area_t.SIDEBAR0].position == context_raw.last_htab0_pos) { + if (time_time() - context_raw.select_time < 0.25) { + context_raw.maximized_sidebar_width = config_raw.layout[layout_size_t.SIDEBAR_W]; + config_raw.layout[layout_size_t.SIDEBAR_W] = 0; + } + context_raw.select_time = time_time(); + } + context_raw.last_htab0_pos = ui_base_htabs[tab_area_t.SIDEBAR0].position; +} + +function ui_base_render_cursor() { + if (!base_ui_enabled) return; + + ///if is_paint + if (context_raw.tool == workspace_tool_t.MATERIAL || context_raw.tool == workspace_tool_t.BAKE) return; + ///end + + g2_set_color(0xffffffff); + + context_raw.view_index = context_raw.view_index_last; + let mx: i32 = base_x() + context_raw.paint_vec.x * base_w(); + let my: i32 = base_y() + context_raw.paint_vec.y * base_h(); + context_raw.view_index = -1; + + // Radius being scaled + if (context_raw.brush_locked) { + mx += context_raw.lock_started_x - sys_width() / 2; + my += context_raw.lock_started_y - sys_height() / 2; + } + + let tool: workspace_tool_t = context_raw.tool as workspace_tool_t; + + ///if is_paint + if (context_raw.brush_stencil_image != null && + tool != workspace_tool_t.BAKE && + tool != workspace_tool_t.PICKER && + tool != workspace_tool_t.MATERIAL && + tool != workspace_tool_t.COLORID) { + let r: rect_t = ui_base_get_brush_stencil_rect(); + if (!operator_shortcut(config_keymap.stencil_hide, shortcut_type_t.DOWN)) { + g2_set_color(0x88ffffff); + let angle: f32 = context_raw.brush_stencil_angle; + let cx: f32 = r.x + r.w / 2; + let cy: f32 = r.y + r.h / 2; + g2_set_transformation(mat3_multmat(mat3_multmat(mat3_translation(cx, cy), mat3_rotation(-angle)), mat3_translation(-cx, -cy))); + g2_draw_scaled_image(context_raw.brush_stencil_image, r.x, r.y, r.w, r.h); + g2_set_transformation(null); + g2_set_color(0xffffffff); + } + let transform: bool = operator_shortcut(config_keymap.stencil_transform, shortcut_type_t.DOWN); + if (transform) { + // Outline + g2_draw_rect(r.x, r.y, r.w, r.h); + // Scale + g2_draw_rect(r.x - 8, r.y - 8, 16, 16); + g2_draw_rect(r.x - 8 + r.w, r.y - 8, 16, 16); + g2_draw_rect(r.x - 8, r.y - 8 + r.h, 16, 16); + g2_draw_rect(r.x - 8 + r.w, r.y - 8 + r.h, 16, 16); + // Rotate + let angle: f32 = context_raw.brush_stencil_angle; + let cx: f32 = r.x + r.w / 2; + let cy: f32 = r.y + r.h / 2; + g2_set_transformation(mat3_multmat(mat3_multmat(mat3_translation(cx, cy), mat3_rotation(-angle)), mat3_translation(-cx, -cy))); + g2_fill_circle(r.x + r.w / 2, r.y - 4, 8); + g2_set_transformation(null); + } + } + ///end + + // Show picked material next to cursor + if (context_raw.tool == workspace_tool_t.PICKER && context_raw.picker_select_material && context_raw.color_picker_callback == null) { + let img: image_t = context_raw.material.image_icon; + ///if krom_opengl + g2_draw_scaled_image(img, mx + 10, my + 10 + img.height, img.width, -img.height); + ///else + g2_draw_image(img, mx + 10, my + 10); + ///end + } + if (context_raw.tool == workspace_tool_t.PICKER && context_raw.color_picker_callback != null) { + let img: image_t = resource_get("icons.k"); + let rect: rect_t = resource_tile50(img, workspace_tool_t.PICKER, 0); + g2_draw_sub_image(img, mx + 10, my + 10, rect.x, rect.y, rect.w, rect.h); + } + + let cursor_img: image_t = resource_get("cursor.k"); + let psize: i32 = math_floor(cursor_img.width * (context_raw.brush_radius * context_raw.brush_nodes_radius) * zui_SCALE(ui_base_ui)); + + // Clone source cursor + if (context_raw.tool == workspace_tool_t.CLONE && !keyboard_down("alt") && (mouse_down() || pen_down())) { + g2_set_color(0x66ffffff); + g2_draw_scaled_image(cursor_img, mx + context_raw.clone_delta_x * app_w() - psize / 2, my + context_raw.clone_delta_y * app_h() - psize / 2, psize, psize); + g2_set_color(0xffffffff); + } + + let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; + + if (!config_raw.brush_3d || context_in_2d_view() || decal) { + let decal_mask: bool = decal && operator_shortcut(config_keymap.decal_mask, shortcut_type_t.DOWN); + if (decal && !context_in_nodes()) { + let decal_alpha: f32 = 0.5; + if (!decal_mask) { + context_raw.decal_x = context_raw.paint_vec.x; + context_raw.decal_y = context_raw.paint_vec.y; + decal_alpha = context_raw.brush_opacity; + + // Radius being scaled + if (context_raw.brush_locked) { + context_raw.decal_x += (context_raw.lock_started_x - sys_width() / 2) / base_w(); + context_raw.decal_y += (context_raw.lock_started_y - sys_height() / 2) / base_h(); + } + } + + if (!config_raw.brush_live) { + let psizex: i32 = math_floor(256 * zui_SCALE(ui_base_ui) * (context_raw.brush_radius * context_raw.brush_nodes_radius * context_raw.brush_scale_x)); + let psizey: i32 = math_floor(256 * zui_SCALE(ui_base_ui) * (context_raw.brush_radius * context_raw.brush_nodes_radius)); + + context_raw.view_index = context_raw.view_index_last; + let decalx: f32 = base_x() + context_raw.decal_x * base_w() - psizex / 2; + let decaly: f32 = base_y() + context_raw.decal_y * base_h() - psizey / 2; + context_raw.view_index = -1; + + g2_set_color(color_from_floats(1, 1, 1, decal_alpha)); + let angle: f32 = (context_raw.brush_angle + context_raw.brush_nodes_angle) * (math_pi() / 180); + let cx: f32 = decalx + psizex / 2; + let cy: f32 = decaly + psizey / 2; + g2_set_transformation(mat3_multmat(mat3_multmat(mat3_translation(cx, cy), mat3_rotation(angle)), mat3_translation(-cx, -cy))); + ///if (krom_direct3d11 || krom_direct3d12 || krom_metal || krom_vulkan) + g2_draw_scaled_image(context_raw.decal_image, decalx, decaly, psizex, psizey); + ///else + g2_draw_scaled_image(context_raw.decal_image, decalx, decaly + psizey, psizex, -psizey); + ///end + g2_set_transformation(null); + g2_set_color(0xffffffff); + } + } + if (context_raw.tool == workspace_tool_t.BRUSH || + context_raw.tool == workspace_tool_t.ERASER || + context_raw.tool == workspace_tool_t.CLONE || + context_raw.tool == workspace_tool_t.BLUR || + context_raw.tool == workspace_tool_t.SMUDGE || + context_raw.tool == workspace_tool_t.PARTICLE || + (decal_mask && !config_raw.brush_3d) || + (decal_mask && context_in_2d_view())) { + if (decal_mask) { + psize = math_floor(cursor_img.width * (context_raw.brush_decal_mask_radius * context_raw.brush_nodes_radius) * zui_SCALE(ui_base_ui)); + } + if (config_raw.brush_3d && context_in_2d_view()) { + psize = math_floor(psize * ui_view2d_pan_scale); + } + g2_draw_scaled_image(cursor_img, mx - psize / 2, my - psize / 2, psize, psize); + } + } + + if (context_raw.brush_lazy_radius > 0 && !context_raw.brush_locked && + (context_raw.tool == workspace_tool_t.BRUSH || + context_raw.tool == workspace_tool_t.ERASER || + context_raw.tool == workspace_tool_t.DECAL || + context_raw.tool == workspace_tool_t.TEXT || + context_raw.tool == workspace_tool_t.CLONE || + context_raw.tool == workspace_tool_t.BLUR || + context_raw.tool == workspace_tool_t.SMUDGE || + context_raw.tool == workspace_tool_t.PARTICLE)) { + g2_fill_rect(mx - 1, my - 1, 2, 2); + mx = context_raw.brush_lazy_x * base_w() + base_x(); + my = context_raw.brush_lazy_y * base_h() + base_y(); + let radius: f32 = context_raw.brush_lazy_radius * 180; + g2_set_color(0xff666666); + g2_draw_scaled_image(cursor_img, mx - radius / 2, my - radius / 2, radius, radius); + g2_set_color(0xffffffff); + } +} +///end + +function ui_base_show_material_nodes() { + // Clear input state as ui receives input events even when not drawn + zui_end_input(); + + ///if (is_paint || is_sculpt) + ui_nodes_show = !ui_nodes_show || ui_nodes_canvas_type != canvas_type_t.MATERIAL; + ui_nodes_canvas_type = canvas_type_t.MATERIAL; + ///end + ///if is_lab + ui_nodes_show = !ui_nodes_show; + ///end + + base_resize(); +} + +///if (is_paint || is_sculpt) +function ui_base_show_brush_nodes() { + // Clear input state as ui receives input events even when not drawn + zui_end_input(); + ui_nodes_show = !ui_nodes_show || ui_nodes_canvas_type != canvas_type_t.BRUSH; + ui_nodes_canvas_type = canvas_type_t.BRUSH; + base_resize(); +} +///end + +function ui_base_show_2d_view(type: view_2d_type_t) { + // Clear input state as ui receives input events even when not drawn + zui_end_input(); + if (ui_view2d_type != type) ui_view2d_show = true; + else ui_view2d_show = !ui_view2d_show; + ui_view2d_type = type; + ui_view2d_hwnd.redraws = 2; + base_resize(); +} + +function ui_base_toggle_browser() { + let minimized: bool = config_raw.layout[layout_size_t.STATUS_H] <= (ui_status_default_status_h * config_raw.window_scale); + config_raw.layout[layout_size_t.STATUS_H] = minimized ? 240 : ui_status_default_status_h; + config_raw.layout[layout_size_t.STATUS_H] = math_floor(config_raw.layout[layout_size_t.STATUS_H] * config_raw.window_scale); +} + +function ui_base_set_icon_scale() { + if (zui_SCALE(ui_base_ui) > 1) { + resource_load(["icons2x.k"]); + resource_bundled.set("icons.k", resource_get("icons2x.k")); + } + else { + resource_load(["icons.k"]); + } +} + +function ui_base_on_border_hover(handle_ptr: i32, side: i32) { + if (!base_ui_enabled) return; + + ///if (is_paint || is_sculpt) + if (handle_ptr != ui_base_hwnds[tab_area_t.SIDEBAR0].ptr && + handle_ptr != ui_base_hwnds[tab_area_t.SIDEBAR1].ptr && + handle_ptr != ui_base_hwnds[tab_area_t.STATUS].ptr && + handle_ptr != ui_nodes_hwnd.ptr && + handle_ptr != ui_view2d_hwnd.ptr) return; // Scalable handles + if (handle_ptr == ui_view2d_hwnd.ptr && side != border_side_t.LEFT) return; + if (handle_ptr == ui_nodes_hwnd.ptr && side == border_side_t.TOP && !ui_view2d_show) return; + if (handle_ptr == ui_base_hwnds[tab_area_t.SIDEBAR0].ptr && side == border_side_t.TOP) return; + ///end + + ///if is_lab + if (handle_ptr != ui_base_hwnds[tab_area_t.STATUS].ptr && + handle_ptr != ui_nodes_hwnd.ptr && + handle_ptr != ui_view2d_hwnd.ptr) return; // Scalable handles + if (handle_ptr == ui_view2d_hwnd.ptr && side != border_side_t.LEFT) return; + if (handle_ptr == ui_nodes_hwnd.ptr && side == border_side_t.TOP && !ui_view2d_show) return; + ///end + + if (handle_ptr == ui_nodes_hwnd.ptr && side != border_side_t.LEFT && side != border_side_t.TOP) return; + if (handle_ptr == ui_base_hwnds[tab_area_t.STATUS].ptr && side != border_side_t.TOP) return; + if (side == border_side_t.RIGHT) return; // UI is snapped to the right side + + side == border_side_t.LEFT || side == border_side_t.RIGHT ? + krom_set_mouse_cursor(3) : // Horizontal + krom_set_mouse_cursor(4); // Vertical + + if (zui_current.input_started) { + ui_base_border_started = side; + ui_base_border_handle_ptr = handle_ptr; + base_is_resizing = true; + } +} + +function ui_base_on_text_hover() { + krom_set_mouse_cursor(2); // I-cursor +} + +function ui_base_on_deselect_text() { + ///if krom_ios + keyboard_up_listener(key_code_t.SHIFT); + ///end +} + +function ui_base_on_tab_drop(to_ptr: i32, toPosition: i32, from_ptr: i32, fromPosition: i32) { + let i: i32 = -1; + let j: i32 = -1; + for (let k: i32 = 0; k < ui_base_htabs.length; ++k) { + if (ui_base_htabs[k].ptr == to_ptr) i = k; + if (ui_base_htabs[k].ptr == from_ptr) j = k; + } + if (i > -1 && j > -1) { + let element: any = ui_base_hwnd_tabs[j][fromPosition]; + ui_base_hwnd_tabs[j].splice(fromPosition, 1); + ui_base_hwnd_tabs[i].splice(toPosition, 0, element); + ui_base_hwnds[i].redraws = 2; + ui_base_hwnds[j].redraws = 2; + } +} + +function ui_base_tag_ui_redraw() { + ui_header_handle.redraws = 2; + ui_base_hwnds[tab_area_t.STATUS].redraws = 2; + ui_menubar_workspace_handle.redraws = 2; + ui_menubar_menu_handle.redraws = 2; + ///if (is_paint || is_sculpt) + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; + ui_toolbar_handle.redraws = 2; + ///end +} diff --git a/base/Sources/ui_box.ts b/base/Sources/ui_box.ts new file mode 100644 index 00000000..f95a448a --- /dev/null +++ b/base/Sources/ui_box.ts @@ -0,0 +1,184 @@ + +let ui_box_show: bool = false; +let ui_box_draggable: bool = true; +let ui_box_hwnd: zui_handle_t = zui_handle_create(); +let ui_box_title: string = ""; +let ui_box_text: string = ""; +let ui_box_commands: (ui: zui_t)=>void = null; +let ui_box_click_to_hide: bool = true; +let ui_box_modalw: i32 = 400; +let ui_box_modalh: i32 = 170; +let ui_box_modal_on_hide: ()=>void = null; +let ui_box_draws: i32 = 0; +let ui_box_copyable: bool = false; +///if (krom_android || krom_ios) +let ui_box_tween_alpha: f32 = 0.0; +///end + +function ui_box_init() { + ui_box_hwnd.redraws = 2; + ui_box_hwnd.drag_x = 0; + ui_box_hwnd.drag_y = 0; + ui_box_show = true; + ui_box_draws = 0; + ui_box_click_to_hide = true; +} + +function ui_box_render() { + if (!ui_menu_show) { + let ui: zui_t = base_ui_box; + let in_use: bool = ui.combo_selected_handle_ptr != 0; + let is_escape: bool = keyboard_started("escape"); + if (ui_box_draws > 2 && (ui.input_released || is_escape) && !in_use && !ui.is_typing) { + let appw: i32 = sys_width(); + let apph: i32 = sys_height(); + let mw: i32 = math_floor(ui_box_modalw * zui_SCALE(ui)); + let mh: i32 = math_floor(ui_box_modalh * zui_SCALE(ui)); + let left: f32 = (appw / 2 - mw / 2) + ui_box_hwnd.drag_x; + let right: f32 = (appw / 2 + mw / 2) + ui_box_hwnd.drag_x; + let top: f32 = (apph / 2 - mh / 2) + ui_box_hwnd.drag_y; + let bottom: f32 = (apph / 2 + mh / 2) + ui_box_hwnd.drag_y; + let mx: i32 = mouse_x; + let my: i32 = mouse_y; + if ((ui_box_click_to_hide && (mx < left || mx > right || my < top || my > bottom)) || is_escape) { + ui_box_hide(); + } + } + } + + if (config_raw.touch_ui) { // Darken bg + ///if (krom_android || krom_ios) + g2_set_color(color_from_floats(0, 0, 0, ui_box_tween_alpha)); + ///else + g2_set_color(color_from_floats(0, 0, 0, 0.5)); + ///end + g2_fill_rect(0, 0, sys_width(), sys_height()); + } + + g2_end(); + + let ui: zui_t = base_ui_box; + let appw: i32 = sys_width(); + let apph: i32 = sys_height(); + let mw: i32 = math_floor(ui_box_modalw * zui_SCALE(ui)); + let mh: i32 = math_floor(ui_box_modalh * zui_SCALE(ui)); + if (mw > appw) mw = appw; + if (mh > apph) mh = apph; + let left: i32 = math_floor(appw / 2 - mw / 2); + let top: i32 = math_floor(apph / 2 - mh / 2); + + if (ui_box_commands == null) { + zui_begin(ui); + if (zui_window(ui_box_hwnd, left, top, mw, mh, ui_box_draggable)) { + ui._y += 10; + let tab_vertical: bool = config_raw.touch_ui; + if (zui_tab(zui_handle("uibox_0"), ui_box_title, tab_vertical)) { + let htext: zui_handle_t = zui_handle("uibox_1"); + htext.text = ui_box_text; + ui_box_copyable ? + zui_text_area(htext, zui_align_t.LEFT, false) : + zui_text(ui_box_text); + zui_end_element(); + + ///if (krom_windows || krom_linux || krom_darwin) + if (ui_box_copyable) zui_row([1 / 3, 1 / 3, 1 / 3]); + else zui_row([2 / 3, 1 / 3]); + ///else + zui_row([2 / 3, 1 / 3]); + ///end + + zui_end_element(); + + ///if (krom_windows || krom_linux || krom_darwin) + if (ui_box_copyable && zui_button(tr("Copy"))) { + krom_copy_to_clipboard(ui_box_text); + } + ///end + if (zui_button(tr("OK"))) { + ui_box_hide(); + } + } + ui_box_window_border(ui); + } + zui_end(); + } + else { + zui_begin(ui); + if (zui_window(ui_box_hwnd, left, top, mw, mh, ui_box_draggable)) { + ui._y += 10; + ui_box_commands(ui); + ui_box_window_border(ui); + } + zui_end(); + } + + g2_begin(null); + + ui_box_draws++; +} + +function ui_box_show_message(title: string, text: string, copyable: bool = false) { + ui_box_init(); + ui_box_modalw = 400; + ui_box_modalh = 210; + ui_box_title = title; + ui_box_text = text; + ui_box_commands = null; + ui_box_copyable = copyable; + ui_box_draggable = true; + ///if (krom_android || krom_ios) + ui_box_tween_in(); + ///end +} + +function ui_box_show_custom(commands: (ui: zui_t)=>void = null, mw: i32 = 400, mh: i32 = 200, onHide: ()=>void = null, draggable: bool = true) { + ui_box_init(); + ui_box_modalw = mw; + ui_box_modalh = mh; + ui_box_modal_on_hide = onHide; + ui_box_commands = commands; + ui_box_draggable = draggable; + ///if (krom_android || krom_ios) + ui_box_tween_in(); + ///end +} + +function ui_box_hide() { + ///if (krom_android || krom_ios) + ui_box_tween_out(); + ///else + ui_box_hide_internal(); + ///end +} + +function ui_box_hide_internal() { + if (ui_box_modal_on_hide != null) ui_box_modal_on_hide(); + ui_box_show = false; + base_redraw_ui(); +} + +///if (krom_android || krom_ios) +function ui_box_tween_in() { + tween_reset(); + tween_to({target: UIBox, props: { ui_box_tween_alpha: 0.5 }, duration: 0.2, ease: ease_t.EXPO_OUT}); + ui_box_hwnd.drag_y = math_floor(sys_height() / 2); + tween_to({target: ui_box_hwnd, props: { dragY: 0 }, duration: 0.2, ease: ease_t.EXPO_OUT, tick: () => { base_redraw_ui(); }}); +} + +function ui_box_tween_out() { + tween_to({target: UIBox, props: { ui_box_tween_alpha: 0.0 }, duration: 0.2, ease: ease_t.EXPO_IN, done: ui_box_hide_internal}); + tween_to({target: ui_box_hwnd, props: { dragY: sys_height() / 2 }, duration: 0.2, ease: ease_t.EXPO_IN}); +} +///end + +function ui_box_window_border(ui: zui_t) { + if (ui.scissor) { + ui.scissor = false; + g2_disable_scissor(); + } + // Border + g2_set_color(ui.t.SEPARATOR_COL); + g2_fill_rect(0, 0, 1, ui._window_h); + g2_fill_rect(0 + ui._window_w - 1, 0, 1, ui._window_h); + g2_fill_rect(0, 0 + ui._window_h - 1, ui._window_w, 1); +} diff --git a/base/Sources/ui_files.ts b/base/Sources/ui_files.ts new file mode 100644 index 00000000..d99d2822 --- /dev/null +++ b/base/Sources/ui_files.ts @@ -0,0 +1,363 @@ + +let ui_files_default_path: string = + ///if krom_windows + "C:\\Users" + ///elseif krom_android + "/storage/emulated/0/Download" + ///elseif krom_darwin + "/Users" + ///else + "/" + ///end +; + +let ui_files_filename: string; +let ui_files_path: string = ui_files_default_path; +let ui_files_last_path: string = ""; +let ui_files_last_search: string = ""; +let ui_files_files: string[] = null; +let ui_files_icon_map: map_t = null; +let ui_files_selected: i32 = -1; +let ui_files_show_extensions: bool = false; +let ui_files_offline: bool = false; + +function ui_files_show(filters: string, is_save: bool, open_multiple: bool, files_done: (s: string)=>void) { + if (is_save) { + ui_files_path = krom_save_dialog(filters, ""); + if (ui_files_path != null) { + while (ui_files_path.indexOf(path_sep + path_sep) >= 0) ui_files_path = string_replace_all(ui_files_path, path_sep + path_sep, path_sep); + ui_files_path = string_replace_all(ui_files_path, "\r", ""); + ui_files_filename = ui_files_path.substr(ui_files_path.lastIndexOf(path_sep) + 1); + ui_files_path = ui_files_path.substr(0, ui_files_path.lastIndexOf(path_sep)); + files_done(ui_files_path); + } + } + else { + let paths: string[] = krom_open_dialog(filters, "", open_multiple); + if (paths != null) { + for (let path of paths) { + while (path.indexOf(path_sep + path_sep) >= 0) path = string_replace_all(path, path_sep + path_sep, path_sep); + path = string_replace_all(path, "\r", ""); + ui_files_filename = path.substr(path.lastIndexOf(path_sep) + 1); + files_done(path); + } + } + } + + ui_files_release_keys(); +} + +function ui_files_release_keys() { + // File dialog may prevent firing key up events + keyboard_up_listener(key_code_t.SHIFT); + keyboard_up_listener(key_code_t.CONTROL); + ///if krom_darwin + keyboard_up_listener(key_code_t.META); + ///end +} + +function ui_files_file_browser(ui: zui_t, handle: zui_handle_t, foldersOnly: bool = false, dragFiles: bool = false, search: string = "", refresh: bool = false, contextMenu: (s: string)=>void = null): string { + + let icons: image_t = resource_get("icons.k"); + let folder: rect_t = resource_tile50(icons, 2, 1); + let file: rect_t = resource_tile50(icons, 3, 1); + let is_cloud: bool = handle.text.startsWith("cloud"); + + if (is_cloud && file_cloud == null) file_init_cloud(function () { ui_base_hwnds[tab_area_t.STATUS].redraws = 3; }); + if (is_cloud && file_read_directory("cloud", false).length == 0) return handle.text; + + ///if krom_ios + let document_directory: string = krom_save_dialog("", ""); + document_directory = document_directory.substr(0, document_directory.length - 8); // Strip /'untitled' + ///end + + if (handle.text == "") handle.text = ui_files_default_path; + if (handle.text != ui_files_last_path || search != ui_files_last_search || refresh) { + ui_files_files = []; + + // Up directory + let i1: i32 = handle.text.indexOf(path_sep); + let nested: bool = i1 > -1 && handle.text.length - 1 > i1; + ///if krom_windows + // Server addresses like \\server are not nested + nested = nested && !(handle.text.length >= 2 && handle.text.charAt(0) == path_sep && handle.text.charAt(1) == path_sep && handle.text.lastIndexOf(path_sep) == 1); + ///end + if (nested) ui_files_files.push(".."); + + let dir_path: string = handle.text; + ///if krom_ios + if (!is_cloud) dir_path = document_directory + dir_path; + ///end + let files_all: string[] = file_read_directory(dir_path, foldersOnly); + + for (let f of files_all) { + if (f == "" || f.charAt(0) == ".") continue; // Skip hidden + if (f.indexOf(".") > 0 && !path_is_known(f)) continue; // Skip unknown extensions + if (is_cloud && f.indexOf("_icon.") >= 0) continue; // Skip thumbnails + if (f.toLowerCase().indexOf(search.toLowerCase()) < 0) continue; // Search filter + ui_files_files.push(f); + } + } + ui_files_last_path = handle.text; + ui_files_last_search = search; + handle.changed = false; + + let slotw: i32 = math_floor(70 * zui_SCALE(ui)); + let num: i32 = math_floor(ui._w / slotw); + + ui._y += 4; // Don't cut off the border around selected materials + // Directory contents + for (let row: i32 = 0; row < math_floor(math_ceil(ui_files_files.length / num)); ++row) { + let ar: f32[] = []; + for (let i: i32 = 0; i < num * 2; ++i) ar.push(1 / num); + zui_row(ar); + if (row > 0) ui._y += zui_ELEMENT_OFFSET(ui) * 14.0; + + for (let j: i32 = 0; j < num; ++j) { + let i: i32 = j + row * num; + if (i >= ui_files_files.length) { + zui_end_element(slotw); + zui_end_element(slotw); + continue; + } + + let f: string = ui_files_files[i]; + let _x: f32 = ui._x; + + let rect: rect_t = f.indexOf(".") > 0 ? file : folder; + let col: i32 = rect == file ? ui.t.LABEL_COL : ui.t.LABEL_COL - 0x00202020; + if (ui_files_selected == i) col = ui.t.HIGHLIGHT_COL; + + let off: f32 = ui._w / 2 - 25 * zui_SCALE(ui); + ui._x += off; + + let uix: f32 = ui._x; + let uiy: f32 = ui._y; + let state: zui_state_t = zui_state_t.IDLE; + let generic: bool = true; + let icon: image_t = null; + + if (is_cloud && f != ".." && !ui_files_offline) { + if (ui_files_icon_map == null) ui_files_icon_map = map_create(); + icon = ui_files_icon_map.get(handle.text + path_sep + f); + if (icon == null) { + let files_all: string[] = file_read_directory(handle.text); + let icon_file: string = f.substr(0, f.lastIndexOf(".")) + "_icon.jpg"; + if (files_all.indexOf(icon_file) >= 0) { + let empty: image_t = render_path_render_targets.get("empty_black")._image; + ui_files_icon_map.set(handle.text + path_sep + f, empty); + file_cache_cloud(handle.text + path_sep + icon_file, function (abs: string) { + if (abs != null) { + let image: image_t = data_get_image(abs); + app_notify_on_init(function () { + if (base_pipe_copy_rgb == null) base_make_pipe_copy_rgb(); + icon = image_create_render_target(image.width, image.height); + if (f.endsWith(".arm")) { // Used for material sphere alpha cutout + g2_begin(icon); + + ///if (is_paint || is_sculpt) + g2_draw_image(project_materials[0].image, 0, 0); + ///end + } + else { + g2_begin(icon); + g2_clear(0xffffffff); + } + g2_set_pipeline(base_pipe_copy_rgb); + g2_draw_image(image, 0, 0); + g2_set_pipeline(null); + g2_end(); + ui_files_icon_map.set(handle.text + path_sep + f, icon); + ui_base_hwnds[tab_area_t.STATUS].redraws = 3; + }); + } + else ui_files_offline = true; + }); + } + } + if (icon != null) { + let w: i32 = 50; + if (i == ui_files_selected) { + zui_fill(-2, -2, w + 4, 2, ui.t.HIGHLIGHT_COL); + zui_fill(-2, w + 2, w + 4, 2, ui.t.HIGHLIGHT_COL); + zui_fill(-2, 0, 2, w + 4, ui.t.HIGHLIGHT_COL); + zui_fill(w + 2 , -2, 2, w + 6, ui.t.HIGHLIGHT_COL); + } + state = zui_image(icon, 0xffffffff, w * zui_SCALE(ui)); + if (ui.is_hovered) { + zui_tooltip_image(icon); + zui_tooltip(f); + } + generic = false; + } + } + if (f.endsWith(".arm") && !is_cloud) { + if (ui_files_icon_map == null) ui_files_icon_map = map_create(); + let key: string = handle.text + path_sep + f; + icon = ui_files_icon_map.get(key); + if (!ui_files_icon_map.has(key)) { + let blob_path: string = key; + + ///if krom_ios + blob_path = document_directory + blob_path; + // TODO: implement native .arm parsing first + ///else + + let buffer: buffer_t = krom_load_blob(blob_path); + let raw: any = armpack_decode(buffer); + if (raw.material_icons != null) { + let bytes_icon: any = raw.material_icons[0]; + icon = image_from_bytes(lz4_decode(bytes_icon, 256 * 256 * 4), 256, 256); + } + + ///if (is_paint || is_sculpt) + else if (raw.mesh_icons != null) { + let bytes_icon: any = raw.mesh_icons[0]; + icon = image_from_bytes(lz4_decode(bytes_icon, 256 * 256 * 4), 256, 256); + } + else if (raw.brush_icons != null) { + let bytes_icon: any = raw.brush_icons[0]; + icon = image_from_bytes(lz4_decode(bytes_icon, 256 * 256 * 4), 256, 256); + } + ///end + + ///if is_lab + if (raw.mesh_icon != null) { + let bytes_icon: any = raw.mesh_icon; + icon = image_from_bytes(lz4_decode(bytes_icon, 256 * 256 * 4), 256, 256); + } + ///end + + ui_files_icon_map.set(key, icon); + ///end + } + if (icon != null) { + let w: i32 = 50; + if (i == ui_files_selected) { + zui_fill(-2, -2, w + 4, 2, ui.t.HIGHLIGHT_COL); + zui_fill(-2, w + 2, w + 4, 2, ui.t.HIGHLIGHT_COL); + zui_fill(-2, 0, 2, w + 4, ui.t.HIGHLIGHT_COL); + zui_fill(w + 2 , -2, 2, w + 6, ui.t.HIGHLIGHT_COL); + } + state = zui_image(icon, 0xffffffff, w * zui_SCALE(ui)); + if (ui.is_hovered) { + zui_tooltip_image(icon); + zui_tooltip(f); + } + generic = false; + } + } + + if (path_is_texture(f) && !is_cloud) { + let w: i32 = 50; + if (ui_files_icon_map == null) ui_files_icon_map = map_create(); + let shandle: string = handle.text + path_sep + f; + icon = ui_files_icon_map.get(shandle); + if (icon == null) { + let empty: image_t = render_path_render_targets.get("empty_black")._image; + ui_files_icon_map.set(shandle, empty); + let image: image_t = data_get_image(shandle); + app_notify_on_init(function () { + if (base_pipe_copy_rgb == null) base_make_pipe_copy_rgb(); + let sw: i32 = image.width > image.height ? w : math_floor(1.0 * image.width / image.height * w); + let sh: i32 = image.width > image.height ? math_floor(1.0 * image.height / image.width * w) : w; + icon = image_create_render_target(sw, sh); + g2_begin(icon); + g2_clear(0xffffffff); + g2_set_pipeline(base_pipe_copy_rgb); + g2_draw_scaled_image(image, 0, 0, sw, sh); + g2_set_pipeline(null); + g2_end(); + ui_files_icon_map.set(shandle, icon); + ui_base_hwnds[tab_area_t.STATUS].redraws = 3; + data_delete_image(shandle); // The big image is not needed anymore + }); + } + if (icon != null) { + if (i == ui_files_selected) { + zui_fill(-2, -2, w + 4, 2, ui.t.HIGHLIGHT_COL); + zui_fill(-2, w + 2, w + 4, 2, ui.t.HIGHLIGHT_COL); + zui_fill(-2, 0, 2, w + 4, ui.t.HIGHLIGHT_COL); + zui_fill(w + 2 , -2, 2, w + 6, ui.t.HIGHLIGHT_COL); + } + state = zui_image(icon, 0xffffffff, icon.height * zui_SCALE(ui)); + generic = false; + } + } + + if (generic) { + state = zui_image(icons, col, 50 * zui_SCALE(ui), rect.x, rect.y, rect.w, rect.h); + } + + if (ui.is_hovered && ui.input_released_r && contextMenu != null) { + contextMenu(handle.text + path_sep + f); + } + + if (state == zui_state_t.STARTED) { + if (f != ".." && dragFiles) { + base_drag_off_x = -(mouse_x - uix - ui._window_x - 3); + base_drag_off_y = -(mouse_y - uiy - ui._window_y + 1); + base_drag_file = handle.text; + ///if krom_ios + if (!is_cloud) base_drag_file = document_directory + base_drag_file; + ///end + if (base_drag_file.charAt(base_drag_file.length - 1) != path_sep) { + base_drag_file += path_sep; + } + base_drag_file += f; + base_drag_file_icon = icon; + } + + ui_files_selected = i; + if (time_time() - context_raw.select_time < 0.25) { + base_drag_file = null; + base_drag_file_icon = null; + base_is_dragging = false; + handle.changed = ui.changed = true; + if (f == "..") { // Up + handle.text = handle.text.substring(0, handle.text.lastIndexOf(path_sep)); + // Drive root + if (handle.text.length == 2 && handle.text.charAt(1) == ":") handle.text += path_sep; + } + else { + if (handle.text.charAt(handle.text.length - 1) != path_sep) { + handle.text += path_sep; + } + handle.text += f; + } + ui_files_selected = -1; + } + context_raw.select_time = time_time(); + } + + // Label + ui._x = _x; + ui._y += slotw * 0.75; + let label0: string = (ui_files_show_extensions || f.indexOf(".") <= 0) ? f : f.substr(0, f.lastIndexOf(".")); + let label1: string = ""; + while (label0.length > 0 && g2_font_width(ui.font, ui.font_size, label0) > ui._w - 6) { // 2 line split + label1 = label0.charAt(label0.length - 1) + label1; + label0 = label0.substr(0, label0.length - 1); + } + if (label1 != "") ui.cur_ratio--; + zui_text(label0, zui_align_t.CENTER); + if (ui.is_hovered) zui_tooltip(label0 + label1); + if (label1 != "") { // Second line + ui._x = _x; + ui._y += g2_font_height(ui.font, ui.font_size); + zui_text(label1, zui_align_t.CENTER); + if (ui.is_hovered) zui_tooltip(label0 + label1); + ui._y -= g2_font_height(ui.font, ui.font_size); + } + + ui._y -= slotw * 0.75; + + if (handle.changed) break; + } + + if (handle.changed) break; + } + ui._y += slotw * 0.8; + + return handle.text; +} diff --git a/base/Sources/ui_header.ts b/base/Sources/ui_header.ts new file mode 100644 index 00000000..f72f9dba --- /dev/null +++ b/base/Sources/ui_header.ts @@ -0,0 +1,500 @@ + +let ui_header_default_h: i32 = 28; +let ui_header_h: i32 = ui_header_default_h; +let ui_header_handle: zui_handle_t = zui_handle_create({ layout: zui_layout_t.HORIZONTAL }); +let ui_header_worktab: zui_handle_t = zui_handle_create(); + +function ui_header_init() { + +} + +function ui_header_render_ui() { + let ui: zui_t = ui_base_ui; + if (config_raw.touch_ui) { + ui_header_h = ui_header_default_h + 6; + } + else { + ui_header_h = ui_header_default_h; + } + ui_header_h = math_floor(ui_header_h * zui_SCALE(ui)); + + if (config_raw.layout[layout_size_t.HEADER] == 0) return; + + let nodesw: i32 = (ui_nodes_show || ui_view2d_show) ? config_raw.layout[layout_size_t.NODES_W] : 0; + ///if is_lab + let ww: i32 = sys_width() - nodesw; + ///else + let ww: i32 = sys_width() - ui_toolbar_w - config_raw.layout[layout_size_t.SIDEBAR_W] - nodesw; + ///end + + if (zui_window(ui_header_handle, app_x(), ui_header_h, ww, ui_header_h)) { + ui._y += 2; + ui_header_draw_tool_properties(ui); + } +} + +///if is_paint + +function ui_header_draw_tool_properties(ui: zui_t) { + if (context_raw.tool == workspace_tool_t.COLORID) { + zui_text(tr("Picked Color")); + if (context_raw.colorid_picked) { + zui_image(render_path_render_targets.get("texpaint_colorid")._image, 0xffffffff, 64); + } + ui.enabled = context_raw.colorid_picked; + if (zui_button(tr("Clear"))) { + context_raw.colorid_picked = false; + ui_toolbar_handle.redraws = 1; + } + ui.enabled = true; + zui_text(tr("Color ID Map")); + if (project_asset_names.length > 0) { + let cid: i32 = zui_combo(context_raw.colorid_handle, base_enum_texts("TEX_IMAGE"), tr("Color ID")); + if (context_raw.colorid_handle.changed) { + context_raw.ddirty = 2; + context_raw.colorid_picked = false; + ui_toolbar_handle.redraws = 1; + } + zui_image(project_get_image(project_assets[cid])); + if (ui.is_hovered) zui_tooltip_image(project_get_image(project_assets[cid]), 256); + } + if (zui_button(tr("Import"))) { + ui_files_show(path_texture_formats.join(","), false, true, function (path: string) { + ImportAsset.run(path, -1.0, -1.0, true, false); + + context_raw.colorid_handle.position = project_asset_names.length - 1; + for (let a of project_assets) { + // Already imported + if (a.file == path) context_raw.colorid_handle.position = project_assets.indexOf(a); + } + context_raw.ddirty = 2; + context_raw.colorid_picked = false; + ui_toolbar_handle.redraws = 1; + ui_base_hwnds[2].redraws = 2; + }); + } + ui.enabled = context_raw.colorid_picked; + if (zui_button(tr("To Mask"))) { + if (SlotLayer.is_mask(context_raw.layer)) context_set_layer(context_raw.layer.parent); + let m: SlotLayerRaw = base_new_mask(false, context_raw.layer); + let _next = function () { + if (base_pipe_merge == null) base_make_pipe(); + if (const_data_screen_aligned_vb == null) const_data_create_screen_aligned_data(); + g4_begin(m.texpaint); + g4_set_pipeline(base_pipe_colorid_to_mask); + g4_set_tex(base_texpaint_colorid,render_path_render_targets.get("texpaint_colorid")._image); + g4_set_tex(base_tex_colorid, project_get_image(project_assets[context_raw.colorid_handle.position])); + g4_set_vertex_buffer(const_data_screen_aligned_vb); + g4_set_index_buffer(const_data_screen_aligned_ib); + g4_draw(); + g4_end(); + context_raw.colorid_picked = false; + ui_toolbar_handle.redraws = 1; + ui_header_handle.redraws = 1; + context_raw.layer_preview_dirty = true; + base_update_fill_layers(); + } + base_notify_on_next_frame(_next); + history_new_white_mask(); + } + ui.enabled = true; + } + else if (context_raw.tool == workspace_tool_t.PICKER || context_raw.tool == workspace_tool_t.MATERIAL) { + let base_r_picked: f32 = math_round(color_get_rb(context_raw.picked_color.base) / 255 * 10) / 10; + let base_g_picked: f32 = math_round(color_get_gb(context_raw.picked_color.base) / 255 * 10) / 10; + let base_b_picked: f32 = math_round(color_get_bb(context_raw.picked_color.base) / 255 * 10) / 10; + let normal_r_picked: f32 = math_round(color_get_rb(context_raw.picked_color.normal) / 255 * 10) / 10; + let normal_g_picked: f32 = math_round(color_get_gb(context_raw.picked_color.normal) / 255 * 10) / 10; + let normal_b_picked: f32 = math_round(color_get_bb(context_raw.picked_color.normal) / 255 * 10) / 10; + let occlusion_picked: f32 = math_round(context_raw.picked_color.occlusion * 100) / 100; + let roughness_picked: f32 = math_round(context_raw.picked_color.roughness * 100) / 100; + let metallic_picked: f32 = math_round(context_raw.picked_color.metallic * 100) / 100; + let height_picked: f32 = math_round(context_raw.picked_color.height * 100) / 100; + let opacity_picked: f32 = math_round(context_raw.picked_color.opacity * 100) / 100; + + let h: zui_handle_t = zui_handle("uiheader_0"); + let color: color_t = 0xffffffff; + color = color_set_rb(color, base_r_picked * 255); + color = color_set_gb(color, base_g_picked * 255); + color = color_set_bb(color, base_b_picked * 255); + h.color = color; + let state: zui_state_t = zui_text("", 0, h.color); + if (state == zui_state_t.STARTED) { + let uix: i32 = ui._x; + let uiy: i32 = ui._y; + base_drag_off_x = -(mouse_x - uix - ui._window_x - 3); + base_drag_off_y = -(mouse_y - uiy - ui._window_y + 1); + base_drag_swatch = project_clone_swatch(context_raw.picked_color); + } + if (ui.is_hovered) zui_tooltip(tr("Drag and drop picked color to swatches, materials, layers or to the node editor")); + if (ui.is_hovered && ui.input_released) { + ui_menu_draw(function (ui: zui_t) { + zui_fill(0, 0, ui._w / zui_SCALE(ui), ui.t.ELEMENT_H * 9, ui.t.SEPARATOR_COL); + ui.changed = false; + zui_color_wheel(h, false, null, 10 * ui.t.ELEMENT_H * zui_SCALE(ui), false); + if (ui.changed) ui_menu_keep_open = true; + }, 10); + } + if (zui_button(tr("Add Swatch"))) { + let new_swatch: swatch_color_t = project_clone_swatch(context_raw.picked_color); + context_set_swatch(new_swatch); + project_raw.swatches.push(new_swatch); + ui_base_hwnds[2].redraws = 1; + } + if (ui.is_hovered) zui_tooltip(tr("Add picked color to swatches")); + + zui_text(tr("Base") + ` (${base_r_picked},${base_g_picked},${base_b_picked})`); + zui_text(tr("Normal") + ` (${normal_r_picked},${normal_g_picked},${normal_b_picked})`); + zui_text(tr("Occlusion") + ` (${occlusion_picked})`); + zui_text(tr("Roughness") + ` (${roughness_picked})`); + zui_text(tr("Metallic") + ` (${metallic_picked})`); + zui_text(tr("Height") + ` (${height_picked})`); + zui_text(tr("Opacity") + ` (${opacity_picked})`); + context_raw.picker_select_material = zui_check(zui_handle("uiheader_1", { selected: context_raw.picker_select_material }), tr("Select Material")); + zui_combo(context_raw.picker_mask_handle, [tr("None"), tr("Material")], tr("Mask"), true); + if (context_raw.picker_mask_handle.changed) { + MakeMaterial.parse_paint_material(); + } + } + else if (context_raw.tool == workspace_tool_t.BAKE) { + ui.changed = false; + + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + let baking: bool = context_raw.pdirty > 0; + let rt_bake: bool = context_raw.bake_type == bake_type_t.AO || context_raw.bake_type == bake_type_t.LIGHTMAP || context_raw.bake_type == bake_type_t.BENT_NORMAL || context_raw.bake_type == bake_type_t.THICKNESS; + if (baking && zui_button(tr("Stop"))) { + context_raw.pdirty = 0; + context_raw.rdirty = 2; + } + ///else + let baking: bool = false; + let rt_bake: bool = false; + ///end + + if (!baking && zui_button(tr("Bake"))) { + context_raw.pdirty = rt_bake ? context_raw.bake_samples : 1; + context_raw.rdirty = 3; + base_notify_on_next_frame(function () { + context_raw.layer_preview_dirty = true; + }); + ui_base_hwnds[0].redraws = 2; + history_push_undo = true; + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + RenderPathRaytraceBake.current_sample = 0; + ///end + } + + let bake_handle: zui_handle_t = zui_handle("uiheader_2", { position: context_raw.bake_type }); + let bakes: string[] = [ + tr("AO"), + tr("Curvature"), + tr("Normal"), + tr("Object Normal"), + tr("Height"), + tr("Derivative"), + tr("Position"), + tr("TexCoord"), + tr("Material ID"), + tr("Object ID"), + tr("Vertex Color"), + ]; + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + if (krom_raytrace_supported()) { + bakes.push(tr("Lightmap")); + bakes.push(tr("Bent Normal")); + bakes.push(tr("Thickness")); + } + else { + bakes.shift(); // Remove AO + } + ///end + + context_raw.bake_type = zui_combo(bake_handle, bakes, tr("Bake")); + + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + if (!krom_raytrace_supported()) { + context_raw.bake_type += 1; // Offset for removed AO + } + ///end + + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + if (rt_bake) { + let samples_handle: zui_handle_t = zui_handle("uiheader_3", { value: context_raw.bake_samples }); + context_raw.bake_samples = math_floor(zui_slider(samples_handle, tr("Samples"), 1, 512, true, 1)); + } + ///end + + if (context_raw.bake_type == bake_type_t.NORMAL_OBJECT || context_raw.bake_type == bake_type_t.POSITION || context_raw.bake_type == bake_type_t.BENT_NORMAL) { + let bake_up_axis_handle: zui_handle_t = zui_handle("uiheader_4", { 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); + } + 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("uiheader_5", { 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); + } + if (context_raw.bake_type == bake_type_t.AO) { + let strength_handle: zui_handle_t = zui_handle("uiheader_6", { value: context_raw.bake_ao_strength }); + context_raw.bake_ao_strength = zui_slider(strength_handle, tr("Strength"), 0.0, 2.0, true); + let radius_handle: zui_handle_t = zui_handle("uiheader_7", { value: context_raw.bake_ao_radius }); + context_raw.bake_ao_radius = zui_slider(radius_handle, tr("Radius"), 0.0, 2.0, true); + let offset_handle: zui_handle_t = zui_handle("uiheader_8", { value: context_raw.bake_ao_offset }); + context_raw.bake_ao_offset = zui_slider(offset_handle, tr("Offset"), 0.0, 2.0, true); + } + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + if (rt_bake) { + let progress: f32 = RenderPathRaytraceBake.current_sample / context_raw.bake_samples; + if (progress > 1.0) progress = 1.0; + // Progress bar + g2_set_color(ui.t.SEPARATOR_COL); + zui_draw_rect(true, ui._x + 1, ui._y, ui._w - 2, zui_ELEMENT_H(ui)); + g2_set_color(ui.t.HIGHLIGHT_COL); + zui_draw_rect(true, ui._x + 1, ui._y, (ui._w - 2) * progress, zui_ELEMENT_H(ui)); + g2_set_color(0xffffffff); + zui_text(tr("Samples") + ": " + RenderPathRaytraceBake.current_sample); + zui_text(tr("Rays/pixel" + ": ") + RenderPathRaytraceBake.rays_pix); + zui_text(tr("Rays/second" + ": ") + RenderPathRaytraceBake.rays_sec); + } + ///end + if (context_raw.bake_type == bake_type_t.CURVATURE) { + let strength_handle: zui_handle_t = zui_handle("uiheader_9", { value: context_raw.bake_curv_strength }); + context_raw.bake_curv_strength = zui_slider(strength_handle, tr("Strength"), 0.0, 2.0, true); + let radius_handle: zui_handle_t = zui_handle("uiheader_10", { value: context_raw.bake_curv_radius }); + context_raw.bake_curv_radius = zui_slider(radius_handle, tr("Radius"), 0.0, 2.0, true); + let offset_handle: zui_handle_t = zui_handle("uiheader_11", { value: context_raw.bake_curv_offset }); + context_raw.bake_curv_offset = zui_slider(offset_handle, tr("Offset"), -2.0, 2.0, true); + let smooth_handle: zui_handle_t = zui_handle("uiheader_12", { value: context_raw.bake_curv_smooth }); + context_raw.bake_curv_smooth = math_floor(zui_slider(smooth_handle, tr("Smooth"), 0, 5, false, 1)); + } + if (context_raw.bake_type == bake_type_t.NORMAL || context_raw.bake_type == bake_type_t.HEIGHT || context_raw.bake_type == bake_type_t.DERIVATIVE) { + let ar: string[] = []; + for (let p of project_paint_objects) ar.push(p.base.name); + let poly_handle: zui_handle_t = zui_handle("uiheader_13", { position: context_raw.bake_high_poly }); + context_raw.bake_high_poly = zui_combo(poly_handle, ar, tr("High Poly")); + } + if (ui.changed) { + MakeMaterial.parse_paint_material(); + } + } + else if (context_raw.tool == workspace_tool_t.BRUSH || + context_raw.tool == workspace_tool_t.ERASER || + context_raw.tool == workspace_tool_t.FILL || + context_raw.tool == workspace_tool_t.DECAL || + context_raw.tool == workspace_tool_t.TEXT || + context_raw.tool == workspace_tool_t.CLONE || + context_raw.tool == workspace_tool_t.BLUR || + context_raw.tool == workspace_tool_t.SMUDGE || + context_raw.tool == workspace_tool_t.PARTICLE) { + + let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; + let decal_mask: bool = decal && operator_shortcut(config_keymap.decal_mask, shortcut_type_t.DOWN); + if (context_raw.tool != workspace_tool_t.FILL) { + if (decal_mask) { + context_raw.brush_decal_mask_radius = zui_slider(context_raw.brush_decal_mask_radius_handle, tr("Radius"), 0.01, 2.0, true); + if (ui.is_hovered) zui_tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", new Map([["brush_radius", config_keymap.brush_radius], ["brush_radius_decrease", config_keymap.brush_radius_decrease], ["brush_radius_increase", config_keymap.brush_radius_increase]]))); + } + else { + context_raw.brush_radius = zui_slider(context_raw.brush_radius_handle, tr("Radius"), 0.01, 2.0, true); + if (ui.is_hovered) zui_tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", new Map([["brush_radius", config_keymap.brush_radius], ["brush_radius_decrease", config_keymap.brush_radius_decrease], ["brush_radius_increase", config_keymap.brush_radius_increase]]))); + } + } + + if (context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT) { + context_raw.brush_scale_x = zui_slider(context_raw.brush_scale_x_handle, tr("Scale X"), 0.01, 2.0, true); + } + + if (context_raw.tool == workspace_tool_t.BRUSH || + context_raw.tool == workspace_tool_t.FILL || + context_raw.tool == workspace_tool_t.DECAL || + context_raw.tool == workspace_tool_t.TEXT) { + let brush_scale_handle: zui_handle_t = zui_handle("uiheader_14", { value: context_raw.brush_scale }); + context_raw.brush_scale = zui_slider(brush_scale_handle, tr("UV Scale"), 0.01, 5.0, true); + if (brush_scale_handle.changed) { + if (context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT) { + let current: image_t = _g2_current; + g2_end(); + util_render_make_decal_preview(); + g2_begin(current); + } + } + + context_raw.brush_angle = zui_slider(context_raw.brush_angle_handle, tr("Angle"), 0.0, 360.0, true, 1); + if (ui.is_hovered) zui_tooltip(tr("Hold {brush_angle} and move mouse to the left to decrease the angle\nHold {brush_angle} and move mouse to the right to increase the angle", new Map([["brush_angle", config_keymap.brush_angle]]))); + + if (context_raw.brush_angle_handle.changed) { + MakeMaterial.parse_paint_material(); + } + } + + context_raw.brush_opacity = zui_slider(context_raw.brush_opacity_handle, tr("Opacity"), 0.0, 1.0, true); + if (ui.is_hovered) zui_tooltip(tr("Hold {brush_opacity} and move mouse to the left to decrease the opacity\nHold {brush_opacity} and move mouse to the right to increase the opacity", new Map([["brush_opacity", config_keymap.brush_opacity]]))); + + if (context_raw.tool == workspace_tool_t.BRUSH || context_raw.tool == workspace_tool_t.ERASER || context_raw.tool == workspace_tool_t.CLONE || decal_mask) { + context_raw.brush_hardness = zui_slider(zui_handle("uiheader_15", { value: context_raw.brush_hardness }), tr("Hardness"), 0.0, 1.0, true); + } + + if (context_raw.tool != workspace_tool_t.ERASER) { + let brush_blending_handle: zui_handle_t = zui_handle("uiheader_16", { value: context_raw.brush_blending }); + context_raw.brush_blending = zui_combo(brush_blending_handle, [ + tr("Mix"), + tr("Darken"), + tr("Multiply"), + tr("Burn"), + tr("Lighten"), + tr("Screen"), + tr("Dodge"), + tr("Add"), + tr("Overlay"), + tr("Soft Light"), + tr("Linear Light"), + tr("Difference"), + tr("Subtract"), + tr("Divide"), + tr("Hue"), + tr("Saturation"), + tr("Color"), + tr("Value"), + ], tr("Blending")); + if (brush_blending_handle.changed) { + MakeMaterial.parse_paint_material(); + } + } + + if (context_raw.tool == workspace_tool_t.BRUSH || context_raw.tool == workspace_tool_t.FILL) { + let paint_handle: zui_handle_t = zui_handle("uiheader_17"); + context_raw.brush_paint = zui_combo(paint_handle, [tr("UV Map"), tr("Triplanar"), tr("Project")], tr("TexCoord")); + if (paint_handle.changed) { + MakeMaterial.parse_paint_material(); + } + } + if (context_raw.tool == workspace_tool_t.TEXT) { + let h: zui_handle_t = zui_handle("uiheader_18"); + h.text = context_raw.text_tool_text; + let w: i32 = ui._w; + if (ui.text_selected_handle_ptr == h.ptr || ui.submit_text_handle_ptr == h.ptr) { + ui._w *= 3; + } + + context_raw.text_tool_text = zui_text_input(h, "", zui_align_t.LEFT, true, true); + ui._w = w; + + if (h.changed) { + let current: image_t = _g2_current; + g2_end(); + util_render_make_text_preview(); + util_render_make_decal_preview(); + g2_begin(current); + } + } + + 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")); + if (context_raw.fill_type_handle.changed) { + if (context_raw.fill_type_handle.position == fill_type_t.FACE) { + let current: image_t = _g2_current; + g2_end(); + // cacheUVMap(); + util_uv_cache_triangle_map(); + g2_begin(current); + // wireframeHandle.selected = drawWireframe = true; + } + MakeMaterial.parse_paint_material(); + MakeMaterial.parse_mesh_material(); + } + } + else { + let _w: i32 = ui._w; + let sc: f32 = zui_SCALE(ui); + let touch_header: bool = (config_raw.touch_ui && config_raw.layout[layout_size_t.HEADER] == 1); + if (touch_header) ui._x -= 4 * sc; + ui._w = math_floor((touch_header ? 54 : 60) * sc); + + let xray_handle: zui_handle_t = zui_handle("uiheader_19", { selected: context_raw.xray }); + context_raw.xray = zui_check(xray_handle, tr("X-Ray")); + if (xray_handle.changed) { + MakeMaterial.parse_paint_material(); + } + + let sym_x_handle: zui_handle_t = zui_handle("uiheader_20", { selected: false }); + let sym_y_handle: zui_handle_t = zui_handle("uiheader_21", { selected: false }); + let sym_z_handle: zui_handle_t = zui_handle("uiheader_22", { selected: false }); + + if (config_raw.layout[layout_size_t.HEADER] == 1) { + if (config_raw.touch_ui) { + ui._w = math_floor(19 * sc); + context_raw.sym_x = zui_check(sym_x_handle, ""); + ui._x -= 4 * sc; + context_raw.sym_y = zui_check(sym_y_handle, ""); + ui._x -= 4 * sc; + context_raw.sym_z = zui_check(sym_z_handle, ""); + ui._x -= 4 * sc; + ui._w = math_floor(40 * sc); + zui_text(tr("X") + tr("Y") + tr("Z")); + } + else { + ui._w = math_floor(56 * sc); + zui_text(tr("Symmetry")); + ui._w = math_floor(25 * sc); + context_raw.sym_x = zui_check(sym_x_handle, tr("X")); + context_raw.sym_y = zui_check(sym_y_handle, tr("Y")); + context_raw.sym_z = zui_check(sym_z_handle, tr("Z")); + } + ui._w = _w; + } + else { + // Popup + ui._w = _w; + context_raw.sym_x = zui_check(sym_x_handle, tr("Symmetry") + " " + tr("X")); + context_raw.sym_y = zui_check(sym_y_handle, tr("Symmetry") + " " + tr("Y")); + context_raw.sym_z = zui_check(sym_z_handle, tr("Symmetry") + " " + tr("Z")); + } + + if (sym_x_handle.changed || sym_y_handle.changed || sym_z_handle.changed) { + MakeMaterial.parse_paint_material(); + } + } + + ///if arm_physics + if (context_raw.tool == workspace_tool_t.PARTICLE) { + ui._x += 10 * zui_SCALE(ui); + let phys_handle: zui_handle_t = zui_handle("uiheader_23", { selected: false }); + context_raw.particle_physics = zui_check(phys_handle, tr("Physics")); + if (phys_handle.changed) { + util_particle_init_physics(); + MakeMaterial.parse_paint_material(); + } + } + ///end + } +} + +///end + +///if is_sculpt +function ui_header_draw_tool_properties(ui: zui_t) { + if (context_raw.tool == workspace_tool_t.BRUSH) { + context_raw.brush_radius = zui_slider(context_raw.brush_radius_handle, tr("Radius"), 0.01, 2.0, true); + if (ui.is_hovered) zui_tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", new Map([["brush_radius", config_keymap.brush_radius], ["brush_radius_decrease", config_keymap.brush_radius_decrease], ["brush_radius_increase", config_keymap.brush_radius_increase]]))); + } +} +///end + +///if is_lab +function ui_header_draw_tool_properties(ui: zui_t) { + if (context_raw.tool == workspace_tool_t.PICKER) { + + } + else if (context_raw.tool == workspace_tool_t.ERASER || + context_raw.tool == workspace_tool_t.CLONE || + context_raw.tool == workspace_tool_t.BLUR || + context_raw.tool == workspace_tool_t.SMUDGE) { + + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + let canvas: zui_node_canvas_t = ui_nodes_get_canvas(true); + let inpaint: bool = nodes.nodes_selected_id.length > 0 && zui_get_node(canvas.nodes, nodes.nodes_selected_id[0]).type == "InpaintNode"; + if (inpaint) { + context_raw.brush_radius = zui_slider(context_raw.brush_radius_handle, tr("Radius"), 0.01, 2.0, true); + if (ui.is_hovered) zui_tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", new Map([["brush_radius", config_keymap.brush_radius], ["brush_radius_decrease", config_keymap.brush_radius_decrease], ["brush_radius_increase", config_keymap.brush_radius_increase]]))); + } + } +} +///end diff --git a/base/Sources/ui_menu.ts b/base/Sources/ui_menu.ts new file mode 100644 index 00000000..00208530 --- /dev/null +++ b/base/Sources/ui_menu.ts @@ -0,0 +1,622 @@ + +let ui_menu_show: bool = false; +let ui_menu_category: i32 = 0; +let ui_menu_category_w: i32 = 0; +let ui_menu_category_h: i32 = 0; +let ui_menu_x: i32 = 0; +let ui_menu_y: i32 = 0; +let ui_menu_elements: i32 = 0; +let ui_menu_keep_open: bool = false; +let ui_menu_commands: (ui: zui_t)=>void = null; +let ui_menu_show_first: bool = true; +let ui_menu_hide_flag: bool = false; + +function ui_menu_render() { + let ui: zui_t = base_ui_menu; + let menu_w: i32 = ui_menu_commands != null ? math_floor(base_default_element_w * zui_SCALE(base_ui_menu) * 2.3) : math_floor(zui_ELEMENT_W(ui) * 2.3); + let _BUTTON_COL: i32 = ui.t.BUTTON_COL; + ui.t.BUTTON_COL = ui.t.SEPARATOR_COL; + let _ELEMENT_OFFSET: i32 = ui.t.ELEMENT_OFFSET; + ui.t.ELEMENT_OFFSET = 0; + let _ELEMENT_H: i32 = ui.t.ELEMENT_H; + ui.t.ELEMENT_H = config_raw.touch_ui ? (28 + 2) : 28; + + zui_begin_region(ui, ui_menu_x, ui_menu_y, menu_w); + + if (ui_menu_commands != null) { + g2_set_color(ui.t.ACCENT_SELECT_COL); + zui_draw_rect(true, ui._x + -1, ui._y + -1, ui._w + 2, zui_ELEMENT_H(ui) * ui_menu_elements + 2); + g2_set_color(ui.t.SEPARATOR_COL); + zui_draw_rect(true, ui._x + 0, ui._y + 0, ui._w, zui_ELEMENT_H(ui) * ui_menu_elements); + g2_set_color(0xffffffff); + + ui_menu_commands(ui); + } + else { + ui_menu_start(ui); + if (ui_menu_category == menu_category_t.FILE) { + if (ui_menu_button(ui, tr("New .."), config_keymap.file_new)) project_new_box(); + if (ui_menu_button(ui, tr("Open..."), config_keymap.file_open)) project_open(); + if (ui_menu_button(ui, tr("Open Recent..."), config_keymap.file_open_recent)) BoxProjects.show(); + if (ui_menu_button(ui, tr("Save"), config_keymap.file_save)) project_save(); + if (ui_menu_button(ui, tr("Save As..."), config_keymap.file_save_as)) project_save_as(); + ui_menu_separator(ui); + if (ui_menu_button(ui, tr("Import Texture..."), config_keymap.file_import_assets)) project_import_asset(path_texture_formats.join(","), false); + if (ui_menu_button(ui, tr("Import Envmap..."))) { + ui_files_show("hdr", false, false, function (path: string) { + if (!path.endsWith(".hdr")) { + console_error(tr("Error: .hdr file expected")); + return; + } + ImportAsset.run(path); + }); + } + + ///if (is_paint || is_sculpt) + if (ui_menu_button(ui, tr("Import Font..."))) project_import_asset("ttf,ttc,otf"); + if (ui_menu_button(ui, tr("Import Material..."))) project_import_material(); + if (ui_menu_button(ui, tr("Import Brush..."))) project_import_brush(); + ///end + + ///if (is_paint || is_lab) + if (ui_menu_button(ui, tr("Import Swatches..."))) project_import_swatches(); + ///end + if (ui_menu_button(ui, tr("Import Mesh..."))) project_import_mesh(); + if (ui_menu_button(ui, tr("Reimport Mesh"), config_keymap.file_reimport_mesh)) project_reimport_mesh(); + if (ui_menu_button(ui, tr("Reimport Textures"), config_keymap.file_reimport_textures)) project_reimport_textures(); + ui_menu_separator(ui); + ///if (is_paint || is_lab) + if (ui_menu_button(ui, tr("Export Textures..."), config_keymap.file_export_textures_as)) { + ///if is_paint + context_raw.layers_export = export_mode_t.VISIBLE; + ///end + BoxExport.show_textures(); + } + if (ui_menu_button(ui, tr("Export Swatches..."))) project_export_swatches(); + ///end + if (ui_menu_button(ui, tr("Export Mesh..."))) { + context_raw.export_mesh_index = 0; // All + BoxExport.show_mesh(); + } + + ///if is_paint + if (ui_menu_button(ui, tr("Bake Material..."))) BoxExport.show_bake_material(); + ///end + + ui_menu_separator(ui); + if (ui_menu_button(ui, tr("Exit"))) sys_stop(); + } + else if (ui_menu_category == menu_category_t.EDIT) { + let step_undo: string = ""; + let step_redo: string = ""; + if (history_undos > 0) { + step_undo = history_steps[history_steps.length - 1 - history_redos].name; + } + if (history_redos > 0) { + step_redo = history_steps[history_steps.length - history_redos].name; + } + ui.enabled = history_undos > 0; + if (ui_menu_button(ui, tr("Undo {step}", new Map([["step", step_undo]])), config_keymap.edit_undo)) history_undo(); + ui.enabled = history_redos > 0; + if (ui_menu_button(ui, tr("Redo {step}", new Map([["step", step_redo]])), config_keymap.edit_redo)) history_redo(); + ui.enabled = true; + ui_menu_separator(ui); + if (ui_menu_button(ui, tr("Preferences..."), config_keymap.edit_prefs)) BoxPreferences.show(); + } + else if (ui_menu_category == menu_category_t.VIEWPORT) { + if (ui_menu_button(ui, tr("Distract Free"), config_keymap.view_distract_free)) { + ui_base_toggle_distract_free(); + ui_base_ui.is_hovered = false; + } + + ///if !(krom_android || krom_ios) + if (ui_menu_button(ui, tr("Toggle Fullscreen"), "alt+enter")) { + base_toggle_fullscreen(); + } + ///end + + ui.changed = false; + + ui_menu_fill(ui); + let p: world_data_t = scene_world; + let env_handle: zui_handle_t = zui_handle("uimenu_0"); + env_handle.value = p.strength; + ui_menu_align(ui); + p.strength = zui_slider(env_handle, tr("Environment"), 0.0, 8.0, true); + if (env_handle.changed) context_raw.ddirty = 2; + + ui_menu_fill(ui); + let enva_handle: zui_handle_t = zui_handle("uimenu_1"); + enva_handle.value = context_raw.envmap_angle / math_pi() * 180.0; + if (enva_handle.value < 0) { + enva_handle.value += (math_floor(-enva_handle.value / 360) + 1) * 360; + } + else if (enva_handle.value > 360) { + enva_handle.value -= math_floor(enva_handle.value / 360) * 360; + } + ui_menu_align(ui); + context_raw.envmap_angle = zui_slider(enva_handle, tr("Environment Angle"), 0.0, 360.0, true, 1) / 180.0 * math_pi(); + if (ui.is_hovered) zui_tooltip(tr("{shortcut} and move mouse", new Map([["shortcut", config_keymap.rotate_envmap]]))); + if (enva_handle.changed) context_raw.ddirty = 2; + + if (scene_lights.length > 0) { + let light: light_object_t = scene_lights[0]; + + ui_menu_fill(ui); + let lhandle: zui_handle_t = zui_handle("uimenu_2"); + let scale: f32 = 1333; + lhandle.value = light.data.strength / scale; + lhandle.value = math_floor(lhandle.value * 100) / 100; + ui_menu_align(ui); + light.data.strength = zui_slider(lhandle, tr("Light"), 0.0, 4.0, true) * scale; + if (lhandle.changed) context_raw.ddirty = 2; + + ui_menu_fill(ui); + light = scene_lights[0]; + let lahandle: zui_handle_t = zui_handle("uimenu_3"); + lahandle.value = context_raw.light_angle / math_pi() * 180; + ui_menu_align(ui); + let new_angle: f32 = zui_slider(lahandle, tr("Light Angle"), 0.0, 360.0, true, 1) / 180 * math_pi(); + if (ui.is_hovered) zui_tooltip(tr("{shortcut} and move mouse", new Map([["shortcut", config_keymap.rotate_light]]))); + let ldiff: f32 = new_angle - context_raw.light_angle; + if (math_abs(ldiff) > 0.005) { + if (new_angle < 0) new_angle += (math_floor(-new_angle / (2 * math_pi())) + 1) * 2 * math_pi(); + else if (new_angle > 2 * math_pi()) new_angle -= math_floor(new_angle / (2 * math_pi())) * 2 * math_pi(); + context_raw.light_angle = new_angle; + let m: mat4_t = mat4_rot_z(ldiff); + mat4_mult_mat(light.base.transform.local, m); + transform_decompose(light.base.transform); + context_raw.ddirty = 2; + } + + ui_menu_fill(ui); + let sxhandle: zui_handle_t = zui_handle("uimenu_4"); + sxhandle.value = light.data.size; + ui_menu_align(ui); + light.data.size = zui_slider(sxhandle, tr("Light Size"), 0.0, 4.0, true); + if (sxhandle.changed) context_raw.ddirty = 2; + } + + ///if (is_paint || is_sculpt) + ui_menu_fill(ui); + let split_view_handle: zui_handle_t = zui_handle("uimenu_5", { selected: context_raw.split_view }); + context_raw.split_view = zui_check(split_view_handle, " " + tr("Split View")); + if (split_view_handle.changed) { + base_resize(); + } + ///end + + ///if is_lab + ui_menu_fill(ui); + let brush_scale_handle: zui_handle_t = zui_handle("uimenu_6", { value: context_raw.brush_scale }); + ui_menu_align(ui); + context_raw.brush_scale = zui_slider(brush_scale_handle, tr("UV Scale"), 0.01, 5.0, true); + if (brush_scale_handle.changed) { + MakeMaterial.parse_mesh_material(); + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + RenderPathRaytrace.uv_scale = context_raw.brush_scale; + RenderPathRaytrace.ready = false; + ///end + } + ///end + + ui_menu_fill(ui); + let cull_handle: zui_handle_t = zui_handle("uimenu_7", { selected: context_raw.cull_backfaces }); + context_raw.cull_backfaces = zui_check(cull_handle, " " + tr("Cull Backfaces")); + if (cull_handle.changed) { + MakeMaterial.parse_mesh_material(); + } + + ui_menu_fill(ui); + let filter_handle: zui_handle_t = zui_handle("uimenu_8", { selected: context_raw.texture_filter }); + context_raw.texture_filter = zui_check(filter_handle, " " + tr("Filter Textures")); + if (filter_handle.changed) { + MakeMaterial.parse_paint_material(); + MakeMaterial.parse_mesh_material(); + } + + ///if (is_paint || is_sculpt) + ui_menu_fill(ui); + context_raw.draw_wireframe = zui_check(context_raw.wireframe_handle, " " + tr("Wireframe")); + if (context_raw.wireframe_handle.changed) { + let current: image_t = _g2_current; + g2_end(); + util_uv_cache_uv_map(); + g2_begin(current); + MakeMaterial.parse_mesh_material(); + } + ///end + + ///if is_paint + ui_menu_fill(ui); + context_raw.draw_texels = zui_check(context_raw.texels_handle, " " + tr("Texels")); + if (context_raw.texels_handle.changed) { + MakeMaterial.parse_mesh_material(); + } + ///end + + ui_menu_fill(ui); + let compass_handle: zui_handle_t = zui_handle("uimenu_9", { selected: context_raw.show_compass }); + context_raw.show_compass = zui_check(compass_handle, " " + tr("Compass")); + if (compass_handle.changed) context_raw.ddirty = 2; + + ui_menu_fill(ui); + context_raw.show_envmap = zui_check(context_raw.show_envmap_handle, " " + tr("Envmap")); + if (context_raw.show_envmap_handle.changed) { + context_load_envmap(); + context_raw.ddirty = 2; + } + + ui_menu_fill(ui); + context_raw.show_envmap_blur = zui_check(context_raw.show_envmap_blur_handle, " " + tr("Blur Envmap")); + if (context_raw.show_envmap_blur_handle.changed) context_raw.ddirty = 2; + + context_update_envmap(); + + if (ui.changed) ui_menu_keep_open = true; + } + else if (ui_menu_category == menu_category_t.MODE) { + let mode_handle: zui_handle_t = zui_handle("uimenu_10"); + mode_handle.position = context_raw.viewport_mode; + let modes: string[] = [ + tr("Lit"), + tr("Base Color"), + ///if (is_paint || is_lab) + tr("Normal"), + tr("Occlusion"), + tr("Roughness"), + tr("Metallic"), + tr("Opacity"), + tr("Height"), + ///end + ///if (is_paint) + tr("Emission"), + tr("Subsurface"), + ///end + ///if (is_paint || is_sculpt) + tr("TexCoord"), + tr("Object Normal"), + tr("Material ID"), + tr("Object ID"), + tr("Mask") + ///end + ]; + let shortcuts: string[] = ["l", "b", "n", "o", "r", "m", "a", "h", "e", "s", "t", "1", "2", "3", "4"]; + + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + if (krom_raytrace_supported()) { + modes.push(tr("Path Traced")); + shortcuts.push("p"); + } + ///end + + for (let i: i32 = 0; i < modes.length; ++i) { + ui_menu_fill(ui); + let shortcut: string = config_raw.touch_ui ? "" : config_keymap.viewport_mode + ", " + shortcuts[i]; + zui_radio(mode_handle, i, modes[i], shortcut); + } + + if (mode_handle.changed) { + context_set_viewport_mode(mode_handle.position); + // TODO: rotate mode is not supported for path tracing yet + if (mode_handle.position == viewport_mode_t.PATH_TRACE && context_raw.camera_controls == camera_controls_t.ROTATE) { + context_raw.camera_controls = camera_controls_t.ORBIT; + viewport_reset(); + } + } + } + else if (ui_menu_category == menu_category_t.CAMERA) { + if (ui_menu_button(ui, tr("Reset"), config_keymap.view_reset)) { + viewport_reset(); + viewport_scale_to_bounds(); + } + ui_menu_separator(ui); + if (ui_menu_button(ui, tr("Front"), config_keymap.view_front)) { + viewport_set_view(0, -1, 0, math_pi() / 2, 0, 0); + } + if (ui_menu_button(ui, tr("Back"), config_keymap.view_back)) { + viewport_set_view(0, 1, 0, math_pi() / 2, 0, math_pi()); + } + if (ui_menu_button(ui, tr("Right"), config_keymap.view_right)) { + viewport_set_view(1, 0, 0, math_pi() / 2, 0, math_pi() / 2); + } + if (ui_menu_button(ui, tr("Left"), config_keymap.view_left)) { + viewport_set_view(-1, 0, 0, math_pi() / 2, 0, -math_pi() / 2); + } + if (ui_menu_button(ui, tr("Top"), config_keymap.view_top)) { + viewport_set_view(0, 0, 1, 0, 0, 0); + } + if (ui_menu_button(ui, tr("Bottom"), config_keymap.view_bottom)) { + viewport_set_view(0, 0, -1, math_pi(), 0, math_pi()); + } + ui_menu_separator(ui); + + ui.changed = false; + + if (ui_menu_button(ui, tr("Orbit Left"), config_keymap.view_orbit_left)) { + viewport_orbit(-math_pi() / 12, 0); + } + if (ui_menu_button(ui, tr("Orbit Right"), config_keymap.view_orbit_right)) { + viewport_orbit(math_pi() / 12, 0); + } + if (ui_menu_button(ui, tr("Orbit Up"), config_keymap.view_orbit_up)) { + viewport_orbit(0, -math_pi() / 12); + } + if (ui_menu_button(ui, tr("Orbit Down"), config_keymap.view_orbit_down)) { + viewport_orbit(0, math_pi() / 12); + } + if (ui_menu_button(ui, tr("Orbit Opposite"), config_keymap.view_orbit_opposite)) { + viewport_orbit_opposite(); + } + if (ui_menu_button(ui, tr("Zoom In"), config_keymap.view_zoom_in)) { + viewport_zoom(0.2); + } + if (ui_menu_button(ui, tr("Zoom Out"), config_keymap.view_zoom_out)) { + viewport_zoom(-0.2); + } + // menuSeparator(ui); + + ui_menu_fill(ui); + let cam: camera_object_t = scene_camera; + context_raw.fov_handle = zui_handle("uimenu_11", { value: math_floor(cam.data.fov * 100) / 100 }); + ui_menu_align(ui); + cam.data.fov = zui_slider(context_raw.fov_handle, tr("FoV"), 0.3, 1.4, true); + if (context_raw.fov_handle.changed) { + viewport_update_camera_type(context_raw.camera_type); + } + + ui_menu_fill(ui); + ui_menu_align(ui); + let camera_controls_handle: zui_handle_t = zui_handle("uimenu_12"); + camera_controls_handle.position = context_raw.camera_controls; + context_raw.camera_controls = zui_inline_radio(camera_controls_handle, [tr("Orbit"), tr("Rotate"), tr("Fly")], zui_align_t.LEFT); + + let orbit_and_rotate_tooltip: string = tr("Orbit and Rotate mode:\n{rotate_shortcut} or move right mouse button to rotate.\n{zoom_shortcut} or scroll to zoom.\n{pan_shortcut} or move middle mouse to pan.", + new Map([ + ["rotate_shortcut", config_keymap.action_rotate], + ["zoom_shortcut", config_keymap.action_zoom], + ["pan_shortcut", config_keymap.action_pan] + ]) + ); + let fly_tooltip: string = tr("Fly mode:\nHold the right mouse button and one of the following commands:\nmove mouse to rotate.\nw, up or scroll up to move forward.\ns, down or scroll down to move backward.\na or left to move left.\nd or right to move right.\ne to move up.\nq to move down.\nHold shift to move faster or alt to move slower."); + if (ui.is_hovered) zui_tooltip(orbit_and_rotate_tooltip + "\n\n" + fly_tooltip); + + ui_menu_fill(ui); + ui_menu_align(ui); + context_raw.camera_type = zui_inline_radio(context_raw.cam_handle, [tr("Perspective"), tr("Orthographic")], zui_align_t.LEFT); + if (ui.is_hovered) zui_tooltip(tr("Camera Type") + ` (${config_keymap.view_camera_type})`); + if (context_raw.cam_handle.changed) { + viewport_update_camera_type(context_raw.camera_type); + } + + if (ui.changed) ui_menu_keep_open = true; + } + else if (ui_menu_category == menu_category_t.HELP) { + if (ui_menu_button(ui, tr("Manual"))) { + file_load_url(manifest_url + "/manual"); + } + if (ui_menu_button(ui, tr("How To"))) { + file_load_url(manifest_url + "/howto"); + } + if (ui_menu_button(ui, tr("What's New"))) { + file_load_url(manifest_url + "/notes"); + } + if (ui_menu_button(ui, tr("Issue Tracker"))) { + file_load_url("https://github.com/armory3d/armortools/issues"); + } + if (ui_menu_button(ui, tr("Report Bug"))) { + ///if (krom_darwin || krom_ios) // Limited url length + file_load_url("https://github.com/armory3d/armortools/issues/new?labels=bug&template=bug_report.md&body=*" + manifest_title + "%20" + manifest_version + "-" + config_get_sha() + ",%20" + sys_system_id()); + ///else + file_load_url("https://github.com/armory3d/armortools/issues/new?labels=bug&template=bug_report.md&body=*" + manifest_title + "%20" + manifest_version + "-" + config_get_sha() + ",%20" + sys_system_id() + "*%0A%0A**Issue description:**%0A%0A**Steps to reproduce:**%0A%0A"); + ///end + } + if (ui_menu_button(ui, tr("Request Feature"))) { + ///if (krom_darwin || krom_ios) // Limited url length + file_load_url("https://github.com/armory3d/armortools/issues/new?labels=feature%20request&template=feature_request.md&body=*" + manifest_title + "%20" + manifest_version + "-" + config_get_sha() + ",%20" + sys_system_id()); + ///else + file_load_url("https://github.com/armory3d/armortools/issues/new?labels=feature%20request&template=feature_request.md&body=*" + manifest_title + "%20" + manifest_version + "-" + config_get_sha() + ",%20" + sys_system_id() + "*%0A%0A**Feature description:**%0A%0A"); + ///end + } + ui_menu_separator(ui); + + if (ui_menu_button(ui, tr("Check for Updates..."))) { + ///if krom_android + file_load_url(manifest_url_android); + ///elseif krom_ios + file_load_url(manifest_url_ios); + ///else + // Retrieve latest version number + file_download_bytes("https://server.armorpaint.org/" + manifest_title.toLowerCase() + ".html", function (buffer: ArrayBuffer) { + if (buffer != null) { + // Compare versions + let update: any = json_parse(sys_buffer_to_string(buffer)); + let update_version: i32 = math_floor(update.version); + if (update_version > 0) { + let date: string = config_get_date().substr(2); // 2019 -> 19 + let date_int: i32 = parseInt(string_replace_all(date, "-", "")); + if (update_version > date_int) { + ui_box_show_message(tr("Update"), tr("Update is available!\nPlease visit {url}.", new Map([["url", manifest_url]]))); + } + else { + ui_box_show_message(tr("Update"), tr("You are up to date!")); + } + } + } + else { + ui_box_show_message(tr("Update"), tr("Unable to check for updates.\nPlease visit {url}.", new Map([["url", manifest_url]]))); + } + }); + ///end + } + + if (ui_menu_button(ui, tr("About..."))) { + + let msg: string = manifest_title + ".org - v" + manifest_version + " (" + config_get_date() + ") - " + config_get_sha() + "\n"; + msg += sys_system_id() + " - " + strings_graphics_api(); + + ///if krom_windows + let save: string = (path_is_protected() ? krom_save_path() : path_data()) + path_sep + "tmp.txt"; + krom_sys_command('wmic path win32_VideoController get name > "' + save + '"'); + let blob: buffer_t = krom_load_blob(save); + let u8: Uint8Array = new Uint8Array(blob); + let gpu_raw: string = ""; + for (let i: i32 = 0; i < math_floor(u8.length / 2); ++i) { + let c: string = String.fromCharCode(u8[i * 2]); + gpu_raw += c; + } + + let gpus: string[] = gpu_raw.split("\n"); + gpus = gpus.splice(1, gpus.length - 2); + let gpu: string = ""; + for (let g of gpus) { + gpu += trim_end(g) + ", "; + } + gpu = gpu.substr(0, gpu.length - 2); + msg += `\n${gpu}`; + ///else + // { lshw -C display } + ///end + + ui_box_show_custom(function (ui: zui_t) { + let tab_vertical: bool = config_raw.touch_ui; + if (zui_tab(zui_handle("uimenu_13"), tr("About"), tab_vertical)) { + + let img: image_t = data_get_image("badge.k"); + zui_image(img); + zui_end_element(); + + zui_text_area(zui_handle("uimenu_14", { text: msg }), zui_align_t.LEFT, false); + + zui_row([1 / 3, 1 / 3, 1 / 3]); + + ///if (krom_windows || krom_linux || krom_darwin) + if (zui_button(tr("Copy"))) { + krom_copy_to_clipboard(msg); + } + ///else + zui_end_element(); + ///end + + if (zui_button(tr("Contributors"))) { + file_load_url("https://github.com/armory3d/armortools/graphs/contributors"); + } + if (zui_button(tr("OK"))) { + ui_box_hide(); + } + } + }, 400, 320); + } + } + } + + ui_menu_hide_flag = ui.combo_selected_handle_ptr == 0 && !ui_menu_keep_open && !ui_menu_show_first && (ui.changed || ui.input_released || ui.input_released_r || ui.is_escape_down); + ui_menu_show_first = false; + ui_menu_keep_open = false; + + ui.t.BUTTON_COL = _BUTTON_COL; + ui.t.ELEMENT_OFFSET = _ELEMENT_OFFSET; + ui.t.ELEMENT_H = _ELEMENT_H; + zui_end_region(); + + if (ui_menu_hide_flag) { + ui_menu_hide(); + ui_menu_show_first = true; + ui_menu_commands = null; + } +} + +function ui_menu_hide() { + ui_menu_show = false; + base_redraw_ui(); +} + +function ui_menu_draw(commands: (ui: zui_t)=>void = null, elements: i32, x: i32 = -1, y: i32 = -1) { + zui_end_input(); + ui_menu_show = true; + ui_menu_commands = commands; + ui_menu_elements = elements; + ui_menu_x = x > -1 ? x : math_floor(mouse_x + 1); + ui_menu_y = y > -1 ? y : math_floor(mouse_y + 1); + ui_menu_fit_to_screen(); +} + +function ui_menu_fit_to_screen() { + // Prevent the menu going out of screen + let menu_w: f32 = base_default_element_w * zui_SCALE(base_ui_menu) * 2.3; + if (ui_menu_x + menu_w > sys_width()) { + if (ui_menu_x - menu_w > 0) { + ui_menu_x = math_floor(ui_menu_x - menu_w); + } + else { + ui_menu_x = math_floor(sys_width() - menu_w); + } + } + let menu_h: f32 = math_floor(ui_menu_elements * 30 * zui_SCALE(base_ui_menu)); // ui.t.ELEMENT_H + if (ui_menu_y + menu_h > sys_height()) { + if (ui_menu_y - menu_h > 0) { + ui_menu_y = math_floor(ui_menu_y - menu_h); + } + else { + ui_menu_y = sys_height() - menu_h; + } + ui_menu_x += 1; // Move out of mouse focus + } +} + +function ui_menu_fill(ui: zui_t) { + g2_set_color(ui.t.ACCENT_SELECT_COL); + g2_fill_rect(ui._x - 1, ui._y, ui._w + 2, zui_ELEMENT_H(ui) + 1 + 1); + g2_set_color(ui.t.SEPARATOR_COL); + g2_fill_rect(ui._x, ui._y, ui._w, zui_ELEMENT_H(ui) + 1); + g2_set_color(0xffffffff); +} + +function ui_menu_separator(ui: zui_t) { + ui._y++; + if (config_raw.touch_ui) { + zui_fill(0, 0, ui._w / zui_SCALE(ui), 1, ui.t.ACCENT_SELECT_COL); + } + else { + zui_fill(26, 0, ui._w / zui_SCALE(ui) - 26, 1, ui.t.ACCENT_SELECT_COL); + } +} + +function ui_menu_button(ui: zui_t, text: string, label: string = ""/*, icon: i32 = -1*/): bool { + ui_menu_fill(ui); + if (config_raw.touch_ui) { + label = ""; + } + + // let icons: image_t = icon > -1 ? get("icons.k") : null; + // let r: rect_t = tile25(icons, icon, 8); + // return Zui.button(config_button_spacing + text, config_button_align, label, icons, r.x, r.y, r.w, r.h); + + return zui_button(config_button_spacing + text, config_button_align, label); +} + +function ui_menu_align(ui: zui_t) { + if (!config_raw.touch_ui) { + zui_row([12 / 100, 88 / 100]); + zui_end_element(); + } +} + +function ui_menu_start(ui: zui_t) { + // Draw top border + g2_set_color(ui.t.ACCENT_SELECT_COL); + if (config_raw.touch_ui) { + g2_fill_rect(ui._x + ui._w / 2 + ui_menu_category_w / 2, ui._y - 1, ui._w / 2 - ui_menu_category_w / 2 + 1, 1); + g2_fill_rect(ui._x - 1, ui._y - 1, ui._w / 2 - ui_menu_category_w / 2 + 1, 1); + g2_fill_rect(ui._x + ui._w / 2 - ui_menu_category_w / 2, ui._y - ui_menu_category_h, ui_menu_category_w, 1); + g2_fill_rect(ui._x + ui._w / 2 - ui_menu_category_w / 2, ui._y - ui_menu_category_h, 1, ui_menu_category_h); + g2_fill_rect(ui._x + ui._w / 2 + ui_menu_category_w / 2, ui._y - ui_menu_category_h, 1, ui_menu_category_h); + } + else { + g2_fill_rect(ui._x - 1 + ui_menu_category_w, ui._y - 1, ui._w + 2 - ui_menu_category_w, 1); + g2_fill_rect(ui._x - 1, ui._y - ui_menu_category_h, ui_menu_category_w, 1); + g2_fill_rect(ui._x - 1, ui._y - ui_menu_category_h, 1, ui_menu_category_h); + g2_fill_rect(ui._x - 1 + ui_menu_category_w, ui._y - ui_menu_category_h, 1, ui_menu_category_h); + } + g2_set_color(0xffffffff); +} diff --git a/base/Sources/ui_menubar.ts b/base/Sources/ui_menubar.ts new file mode 100644 index 00000000..7c3e8ccf --- /dev/null +++ b/base/Sources/ui_menubar.ts @@ -0,0 +1,184 @@ + +let ui_menubar_default_w: i32 = 330; +let ui_menubar_workspace_handle: zui_handle_t = zui_handle_create({ layout: zui_layout_t.HORIZONTAL }); +let ui_menubar_menu_handle: zui_handle_t = zui_handle_create({ layout: zui_layout_t.HORIZONTAL }); +let ui_menubar_w: i32 = ui_menubar_default_w; + +///if is_lab +let _ui_menubar_saved_camera: mat4_t = null; +let _ui_menubar_plane: mesh_object_t = null; +///end + +function ui_menubar_init() { +} + +function ui_menubar_render_ui() { + let ui: zui_t = ui_base_ui; + + ///if (is_paint || is_sculpt) + let panelx: i32 = app_x() - ui_toolbar_w; + ///end + ///if is_lab + let panelx: i32 = app_x(); + ///end + + if (zui_window(ui_menubar_menu_handle, panelx, 0, ui_menubar_w, ui_header_h)) { + ui._x += 1; // Prevent "File" button highlight on startup + + zui_begin_menu(); + + if (config_raw.touch_ui) { + + ///if (is_paint || is_sculpt) + ui._w = ui_toolbar_w; + ///end + ///if is_lab + ui._w = 36; + ///end + + if (ui_menubar_icon_button(ui, 0, 2)) BoxPreferences.show(); + if (ui_menubar_icon_button(ui, 0, 3)) { + ///if (krom_android || krom_ios) + console_toast(tr("Saving project")); + project_save(); + ///end + base_notify_on_next_frame(function () { + BoxProjects.show(); + }); + } + if (ui_menubar_icon_button(ui, 4, 2)) project_import_asset(); + ///if (is_paint || is_lab) + if (ui_menubar_icon_button(ui, 5, 2)) BoxExport.show_textures(); + ///end + let size: i32 = math_floor(ui._w / zui_SCALE(ui)); + if (ui_menu_show && ui_menu_category == menu_category_t.VIEWPORT) zui_fill(0, -6, size, size - 4, ui.t.HIGHLIGHT_COL); + if (ui_menubar_icon_button(ui, 8, 2)) ui_menubar_show_menu(ui, menu_category_t.VIEWPORT); + if (ui_menu_show && ui_menu_category == menu_category_t.MODE) zui_fill(0, -6, size, size - 4, ui.t.HIGHLIGHT_COL); + if (ui_menubar_icon_button(ui, 9, 2)) ui_menubar_show_menu(ui, menu_category_t.MODE); + if (ui_menu_show && ui_menu_category == menu_category_t.CAMERA) zui_fill(0, -6, size, size - 4, ui.t.HIGHLIGHT_COL); + if (ui_menubar_icon_button(ui, 10, 2)) ui_menubar_show_menu(ui, menu_category_t.CAMERA); + if (ui_menu_show && ui_menu_category == menu_category_t.HELP) zui_fill(0, -6, size, size - 4, ui.t.HIGHLIGHT_COL); + if (ui_menubar_icon_button(ui, 11, 2)) ui_menubar_show_menu(ui, menu_category_t.HELP); + ui.enabled = history_undos > 0; + if (ui_menubar_icon_button(ui, 6, 2)) history_undo(); + ui.enabled = history_redos > 0; + if (ui_menubar_icon_button(ui, 7, 2)) history_redo(); + ui.enabled = true; + } + else { + let categories: string[] = [tr("File"), tr("Edit"), tr("Viewport"), tr("Mode"), tr("Camera"), tr("Help")]; + for (let i: i32 = 0; i < categories.length; ++i) { + if (zui_menu_button(categories[i]) || (ui_menu_show && ui_menu_commands == null && ui.is_hovered)) { + ui_menubar_show_menu(ui, i); + } + } + } + + if (ui_menubar_w < ui._x + 10) { + ui_menubar_w = math_floor(ui._x + 10); + + ///if (is_paint || is_sculpt) + ui_toolbar_handle.redraws = 2; + ///end + } + + zui_end_menu(); + } + + let nodesw: i32 = (ui_nodes_show || ui_view2d_show) ? config_raw.layout[layout_size_t.NODES_W] : 0; + ///if (is_paint || is_sculpt) + let ww: i32 = sys_width() - config_raw.layout[layout_size_t.SIDEBAR_W] - ui_menubar_w - nodesw; + panelx = (app_x() - ui_toolbar_w) + ui_menubar_w; + ///else + let ww: i32 = sys_width() - ui_menubar_w - nodesw; + panelx = (app_x()) + ui_menubar_w; + ///end + + if (zui_window(ui_menubar_workspace_handle, panelx, 0, ww, ui_header_h)) { + + if (!config_raw.touch_ui) { + zui_tab(ui_header_worktab, tr("3D View")); + } + else { + zui_fill(0, 0, ui._window_w, ui._window_h + 4, ui.t.SEPARATOR_COL); + } + + ///if is_lab + zui_tab(ui_header_worktab, tr("2D View")); + if (ui_header_worktab.changed) { + context_raw.ddirty = 2; + context_raw.brush_blend_dirty = true; + ui_header_handle.redraws = 2; + context_main_object().skip_context = null; + + if (ui_header_worktab.position == space_type_t.SPACE3D) { + if (_ui_menubar_saved_camera != null) { + transform_set_matrix(scene_camera.base.transform, _ui_menubar_saved_camera); + _ui_menubar_saved_camera = null; + } + scene_meshes = [context_main_object()]; + } + else { // Space2D + if (_ui_menubar_plane == null) { + let mesh: any = geom_make_plane(1, 1, 2, 2); + let raw: any = { + name: "2DView", + vertex_arrays: [ + { values: mesh.posa, attrib: "pos", data: "short4norm" }, + { values: mesh.nora, attrib: "nor", data: "short2norm" }, + { values: mesh.texa, attrib: "tex", data: "short2norm" } + ], + index_arrays: [ + { values: mesh.inda, material: 0 } + ], + scale_pos: mesh.scale_pos, + scale_tex: mesh.scale_tex + }; + let md: mesh_data_t = mesh_data_create(raw); + let dot_plane: mesh_object_t = scene_get_child(".Plane").ext; + _ui_menubar_plane = mesh_object_create(md, dot_plane.materials); + array_remove(scene_meshes, _ui_menubar_plane); + } + + if (_ui_menubar_saved_camera == null) { + _ui_menubar_saved_camera = mat4_clone(scene_camera.base.transform.local); + } + scene_meshes = [_ui_menubar_plane]; + let m: mat4_t = mat4_identity(); + mat4_translate(m, 0, 0, 1.6); + transform_set_matrix(scene_camera.base.transform, m); + } + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + RenderPathRaytrace.ready = false; + ///end + } + ///end + } +} + +function ui_menubar_show_menu(ui: zui_t, category: i32) { + ui_menu_show = true; + ui_menu_commands = null; + ui_menu_category = category; + ui_menu_category_w = ui._w; + ui_menu_category_h = math_floor(zui_MENUBAR_H(ui)); + ui_menu_x = math_floor(ui._x - ui._w); + ui_menu_y = math_floor(zui_MENUBAR_H(ui)); + if (config_raw.touch_ui) { + let menuW: i32 = math_floor(base_default_element_w * zui_SCALE(base_ui_menu) * 2.0); + ui_menu_x -= math_floor((menuW - ui._w) / 2) + math_floor(ui_header_h / 2); + ui_menu_x += math_floor(2 * zui_SCALE(base_ui_menu)); + ui_menu_y -= math_floor(2 * zui_SCALE(base_ui_menu)); + ui_menu_keep_open = true; + } +} + +function ui_menubar_icon_button(ui: zui_t, i: i32, j: i32): bool { + let col: i32 = ui.t.WINDOW_BG_COL; + if (col < 0) col += 4294967296; + let light: bool = col > (0xff666666 + 4294967296); + let icon_accent: i32 = light ? 0xff666666 : 0xffaaaaaa; + let img: image_t = resource_get("icons.k"); + let rect: rect_t = resource_tile50(img, i, j); + return zui_image(img, icon_accent, -1.0, rect.x, rect.y, rect.w, rect.h) == zui_state_t.RELEASED; +} diff --git a/base/Sources/ui_nodes.ts b/base/Sources/ui_nodes.ts new file mode 100644 index 00000000..f40da0de --- /dev/null +++ b/base/Sources/ui_nodes.ts @@ -0,0 +1,1292 @@ + +///if (is_paint || is_sculpt) +let ui_nodes_show: bool = false; +///end +///if is_lab +let ui_nodes_show: bool = true; +///end + +let ui_nodes_wx: i32; +let ui_nodes_wy: i32; +let ui_nodes_ww: i32; +let ui_nodes_wh: i32; + +let ui_nodes_ui: zui_t; +let ui_nodes_canvas_type = canvas_type_t.MATERIAL; +let ui_nodes_show_menu: bool = false; +let ui_nodes_show_menu_first: bool = true; +let ui_nodes_hide_menu: bool = false; +let ui_nodes_menu_category: i32 = 0; +let ui_nodes_popup_x: f32 = 0.0; +let ui_nodes_popup_y: f32 = 0.0; + +let ui_nodes_uichanged_last: bool = false; +let ui_nodes_recompile_mat: bool = false; // Mat preview +let ui_nodes_recompile_mat_final: bool = false; +let ui_nodes_node_search_spawn: zui_node_t = null; +let ui_nodes_node_search_offset: i32 = 0; +let ui_nodes_last_canvas: zui_node_canvas_t = null; +let ui_nodes_last_node_selected_id: i32 = -1; +let ui_nodes_release_link: bool = false; +let ui_nodes_is_node_menu_op: bool = false; + +let ui_nodes_grid: image_t = null; +let ui_nodes_hwnd: zui_handle_t = zui_handle_create(); +let ui_nodes_group_stack: node_group_t[] = []; +let ui_nodes_controls_down: bool = false; + +function ui_nodes_init() { + zui_set_on_link_drag(ui_nodes_on_link_drag); + zui_set_on_socket_released(ui_nodes_on_socket_released); + zui_set_on_canvas_released(ui_nodes_on_canvas_released); + 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 }); + ui_nodes_ui.scroll_enabled = false; +} + +function ui_nodes_on_link_drag(link_drag_id: i32, is_new_link: bool) { + if (is_new_link) { + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + let link_drag: zui_node_link_t = zui_get_link(ui_nodes_get_canvas(true).links, link_drag_id); + let node: zui_node_t = zui_get_node(ui_nodes_get_canvas(true).nodes, link_drag.from_id > -1 ? link_drag.from_id : link_drag.to_id); + let link_x: i32 = ui_nodes_ui._window_x + zui_nodes_NODE_X(node); + let link_y: i32 = ui_nodes_ui._window_y + zui_nodes_NODE_Y(node); + if (link_drag.from_id > -1) { + link_x += zui_nodes_NODE_W(node); + link_y += zui_nodes_OUTPUT_Y(node.outputs, link_drag.from_socket); + } + else { + link_y += zui_nodes_INPUT_Y(ui_nodes_get_canvas(true), node.inputs, link_drag.to_socket) + zui_nodes_OUTPUTS_H(node.outputs) + zui_nodes_BUTTONS_H(node); + } + if (math_abs(mouse_x - link_x) > 5 || math_abs(mouse_y - link_y) > 5) { // Link length + ui_nodes_node_search(-1, -1, function () { + let n: zui_node_t = zui_get_node(ui_nodes_get_canvas(true).nodes, nodes.nodes_selected_id[0]); + if (link_drag.to_id == -1 && n.inputs.length > 0) { + link_drag.to_id = n.id; + let from_type: string = node.outputs[link_drag.from_socket].type; + // Connect to the first socket + link_drag.to_socket = 0; + // Try to find the first type-matching socket and use it if present + for (let socket of n.inputs) { + if (socket.type == from_type) { + link_drag.to_socket = n.inputs.indexOf(socket); + break; + } + } + ui_nodes_get_canvas(true).links.push(link_drag); + } + else if (link_drag.from_id == -1 && n.outputs.length > 0) { + link_drag.from_id = n.id; + link_drag.from_socket = 0; + ui_nodes_get_canvas(true).links.push(link_drag); + } + ///if is_lab + ParserLogic.parse(ui_nodes_get_canvas(true)); + context_raw.rdirty = 5; + ///end + }); + } + // Selecting which node socket to preview + else if (node.id == nodes.nodes_selected_id[0]) { + context_raw.node_preview_socket = link_drag.from_id > -1 ? link_drag.from_socket : 0; + ///if (is_paint || is_sculpt) + context_raw.node_preview_dirty = true; + ///end + } + } +} + +function ui_nodes_on_socket_released(socket_id: i32) { + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + let canvas: zui_node_canvas_t = ui_nodes_get_canvas(true); + let socket: zui_node_socket_t = zui_get_socket(canvas.nodes, socket_id); + let node: zui_node_t = zui_get_node(canvas.nodes, socket.node_id); + if (ui_nodes_ui.input_released_r) { + if (node.type == "GROUP_INPUT" || node.type == "GROUP_OUTPUT") { + base_notify_on_next_frame(function () { + ui_menu_draw(function (ui: zui_t) { + if (ui_menu_button(ui, tr("Edit"))) { + let htype: zui_handle_t = zui_handle("uinodes_0"); + let hname: zui_handle_t = zui_handle("uinodes_1"); + let hmin: zui_handle_t = zui_handle("uinodes_2"); + let hmax: zui_handle_t = zui_handle("uinodes_3"); + let hval0: zui_handle_t = zui_handle("uinodes_4"); + let hval1: zui_handle_t = zui_handle("uinodes_5"); + let hval2: zui_handle_t = zui_handle("uinodes_6"); + let hval3: zui_handle_t = zui_handle("uinodes_7"); + htype.position = socket.type == "RGBA" ? 0 : socket.type == "VECTOR" ? 1 : 2; + hname.text = socket.name; + hmin.value = socket.min; + hmax.value = socket.max; + if (socket.type == "RGBA" || socket.type == "VECTOR") { + hval0.value = socket.default_value[0]; + hval1.value = socket.default_value[1]; + hval2.value = socket.default_value[2]; + if (socket.type == "RGBA") { + hval3.value = socket.default_value[3]; + } + } + else hval0.value = socket.default_value; + base_notify_on_next_frame(function () { + zui_end_input(); + ui_box_show_custom(function (ui: zui_t) { + if (zui_tab(zui_handle("uinodes_8"), tr("Socket"))) { + let type: i32 = zui_combo(htype, [tr("Color"), tr("Vector"), tr("Value")], tr("Type"), true); + if (htype.changed) hname.text = type == 0 ? tr("Color") : type == 1 ? tr("Vector") : tr("Value"); + let name: string = zui_text_input(hname, tr("Name")); + let min: f32 = zui_float_input(hmin, tr("Min")); + let max: f32 = zui_float_input(hmax, tr("Max")); + let default_value: any = null; + if (type == 0) { + zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]); + zui_float_input(hval0, tr("R")); + zui_float_input(hval1, tr("G")); + zui_float_input(hval2, tr("B")); + zui_float_input(hval3, tr("A")); + default_value = new Float32Array([hval0.value, hval1.value, hval2.value, hval3.value]); + } + else if (type == 1) { + zui_row([1 / 3, 1 / 3, 1 / 3]); + hval0.value = zui_float_input(hval0, tr("X")); + hval1.value = zui_float_input(hval1, tr("Y")); + hval2.value = zui_float_input(hval2, tr("Z")); + default_value = new Float32Array([hval0.value, hval1.value, hval2.value]); + } + else { + default_value = zui_float_input(hval0, tr("default_value")); + } + if (zui_button(tr("OK"))) { // || ui.isReturnDown + socket.name = name; + socket.type = type == 0 ? "RGBA" : type == 1 ? "VECTOR" : "VALUE"; + socket.color = NodesMaterial.get_socket_color(socket.type); + socket.min = min; + socket.max = max; + socket.default_value = default_value; + ui_box_hide(); + NodesMaterial.sync_sockets(node); + ui_nodes_hwnd.redraws = 2; + } + } + }, 400, 250); + }); + } + if (ui_menu_button(ui, tr("Delete"))) { + let i: i32 = 0; + // Remove links connected to the socket + while (i < canvas.links.length) { + let l: zui_node_link_t = canvas.links[i]; + if ((l.from_id == node.id && l.from_socket == node.outputs.indexOf(socket)) || + (l.to_id == node.id && l.to_socket == node.inputs.indexOf(socket))) { + canvas.links.splice(i, 1); + } + else i++; + } + // Remove socket + array_remove(node.inputs, socket); + array_remove(node.outputs, socket); + NodesMaterial.sync_sockets(node); + } + }, 2); + }); + } + else ui_nodes_on_canvas_released(); + } + // Selecting which node socket to preview + else if (node.id == nodes.nodes_selected_id[0]) { + let i: i32 = node.outputs.indexOf(socket); + if (i > -1) { + context_raw.node_preview_socket = i; + ///if (is_paint || is_sculpt) + context_raw.node_preview_dirty = true; + ///end + } + } +} + +function ui_nodes_on_canvas_released() { + if (ui_nodes_ui.input_released_r && math_abs(ui_nodes_ui.input_x - ui_nodes_ui.input_started_x) < 2 && math_abs(ui_nodes_ui.input_y - ui_nodes_ui.input_started_y) < 2) { + // Node selection + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + let canvas: zui_node_canvas_t = ui_nodes_get_canvas(true); + let selected: zui_node_t = null; + for (let node of canvas.nodes) { + if (zui_get_input_in_rect(ui_nodes_ui._window_x + zui_nodes_NODE_X(node), ui_nodes_ui._window_y + zui_nodes_NODE_Y(node), zui_nodes_NODE_W(node), zui_nodes_NODE_H(canvas, node))) { + selected = node; + break; + } + } + if (selected == null) nodes.nodes_selected_id = []; + else if (nodes.nodes_selected_id.indexOf(selected.id) == -1) nodes.nodes_selected_id = [selected.id]; + + // Node context menu + if (!zui_socket_released()) { + let number_of_entries: i32 = 5; + if (ui_nodes_canvas_type == canvas_type_t.MATERIAL) ++number_of_entries; + if (selected != null && selected.type == "RGB") ++number_of_entries; + + ui_menu_draw(function (ui_menu: zui_t) { + ui_menu._y += 1; + let is_protected: bool = selected == null || + ///if (is_paint || is_sculpt) + selected.type == "OUTPUT_MATERIAL_PBR" || + ///end + selected.type == "GROUP_INPUT" || + selected.type == "GROUP_OUTPUT" || + selected.type == "BrushOutputNode"; + ui_menu.enabled = !is_protected; + if (ui_menu_button(ui_menu, tr("Cut"), "ctrl+x")) { + base_notify_on_next_frame(function () { + ui_nodes_hwnd.redraws = 2; + zui_set_is_copy(true); + zui_set_is_cut(true); + ui_nodes_is_node_menu_op = true; + }); + } + if (ui_menu_button(ui_menu, tr("Copy"), "ctrl+c")) { + base_notify_on_next_frame(function () { + zui_set_is_copy(true); + ui_nodes_is_node_menu_op = true; + }); + } + ui_menu.enabled = zui_clipboard != ""; + if (ui_menu_button(ui_menu, tr("Paste"), "ctrl+v")) { + base_notify_on_next_frame(function () { + ui_nodes_hwnd.redraws = 2; + zui_set_is_paste(true); + ui_nodes_is_node_menu_op = true; + }); + } + ui_menu.enabled = !is_protected; + if (ui_menu_button(ui_menu, tr("Delete"), "delete")) { + base_notify_on_next_frame(function () { + ui_nodes_hwnd.redraws = 2; + ui_nodes_ui.is_delete_down = true; + ui_nodes_is_node_menu_op = true; + }); + } + if (ui_menu_button(ui_menu, tr("Duplicate"))) { + base_notify_on_next_frame(function () { + ui_nodes_hwnd.redraws = 2; + zui_set_is_copy(true); + zui_set_is_paste(true); + ui_nodes_is_node_menu_op = true; + }); + } + if (selected != null && selected.type == "RGB") { + if (ui_menu_button(ui_menu, tr("Add Swatch"))) { + let color: any = selected.outputs[0].default_value; + let new_swatch: swatch_color_t = make_swatch(color_from_floats(color[0], color[1], color[2], color[3])); + context_set_swatch(new_swatch); + project_raw.swatches.push(new_swatch); + ui_base_hwnds[tab_area_t.STATUS].redraws = 1; + } + } + + if (ui_nodes_canvas_type == canvas_type_t.MATERIAL) { + ui_menu_separator(ui_menu); + if (ui_menu_button(ui_menu, tr("2D View"))) { + ui_base_show_2d_view(view_2d_type_t.NODE); + } + } + + ui_menu.enabled = true; + }, number_of_entries); + } + } + + if (ui_nodes_ui.input_released) { + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + let canvas: zui_node_canvas_t = ui_nodes_get_canvas(true); + for (let node of canvas.nodes) { + if (zui_get_input_in_rect(ui_nodes_ui._window_x + zui_nodes_NODE_X(node), ui_nodes_ui._window_y + zui_nodes_NODE_Y(node), zui_nodes_NODE_W(node), zui_nodes_NODE_H(canvas, node))) { + if (node.id == nodes.nodes_selected_id[0]) { + ui_view2d_hwnd.redraws = 2; + if (time_time() - context_raw.select_time < 0.25) ui_base_show_2d_view(view_2d_type_t.NODE); + context_raw.select_time = time_time(); + } + break; + } + } + } +} + +function ui_nodes_on_canvas_control(): zui_canvas_control_t { + let control: zui_canvas_control_t = ui_nodes_get_canvas_control(ui_nodes_ui, ui_nodes_controls_down); + ui_nodes_controls_down = control.controls_down; + return control; +} + +function ui_nodes_get_canvas_control(ui: zui_t, controls_down: bool): zui_canvas_control_t { + if (config_raw.wrap_mouse && controls_down) { + if (ui.input_x < ui._window_x) { + ui.input_x = ui._window_x + ui._window_w; + krom_set_mouse_position(math_floor(ui.input_x), math_floor(ui.input_y)); + } + else if (ui.input_x > ui._window_x + ui._window_w) { + ui.input_x = ui._window_x; + krom_set_mouse_position(math_floor(ui.input_x), math_floor(ui.input_y)); + } + else if (ui.input_y < ui._window_y) { + ui.input_y = ui._window_y + ui._window_h; + krom_set_mouse_position(math_floor(ui.input_x), math_floor(ui.input_y)); + } + else if (ui.input_y > ui._window_y + ui._window_h) { + ui.input_y = ui._window_y; + krom_set_mouse_position(math_floor(ui.input_x), math_floor(ui.input_y)); + } + } + + if (operator_shortcut(config_keymap.action_pan, shortcut_type_t.STARTED) || + operator_shortcut(config_keymap.action_zoom, shortcut_type_t.STARTED) || + ui.input_started_r || + ui.input_wheel_delta != 0.0) { + controls_down = true; + } + else if (!operator_shortcut(config_keymap.action_pan, shortcut_type_t.DOWN) && + !operator_shortcut(config_keymap.action_zoom, shortcut_type_t.DOWN) && + !ui.input_down_r && + ui.input_wheel_delta == 0.0) { + controls_down = false; + } + if (!controls_down) { + return { + pan_x: 0, + pan_y: 0, + zoom: 0, + controls_down: controls_down + } + } + + let pan: bool = ui.input_down_r || operator_shortcut(config_keymap.action_pan, shortcut_type_t.DOWN); + let zoom_delta: f32 = operator_shortcut(config_keymap.action_zoom, shortcut_type_t.DOWN) ? ui_nodes_get_zoom_delta(ui) / 100.0 : 0.0; + let control: zui_canvas_control_t = { + pan_x: pan ? ui.input_dx : 0.0, + pan_y: pan ? ui.input_dy : 0.0, + zoom: ui.input_wheel_delta != 0.0 ? -ui.input_wheel_delta / 10 : zoom_delta, + controls_down: controls_down + }; + if (base_is_combo_selected()) control.zoom = 0.0; + return control; +} + +function ui_nodes_get_zoom_delta(ui: zui_t): f32 { + return config_raw.zoom_direction == zoom_direction_t.VERTICAL ? -ui.input_dy : + config_raw.zoom_direction == zoom_direction_t.VERTICAL_INVERTED ? -ui.input_dy : + config_raw.zoom_direction == zoom_direction_t.HORIZONTAL ? ui.input_dx : + config_raw.zoom_direction == zoom_direction_t.HORIZONTAL_INVERTED ? ui.input_dx : + -(ui.input_dy - ui.input_dx); +} + +function ui_nodes_get_canvas(groups: bool = false): zui_node_canvas_t { + ///if (is_paint || is_sculpt) + if (ui_nodes_canvas_type == canvas_type_t.MATERIAL) { + if (groups && ui_nodes_group_stack.length > 0) return ui_nodes_group_stack[ui_nodes_group_stack.length - 1].canvas; + else return ui_nodes_get_canvas_material(); + } + else return context_raw.brush.canvas; + ///end + + ///if is_lab + return project_canvas; + ///end +} + +///if (is_paint || is_sculpt) +function ui_nodes_get_canvas_material(): zui_node_canvas_t { + return context_raw.material.canvas; +} +///end + +function ui_nodes_get_nodes(): zui_nodes_t { + ///if (is_paint || is_sculpt) + if (ui_nodes_canvas_type == canvas_type_t.MATERIAL) { + if (ui_nodes_group_stack.length > 0) return ui_nodes_group_stack[ui_nodes_group_stack.length - 1].nodes; + else return context_raw.material.nodes; + } + else return context_raw.brush.nodes; + ///end + + ///if is_lab + if (ui_nodes_group_stack.length > 0) return ui_nodes_group_stack[ui_nodes_group_stack.length - 1].nodes; + else return project_nodes; + ///end +} + +function ui_nodes_update() { + if (!ui_nodes_show || !base_ui_enabled) return; + + ///if (is_paint || is_sculpt) + ui_nodes_wx = math_floor(app_w()) + ui_toolbar_w; + ///end + ///if is_lab + ui_nodes_wx = math_floor(app_w()); + ///end + ui_nodes_wy = ui_header_h * 2; + + if (ui_view2d_show) { + ui_nodes_wy += app_h() - config_raw.layout[layout_size_t.NODES_H]; + } + + let ww: i32 = config_raw.layout[layout_size_t.NODES_W]; + if (!ui_base_show) { + ///if (is_paint || is_sculpt) + ww += config_raw.layout[layout_size_t.SIDEBAR_W] + ui_toolbar_w; + ui_nodes_wx -= ui_toolbar_w; + ///end + ui_nodes_wy = 0; + } + + let mx: i32 = mouse_x; + let my: i32 = mouse_y; + if (mx < ui_nodes_wx || mx > ui_nodes_wx + ww || my < ui_nodes_wy) return; + if (ui_nodes_ui.is_typing || !ui_nodes_ui.input_enabled) return; + + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + if (nodes.nodes_selected_id.length > 0 && ui_nodes_ui.is_key_pressed) { + if (ui_nodes_ui.key == key_code_t.LEFT) for (let n of nodes.nodes_selected_id) zui_get_node(ui_nodes_get_canvas(true).nodes, n).x -= 1; + else if (ui_nodes_ui.key == key_code_t.RIGHT) for (let n of nodes.nodes_selected_id) zui_get_node(ui_nodes_get_canvas(true).nodes, n).x += 1; + if (ui_nodes_ui.key == key_code_t.UP) for (let n of nodes.nodes_selected_id) zui_get_node(ui_nodes_get_canvas(true).nodes, n).y -= 1; + else if (ui_nodes_ui.key == key_code_t.DOWN) for (let n of nodes.nodes_selected_id) zui_get_node(ui_nodes_get_canvas(true).nodes, n).y += 1; + } + + // Node search popup + if (operator_shortcut(config_keymap.node_search)) ui_nodes_node_search(); + if (ui_nodes_node_search_spawn != null) { + ui_nodes_ui.input_x = mouse_x; // Fix inputDX after popup removal + ui_nodes_ui.input_y = mouse_y; + ui_nodes_node_search_spawn = null; + } + + if (operator_shortcut(config_keymap.view_reset)) { + nodes.panX = 0.0; + nodes.panY = 0.0; + nodes.zoom = 1.0; + } +} + +function ui_nodes_canvas_changed() { + ui_nodes_recompile_mat = true; + ui_nodes_recompile_mat_final = true; +} + +function ui_nodes_node_search(x: i32 = -1, y: i32 = -1, done: ()=>void = null) { + let search_handle: zui_handle_t = zui_handle("uinodes_9"); + let first: bool = true; + ui_menu_draw(function (ui: zui_t) { + g2_set_color(ui.t.SEPARATOR_COL); + zui_draw_rect(true, ui._x, ui._y, ui._w, zui_ELEMENT_H(ui) * 8); + g2_set_color(0xffffffff); + + let search: string = zui_text_input(search_handle, "", zui_align_t.LEFT, true, true).toLowerCase(); + ui.changed = false; + if (first) { + first = false; + search_handle.text = ""; + zui_start_text_edit(search_handle); // Focus search bar + } + + if (search_handle.changed) ui_nodes_node_search_offset = 0; + + if (ui.is_key_pressed) { // Move selection + if (ui.key == key_code_t.DOWN && ui_nodes_node_search_offset < 6) ui_nodes_node_search_offset++; + if (ui.key == key_code_t.UP && ui_nodes_node_search_offset > 0) ui_nodes_node_search_offset--; + } + let enter: bool = keyboard_down("enter"); + let count: i32 = 0; + let BUTTON_COL: i32 = ui.t.BUTTON_COL; + + ///if (is_paint || is_sculpt) + let node_list: zui_node_t[][] = ui_nodes_canvas_type == canvas_type_t.MATERIAL ? NodesMaterial.list : NodesBrush.list; + ///end + ///if is_lab + let node_list: zui_node_t[][] = NodesBrush.list; + ///end + + for (let list of node_list) { + for (let n of list) { + if (tr(n.name).toLowerCase().indexOf(search) >= 0) { + ui.t.BUTTON_COL = count == ui_nodes_node_search_offset ? ui.t.HIGHLIGHT_COL : ui.t.SEPARATOR_COL; + if (zui_button(tr(n.name), zui_align_t.LEFT) || (enter && count == ui_nodes_node_search_offset)) { + ui_nodes_push_undo(); + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + let canvas: zui_node_canvas_t = ui_nodes_get_canvas(true); + ui_nodes_node_search_spawn = ui_nodes_make_node(n, nodes, canvas); // Spawn selected node + canvas.nodes.push(ui_nodes_node_search_spawn); + nodes.nodes_selected_id = [ui_nodes_node_search_spawn.id]; + nodes.nodesDrag = true; + + ///if is_lab + ParserLogic.parse(canvas); + ///end + + ui_nodes_hwnd.redraws = 2; + if (enter) { + ui.changed = true; + count = 6; // Trigger break + } + if (done != null) done(); + } + if (++count > 6) break; + } + } + if (count > 6) break; + } + if (enter && count == 0) { // Hide popup on enter when node is not found + ui.changed = true; + search_handle.text = ""; + } + ui.t.BUTTON_COL = BUTTON_COL; + }, 8, x, y); +} + +function ui_nodes_get_node_x(): i32 { + return math_floor((mouse_x - ui_nodes_wx - zui_nodes_PAN_X()) / zui_nodes_SCALE()); +} + +function ui_nodes_get_node_y(): i32 { + return math_floor((mouse_y - ui_nodes_wy - zui_nodes_PAN_Y()) / zui_nodes_SCALE()); +} + +function ui_nodes_draw_grid() { + let ww: i32 = config_raw.layout[layout_size_t.NODES_W]; + + ///if (is_paint || is_sculpt) + if (!ui_base_show) { + ww += config_raw.layout[layout_size_t.SIDEBAR_W] + ui_toolbar_w; + } + ///end + + let wh: i32 = app_h(); + let step: f32 = 100 * zui_SCALE(ui_nodes_ui); + let w: i32 = math_floor(ww + step * 3); + let h: i32 = math_floor(wh + step * 3); + if (w < 1) w = 1; + if (h < 1) h = 1; + ui_nodes_grid = image_create_render_target(w, h); + g2_begin(ui_nodes_grid); + g2_clear(ui_nodes_ui.t.SEPARATOR_COL); + + g2_set_color(ui_nodes_ui.t.SEPARATOR_COL - 0x00050505); + step = 20 * zui_SCALE(ui_nodes_ui); + for (let i: i32 = 0; i < math_floor(h / step) + 1; ++i) { + g2_draw_line(0, i * step, w, i * step); + } + for (let i: i32 = 0; i < math_floor(w / step) + 1; ++i) { + g2_draw_line(i * step, 0, i * step, h); + } + + g2_set_color(ui_nodes_ui.t.SEPARATOR_COL - 0x00090909); + step = 100 * zui_SCALE(ui_nodes_ui); + for (let i: i32 = 0; i < math_floor(h / step) + 1; ++i) { + g2_draw_line(0, i * step, w, i * step); + } + for (let i: i32 = 0; i < math_floor(w / step) + 1; ++i) { + g2_draw_line(i * step, 0, i * step, h); + } + + g2_end(); +} + +function ui_nodes_render() { + if (ui_nodes_recompile_mat) { + ///if (is_paint || is_sculpt) + if (ui_nodes_canvas_type == canvas_type_t.BRUSH) { + MakeMaterial.parse_brush(); + util_render_make_brush_preview(); + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; + } + else { + base_is_fill_material() ? base_update_fill_layers() : util_render_make_material_preview(); + if (ui_view2d_show && ui_view2d_type == view_2d_type_t.NODE) { + ui_view2d_hwnd.redraws = 2; + } + } + + ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; + if (context_raw.split_view) context_raw.ddirty = 2; + ///end + + ///if is_lab + ParserLogic.parse(project_canvas); + ///end + + ui_nodes_recompile_mat = false; + } + else if (ui_nodes_recompile_mat_final) { + ///if (is_paint || is_sculpt) + MakeMaterial.parse_paint_material(); + + if (ui_nodes_canvas_type == canvas_type_t.MATERIAL && base_is_fill_material()) { + base_update_fill_layers(); + util_render_make_material_preview(); + } + + let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; + if (decal) util_render_make_decal_preview(); + + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + context_raw.node_preview_dirty = true; + ///end + + ui_nodes_recompile_mat_final = false; + } + + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + if (nodes.nodes_selected_id.length > 0 && nodes.nodes_selected_id[0] != ui_nodes_last_node_selected_id) { + ui_nodes_last_node_selected_id = nodes.nodes_selected_id[0]; + ///if (is_paint || is_sculpt) + context_raw.node_preview_dirty = true; + ///end + + ///if is_lab + context_raw.ddirty = 2; // Show selected node texture in viewport + ui_header_handle.redraws = 2; + ///end + + context_raw.node_preview_socket = 0; + } + + // Remove dragged link when mouse is released out of the node viewport + let c: zui_node_canvas_t = ui_nodes_get_canvas(true); + if (ui_nodes_release_link && nodes.linkDragId != -1) { + array_remove(c.links, zui_get_link(c.links, nodes.linkDragId)); + nodes.linkDragId = -1; + } + ui_nodes_release_link = ui_nodes_ui.input_released; + + if (!ui_nodes_show || sys_width() == 0 || sys_height() == 0) return; + + ui_nodes_ui.input_enabled = base_ui_enabled; + + g2_end(); + + if (ui_nodes_grid == null) ui_nodes_draw_grid(); + + ///if (is_paint || is_sculpt) + if (config_raw.node_preview && context_raw.node_preview_dirty) { + ui_nodes_make_node_preview(); + } + ///end + + // Start with UI + zui_begin(ui_nodes_ui); + + // Make window + ui_nodes_ww = config_raw.layout[layout_size_t.NODES_W]; + + ///if (is_paint || is_sculpt) + ui_nodes_wx = math_floor(app_w()) + ui_toolbar_w; + ///end + ///if is_lab + ui_nodes_wx = math_floor(app_w()); + ///end + + ui_nodes_wy = 0; + + ///if (is_paint || is_sculpt) + if (!ui_base_show) { + ui_nodes_ww += config_raw.layout[layout_size_t.SIDEBAR_W] + ui_toolbar_w; + ui_nodes_wx -= ui_toolbar_w; + } + ///end + + let ew: i32 = math_floor(zui_ELEMENT_W(ui_nodes_ui) * 0.7); + ui_nodes_wh = app_h() + ui_header_h; + if (config_raw.layout[layout_size_t.HEADER] == 1) ui_nodes_wh += ui_header_h; + + if (ui_view2d_show) { + ui_nodes_wh = config_raw.layout[layout_size_t.NODES_H]; + ui_nodes_wy = app_h() - config_raw.layout[layout_size_t.NODES_H] + ui_header_h; + if (config_raw.layout[layout_size_t.HEADER] == 1) ui_nodes_wy += ui_header_h; + if (!ui_base_show) { + ui_nodes_wy -= ui_header_h * 2; + } + } + + if (zui_window(ui_nodes_hwnd, ui_nodes_wx, ui_nodes_wy, ui_nodes_ww, ui_nodes_wh)) { + + zui_tab(zui_handle("uinodes_10"), tr("Nodes")); + + // Grid + g2_set_color(0xffffffff); + let step: f32 = 100 * zui_SCALE(ui_nodes_ui); + g2_draw_image(ui_nodes_grid, (nodes.panX * zui_nodes_SCALE()) % step - step, (nodes.panY * zui_nodes_SCALE()) % step - step); + + // Undo + if (ui_nodes_ui.input_started || ui_nodes_ui.is_key_pressed) { + ui_nodes_last_canvas = json_parse(json_stringify(ui_nodes_get_canvas(true))); + } + + // Nodes + let _input_enabled: bool = ui_nodes_ui.input_enabled; + ui_nodes_ui.input_enabled = _input_enabled && !ui_nodes_show_menu; + ///if (is_paint || is_sculpt) + ui_nodes_ui.window_border_right = config_raw.layout[layout_size_t.SIDEBAR_W]; + ///end + ui_nodes_ui.window_border_top = ui_header_h * 2; + ui_nodes_ui.window_border_bottom = config_raw.layout[layout_size_t.STATUS_H]; + zui_node_canvas(nodes, ui_nodes_ui, c); + ui_nodes_ui.input_enabled = _input_enabled; + + if (nodes.colorPickerCallback != null) { + context_raw.color_picker_previous_tool = context_raw.tool; + context_select_tool(workspace_tool_t.PICKER); + let tmp: (col: i32)=>void = nodes.colorPickerCallback; + context_raw.color_picker_callback = function (color: swatch_color_t) { + tmp(color.base); + ui_nodes_hwnd.redraws = 2; + + ///if (is_paint || is_sculpt) + let material_live: bool = config_raw.material_live; + ///end + ///if is_lab + let material_live: bool = true; + ///end + + if (material_live) { + ui_nodes_canvas_changed(); + } + }; + nodes.colorPickerCallback = null; + } + + // Remove nodes with unknown id for this canvas type + if (zui_is_paste) { + ///if (is_paint || is_sculpt) + let node_list: zui_node_t[][] = ui_nodes_canvas_type == canvas_type_t.MATERIAL ? NodesMaterial.list : NodesBrush.list; + ///end + ///if is_lab + let node_list: zui_node_t[][] = NodesBrush.list; + ///end + + let i: i32 = 0; + while (i++ < c.nodes.length) { + let canvas_node: zui_node_t = c.nodes[i - 1]; + if (zui_exclude_remove.indexOf(canvas_node.type) >= 0) { + continue; + } + let found: bool = false; + for (let list of node_list) { + for (let list_node of list) { + if (canvas_node.type == list_node.type) { + found = true; + break; + } + } + if (found) break; + } + if (canvas_node.type == "GROUP" && !ui_nodes_can_place_group(canvas_node.name)) { + found = false; + } + if (!found) { + zui_remove_node(canvas_node, c); + array_remove(nodes.nodes_selected_id, canvas_node.id); + i--; + } + } + } + + if (ui_nodes_is_node_menu_op) { + zui_set_is_copy(false); + zui_set_is_cut(false); + zui_set_is_paste(false); + ui_nodes_ui.is_delete_down = false; + } + + // Recompile material on change + if (ui_nodes_ui.changed) { + ///if (is_paint || is_sculpt) + ui_nodes_recompile_mat = (ui_nodes_ui.input_dx != 0 || ui_nodes_ui.input_dy != 0 || !ui_nodes_uichanged_last) && config_raw.material_live; // Instant preview + ///end + ///if is_lab + ui_nodes_recompile_mat = (ui_nodes_ui.input_dx != 0 || ui_nodes_ui.input_dy != 0 || !ui_nodes_uichanged_last); // Instant preview + ///end + } + else if (ui_nodes_uichanged_last) { + ui_nodes_canvas_changed(); + ui_nodes_push_undo(ui_nodes_last_canvas); + } + ui_nodes_uichanged_last = ui_nodes_ui.changed; + + // Node previews + if (config_raw.node_preview && nodes.nodes_selected_id.length > 0) { + let img: image_t = null; + let sel: zui_node_t = zui_get_node(c.nodes, nodes.nodes_selected_id[0]); + + ///if (is_paint || is_sculpt) + + let single_channel: bool = sel.type == "LAYER_MASK"; + if (sel.type == "LAYER" || sel.type == "LAYER_MASK") { + let id: any = sel.buttons[0].default_value; + if (id < project_layers.length) { + ///if is_paint + img = project_layers[id].texpaint_preview; + ///end + } + } + else if (sel.type == "MATERIAL") { + let id: any = sel.buttons[0].default_value; + if (id < project_materials.length) { + img = project_materials[id].image; + } + } + else if (sel.type == "OUTPUT_MATERIAL_PBR") { + img = context_raw.material.image; + } + else if (sel.type == "BrushOutputNode") { + img = context_raw.brush.image; + } + else if (ui_nodes_canvas_type == canvas_type_t.MATERIAL) { + img = context_raw.node_preview; + } + + ///else + + let brush_node: LogicNode = ParserLogic.get_logic_node(sel); + if (brush_node != null) { + img = brush_node.get_cached_image(); + } + + ///end + + if (img != null) { + let tw: f32 = 128 * zui_SCALE(ui_nodes_ui); + let th: f32 = tw * (img.height / img.width); + let tx: f32 = ui_nodes_ww - tw - 8 * zui_SCALE(ui_nodes_ui); + let ty: f32 = ui_nodes_wh - th - 8 * zui_SCALE(ui_nodes_ui); + + ///if krom_opengl + let invert_y: bool = sel.type == "MATERIAL"; + ///else + let invert_y: bool = false; + ///end + + ///if (is_paint || is_sculpt) + if (single_channel) { + g2_set_pipeline(ui_view2d_pipe); + ///if krom_opengl + krom_g4_set_pipeline(ui_view2d_pipe.pipeline_); + ///end + krom_g4_set_int(ui_view2d_channel_loc, 1); + } + ///end + + g2_set_color(0xffffffff); + invert_y ? + g2_draw_scaled_image(img, tx, ty + th, tw, -th) : + g2_draw_scaled_image(img, tx, ty, tw, th); + + ///if (is_paint || is_sculpt) + if (single_channel) { + g2_set_pipeline(null); + } + ///end + } + } + + // Menu + g2_set_color(ui_nodes_ui.t.SEPARATOR_COL); + g2_fill_rect(0, zui_ELEMENT_H(ui_nodes_ui), ui_nodes_ww, zui_ELEMENT_H(ui_nodes_ui) + zui_ELEMENT_OFFSET(ui_nodes_ui) * 2); + g2_set_color(0xffffffff); + + let start_y: i32 = zui_ELEMENT_H(ui_nodes_ui) + zui_ELEMENT_OFFSET(ui_nodes_ui); + ui_nodes_ui._x = 0; + ui_nodes_ui._y = 2 + start_y; + ui_nodes_ui._w = ew; + + ///if (is_paint || is_sculpt) + // Editable canvas name + let h: zui_handle_t = zui_handle("uinodes_11"); + h.text = c.name; + ui_nodes_ui._w = math_floor(math_min(g2_font_width(ui_nodes_ui.font, ui_nodes_ui.font_size, h.text) + 15 * zui_SCALE(ui_nodes_ui), 100 * zui_SCALE(ui_nodes_ui))); + let new_name: string = zui_text_input(h, ""); + ui_nodes_ui._x += ui_nodes_ui._w + 3; + ui_nodes_ui._y = 2 + start_y; + ui_nodes_ui._w = ew; + + if (h.changed) { // Check whether renaming is possible and update group links + if (ui_nodes_group_stack.length > 0) { + let can_rename: bool = true; + for (let m of project_material_groups) { + if (m.canvas.name == new_name) can_rename = false; // Name already used + } + + if (can_rename) { + let old_name: string = c.name; + c.name = new_name; + let canvases: zui_node_canvas_t[] = []; + for (let m of project_materials) canvases.push(m.canvas); + for (let m of project_material_groups) canvases.push(m.canvas); + for (let canvas of canvases) { + for (let n of canvas.nodes) { + if (n.type == "GROUP" && n.name == old_name) { + n.name = c.name; + } + } + } + } + } + else { + c.name = new_name; + } + } + ///end + + ///if is_lab + ui_nodes_ui.window_border_top = 0; + UINodesExt.drawButtons(ew, start_y); + ///end + + let _BUTTON_COL: i32 = ui_nodes_ui.t.BUTTON_COL; + ui_nodes_ui.t.BUTTON_COL = ui_nodes_ui.t.SEPARATOR_COL; + + ///if (is_paint || is_sculpt) + let cats: string[] = ui_nodes_canvas_type == canvas_type_t.MATERIAL ? NodesMaterial.categories : NodesBrush.categories; + ///end + ///if is_lab + let cats: string[] = NodesBrush.categories; + ///end + + for (let i: i32 = 0; i < cats.length; ++i) { + if ((zui_menu_button(tr(cats[i]))) || (ui_nodes_ui.is_hovered && ui_nodes_show_menu)) { + ui_nodes_show_menu = true; + ui_nodes_menu_category = i; + ui_nodes_popup_x = ui_nodes_wx + ui_nodes_ui._x; + ui_nodes_popup_y = ui_nodes_wy + ui_nodes_ui._y; + if (config_raw.touch_ui) { + ui_nodes_show_menu_first = true; + let menuw: i32 = math_floor(ew * 2.3); + ui_nodes_popup_x -= menuw / 2; + ui_nodes_popup_x += ui_nodes_ui._w / 2; + } + ui_menu_category_w = ui_nodes_ui._w; + ui_menu_category_h = math_floor(zui_MENUBAR_H(ui_nodes_ui)); + } + ui_nodes_ui._x += ui_nodes_ui._w + 3; + ui_nodes_ui._y = 2 + start_y; + } + + if (config_raw.touch_ui) { + let _w: i32 = ui_nodes_ui._w; + ui_nodes_ui._w = math_floor(36 * zui_SCALE(ui_nodes_ui)); + ui_nodes_ui._y = 4 * zui_SCALE(ui_nodes_ui) + start_y; + if (ui_menubar_icon_button(ui_nodes_ui, 2, 3)) { + ui_nodes_node_search(math_floor(ui_nodes_ui._window_x + ui_nodes_ui._x), math_floor(ui_nodes_ui._window_y + ui_nodes_ui._y)); + } + ui_nodes_ui._w = _w; + } + else { + if (zui_menu_button(tr("Search"))) { + ui_nodes_node_search(math_floor(ui_nodes_ui._window_x + ui_nodes_ui._x), math_floor(ui_nodes_ui._window_y + ui_nodes_ui._y)); + } + } + if (ui_nodes_ui.is_hovered) { + zui_tooltip(tr("Search for nodes") + ` (${config_keymap.node_search})`); + } + ui_nodes_ui._x += ui_nodes_ui._w + 3; + ui_nodes_ui._y = 2 + start_y; + + ui_nodes_ui.t.BUTTON_COL = _BUTTON_COL; + + // Close node group + if (ui_nodes_group_stack.length > 0 && zui_menu_button(tr("Close"))) { + ui_nodes_group_stack.pop(); + } + } + + zui_end(!ui_nodes_show_menu); + + g2_begin(null); + + if (ui_nodes_show_menu) { + ///if (is_paint || is_sculpt) + let list:zui_node_t[][] = ui_nodes_canvas_type == canvas_type_t.MATERIAL ? NodesMaterial.list : NodesBrush.list; + ///end + ///if is_lab + let list:zui_node_t[][] = NodesBrush.list; + ///end + + let num_nodes: i32 = list[ui_nodes_menu_category].length; + + ///if (is_paint || is_sculpt) + let is_group_category: bool = ui_nodes_canvas_type == canvas_type_t.MATERIAL && NodesMaterial.categories[ui_nodes_menu_category] == "Group"; + ///end + ///if is_lab + let is_group_category: bool = NodesMaterial.categories[ui_nodes_menu_category] == "Group"; + ///end + + if (is_group_category) num_nodes += project_material_groups.length; + + let py: i32 = ui_nodes_popup_y; + let menuw: i32 = math_floor(ew * 2.3); + zui_begin_region(ui_nodes_ui, math_floor(ui_nodes_popup_x), math_floor(py), menuw); + let _BUTTON_COL: i32 = ui_nodes_ui.t.BUTTON_COL; + ui_nodes_ui.t.BUTTON_COL = ui_nodes_ui.t.SEPARATOR_COL; + let _ELEMENT_OFFSET: i32 = ui_nodes_ui.t.ELEMENT_OFFSET; + ui_nodes_ui.t.ELEMENT_OFFSET = 0; + let _ELEMENT_H: i32 = ui_nodes_ui.t.ELEMENT_H; + ui_nodes_ui.t.ELEMENT_H = config_raw.touch_ui ? (28 + 2) : 28; + + ui_menu_start(ui_nodes_ui); + + for (let n of list[ui_nodes_menu_category]) { + if (ui_menu_button(ui_nodes_ui, tr(n.name))) { + ui_nodes_push_undo(); + let canvas: zui_node_canvas_t = ui_nodes_get_canvas(true); + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + let node: zui_node_t = ui_nodes_make_node(n, nodes, canvas); + canvas.nodes.push(node); + nodes.nodes_selected_id = [node.id]; + nodes.nodesDrag = true; + ///if is_lab + ParserLogic.parse(canvas); + ///end + } + // Next column + if (ui_nodes_ui._y - ui_nodes_wy + zui_ELEMENT_H(ui_nodes_ui) / 2 > ui_nodes_wh) { + ui_nodes_ui._x += menuw; + ui_nodes_ui._y = py; + } + } + if (is_group_category) { + for (let g of project_material_groups) { + zui_fill(0, 1, ui_nodes_ui._w / zui_SCALE(ui_nodes_ui), ui_nodes_ui.t.BUTTON_H + 2, ui_nodes_ui.t.ACCENT_SELECT_COL); + zui_fill(1, 1, ui_nodes_ui._w / zui_SCALE(ui_nodes_ui) - 2, ui_nodes_ui.t.BUTTON_H + 1, ui_nodes_ui.t.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]); + 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); + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + let node: zui_node_t = ui_nodes_make_group_node(g.canvas, nodes, canvas); + canvas.nodes.push(node); + nodes.nodes_selected_id = [node.id]; + nodes.nodesDrag = true; + } + + ///if (is_paint || is_sculpt) + ui_nodes_ui.enabled = !project_is_material_group_in_use(g); + if (zui_button("x", zui_align_t.CENTER)) { + history_delete_material_group(g); + array_remove(project_material_groups, g); + } + ///end + + ui_nodes_ui.enabled = true; + } + } + + ui_nodes_hide_menu = ui_nodes_ui.combo_selected_handle_ptr == 0 && !ui_nodes_show_menu_first && (ui_nodes_ui.changed || ui_nodes_ui.input_released || ui_nodes_ui.input_released_r || ui_nodes_ui.is_escape_down); + ui_nodes_show_menu_first = false; + + ui_nodes_ui.t.BUTTON_COL = _BUTTON_COL; + ui_nodes_ui.t.ELEMENT_OFFSET = _ELEMENT_OFFSET; + ui_nodes_ui.t.ELEMENT_H = _ELEMENT_H; + zui_end_region(); + } + + if (ui_nodes_hide_menu) { + ui_nodes_show_menu = false; + ui_nodes_show_menu_first = true; + } +} + +function ui_nodes_contains_node_group_recursive(group: node_group_t, group_name: string): bool { + if (group.canvas.name == group_name) { + return true; + } + for (let n of group.canvas.nodes) { + if (n.type == "GROUP") { + let g: node_group_t = project_get_material_group_by_name(n.name); + if (g != null && ui_nodes_contains_node_group_recursive(g, group_name)) { + return true; + } + } + } + return false; +} + +function ui_nodes_can_place_group(group_name: string): bool { + // Prevent Recursive node groups + // The group to place must not contain the current group or a group that contains the current group + if (ui_nodes_group_stack.length > 0) { + for (let g of ui_nodes_group_stack) { + if (ui_nodes_contains_node_group_recursive(project_get_material_group_by_name(group_name), g.canvas.name)) return false; + } + } + // Group was deleted / renamed + let group_exists: bool = false; + for (let group of project_material_groups) { + if (group_name == group.canvas.name) { + group_exists = true; + } + } + if (!group_exists) return false; + return true; +} + +function ui_nodes_push_undo(last_canvas: zui_node_canvas_t = null) { + if (last_canvas == null) last_canvas = ui_nodes_get_canvas(true); + let canvas_group: i32 = ui_nodes_group_stack.length > 0 ? project_material_groups.indexOf(ui_nodes_group_stack[ui_nodes_group_stack.length - 1]) : null; + + ///if (is_paint || is_sculpt) + ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; + history_edit_nodes(last_canvas, ui_nodes_canvas_type, canvas_group); + ///end + ///if is_lab + history_edit_nodes(last_canvas, canvas_group); + ///end +} + +function ui_nodes_accept_asset_drag(index: i32) { + ui_nodes_push_undo(); + let g: node_group_t = ui_nodes_group_stack.length > 0 ? ui_nodes_group_stack[ui_nodes_group_stack.length - 1] : null; + ///if (is_paint || is_sculpt) + let n: zui_node_t = ui_nodes_canvas_type == canvas_type_t.MATERIAL ? NodesMaterial.create_node("TEX_IMAGE", g) : NodesBrush.create_node("TEX_IMAGE"); + ///end + ///if is_lab + let n: zui_node_t = NodesBrush.create_node("ImageTextureNode"); + ///end + + n.buttons[0].default_value = index; + ui_nodes_get_nodes().nodes_selected_id = [n.id]; + + ///if is_lab + ParserLogic.parse(project_canvas); + ///end +} + +///if (is_paint || is_sculpt) +function ui_nodes_accept_layer_drag(index: i32) { + ui_nodes_push_undo(); + if (SlotLayer.is_group(project_layers[index])) return; + let g: node_group_t = ui_nodes_group_stack.length > 0 ? ui_nodes_group_stack[ui_nodes_group_stack.length - 1] : null; + let n: zui_node_t = NodesMaterial.create_node(SlotLayer.is_mask(context_raw.layer) ? "LAYER_MASK" : "LAYER", g); + n.buttons[0].default_value = index; + ui_nodes_get_nodes().nodes_selected_id = [n.id]; +} + +function ui_nodes_accept_material_drag(index: i32) { + ui_nodes_push_undo(); + let g: node_group_t = ui_nodes_group_stack.length > 0 ? ui_nodes_group_stack[ui_nodes_group_stack.length - 1] : null; + let n: zui_node_t = NodesMaterial.create_node("MATERIAL", g); + n.buttons[0].default_value = index; + ui_nodes_get_nodes().nodes_selected_id = [n.id]; +} +///end + +function ui_nodes_accept_swatch_drag(swatch: swatch_color_t) { + ///if (is_paint || is_sculpt) + ui_nodes_push_undo(); + let g: node_group_t = ui_nodes_group_stack.length > 0 ? ui_nodes_group_stack[ui_nodes_group_stack.length - 1] : null; + let n: zui_node_t = NodesMaterial.create_node("RGB", g); + n.outputs[0].default_value = [ + color_get_rb(swatch.base) / 255, + color_get_gb(swatch.base) / 255, + color_get_bb(swatch.base) / 255, + color_get_ab(swatch.base) / 255 + ]; + ui_nodes_get_nodes().nodes_selected_id = [n.id]; + ///end +} + +function ui_nodes_make_node(n: zui_node_t, nodes: zui_nodes_t, canvas: zui_node_canvas_t): zui_node_t { + let node: zui_node_t = json_parse(json_stringify(n)); + node.id = zui_get_node_id(canvas.nodes); + node.x = ui_nodes_get_node_x(); + node.y = ui_nodes_get_node_y(); + let count: i32 = 0; + for (let soc of node.inputs) { + soc.id = zui_get_socket_id(canvas.nodes) + count; + soc.node_id = node.id; + count++; + } + for (let soc of node.outputs) { + soc.id = zui_get_socket_id(canvas.nodes) + count; + soc.node_id = node.id; + count++; + } + return node; +} + +function ui_nodes_make_group_node(group_canvas: zui_node_canvas_t, nodes: zui_nodes_t, canvas: zui_node_canvas_t): zui_node_t { + let n: zui_node_t = NodesMaterial.list[5][0]; + let node: zui_node_t = json_parse(json_stringify(n)); + node.name = group_canvas.name; + node.id = zui_get_node_id(canvas.nodes); + node.x = ui_nodes_get_node_x(); + node.y = ui_nodes_get_node_y(); + let group_input: zui_node_t = null; + let group_output: zui_node_t = null; + for (let g of project_material_groups) { + if (g.canvas.name == node.name) { + for (let n of g.canvas.nodes) { + if (n.type == "GROUP_INPUT") group_input = n; + else if (n.type == "GROUP_OUTPUT") group_output = n; + } + break; + } + } + if (group_input != null && group_output != null) { + for (let soc of group_input.outputs) { + node.inputs.push(NodesMaterial.create_socket(nodes, node, soc.name, soc.type, canvas, soc.min, soc.max, soc.default_value)); + } + for (let soc of group_output.inputs) { + node.outputs.push(NodesMaterial.create_socket(nodes, node, soc.name, soc.type, canvas, soc.min, soc.max, soc.default_value)); + } + } + return node; +} + +///if (is_paint || is_sculpt) +function ui_nodes_make_node_preview() { + let nodes: zui_nodes_t = context_raw.material.nodes; + if (nodes.nodes_selected_id.length == 0) return; + + let node: zui_node_t = zui_get_node(context_raw.material.canvas.nodes, nodes.nodes_selected_id[0]); + // if (node == null) return; + context_raw.node_preview_name = node.name; + + if (node.type == "LAYER" || + node.type == "LAYER_MASK" || + node.type == "MATERIAL" || + node.type == "OUTPUT_MATERIAL_PBR") return; + + if (context_raw.material.canvas.nodes.indexOf(node) == -1) return; + + if (context_raw.node_preview == null) { + context_raw.node_preview = image_create_render_target(util_render_material_preview_size, util_render_material_preview_size); + } + + context_raw.node_preview_dirty = false; + ui_nodes_hwnd.redraws = 2; + util_render_make_node_preview(context_raw.material.canvas, node, context_raw.node_preview); +} +///end + +function ui_nodes_has_group(c: zui_node_canvas_t): bool { + for (let n of c.nodes) if (n.type == "GROUP") return true; + return false; +} + +function ui_nodes_traverse_group(mgroups: zui_node_canvas_t[], c: zui_node_canvas_t) { + for (let n of c.nodes) { + if (n.type == "GROUP") { + if (ui_nodes_get_group(mgroups, n.name) == null) { + let canvases: zui_node_canvas_t[] = []; + for (let g of project_material_groups) canvases.push(g.canvas); + let group: zui_node_canvas_t = ui_nodes_get_group(canvases, n.name); + mgroups.push(json_parse(json_stringify(group))); + ui_nodes_traverse_group(mgroups, group); + } + } + } +} + +function ui_nodes_get_group(canvases: zui_node_canvas_t[], name: string): zui_node_canvas_t { + for (let c of canvases) if (c.name == name) return c; + return null; +} diff --git a/base/Sources/ui_status.ts b/base/Sources/ui_status.ts new file mode 100644 index 00000000..0c03c0de --- /dev/null +++ b/base/Sources/ui_status.ts @@ -0,0 +1,48 @@ + +let ui_status_default_status_h: i32 = 33; + +function ui_status_init() { +} + +function ui_status_width(): i32 { + ///if (is_paint || is_sculpt) + return sys_width() - ui_toolbar_w - config_raw.layout[layout_size_t.SIDEBAR_W]; + ///end + ///if is_lab + return sys_width(); + ///end +} + +function ui_status_render_ui() { + let ui: zui_t = ui_base_ui; + + let statush: i32 = config_raw.layout[layout_size_t.STATUS_H]; + + if (zui_window(ui_base_hwnds[tab_area_t.STATUS], app_x(), sys_height() - statush, ui_status_width(), statush)) { + ui._y += 2; + + // Border + g2_set_color(ui.t.SEPARATOR_COL); + g2_fill_rect(0, 0, 1, ui._window_h); + g2_fill_rect(ui._window_w - 1, 0, 1, ui._window_h); + + // Draw tabs + for (let draw of ui_base_hwnd_tabs[tab_area_t.STATUS]) draw(ui_base_htabs[tab_area_t.STATUS]); + + let minimized: bool = statush <= ui_status_default_status_h * config_raw.window_scale; + if (ui_base_htabs[tab_area_t.STATUS].changed && (ui_base_htabs[tab_area_t.STATUS].position == context_raw.last_status_position || minimized)) { + ui_base_toggle_browser(); + } + context_raw.last_status_position = ui_base_htabs[tab_area_t.STATUS].position; + } +} + +function ui_status_draw_version_tab(htab: zui_handle_t) { + // Version label + if (!config_raw.touch_ui) { + let ui: zui_t = ui_base_ui; + ui.enabled = false; + zui_tab(ui_base_htabs[tab_area_t.STATUS], manifest_version); + ui.enabled = true; + } +} diff --git a/base/Sources/ui_toolbar.ts b/base/Sources/ui_toolbar.ts new file mode 100644 index 00000000..0fe90cd4 --- /dev/null +++ b/base/Sources/ui_toolbar.ts @@ -0,0 +1,204 @@ + +///if (is_paint || is_sculpt) + +let ui_toolbar_default_w: i32 = 36; + +let ui_toolbar_handle: zui_handle_t = zui_handle_create(); +let ui_toolbar_w: i32 = ui_toolbar_default_w; +let ui_toolbar_last_tool: i32 = 0; + +let ui_toolbar_tool_names: string[] = [ + _tr("Brush"), + _tr("Eraser"), + _tr("Fill"), + _tr("Decal"), + _tr("Text"), + _tr("Clone"), + _tr("Blur"), + _tr("Smudge"), + _tr("Particle"), + _tr("ColorID"), + _tr("Picker"), + _tr("Bake"), + _tr("Gizmo"), + _tr("Material"), +]; + +function ui_toolbar_init() { +} + +function ui_toolbar_render_ui() { + let ui: zui_t = ui_base_ui; + + if (config_raw.touch_ui) { + ui_toolbar_w = ui_toolbar_default_w + 6; + } + else { + ui_toolbar_w = ui_toolbar_default_w; + } + ui_toolbar_w = math_floor(ui_toolbar_w * zui_SCALE(ui)); + + if (zui_window(ui_toolbar_handle, 0, ui_header_h, ui_toolbar_w, sys_height() - ui_header_h)) { + ui._y -= 4 * zui_SCALE(ui); + + ui.image_scroll_align = false; + let img: image_t = resource_get("icons.k"); + + let col: i32 = ui.t.WINDOW_BG_COL; + if (col < 0) col += 4294967296; + let light: bool = col > (0xff666666 + 4294967296); + let icon_accent: i32 = light ? 0xff666666 : -1; + + // Properties icon + if (config_raw.layout[layout_size_t.HEADER] == 1) { + let rect: rect_t = resource_tile50(img, 7, 1); + if (zui_image(img, light ? 0xff666666 : ui.t.BUTTON_COL, -1.0, rect.x, rect.y, rect.w, rect.h) == zui_state_t.RELEASED) { + config_raw.layout[layout_size_t.HEADER] = 0; + } + } + // Draw ">>" button if header is hidden + else { + let _ELEMENT_H: i32 = ui.t.ELEMENT_H; + let _BUTTON_H: i32 = ui.t.BUTTON_H; + let _BUTTON_COL: i32 = ui.t.BUTTON_COL; + let _fontOffsetY: i32 = ui.font_offset_y; + ui.t.ELEMENT_H = math_floor(ui.t.ELEMENT_H * 1.5); + ui.t.BUTTON_H = ui.t.ELEMENT_H; + ui.t.BUTTON_COL = ui.t.WINDOW_BG_COL; + let font_height: i32 = g2_font_height(ui.font, ui.font_size); + ui.font_offset_y = (zui_ELEMENT_H(ui) - font_height) / 2; + let _w: i32 = ui._w; + ui._w = ui_toolbar_w; + + if (zui_button(">>")) { + ui_toolbar_tool_properties_menu(); + } + + ui._w = _w; + ui.t.ELEMENT_H = _ELEMENT_H; + ui.t.BUTTON_H = _BUTTON_H; + ui.t.BUTTON_COL = _BUTTON_COL; + ui.font_offset_y = _fontOffsetY; + } + if (ui.is_hovered) zui_tooltip(tr("Toggle header")); + ui._y -= 4 * zui_SCALE(ui); + + let keys: string[] = [ + "(" + config_keymap.tool_brush + ") - " + tr("Hold {action_paint} to paint\nHold {key} and press {action_paint} to paint a straight line (ruler mode)", new Map([["key", config_keymap.brush_ruler], ["action_paint", config_keymap.action_paint]])), + "(" + config_keymap.tool_eraser + ") - " + tr("Hold {action_paint} to erase\nHold {key} and press {action_paint} to erase a straight line (ruler mode)", new Map([["key", config_keymap.brush_ruler], ["action_paint", config_keymap.action_paint]])), + "(" + config_keymap.tool_fill + ")", + "(" + config_keymap.tool_decal + ") - " + tr("Hold {key} to paint on a decal mask", new Map([["key", config_keymap.decal_mask]])), + "(" + config_keymap.tool_text + ") - " + tr("Hold {key} to use the text as a mask", new Map([["key", config_keymap.decal_mask]])), + "(" + config_keymap.tool_clone + ") - " + tr("Hold {key} to set source", new Map([["key", config_keymap.set_clone_source]])), + "(" + config_keymap.tool_blur + ")", + "(" + config_keymap.tool_smudge + ")", + "(" + config_keymap.tool_particle + ")", + "(" + config_keymap.tool_colorid + ")", + "(" + config_keymap.tool_picker + ")", + "(" + config_keymap.tool_bake + ")", + "(" + config_keymap.tool_gizmo + ")", + "(" + config_keymap.tool_material + ")", + ]; + + let draw_tool = function (i: i32) { + ui._x += 2; + if (context_raw.tool == i) ui_toolbar_draw_highlight(); + let tile_y: i32 = math_floor(i / 12); + let tile_x: i32 = tile_y % 2 == 0 ? i % 12 : (11 - (i % 12)); + let rect: rect_t = resource_tile50(img, tile_x, tile_y); + let _y: i32 = ui._y; + + let image_state: zui_state_t = zui_image(img, icon_accent, -1.0, rect.x, rect.y, rect.w, rect.h); + if (image_state == zui_state_t.STARTED) { + context_select_tool(i); + } + else if (image_state == zui_state_t.RELEASED && config_raw.layout[layout_size_t.HEADER] == 0) { + if (ui_toolbar_last_tool == i) { + ui_toolbar_tool_properties_menu(); + } + ui_toolbar_last_tool = i; + } + + ///if is_paint + if (i == workspace_tool_t.COLORID && context_raw.colorid_picked) { + g2_draw_scaled_sub_image(render_path_render_targets.get("texpaint_colorid")._image, 0, 0, 1, 1, 0, _y + 1.5 * zui_SCALE(ui), 5 * zui_SCALE(ui), 34 * zui_SCALE(ui)); + } + ///end + + if (ui.is_hovered) zui_tooltip(tr(ui_toolbar_tool_names[i]) + " " + keys[i]); + ui._x -= 2; + ui._y += 2; + } + + draw_tool(workspace_tool_t.BRUSH); + ///if is_paint + draw_tool(workspace_tool_t.ERASER); + draw_tool(workspace_tool_t.FILL); + draw_tool(workspace_tool_t.DECAL); + draw_tool(workspace_tool_t.TEXT); + draw_tool(workspace_tool_t.CLONE); + draw_tool(workspace_tool_t.BLUR); + draw_tool(workspace_tool_t.SMUDGE); + draw_tool(workspace_tool_t.PARTICLE); + draw_tool(workspace_tool_t.COLORID); + draw_tool(workspace_tool_t.PICKER); + draw_tool(workspace_tool_t.BAKE); + draw_tool(workspace_tool_t.MATERIAL); + ///end + + ///if is_forge + draw_tool(workspace_tool_t.GIZMO); + ///end + + ui.image_scroll_align = true; + } + + if (config_raw.touch_ui) { + // Hide scrollbar + let _SCROLL_W: i32 = ui.t.SCROLL_W; + ui.t.SCROLL_W = 0; + zui_end_window(); + ui.t.SCROLL_W = _SCROLL_W; + } +} + +function ui_toolbar_tool_properties_menu() { + let ui: zui_t = ui_base_ui; + let _x: i32 = ui._x; + let _y: i32 = ui._y; + let _w: i32 = ui._w; + ui_menu_draw(function (ui: zui_t) { + let start_y: i32 = ui._y; + ui.changed = false; + + ui_header_draw_tool_properties(ui); + + if (ui.changed) { + ui_menu_keep_open = true; + } + + if (zui_button(tr("Pin to Header"), zui_align_t.LEFT)) { + config_raw.layout[layout_size_t.HEADER] = 1; + } + + let h: i32 = ui._y - start_y; + ui_menu_elements = math_floor(h / zui_ELEMENT_H(ui)); + ui_menu_x = math_floor(_x + _w + 2); + ui_menu_y = math_floor(_y - 6 * zui_SCALE(ui)); + ui_menu_fit_to_screen(); + + }, 0); + + // First draw out of screen, then align the menu based on menu height + ui_menu_x = -sys_width(); + ui_menu_y = -sys_height(); +} + +function ui_toolbar_draw_highlight() { + let ui: zui_t = ui_base_ui; + let size: i32 = ui_toolbar_w - 4; + g2_set_color(ui.t.HIGHLIGHT_COL); + zui_draw_rect(true, ui._x + -1, ui._y + 2, size + 2, size + 2); +} + +///end diff --git a/base/Sources/ui_view2d.ts b/base/Sources/ui_view2d.ts new file mode 100644 index 00000000..369a5a00 --- /dev/null +++ b/base/Sources/ui_view2d.ts @@ -0,0 +1,460 @@ + +///if (is_paint || is_sculpt) +let ui_view2d_pipe: pipeline_t; +let ui_view2d_channel_loc: kinc_const_loc_t; +let ui_view2d_text_input_hover: bool = false; +let ui_view2d_uvmap_show: bool = false; +let ui_view2d_tex_type: paint_tex_t = paint_tex_t.BASE; +let ui_view2d_layer_mode: view_2d_layer_mode_t = view_2d_layer_mode_t.SELECTED; +///end + +///if (is_paint || is_sculpt) +let ui_view2d_type: view_2d_type_t = view_2d_type_t.LAYER; +///else +let ui_view2d_type: view_2d_type_t = view_2d_type_t.ASSET; +///end + +let ui_view2d_show: bool = false; +let ui_view2d_wx: i32; +let ui_view2d_wy: i32; +let ui_view2d_ww: i32; +let ui_view2d_wh: i32; +let ui_view2d_ui: zui_t; +let ui_view2d_hwnd: zui_handle_t = zui_handle_create(); +let ui_view2d_pan_x: f32 = 0.0; +let ui_view2d_pan_y: f32 = 0.0; +let ui_view2d_pan_scale: f32 = 1.0; +let ui_view2d_tiled_show: bool = false; +let ui_view2d_controls_down: bool = false; + +function ui_view2d_init() { + ///if (is_paint || is_sculpt) + ui_view2d_pipe = g4_pipeline_create(); + ui_view2d_pipe.vertex_shader = sys_get_shader("layer_view.vert"); + ui_view2d_pipe.fragment_shader = sys_get_shader("layer_view.frag"); + let vs: vertex_struct_t = g4_vertex_struct_create(); + g4_vertex_struct_add(vs, "pos", vertex_data_t.F32_3X); + g4_vertex_struct_add(vs, "tex", vertex_data_t.F32_2X); + g4_vertex_struct_add(vs, "col", vertex_data_t.U8_4X_NORM); + ui_view2d_pipe.input_layout = [vs]; + ui_view2d_pipe.blend_source = blend_factor_t.BLEND_ONE; + ui_view2d_pipe.blend_dest = blend_factor_t.BLEND_ZERO; + ui_view2d_pipe.color_write_masks_alpha[0] = false; + g4_pipeline_compile(ui_view2d_pipe); + ui_view2d_channel_loc = g4_pipeline_get_const_loc(ui_view2d_pipe, "channel"); + ///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 }); + ui_view2d_ui.scroll_enabled = false; +} + +function ui_view2d_render() { + + ui_view2d_ww = config_raw.layout[layout_size_t.NODES_W]; + + ///if (is_paint || is_sculpt) + ui_view2d_wx = math_floor(app_w()) + ui_toolbar_w; + ///else + ui_view2d_wx = math_floor(app_w()); + ///end + + ui_view2d_wy = 0; + + ///if (is_paint || is_sculpt) + if (!ui_base_show) { + ui_view2d_ww += config_raw.layout[layout_size_t.SIDEBAR_W] + ui_toolbar_w; + ui_view2d_wx -= ui_toolbar_w; + } + ///end + + if (!ui_view2d_show) return; + if (sys_width() == 0 || sys_height() == 0) return; + + if (context_raw.pdirty >= 0) ui_view2d_hwnd.redraws = 2; // Paint was active + + g2_end(); + + // Cache grid + if (ui_nodes_grid == null) ui_nodes_draw_grid(); + + // Ensure UV map is drawn + ///if (is_paint || is_sculpt) + if (ui_view2d_uvmap_show) util_uv_cache_uv_map(); + ///end + + // Ensure font image is drawn + ///if (is_paint || is_sculpt) + if (context_raw.font.image == null) util_render_make_font_preview(); + ///end + + zui_begin(ui_view2d_ui); + + let headerh: i32 = config_raw.layout[layout_size_t.HEADER] == 1 ? ui_header_h * 2 : ui_header_h; + let apph: i32 = sys_height() - config_raw.layout[layout_size_t.STATUS_H] + headerh; + ui_view2d_wh = sys_height() - config_raw.layout[layout_size_t.STATUS_H]; + + if (ui_nodes_show) { + ui_view2d_wh -= config_raw.layout[layout_size_t.NODES_H]; + if (config_raw.touch_ui) ui_view2d_wh += ui_header_h; + } + + if (zui_window(ui_view2d_hwnd, ui_view2d_wx, ui_view2d_wy, ui_view2d_ww, ui_view2d_wh)) { + + zui_tab(zui_handle("uiview2d_0"), tr("2D View")); + + // Grid + g2_set_color(0xffffffff); + g2_draw_image(ui_nodes_grid, (ui_view2d_pan_x * ui_view2d_pan_scale) % 100 - 100, (ui_view2d_pan_y * ui_view2d_pan_scale) % 100 - 100); + + // Texture + let tex: image_t = null; + + ///if (is_paint || is_sculpt) + let l: SlotLayerRaw = context_raw.layer; + let channel: i32 = 0; + ///end + + let tw: f32 = ui_view2d_ww * 0.95 * ui_view2d_pan_scale; + let tx: f32 = ui_view2d_ww / 2 - tw / 2 + ui_view2d_pan_x; + let ty: f32 = apph / 2 - tw / 2 + ui_view2d_pan_y; + + if (ui_view2d_type == view_2d_type_t.ASSET) { + tex = project_get_image(context_raw.texture); + } + else if (ui_view2d_type == view_2d_type_t.NODE) { + ///if (is_paint || is_sculpt) + + tex = context_raw.node_preview; + + ///else + + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + if (nodes.nodes_selected_id.length > 0) { + let sel: zui_node_t = zui_get_node(ui_nodes_get_canvas(true).nodes, nodes.nodes_selected_id[0]); + let brush_node: LogicNode = ParserLogic.get_logic_node(sel); + if (brush_node != null) { + tex = brush_node.get_cached_image(); + } + } + + ///end + } + ///if is_paint + else if (ui_view2d_type == view_2d_type_t.LAYER) { + let layer: SlotLayerRaw = l; + + if (config_raw.brush_live && RenderPathPaint.live_layer_drawn > 0) { + layer = RenderPathPaint.live_layer; + } + + if (ui_view2d_layer_mode == view_2d_layer_mode_t.VISIBLE) { + let current: image_t = _g2_current; + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); + layer = base_flatten(); + if (g2_in_use) g2_begin(current); + } + else if (SlotLayer.is_group(layer)) { + let current: image_t = _g2_current; + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); + layer = base_flatten(false, SlotLayer.get_children(layer)); + if (g2_in_use) g2_begin(current); + } + + tex = + SlotLayer.is_mask(context_raw.layer) ? layer.texpaint : + ui_view2d_tex_type == paint_tex_t.BASE ? layer.texpaint : + ui_view2d_tex_type == paint_tex_t.OPACITY ? layer.texpaint : + ui_view2d_tex_type == paint_tex_t.NORMAL ? layer.texpaint_nor : + layer.texpaint_pack; + + channel = + SlotLayer.is_mask(context_raw.layer) ? 1 : + ui_view2d_tex_type == paint_tex_t.OCCLUSION ? 1 : + ui_view2d_tex_type == paint_tex_t.ROUGHNESS ? 2 : + ui_view2d_tex_type == paint_tex_t.METALLIC ? 3 : + ui_view2d_tex_type == paint_tex_t.OPACITY ? 4 : + ui_view2d_tex_type == paint_tex_t.HEIGHT ? 4 : + ui_view2d_tex_type == paint_tex_t.NORMAL ? 5 : + 0; + } + else if (ui_view2d_type == view_2d_type_t.FONT) { + tex = context_raw.font.image; + } + ///end + + let th: f32 = tw; + if (tex != null) { + th = tw * (tex.height / tex.width); + ty = apph / 2 - th / 2 + ui_view2d_pan_y; + + ///if (is_paint || is_sculpt) + if (ui_view2d_type == view_2d_type_t.LAYER) { + ///if (!krom_opengl) + g2_set_pipeline(ui_view2d_pipe); + ///end + if (!context_raw.texture_filter) { + g2_set_bilinear_filter(false); + } + ///if krom_opengl + krom_g4_set_pipeline(ui_view2d_pipe.pipeline_); + ///end + krom_g4_set_int(ui_view2d_channel_loc, channel); + } + ///end + + g2_draw_scaled_image(tex, tx, ty, tw, th); + + if (ui_view2d_tiled_show) { + g2_draw_scaled_image(tex, tx - tw, ty, tw, th); + g2_draw_scaled_image(tex, tx - tw, ty - th, tw, th); + g2_draw_scaled_image(tex, tx - tw, ty + th, tw, th); + g2_draw_scaled_image(tex, tx + tw, ty, tw, th); + g2_draw_scaled_image(tex, tx + tw, ty - th, tw, th); + g2_draw_scaled_image(tex, tx + tw, ty + th, tw, th); + g2_draw_scaled_image(tex, tx, ty - th, tw, th); + g2_draw_scaled_image(tex, tx, ty + th, tw, th); + } + + ///if (is_paint || is_sculpt) + if (ui_view2d_type == view_2d_type_t.LAYER) { + g2_set_pipeline(null); + if (!context_raw.texture_filter) { + g2_set_bilinear_filter(true); + } + } + + // Texture and node preview color picking + 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() { + let texpaint_picker: image_t = render_path_render_targets.get("texpaint_picker")._image; + g2_begin(texpaint_picker); + g2_draw_scaled_image(tex, -x, -y, tw, th); + g2_end(); + let a: DataView = new DataView(image_get_pixels(texpaint_picker)); + ///if (krom_metal || krom_vulkan) + let i0: i32 = 2; + let i1: i32 = 1; + let i2: i32 = 0; + ///else + let i0: i32 = 0; + let i1: i32 = 1; + let i2: i32 = 2; + ///end + + context_raw.picked_color.base = color_set_rb(context_raw.picked_color.base, a.getUint8(i0)); + context_raw.picked_color.base = color_set_gb(context_raw.picked_color.base, a.getUint8(i1)); + context_raw.picked_color.base = color_set_bb(context_raw.picked_color.base, a.getUint8(i2)); + ui_header_handle.redraws = 2; + }); + } + ///end + } + + ///if (is_paint || is_sculpt) + // UV map + if (ui_view2d_type == view_2d_type_t.LAYER && ui_view2d_uvmap_show) { + g2_draw_scaled_image(util_uv_uvmap, tx, ty, tw, th); + } + ///end + + // Menu + let ew: i32 = math_floor(zui_ELEMENT_W(ui_view2d_ui)); + g2_set_color(ui_view2d_ui.t.SEPARATOR_COL); + g2_fill_rect(0, zui_ELEMENT_H(ui_view2d_ui), ui_view2d_ww, zui_ELEMENT_H(ui_view2d_ui) + zui_ELEMENT_OFFSET(ui_view2d_ui) * 2); + g2_set_color(0xffffffff); + + let start_y: f32 = zui_ELEMENT_H(ui_view2d_ui) + zui_ELEMENT_OFFSET(ui_view2d_ui); + ui_view2d_ui._x = 2; + ui_view2d_ui._y = 2 + start_y; + ui_view2d_ui._w = ew; + + // Editable layer name + let h: zui_handle_t = zui_handle("uiview2d_1"); + + ///if (is_paint || is_sculpt) + let text: string = ui_view2d_type == view_2d_type_t.NODE ? context_raw.node_preview_name : h.text; + ///else + let text: string = h.text; + ///end + + ui_view2d_ui._w = math_floor(math_min(g2_font_width(ui_view2d_ui.font, ui_view2d_ui.font_size, text) + 15 * zui_SCALE(ui_view2d_ui), 100 * zui_SCALE(ui_view2d_ui))); + + if (ui_view2d_type == view_2d_type_t.ASSET) { + let asset: asset_t = context_raw.texture; + if (asset != null) { + let assetNames: string[] = project_asset_names; + let i: i32 = assetNames.indexOf(asset.name); + h.text = asset.name; + asset.name = zui_text_input(h, ""); + assetNames[i] = asset.name; + } + } + else if (ui_view2d_type == view_2d_type_t.NODE) { + ///if (is_paint || is_sculpt) + + zui_text(context_raw.node_preview_name); + + ///else + + let nodes: zui_nodes_t = ui_nodes_get_nodes(); + if (nodes.nodes_selected_id.length > 0) { + zui_text(zui_get_node(ui_nodes_get_canvas(true).nodes, nodes.nodes_selected_id[0]).name); + } + + ///end + } + ///if (is_paint || is_sculpt) + else if (ui_view2d_type == view_2d_type_t.LAYER) { + h.text = l.name; + l.name = zui_text_input(h, ""); + ui_view2d_text_input_hover = ui_view2d_ui.is_hovered; + } + else if (ui_view2d_type == view_2d_type_t.FONT) { + h.text = context_raw.font.name; + context_raw.font.name = zui_text_input(h, ""); + } + ///end + + if (h.changed) ui_base_hwnds[0].redraws = 2; + ui_view2d_ui._x += ui_view2d_ui._w + 3; + ui_view2d_ui._y = 2 + start_y; + ui_view2d_ui._w = ew; + + ///if (is_paint || is_sculpt) + if (ui_view2d_type == view_2d_type_t.LAYER) { + ui_view2d_layer_mode = zui_combo(zui_handle("uiview2d_2", { position: ui_view2d_layer_mode }), [ + tr("Visible"), + tr("Selected"), + ], tr("Layers")); + ui_view2d_ui._x += ew + 3; + ui_view2d_ui._y = 2 + start_y; + + if (!SlotLayer.is_mask(context_raw.layer)) { + ui_view2d_tex_type = zui_combo(zui_handle("uiview2d_3", { position: ui_view2d_tex_type }), [ + tr("Base Color"), + tr("Normal Map"), + tr("Occlusion"), + tr("Roughness"), + tr("Metallic"), + tr("Opacity"), + tr("Height"), + ], tr("Texture")); + ui_view2d_ui._x += ew + 3; + ui_view2d_ui._y = 2 + start_y; + } + + ui_view2d_ui._w = math_floor(ew * 0.7 + 3); + ui_view2d_uvmap_show = zui_check(zui_handle("uiview2d_4", { selected: ui_view2d_uvmap_show }), tr("UV Map")); + ui_view2d_ui._x += ew * 0.7 + 3; + ui_view2d_ui._y = 2 + start_y; + } + ///end + + ui_view2d_tiled_show = zui_check(zui_handle("uiview2d_5", { selected: ui_view2d_tiled_show }), tr("Tiled")); + ui_view2d_ui._x += ew * 0.7 + 3; + ui_view2d_ui._y = 2 + start_y; + + if (ui_view2d_type == view_2d_type_t.ASSET && tex != null) { // Texture resolution + zui_text(tex.width + "x" + tex.height); + } + + // Picked position + ///if (is_paint || is_sculpt) + if (context_raw.tool == workspace_tool_t.PICKER && (ui_view2d_type == view_2d_type_t.LAYER || ui_view2d_type == view_2d_type_t.ASSET)) { + let cursor_img: image_t = resource_get("cursor.k"); + let hsize: f32 = 16 * zui_SCALE(ui_view2d_ui); + let size: f32 = hsize * 2; + g2_draw_scaled_image(cursor_img, tx + tw * context_raw.uvx_picked - hsize, ty + th * context_raw.uvy_picked - hsize, size, size); + } + ///end + } + zui_end(); + g2_begin(null); +} + +function ui_view2d_update() { + let headerh: f32 = zui_ELEMENT_H(ui_view2d_ui) * 1.4; + + ///if (is_paint || is_sculpt) + context_raw.paint2d = false; + ///end + + if (!base_ui_enabled || + !ui_view2d_show || + mouse_x < ui_view2d_wx || + mouse_x > ui_view2d_wx + ui_view2d_ww || + mouse_y < ui_view2d_wy + headerh || + mouse_y > ui_view2d_wy + ui_view2d_wh) { + if (ui_view2d_controls_down) { + let control: zui_canvas_control_t = ui_nodes_get_canvas_control(ui_view2d_ui, ui_view2d_controls_down); + ui_view2d_controls_down = control.controls_down; + } + return; + } + + let control: zui_canvas_control_t = ui_nodes_get_canvas_control(ui_view2d_ui, ui_view2d_controls_down); + ui_view2d_pan_x += control.pan_x; + ui_view2d_pan_y += control.pan_y; + ui_view2d_controls_down = control.controls_down; + if (control.zoom != 0) { + let _pan_x: f32 = ui_view2d_pan_x / ui_view2d_pan_scale; + let _pan_y: f32 = ui_view2d_pan_y / ui_view2d_pan_scale; + ui_view2d_pan_scale += control.zoom; + if (ui_view2d_pan_scale < 0.1) ui_view2d_pan_scale = 0.1; + if (ui_view2d_pan_scale > 6.0) ui_view2d_pan_scale = 6.0; + ui_view2d_pan_x = _pan_x * ui_view2d_pan_scale; + ui_view2d_pan_y = _pan_y * ui_view2d_pan_scale; + + if (zui_touch_scroll()) { + // Zoom to finger location + ui_view2d_pan_x -= (ui_view2d_ui.input_x - ui_view2d_ui._window_x - ui_view2d_ui._window_w / 2) * control.zoom; + ui_view2d_pan_y -= (ui_view2d_ui.input_y - ui_view2d_ui._window_y - ui_view2d_ui._window_h / 2) * control.zoom; + } + } + + ///if (is_paint || is_sculpt) + let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT; + let decal_mask: bool = decal && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.action_paint, shortcut_type_t.DOWN); + let set_clone_source: bool = context_raw.tool == workspace_tool_t.CLONE && operator_shortcut(config_keymap.set_clone_source + "+" + config_keymap.action_paint, shortcut_type_t.DOWN); + + if (ui_view2d_type == view_2d_type_t.LAYER && + !ui_view2d_text_input_hover && + (operator_shortcut(config_keymap.action_paint, shortcut_type_t.DOWN) || + operator_shortcut(config_keymap.brush_ruler + "+" + config_keymap.action_paint, shortcut_type_t.DOWN) || + decal_mask || + set_clone_source || + config_raw.brush_live)) { + context_raw.paint2d = true; + } + ///end + + if (ui_view2d_ui.is_typing) return; + + if (keyboard_started("left")) ui_view2d_pan_x -= 5; + else if (keyboard_started("right")) ui_view2d_pan_x += 5; + if (keyboard_started("up")) ui_view2d_pan_y -= 5; + else if (keyboard_started("down")) ui_view2d_pan_y += 5; + + // Limit panning to keep texture in viewport + let border: i32 = 32; + let tw: f32 = ui_view2d_ww * 0.95 * ui_view2d_pan_scale; + let tx: f32 = ui_view2d_ww / 2 - tw / 2 + ui_view2d_pan_x; + let hh: f32 = app_h(); + let ty: f32 = hh / 2 - tw / 2 + ui_view2d_pan_y; + + if (tx + border > ui_view2d_ww) ui_view2d_pan_x = ui_view2d_ww / 2 + tw / 2 - border; + else if (tx - border < -tw) ui_view2d_pan_x = -tw / 2 - ui_view2d_ww / 2 + border; + if (ty + border > hh) ui_view2d_pan_y = hh / 2 + tw / 2 - border; + else if (ty - border < -tw) ui_view2d_pan_y = -tw / 2 - hh / 2 + border; + + if (operator_shortcut(config_keymap.view_reset)) { + ui_view2d_pan_x = 0.0; + ui_view2d_pan_y = 0.0; + ui_view2d_pan_scale = 1.0; + } +} diff --git a/base/Sources/uniforms_ext.ts b/base/Sources/uniforms_ext.ts index 8eaaab35..cd2acc18 100644 --- a/base/Sources/uniforms_ext.ts +++ b/base/Sources/uniforms_ext.ts @@ -25,7 +25,7 @@ function uniforms_ext_f32_link(object: object_t, mat: material_data_t, link: str let decal_mask: bool = decal && operator_shortcut(config_keymap.decal_mask + "+" + config_keymap.action_paint, shortcut_type_t.DOWN); let brush_decal_mask_radius: f32 = context_raw.brush_decal_mask_radius; if (config_raw.brush_3d) { - brush_decal_mask_radius *= context_raw.paint2d ? 0.55 * UIView2D.pan_scale : 2.0; + brush_decal_mask_radius *= context_raw.paint2d ? 0.55 * ui_view2d_pan_scale : 2.0; } let radius: f32 = decal_mask ? brush_decal_mask_radius : context_raw.brush_radius; let val: f32 = (radius * context_raw.brush_nodes_radius) / 15.0; @@ -35,7 +35,7 @@ function uniforms_ext_f32_link(object: object_t, mat: material_data_t, link: str let scale2d: f32 = (900 / base_h()) * config_raw.window_scale; if (config_raw.brush_3d && !decal) { - val *= context_raw.paint2d ? 0.55 * scale2d * UIView2D.pan_scale : 2; + val *= context_raw.paint2d ? 0.55 * scale2d * ui_view2d_pan_scale : 2; } else { val *= scale2d; // Projection ratio @@ -89,7 +89,7 @@ function uniforms_ext_f32_link(object: object_t, mat: material_data_t, link: str } if (config_raw.brush_3d) { if (context_raw.paint2d) { - val *= 1.0 / UIView2D.pan_scale; + val *= 1.0 / ui_view2d_pan_scale; } else { val *= val; @@ -107,7 +107,7 @@ function uniforms_ext_f32_link(object: object_t, mat: material_data_t, link: str } ///if is_paint case "_dilateRadius": { - return UtilUV.dilatemap != null ? config_raw.dilate_radius : 0.0; + return util_uv_dilatemap != null ? config_raw.dilate_radius : 0.0; } ///end case "_decalLayerDim": { @@ -169,11 +169,11 @@ function uniforms_ext_vec2_link(object: object_t, mat: material_data_t, link: st case "_brushAngle": { let brush_angle: f32 = context_raw.brush_angle + context_raw.brush_nodes_angle; let angle: f32 = context_raw.layer.fill_layer != null ? context_raw.layer.angle : brush_angle; - angle *= (Math.PI / 180); + angle *= (math_pi() / 180); if (config_raw.pressure_angle && pen_down()) { angle *= pen_pressure * config_raw.pressure_sensitivity; } - vec4_set(uniforms_ext_vec, Math.cos(-angle), Math.sin(-angle), 0); + vec4_set(uniforms_ext_vec, math_cos(-angle), math_sin(-angle), 0); return uniforms_ext_vec; } ///end @@ -200,8 +200,8 @@ function uniforms_ext_vec3_link(object: object_t, mat: material_data_t, link: st x = vec2d(x); lastx = vec2d(lastx); } - let angle: f32 = Math.atan2(-y + lasty, x - lastx) - Math.PI / 2; - vec4_set(v, Math.cos(angle), Math.sin(angle), allow_paint ? 1 : 0); + let angle: f32 = math_atan2(-y + lasty, x - lastx) - math_pi() / 2; + vec4_set(v, math_cos(angle), math_sin(angle), allow_paint ? 1 : 0); context_raw.prev_paint_vec_x = context_raw.last_paint_vec_x; context_raw.prev_paint_vec_y = context_raw.last_paint_vec_y; return v; @@ -256,7 +256,7 @@ function uniforms_ext_vec3_link(object: object_t, mat: material_data_t, link: st function vec2d(x: f32) { // Transform from 3d viewport coord to 2d view coord context_raw.paint2d_view = false; - let res: f32 = (x * base_w() - base_w()) / UIView2D.ww; + let res: f32 = (x * base_w() - base_w()) / ui_view2d_ww; context_raw.paint2d_view = true; return res; } @@ -289,11 +289,11 @@ function uniforms_ext_vec4_link(object: object_t, mat: material_data_t, link: st return uniforms_ext_vec; } case "_envmapData": { - vec4_set(uniforms_ext_vec, context_raw.envmap_angle, Math.sin(-context_raw.envmap_angle), Math.cos(-context_raw.envmap_angle), scene_world.strength); + vec4_set(uniforms_ext_vec, context_raw.envmap_angle, math_sin(-context_raw.envmap_angle), math_cos(-context_raw.envmap_angle), scene_world.strength); return uniforms_ext_vec; } case "_envmapDataWorld": { - vec4_set(uniforms_ext_vec, context_raw.envmap_angle, Math.sin(-context_raw.envmap_angle), Math.cos(-context_raw.envmap_angle), context_raw.show_envmap ? scene_world.strength : 1.0); + vec4_set(uniforms_ext_vec, context_raw.envmap_angle, math_sin(-context_raw.envmap_angle), math_cos(-context_raw.envmap_angle), context_raw.show_envmap ? scene_world.strength : 1.0); return uniforms_ext_vec; } ///if (is_paint || is_sculpt) @@ -394,32 +394,32 @@ function uniforms_ext_tex_link(object: object_t, mat: material_data_t, link: str ///if is_paint case "_texuvmap": { - if (!UtilUV.uvmap_cached) { + if (!util_uv_uvmap_cached) { let _init = () => { - UtilUV.cache_uv_map(); + util_uv_cache_uv_map(); } app_notify_on_init(_init); } - return UtilUV.uvmap; + return util_uv_uvmap; } case "_textrianglemap": { - if (!UtilUV.trianglemap_cached) { + if (!util_uv_trianglemap_cached) { let _init = () => { - UtilUV.cache_triangle_map(); + util_uv_cache_triangle_map(); } app_notify_on_init(_init); } - return UtilUV.trianglemap; + return util_uv_trianglemap; } case "_texuvislandmap": { let _init = () => { - UtilUV.cache_uv_island_map(); + util_uv_cache_uv_island_map(); } app_notify_on_init(_init); - return UtilUV.uvislandmap_cached ? UtilUV.uvislandmap :render_path_render_targets.get("empty_black")._image; + return util_uv_uvislandmap_cached ? util_uv_uvislandmap :render_path_render_targets.get("empty_black")._image; } case "_texdilatemap": { - return UtilUV.dilatemap; + return util_uv_dilatemap; } ///end } diff --git a/base/Sources/util_mesh.ts b/base/Sources/util_mesh.ts new file mode 100644 index 00000000..ce5dd80e --- /dev/null +++ b/base/Sources/util_mesh.ts @@ -0,0 +1,377 @@ + +let util_mesh_unwrappers: map_tvoid)> = map_create(); + +function util_mesh_merge(paint_objects: mesh_object_t[] = null) { + if (paint_objects == null) paint_objects = project_paint_objects; + if (paint_objects.length == 0) return; + context_raw.merged_object_is_atlas = paint_objects.length < project_paint_objects.length; + let vlen: i32 = 0; + let ilen: i32 = 0; + let max_scale: f32 = 0.0; + for (let i: i32 = 0; i < paint_objects.length; ++i) { + vlen += paint_objects[i].data.vertex_arrays[0].values.length; + ilen += paint_objects[i].data.index_arrays[0].values.length; + if (paint_objects[i].data.scale_pos > max_scale) max_scale = paint_objects[i].data.scale_pos; + } + vlen = math_floor(vlen / 4); + let va0: Int16Array = new Int16Array(vlen * 4); + let va1: Int16Array = new Int16Array(vlen * 2); + let va2: Int16Array = new Int16Array(vlen * 2); + let va3: Int16Array = paint_objects[0].data.vertex_arrays.length > 3 ? new Int16Array(vlen * 4) : null; + let ia: Uint32Array = new Uint32Array(ilen); + + let voff: i32 = 0; + let ioff: i32 = 0; + for (let i: i32 = 0; i < paint_objects.length; ++i) { + let vas: vertex_array_t[] = paint_objects[i].data.vertex_arrays; + let ias: index_array_t[] = paint_objects[i].data.index_arrays; + let scale: f32 = paint_objects[i].data.scale_pos; + + // Pos + for (let j: i32 = 0; j < vas[0].values.length; ++j) va0[j + voff * 4] = vas[0].values[j]; + + // Translate + ///if is_forge + for (let j: i32 = 0; j < math_floor(va0.length / 4); ++j) { + va0[j * 4 + voff * 4] += math_floor(transform_world_x(paint_objects[i].base.transform) * 32767); + va0[j * 4 + 1 + voff * 4] += math_floor(transform_world_y(paint_objects[i].base.transform) * 32767); + va0[j * 4 + 2 + voff * 4] += math_floor(transform_world_z(paint_objects[i].base.transform) * 32767); + } + ///end + + // Re-scale + for (let j: i32 = 0; j < math_floor(va0.length / 4); ++j) { + va0[j * 4 + voff * 4] = math_floor((va0[j * 4 + voff * 4] * scale) / max_scale); + va0[j * 4 + 1 + voff * 4] = math_floor((va0[j * 4 + 1 + voff * 4] * scale) / max_scale); + va0[j * 4 + 2 + voff * 4] = math_floor((va0[j * 4 + 2 + voff * 4] * scale) / max_scale); + } + // Nor + for (let j: i32 = 0; j < vas[1].values.length; ++j) va1[j + voff * 2] = vas[1].values[j]; + // Tex + for (let j: i32 = 0; j < vas[2].values.length; ++j) va2[j + voff * 2] = vas[2].values[j]; + // Col + if (va3 != null) for (let j: i32 = 0; j < vas[3].values.length; ++j) va3[j + voff * 4] = vas[3].values[j]; + // Indices + for (let j: i32 = 0; j < ias[0].values.length; ++j) ia[j + ioff] = ias[0].values[j] + voff; + + voff += math_floor(vas[0].values.length / 4); + ioff += math_floor(ias[0].values.length); + } + + let raw: mesh_data_t = { + name: context_raw.paint_object.base.name, + vertex_arrays: [ + { values: va0, attrib: "pos", data: "short4norm" }, + { values: va1, attrib: "nor", data: "short2norm" }, + { values: va2, attrib: "tex", data: "short2norm" } + ], + index_arrays: [ + { values: ia, material: 0 } + ], + scale_pos: max_scale, + scale_tex: 1.0 + }; + if (va3 != null) raw.vertex_arrays.push({ values: va3, attrib: "col", data: "short4norm" }); + + util_mesh_remove_merged(); + let md: mesh_data_t = mesh_data_create(raw); + context_raw.merged_object = mesh_object_create(md, context_raw.paint_object.materials); + context_raw.merged_object.base.name = context_raw.paint_object.base.name + "_merged"; + context_raw.merged_object.force_context = "paint"; + object_set_parent(context_raw.merged_object.base, context_main_object().base); + + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + RenderPathRaytrace.ready = false; + ///end +} + +function util_mesh_remove_merged() { + if (context_raw.merged_object != null) { + mesh_data_delete(context_raw.merged_object.data); + mesh_object_remove(context_raw.merged_object); + context_raw.merged_object = null; + } +} + +function util_mesh_swap_axis(a: i32, b: i32) { + let objects: mesh_object_t[] = project_paint_objects; + for (let o of objects) { + // Remapping vertices, buckle up + // 0 - x, 1 - y, 2 - z + let vas: vertex_array_t[] = o.data.vertex_arrays; + let pa: i16_array_t = vas[0].values; + let na0: i16_array_t = a == 2 ? vas[0].values : vas[1].values; + let na1: i16_array_t = b == 2 ? vas[0].values : vas[1].values; + let c: i32 = a == 2 ? 3 : a; + let d: i32 = b == 2 ? 3 : b; + let e: i32 = a == 2 ? 4 : 2; + let f: i32 = b == 2 ? 4 : 2; + + for (let i: i32 = 0; i < math_floor(pa.length / 4); ++i) { + let t: i32 = pa[i * 4 + a]; + pa[i * 4 + a] = pa[i * 4 + b]; + pa[i * 4 + b] = -t; + t = na0[i * e + c]; + na0[i * e + c] = na1[i * f + d]; + na1[i * f + d] = -t; + } + + let g: mesh_data_t = o.data; + let l: i32 = g4_vertex_struct_byte_size(g._.structure) / 2; + let vertices: buffer_view_t = g4_vertex_buffer_lock(g._.vertex_buffer); // posnortex + for (let i: i32 = 0; i < math_floor(vertices.byteLength / 2 / l); ++i) { + vertices.setInt16((i * l ) * 2, vas[0].values[i * 4 ], true); + vertices.setInt16((i * l + 1) * 2, vas[0].values[i * 4 + 1], true); + vertices.setInt16((i * l + 2) * 2, vas[0].values[i * 4 + 2], true); + vertices.setInt16((i * l + 3) * 2, vas[0].values[i * 4 + 3], true); + vertices.setInt16((i * l + 4) * 2, vas[1].values[i * 2 ], true); + vertices.setInt16((i * l + 5) * 2, vas[1].values[i * 2 + 1], true); + } + g4_vertex_buffer_unlock(g._.vertex_buffer); + } + + util_mesh_remove_merged(); + util_mesh_merge(); +} + +function util_mesh_flip_normals() { + let objects: mesh_object_t[] = project_paint_objects; + for (let o of objects) { + let vas: vertex_array_t[] = o.data.vertex_arrays; + let va0: i16_array_t = vas[0].values; + let va1: i16_array_t = vas[1].values; + let g: mesh_data_t = o.data; + let l: i32 = g4_vertex_struct_byte_size(g._.structure) / 2; + let vertices: buffer_view_t = g4_vertex_buffer_lock(g._.vertex_buffer); // posnortex + for (let i: i32 = 0; i < math_floor(vertices.byteLength / 2 / l); ++i) { + va0[i * 4 + 3] = -va0[i * 4 + 3]; + va1[i * 2] = -va1[i * 2]; + va1[i * 2 + 1] = -va1[i * 2 + 1]; + vertices.setInt16((i * l + 3) * 2, -vertices.getInt16((i * l + 3) * 2, true), true); + vertices.setInt16((i * l + 4) * 2, -vertices.getInt16((i * l + 4) * 2, true), true); + vertices.setInt16((i * l + 5) * 2, -vertices.getInt16((i * l + 5) * 2, true), true); + } + g4_vertex_buffer_unlock(g._.vertex_buffer); + } + + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + RenderPathRaytrace.ready = false; + ///end +} + +function util_mesh_calc_normals(smooth: bool = false) { + let va: vec4_t = vec4_create(); + let vb: vec4_t = vec4_create(); + let vc: vec4_t = vec4_create(); + let cb: vec4_t = vec4_create(); + let ab: vec4_t = vec4_create(); + let objects: mesh_object_t[] = project_paint_objects; + for (let o of objects) { + let g: mesh_data_t = o.data; + let l: i32 = g4_vertex_struct_byte_size(g._.structure) / 2; + let inda: u32_array_t = g._.indices[0]; + let vertices: buffer_view_t = g4_vertex_buffer_lock(g._.vertex_buffer); // posnortex + for (let i: i32 = 0; i < math_floor(inda.length / 3); ++i) { + let i1: i32 = inda[i * 3 ]; + let i2: i32 = inda[i * 3 + 1]; + let i3: i32 = inda[i * 3 + 2]; + vec4_set(va, vertices.getInt16((i1 * l) * 2, true), vertices.getInt16((i1 * l + 1) * 2, true), vertices.getInt16((i1 * l + 2) * 2, true)); + vec4_set(vb, vertices.getInt16((i2 * l) * 2, true), vertices.getInt16((i2 * l + 1) * 2, true), vertices.getInt16((i2 * l + 2) * 2, true)); + vec4_set(vc, vertices.getInt16((i3 * l) * 2, true), vertices.getInt16((i3 * l + 1) * 2, true), vertices.getInt16((i3 * l + 2) * 2, true)); + vec4_sub_vecs(cb, vc, vb); + vec4_sub_vecs(ab, va, vb); + vec4_cross(cb, ab); + vec4_normalize(cb, ); + vertices.setInt16((i1 * l + 4) * 2, math_floor(cb.x * 32767), true); + vertices.setInt16((i1 * l + 5) * 2, math_floor(cb.y * 32767), true); + vertices.setInt16((i1 * l + 3) * 2, math_floor(cb.z * 32767), true); + vertices.setInt16((i2 * l + 4) * 2, math_floor(cb.x * 32767), true); + vertices.setInt16((i2 * l + 5) * 2, math_floor(cb.y * 32767), true); + vertices.setInt16((i2 * l + 3) * 2, math_floor(cb.z * 32767), true); + vertices.setInt16((i3 * l + 4) * 2, math_floor(cb.x * 32767), true); + vertices.setInt16((i3 * l + 5) * 2, math_floor(cb.y * 32767), true); + vertices.setInt16((i3 * l + 3) * 2, math_floor(cb.z * 32767), true); + } + + if (smooth) { + let shared: Uint32Array = new Uint32Array(1024); + let sharedLen: i32 = 0; + let found: i32[] = []; + for (let i: i32 = 0; i < (inda.length - 1); ++i) { + if (found.indexOf(i) >= 0) continue; + let i1: i32 = inda[i]; + sharedLen = 0; + shared[sharedLen++] = i1; + for (let j: i32 = (i + 1); j < inda.length; ++j) { + let i2: i32 = inda[j]; + let i1l: i32 = i1 * l; + let i2l: i32 = i2 * l; + if (vertices.getInt16((i1l ) * 2, true) == vertices.getInt16((i2l ) * 2, true) && + vertices.getInt16((i1l + 1) * 2, true) == vertices.getInt16((i2l + 1) * 2, true) && + vertices.getInt16((i1l + 2) * 2, true) == vertices.getInt16((i2l + 2) * 2, true)) { + // if (n1.dot(n2) > 0) + shared[sharedLen++] = i2; + found.push(j); + if (sharedLen >= 1024) break; + } + } + if (sharedLen > 1) { + vec4_set(va, 0, 0, 0); + for (let j: i32 = 0; j < sharedLen; ++j) { + let i1: i32 = shared[j]; + let i1l: i32 = i1 * l; + vec4_add_f(va, vertices.getInt16((i1l + 4) * 2, true), vertices.getInt16((i1l + 5) * 2, true), vertices.getInt16((i1l + 3) * 2, true)); + } + vec4_mult(va, 1 / sharedLen); + vec4_normalize(va, ); + let vax: i32 = math_floor(va.x * 32767); + let vay: i32 = math_floor(va.y * 32767); + let vaz: i32 = math_floor(va.z * 32767); + for (let j: i32 = 0; j < sharedLen; ++j) { + let i1: i32 = shared[j]; + let i1l: i32 = i1 * l; + vertices.setInt16((i1l + 4) * 2, vax, true); + vertices.setInt16((i1l + 5) * 2, vay, true); + vertices.setInt16((i1l + 3) * 2, vaz, true); + } + } + } + } + g4_vertex_buffer_unlock(g._.vertex_buffer); + + let va0: i16_array_t = o.data.vertex_arrays[0].values; + let va1: i16_array_t = o.data.vertex_arrays[1].values; + for (let i: i32 = 0; i < math_floor(vertices.byteLength / 4 / l); ++i) { + va1[i * 2 ] = vertices.getInt16((i * l + 4) * 2, true); + va1[i * 2 + 1] = vertices.getInt16((i * l + 5) * 2, true); + va0[i * 4 + 3] = vertices.getInt16((i * l + 3) * 2, true); + } + } + + ///if (krom_direct3d12 || krom_vulkan || krom_metal) + util_mesh_merge(); + RenderPathRaytrace.ready = false; + ///end +} + +function util_mesh_to_origin() { + let dx: f32 = 0.0; + let dy: f32 = 0.0; + let dz: f32 = 0.0; + for (let o of project_paint_objects) { + let l: i32 = 4; + let sc: f32 = o.data.scale_pos / 32767; + let va: i16_array_t = o.data.vertex_arrays[0].values; + let minx: f32 = va[0]; + let maxx: f32 = va[0]; + let miny: f32 = va[1]; + let maxy: f32 = va[1]; + let minz: f32 = va[2]; + let maxz: f32 = va[2]; + for (let i: i32 = 1; i < math_floor(va.length / l); ++i) { + if (va[i * l] < minx) minx = va[i * l]; + else if (va[i * l] > maxx) maxx = va[i * l]; + if (va[i * l + 1] < miny) miny = va[i * l + 1]; + else if (va[i * l + 1] > maxy) maxy = va[i * l + 1]; + if (va[i * l + 2] < minz) minz = va[i * l + 2]; + else if (va[i * l + 2] > maxz) maxz = va[i * l + 2]; + } + dx += (minx + maxx) / 2 * sc; + dy += (miny + maxy) / 2 * sc; + dz += (minz + maxz) / 2 * sc; + } + dx /= project_paint_objects.length; + dy /= project_paint_objects.length; + dz /= project_paint_objects.length; + + for (let o of project_paint_objects) { + let g: mesh_data_t = o.data; + let sc: f32 = o.data.scale_pos / 32767; + let va: i16_array_t = o.data.vertex_arrays[0].values; + let max_scale: f32 = 0.0; + for (let i: i32 = 0; i < math_floor(va.length / 4); ++i) { + if (math_abs(va[i * 4 ] * sc - dx) > max_scale) max_scale = math_abs(va[i * 4 ] * sc - dx); + if (math_abs(va[i * 4 + 1] * sc - dy) > max_scale) max_scale = math_abs(va[i * 4 + 1] * sc - dy); + if (math_abs(va[i * 4 + 2] * sc - dz) > max_scale) max_scale = math_abs(va[i * 4 + 2] * sc - dz); + } + o.base.transform.scale_world = o.data.scale_pos = o.data.scale_pos = max_scale; + transform_build_matrix(o.base.transform); + + for (let i: i32 = 0; i < math_floor(va.length / 4); ++i) { + va[i * 4 ] = math_floor((va[i * 4 ] * sc - dx) / max_scale * 32767); + va[i * 4 + 1] = math_floor((va[i * 4 + 1] * sc - dy) / max_scale * 32767); + va[i * 4 + 2] = math_floor((va[i * 4 + 2] * sc - dz) / max_scale * 32767); + } + + let l: i32 = g4_vertex_struct_byte_size(g._.structure) / 2; + let vertices: buffer_view_t = g4_vertex_buffer_lock(g._.vertex_buffer); // posnortex + for (let i: i32 = 0; i < math_floor(vertices.byteLength / 2 / l); ++i) { + vertices.setInt16((i * l ) * 2, va[i * 4 ], true); + vertices.setInt16((i * l + 1) * 2, va[i * 4 + 1], true); + vertices.setInt16((i * l + 2) * 2, va[i * 4 + 2], true); + } + g4_vertex_buffer_unlock(g._.vertex_buffer); + } + + util_mesh_merge(); +} + +function util_mesh_apply_displacement(texpaint_pack: image_t, strength: f32 = 0.1, uvScale: f32 = 1.0) { + let height: buffer_t = image_get_pixels(texpaint_pack); + let height_view: buffer_view_t = new DataView(height); + let res: i32 = texpaint_pack.width; + let o: mesh_object_t = project_paint_objects[0]; + let g: mesh_data_t = o.data; + let l: i32 = g4_vertex_struct_byte_size(g._.structure) / 2; + let vertices: buffer_view_t = g4_vertex_buffer_lock(g._.vertex_buffer); // posnortex + for (let i: i32 = 0; i < math_floor(vertices.byteLength / 2 / l); ++i) { + let x: i32 = math_floor(vertices.getInt16((i * l + 6) * 2, true) / 32767 * res); + let y: i32 = math_floor(vertices.getInt16((i * l + 7) * 2, true) / 32767 * res); + let xx: i32 = math_floor(x * uvScale) % res; + let yy: i32 = math_floor(y * uvScale) % res; + let h: f32 = (1.0 - height_view.getUint8((yy * res + xx) * 4 + 3) / 255) * strength; + vertices.setInt16((i * l ) * 2, vertices.getInt16((i * l ) * 2, true) - math_floor(vertices.getInt16((i * l + 4) * 2, true) * h), true); + vertices.setInt16((i * l + 1) * 2, vertices.getInt16((i * l + 1) * 2, true) - math_floor(vertices.getInt16((i * l + 5) * 2, true) * h), true); + vertices.setInt16((i * l + 2) * 2, vertices.getInt16((i * l + 2) * 2, true) - math_floor(vertices.getInt16((i * l + 3) * 2, true) * h), true); + } + g4_vertex_buffer_unlock(g._.vertex_buffer); + + let va0: i16_array_t = o.data.vertex_arrays[0].values; + for (let i: i32 = 0; i < math_floor(vertices.byteLength / 4 / l); ++i) { + va0[i * 4 ] = vertices.getInt16((i * l ) * 2, true); + va0[i * 4 + 1] = vertices.getInt16((i * l + 1) * 2, true); + va0[i * 4 + 2] = vertices.getInt16((i * l + 2) * 2, true); + } +} + +function util_mesh_equirect_unwrap(mesh: any) { + let verts: i32 = math_floor(mesh.posa.length / 4); + mesh.texa = new Int16Array(verts * 2); + let n: vec4_t = vec4_create(); + for (let i: i32 = 0; i < verts; ++i) { + vec4_normalize(vec4_set(n, mesh.posa[i * 4] / 32767, mesh.posa[i * 4 + 1] / 32767, mesh.posa[i * 4 + 2] / 32767)); + // Sphere projection + // mesh.texa[i * 2 ] = math_atan2(n.x, n.y) / (math_pi() * 2) + 0.5; + // mesh.texa[i * 2 + 1] = n.z * 0.5 + 0.5; + // Equirect + mesh.texa[i * 2 ] = math_floor(((math_atan2(-n.z, n.x) + math_pi()) / (math_pi() * 2)) * 32767); + mesh.texa[i * 2 + 1] = math_floor((math_acos(n.y) / math_pi()) * 32767); + } +} + +function util_mesh_pnpoly(v0x: f32, v0y: f32, v1x: f32, v1y: f32, v2x: f32, v2y: f32, px: f32, py: f32): bool { + // https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html + let c: bool = false; + if (((v0y > py) != (v2y > py)) && (px < (v2x - v0x) * (py - v0y) / (v2y - v0y) + v0x)) c = !c; + if (((v1y > py) != (v0y > py)) && (px < (v0x - v1x) * (py - v1y) / (v0y - v1y) + v1x)) c = !c; + if (((v2y > py) != (v1y > py)) && (px < (v1x - v2x) * (py - v2y) / (v1y - v2y) + v2x)) c = !c; + return c; +} + +function util_mesh_calc_normal(p0: vec4_t, p1: vec4_t, p2: vec4_t): vec4_t { + let cb: vec4_t = vec4_sub_vecs(vec4_create(), p2, p1); + let ab: vec4_t = vec4_sub_vecs(vec4_create(), p0, p1); + vec4_cross(cb, ab); + vec4_normalize(cb); + return cb; +} diff --git a/base/Sources/util_particle.ts b/base/Sources/util_particle.ts new file mode 100644 index 00000000..63766c6f --- /dev/null +++ b/base/Sources/util_particle.ts @@ -0,0 +1,113 @@ + +///if (is_paint || is_sculpt) + +function util_particle_init() { + if (context_raw.particle_material != null) return; + + let raw: particle_data_t = { + name: "Particles", + type: 0, + loop: false, + count: 1000, + frame_start: 0, + frame_end: 1000, + lifetime: 400, + lifetime_random: 0.5, + emit_from: 1, + object_align_factor: new Float32Array([0, 0, -40]), + factor_random: 2.0, + physics_type: 0, + particle_size: 1.0, + size_random: 0, + mass: 1, + instance_object: ".Particle", + weight_gravity: 1 + }; + _scene_raw.particle_datas = [raw]; + let particle_refs: particle_ref_t[] = [ + { + name: "Particles", + particle: "Particles", + seed: 0 + } + ]; + + { + let t: render_target_t = render_target_create(); + t.name = "texparticle"; + t.width = 0; + t.height = 0; + t.format = "R8"; + t.scale = RenderPathBase.get_super_sampling(); + render_path_create_render_target(t); + } + + for (let mat of _scene_raw.material_datas) { + if (mat.name == "Material2") { + let m: material_data_t = json_parse(json_stringify(mat)); + m.name = "MaterialParticle"; + _scene_raw.material_datas.push(m); + break; + } + } + + let md: material_data_t = data_get_material("Scene", "MaterialParticle"); + context_raw.particle_material = md; + + for (let obj of _scene_raw.objects) { + if (obj.name == ".Sphere") { + let particle: obj_t = json_parse(json_stringify(obj)); + particle.name = ".Particle"; + if (particle.particles == null) { + particle.particles = {}; + } + particle.particles.is_particle = true; + particle.material_refs = ["MaterialParticle"]; + _scene_raw.objects.push(particle); + for (let i: i32 = 0; i < 16; ++i) particle.transform[i] *= 0.01; + break; + } + } + + let o: object_t = scene_spawn_object(".Sphere"); + let mo: mesh_object_t = o.ext; + mo.base.name = ".ParticleEmitter"; + mo.base.raw = json_parse(json_stringify(mo.base.raw)); + mo.base.raw.particles.refs = particle_refs; + ///if arm_particles + mesh_object_setup_particle_system(mo, "Scene", particle_refs[0]); + ///end +} + +///if arm_physics + +function util_particle_init_physics() { + if (PhysicsWorld.active != null) { + util_particle_init_mesh(); + return; + } + + PhysicsWorld.load(function () { + PhysicsWorld.create(); + util_particle_init_mesh(); + }); +} + +function util_particle_init_mesh() { + if (context_raw.paint_body != null) return; + + let po: mesh_object_t = context_raw.merged_object != null ? context_raw.merged_object : context_raw.paint_object; + + po.base.transform.scale.x = po.base.parent.transform.scale.x; + po.base.transform.scale.y = po.base.parent.transform.scale.y; + po.base.transform.scale.z = po.base.parent.transform.scale.z; + + context_raw.paint_body = PhysicsBody.create(); + context_raw.paint_body.shape = shape_type_t.MESH; + PhysicsBody.init(context_raw.paint_body, po.base); + (po.base as any).physicsBody = context_raw.paint_body; +} + +///end + +///end diff --git a/base/Sources/util_render.ts b/base/Sources/util_render.ts new file mode 100644 index 00000000..243eac90 --- /dev/null +++ b/base/Sources/util_render.ts @@ -0,0 +1,451 @@ + +///if (is_paint || is_sculpt) + +let util_render_material_preview_size: i32 = 256; +let util_render_decal_preview_size: i32 = 512; +let util_render_layer_preview_size: i32 = 200; +let util_render_screen_aligned_full_vb: vertex_buffer_t = null; +let util_render_screen_aligned_full_ib: index_buffer_t = null; + +function util_render_make_material_preview() { + context_raw.material_preview = true; + + let sphere: mesh_object_t = scene_get_child(".Sphere").ext; + sphere.base.visible = true; + let meshes: mesh_object_t[] = scene_meshes; + scene_meshes = [sphere]; + let painto: mesh_object_t = context_raw.paint_object; + context_raw.paint_object = sphere; + + sphere.materials[0] = project_materials[0].data; + context_raw.material.preview_ready = true; + + mat4_set_from(context_raw.saved_camera, scene_camera.base.transform.local); + let m: mat4_t = mat4_create(0.9146286343879498, -0.0032648027153306235, 0.404281837254303, 0.4659988049397712, 0.404295023959927, 0.007367569133732468, -0.9145989516155143, -1.0687517188018691, 0.000007410128652369705, 0.9999675337275382, 0.008058532943908717, 0.015935682577325486, 0, 0, 0, 1); + transform_set_matrix(scene_camera.base.transform, m); + let saved_fov: f32 = scene_camera.data.fov; + scene_camera.data.fov = 0.92; + viewport_update_camera_type(camera_type_t.PERSPECTIVE); + let light: light_object_t = scene_lights[0]; + let _light_strength: f32 = light.data.strength; + let probe: world_data_t = scene_world; + let _probe_strength: f32 = probe.strength; + light.data.strength = 0; + probe.strength = 7; + let _envmap_angle: f32 = context_raw.envmap_angle; + context_raw.envmap_angle = 6.0; + let _brush_scale: f32 = context_raw.brush_scale; + context_raw.brush_scale = 1.5; + let _brush_nodes_scale: f32 = context_raw.brush_nodes_scale; + context_raw.brush_nodes_scale = 1.0; + + scene_world._.envmap = context_raw.preview_envmap; + // No resize + _render_path_last_w = util_render_material_preview_size; + _render_path_last_h = util_render_material_preview_size; + camera_object_build_proj(scene_camera); + camera_object_build_mat(scene_camera); + + MakeMaterial.parse_mesh_preview_material(); + let _commands: ()=>void = render_path_commands; + render_path_commands = RenderPathPreview.commands_preview; + render_path_render_frame(); + render_path_commands = _commands; + + context_raw.material_preview = false; + _render_path_last_w = app_w(); + _render_path_last_h = app_h(); + + // Restore + sphere.base.visible = false; + scene_meshes = meshes; + context_raw.paint_object = painto; + + transform_set_matrix(scene_camera.base.transform, context_raw.saved_camera); + viewport_update_camera_type(context_raw.camera_type); + scene_camera.data.fov = saved_fov; + camera_object_build_proj(scene_camera); + camera_object_build_mat(scene_camera); + light.data.strength = _light_strength; + probe.strength = _probe_strength; + context_raw.envmap_angle = _envmap_angle; + context_raw.brush_scale = _brush_scale; + context_raw.brush_nodes_scale = _brush_nodes_scale; + scene_world._.envmap = context_raw.show_envmap ? context_raw.saved_envmap : context_raw.empty_envmap; + MakeMaterial.parse_mesh_material(); + context_raw.ddirty = 0; +} + +function util_render_make_decal_preview() { + let current: image_t = _g2_current; + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); + + if (context_raw.decal_image == null) { + context_raw.decal_image = image_create_render_target(util_render_decal_preview_size, util_render_decal_preview_size); + } + context_raw.decal_preview = true; + + let plane: mesh_object_t = scene_get_child(".Plane").ext; + vec4_set(plane.base.transform.scale, 1, 1, 1); + quat_from_euler(plane.base.transform.rot, -math_pi() / 2, 0, 0); + transform_build_matrix(plane.base.transform); + plane.base.visible = true; + let meshes: mesh_object_t[] = scene_meshes; + scene_meshes = [plane]; + let painto: mesh_object_t = context_raw.paint_object; + context_raw.paint_object = plane; + + mat4_set_from(context_raw.saved_camera, scene_camera.base.transform.local); + let m: mat4_t = mat4_identity(); + mat4_translate(m, 0, 0, 1); + transform_set_matrix(scene_camera.base.transform, m); + let saved_fov: f32 = scene_camera.data.fov; + scene_camera.data.fov = 0.92; + viewport_update_camera_type(camera_type_t.PERSPECTIVE); + let light: light_object_t = scene_lights[0]; + light.base.visible = false; + scene_world._.envmap = context_raw.preview_envmap; + + // No resize + _render_path_last_w = util_render_decal_preview_size; + _render_path_last_h = util_render_decal_preview_size; + camera_object_build_proj(scene_camera); + camera_object_build_mat(scene_camera); + + MakeMaterial.parse_mesh_preview_material(); + let _commands: ()=>void = render_path_commands; + render_path_commands = RenderPathPreview.commands_decal; + render_path_render_frame(); + render_path_commands = _commands; + + context_raw.decal_preview = false; + _render_path_last_w = app_w(); + _render_path_last_h = app_h(); + + // Restore + plane.base.visible = false; + scene_meshes = meshes; + context_raw.paint_object = painto; + + transform_set_matrix(scene_camera.base.transform, context_raw.saved_camera); + scene_camera.data.fov = saved_fov; + viewport_update_camera_type(context_raw.camera_type); + camera_object_build_proj(scene_camera); + camera_object_build_mat(scene_camera); + light = scene_lights[0]; + light.base.visible = true; + scene_world._.envmap = context_raw.show_envmap ? context_raw.saved_envmap : context_raw.empty_envmap; + + MakeMaterial.parse_mesh_material(); + context_raw.ddirty = 1; // Refresh depth for decal paint + + if (g2_in_use) g2_begin(current); +} + +function util_render_make_text_preview() { + let current: image_t = _g2_current; + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); + + let text: string = context_raw.text_tool_text; + let font: g2_font_t = context_raw.font.font; + let font_size: i32 = 200; + let text_w: i32 = math_floor(g2_font_width(font, font_size, text)); + let text_h: i32 = math_floor(g2_font_height(font, font_size)); + let texW: i32 = text_w + 32; + if (texW < 512) texW = 512; + if (context_raw.text_tool_image != null && context_raw.text_tool_image.width < texW) { + image_unload(context_raw.text_tool_image); + context_raw.text_tool_image = null; + } + if (context_raw.text_tool_image == null) { + ///if krom_metal + context_raw.text_tool_image = image_create_render_target(texW, texW, tex_format_t.RGBA32); + ///else + context_raw.text_tool_image = image_create_render_target(texW, texW, tex_format_t.R8); + ///end + } + g2_begin(context_raw.text_tool_image); + g2_clear(0xff000000); + g2_set_font(font); + g2_set_font_size(font_size); + g2_set_color(0xffffffff); + g2_draw_string(text, texW / 2 - text_w / 2, texW / 2 - text_h / 2); + g2_end(); + + if (g2_in_use) g2_begin(current); +} + +function util_render_make_font_preview() { + let current: image_t = _g2_current; + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); + + let text: string = "Abg"; + let font: g2_font_t = context_raw.font.font; + let font_size: i32 = 318; + let text_w: i32 = math_floor(g2_font_width(font, font_size, text)) + 8; + let text_h: i32 = math_floor(g2_font_height(font, font_size)) + 8; + if (context_raw.font.image == null) { + context_raw.font.image = image_create_render_target(512, 512, tex_format_t.RGBA32); + } + g2_begin(context_raw.font.image); + g2_clear(0x00000000); + g2_set_font(font); + g2_set_font_size(font_size); + g2_set_color(0xffffffff); + g2_draw_string(text, 512 / 2 - text_w / 2, 512 / 2 - text_h / 2); + g2_end(); + context_raw.font.preview_ready = true; + + if (g2_in_use) g2_begin(current); +} + +function util_render_make_brush_preview() { + if (RenderPathPaint.live_layer_locked) return; + context_raw.material_preview = true; + + let current: image_t = _g2_current; + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); + + // Prepare layers + if (RenderPathPaint.live_layer == null) { + RenderPathPaint.live_layer = SlotLayer.create("_live"); + } + + let l: SlotLayerRaw = RenderPathPaint.live_layer; + SlotLayer.clear(l); + + if (context_raw.brush.image == null) { + context_raw.brush.image = image_create_render_target(util_render_material_preview_size, util_render_material_preview_size); + context_raw.brush.image_icon = image_create_render_target(50, 50); + } + + let _material: SlotMaterialRaw = context_raw.material; + context_raw.material = SlotMaterial.create(); + let _tool: workspace_tool_t = context_raw.tool; + context_raw.tool = workspace_tool_t.BRUSH; + + let _layer: SlotLayerRaw = context_raw.layer; + if (SlotLayer.is_mask(context_raw.layer)) { + context_raw.layer = context_raw.layer.parent; + } + + let _fill_layer: SlotMaterialRaw = context_raw.layer.fill_layer; + context_raw.layer.fill_layer = null; + + RenderPathPaint.use_live_layer(true); + MakeMaterial.parse_paint_material(false); + + let hid: i32 = history_undo_i - 1 < 0 ? config_raw.undo_steps - 1 : history_undo_i - 1; + render_path_render_targets.set("texpaint_undo" + hid,render_path_render_targets.get("empty_black")); + + // Set plane mesh + let painto: mesh_object_t = context_raw.paint_object; + let visibles: bool[] = []; + for (let p of project_paint_objects) { + visibles.push(p.base.visible); + p.base.visible = false; + } + let merged_object_visible: bool = false; + if (context_raw.merged_object != null) { + merged_object_visible = context_raw.merged_object.base.visible; + context_raw.merged_object.base.visible = false; + } + + let cam: camera_object_t = scene_camera; + mat4_set_from(context_raw.saved_camera, cam.base.transform.local); + let saved_fov: f32 = cam.data.fov; + viewport_update_camera_type(camera_type_t.PERSPECTIVE); + let m: mat4_t = mat4_identity(); + mat4_translate(m, 0, 0, 0.5); + transform_set_matrix(cam.base.transform, m); + cam.data.fov = 0.92; + camera_object_build_proj(cam); + camera_object_build_mat(cam); + mat4_get_inv(m, scene_camera.vp); + + let planeo: mesh_object_t = scene_get_child(".Plane").ext; + planeo.base.visible = true; + context_raw.paint_object = planeo; + + let v: vec4_t = vec4_create(); + let sx: f32 = vec4_len(vec4_set(v, m.m[0], m.m[1], m.m[2])); + quat_from_euler(planeo.base.transform.rot, -math_pi() / 2, 0, 0); + vec4_set(planeo.base.transform.scale, sx, 1.0, sx); + vec4_set(planeo.base.transform.loc, m.m[12], -m.m[13], 0.0); + transform_build_matrix(planeo.base.transform); + + RenderPathPaint.live_layer_drawn = 0; + RenderPathBase.draw_gbuffer(); + + // Paint brush preview + let _brush_radius: f32 = context_raw.brush_radius; + let _brush_opacity: f32 = context_raw.brush_opacity; + let _brush_hardness: f32 = context_raw.brush_hardness; + context_raw.brush_radius = 0.33; + context_raw.brush_opacity = 1.0; + context_raw.brush_hardness = 0.8; + let _x: f32 = context_raw.paint_vec.x; + let _y: f32 = context_raw.paint_vec.y; + let _last_x: f32 = context_raw.last_paint_vec_x; + let _last_y: f32 = context_raw.last_paint_vec_y; + let _pdirty: i32 = context_raw.pdirty; + context_raw.pdirty = 2; + + let points_x: f32[] = [0.2, 0.2, 0.35, 0.5, 0.5, 0.5, 0.65, 0.8, 0.8, 0.8]; + let points_y: f32[] = [0.5, 0.5, 0.35 - 0.04, 0.2 - 0.08, 0.4 + 0.015, 0.6 + 0.03, 0.45 - 0.025, 0.3 - 0.05, 0.5 + 0.025, 0.7 + 0.05]; + for (let i: i32 = 1; i < points_x.length; ++i) { + context_raw.last_paint_vec_x = points_x[i - 1]; + context_raw.last_paint_vec_y = points_y[i - 1]; + context_raw.paint_vec.x = points_x[i]; + context_raw.paint_vec.y = points_y[i]; + RenderPathPaint.commands_paint(false); + } + + context_raw.brush_radius = _brush_radius; + context_raw.brush_opacity = _brush_opacity; + context_raw.brush_hardness = _brush_hardness; + context_raw.paint_vec.x = _x; + context_raw.paint_vec.y = _y; + context_raw.last_paint_vec_x = _last_x; + context_raw.last_paint_vec_y = _last_y; + context_raw.prev_paint_vec_x = -1; + context_raw.prev_paint_vec_y = -1; + context_raw.pdirty = _pdirty; + RenderPathPaint.use_live_layer(false); + context_raw.layer.fill_layer = _fill_layer; + context_raw.layer = _layer; + context_raw.material = _material; + context_raw.tool = _tool; + let _init = function () { + MakeMaterial.parse_paint_material(false); + } + app_notify_on_init(_init); + + // Restore paint mesh + context_raw.material_preview = false; + planeo.base.visible = false; + for (let i: i32 = 0; i < project_paint_objects.length; ++i) { + project_paint_objects[i].base.visible = visibles[i]; + } + if (context_raw.merged_object != null) { + context_raw.merged_object.base.visible = merged_object_visible; + } + context_raw.paint_object = painto; + transform_set_matrix(scene_camera.base.transform, context_raw.saved_camera); + scene_camera.data.fov = saved_fov; + viewport_update_camera_type(context_raw.camera_type); + camera_object_build_proj(scene_camera); + camera_object_build_mat(scene_camera); + + // Scale layer down to to image preview + if (base_pipe_merge == null) base_make_pipe(); + l = RenderPathPaint.live_layer; + let target: image_t = context_raw.brush.image; + g2_begin(target); + g2_clear(0x00000000); + g2_set_pipeline(base_pipe_copy); + g2_draw_scaled_image(l.texpaint, 0, 0, target.width, target.height); + g2_set_pipeline(null); + g2_end(); + + // Scale image preview down to to icon + render_path_render_targets.get("texpreview")._image = context_raw.brush.image; + render_path_render_targets.get("texpreview_icon")._image = context_raw.brush.image_icon; + render_path_set_target("texpreview_icon"); + render_path_bind_target("texpreview", "tex"); + render_path_draw_shader("shader_datas/supersample_resolve/supersample_resolve"); + + context_raw.brush.preview_ready = true; + context_raw.brush_blend_dirty = true; + + if (g2_in_use) g2_begin(current); +} + +function util_render_make_node_preview(canvas: zui_node_canvas_t, node: zui_node_t, image: image_t, group: zui_node_canvas_t = null, parents: zui_node_t[] = null) { + let res: any = MakeMaterial.parse_node_preview_material(node, group, parents); + if (res == null || res.scon == null) return; + + if (util_render_screen_aligned_full_vb == null) { + util_render_create_screen_aligned_full_data(); + } + + let _scale_world: f32 = context_raw.paint_object.base.transform.scale_world; + context_raw.paint_object.base.transform.scale_world = 3.0; + transform_build_matrix(context_raw.paint_object.base.transform); + + g4_begin(image); + g4_set_pipeline(res.scon._.pipe_state); + uniforms_set_context_consts(res.scon, [""]); + uniforms_set_obj_consts(res.scon, context_raw.paint_object.base); + uniforms_set_material_consts(res.scon, res.mcon); + g4_set_vertex_buffer(util_render_screen_aligned_full_vb); + g4_set_index_buffer(util_render_screen_aligned_full_ib); + g4_draw(); + g4_end(); + + context_raw.paint_object.base.transform.scale_world = _scale_world; + transform_build_matrix(context_raw.paint_object.base.transform); +} + +function util_render_pick_pos_nor_tex() { + context_raw.pick_pos_nor_tex = true; + context_raw.pdirty = 1; + let _tool: workspace_tool_t = context_raw.tool; + context_raw.tool = workspace_tool_t.PICKER; + MakeMaterial.parse_paint_material(); + if (context_raw.paint2d) { + RenderPathPaint.set_plane_mesh(); + } + RenderPathPaint.commands_paint(false); + ///if krom_metal + // Flush command list + RenderPathPaint.commands_paint(false); + ///end + if (context_raw.paint2d) { + RenderPathPaint.restore_plane_mesh(); + } + context_raw.tool = _tool; + context_raw.pick_pos_nor_tex = false; + MakeMaterial.parse_paint_material(); + context_raw.pdirty = 0; +} + +function util_render_get_decal_mat(): mat4_t { + util_render_pick_pos_nor_tex(); + let decal_mat: mat4_t = mat4_identity(); + let loc: vec4_t = vec4_create(context_raw.posx_picked, context_raw.posy_picked, context_raw.posz_picked); + let rot: quat_t = quat_from_to(quat_create(), vec4_create(0.0, 0.0, -1.0), vec4_create(context_raw.norx_picked, context_raw.nory_picked, context_raw.norz_picked)); + let scale: vec4_t = vec4_create(context_raw.brush_radius * 0.5, context_raw.brush_radius * 0.5, context_raw.brush_radius * 0.5); + mat4_compose(decal_mat, loc, rot, scale); + return decal_mat; +} + +function util_render_create_screen_aligned_full_data() { + // Over-sized triangle + let data: f32[] = [-math_floor(32767 / 3), -math_floor(32767 / 3), 0, 32767, 0, 0, 0, 0, 0, 0, 0, 0, + 32767, -math_floor(32767 / 3), 0, 32767, 0, 0, 0, 0, 0, 0, 0, 0, + -math_floor(32767 / 3), 32767, 0, 32767, 0, 0, 0, 0, 0, 0, 0, 0]; + let indices: i32[] = [0, 1, 2]; + + // Mandatory vertex data names and sizes + let structure: vertex_struct_t = g4_vertex_struct_create(); + g4_vertex_struct_add(structure, "pos", vertex_data_t.I16_4X_NORM); + g4_vertex_struct_add(structure, "nor", vertex_data_t.I16_2X_NORM); + g4_vertex_struct_add(structure, "tex", vertex_data_t.I16_2X_NORM); + g4_vertex_struct_add(structure, "col", vertex_data_t.I16_4X_NORM); + util_render_screen_aligned_full_vb = g4_vertex_buffer_create(math_floor(data.length / math_floor(g4_vertex_struct_byte_size(structure) / 4)), structure, usage_t.STATIC); + let vertices: buffer_view_t = g4_vertex_buffer_lock(util_render_screen_aligned_full_vb); + for (let i: i32 = 0; i < math_floor(vertices.byteLength / 2); ++i) vertices.setInt16(i * 2, data[i], true); + g4_vertex_buffer_unlock(util_render_screen_aligned_full_vb); + + util_render_screen_aligned_full_ib = g4_index_buffer_create(indices.length); + let id: u32_array_t = g4_index_buffer_lock(util_render_screen_aligned_full_ib); + for (let i: i32 = 0; i < id.length; ++i) id[i] = indices[i]; + g4_index_buffer_unlock(util_render_screen_aligned_full_ib); +} + +///end diff --git a/base/Sources/util_uv.ts b/base/Sources/util_uv.ts new file mode 100644 index 00000000..758e394d --- /dev/null +++ b/base/Sources/util_uv.ts @@ -0,0 +1,187 @@ + +///if (is_paint || is_sculpt) + +let util_uv_uvmap: image_t = null; +let util_uv_uvmap_cached: bool = false; +let util_uv_trianglemap: image_t = null; +let util_uv_trianglemap_cached: bool = false; +let util_uv_dilatemap: image_t = null; +let util_uv_dilatemap_cached: bool = false; +let util_uv_uvislandmap: image_t = null; +let util_uv_uvislandmap_cached: bool = false; +let util_uv_dilate_bytes: ArrayBuffer = null; +let util_uv_pipe_dilate: pipeline_t = null; + +function util_uv_cache_uv_map() { + if (util_uv_uvmap != null && (util_uv_uvmap.width != config_get_texture_res_x() || util_uv_uvmap.height != config_get_texture_res_y())) { + image_unload(util_uv_uvmap); + util_uv_uvmap = null; + util_uv_uvmap_cached = false; + } + + if (util_uv_uvmap_cached) return; + + let res_x: i32 = config_get_texture_res_x(); + let res_y: i32 = config_get_texture_res_y(); + if (util_uv_uvmap == null) { + util_uv_uvmap = image_create_render_target(res_x, res_y); + } + + util_uv_uvmap_cached = true; + let merged: mesh_object_t = context_raw.merged_object; + let mesh: mesh_data_t = (context_raw.layer_filter == 0 && merged != null) ? + merged.data : context_raw.paint_object.data; + + let texa: i16_array_t = mesh.vertex_arrays[2].values; + let inda: u32_array_t = mesh.index_arrays[0].values; + g2_begin(util_uv_uvmap); + g2_clear(0x00000000); + g2_set_color(0xffcccccc); + let strength: f32 = res_x > 2048 ? 2.0 : 1.0; + let f: f32 = (1 / 32767) * util_uv_uvmap.width; + for (let i: i32 = 0; i < math_floor(inda.length / 3); ++i) { + let x1: f32 = (texa[inda[i * 3 ] * 2 ]) * f; + let x2: f32 = (texa[inda[i * 3 + 1] * 2 ]) * f; + let x3: f32 = (texa[inda[i * 3 + 2] * 2 ]) * f; + let y1: f32 = (texa[inda[i * 3 ] * 2 + 1]) * f; + let y2: f32 = (texa[inda[i * 3 + 1] * 2 + 1]) * f; + let y3: f32 = (texa[inda[i * 3 + 2] * 2 + 1]) * f; + g2_draw_line(x1, y1, x2, y2, strength); + g2_draw_line(x2, y2, x3, y3, strength); + g2_draw_line(x3, y3, x1, y1, strength); + } + g2_end(); +} + +function util_uv_cache_triangle_map() { + if (util_uv_trianglemap != null && (util_uv_trianglemap.width != config_get_texture_res_x() || util_uv_trianglemap.height != config_get_texture_res_y())) { + image_unload(util_uv_trianglemap); + util_uv_trianglemap = null; + util_uv_trianglemap_cached = false; + } + + if (util_uv_trianglemap_cached) return; + + if (util_uv_trianglemap == null) { + util_uv_trianglemap = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y()); + } + + util_uv_trianglemap_cached = true; + let merged: mesh_data_t = context_raw.merged_object != null ? context_raw.merged_object.data : context_raw.paint_object.data; + let mesh: mesh_data_t = merged; + let texa: i16_array_t = mesh.vertex_arrays[2].values; + let inda: u32_array_t = mesh.index_arrays[0].values; + g2_begin(util_uv_trianglemap); + g2_clear(0xff000000); + let f: f32 = (1 / 32767) * util_uv_trianglemap.width; + let color: i32 = 0xff000001; + for (let i: i32 = 0; i < math_floor(inda.length / 3); ++i) { + if (color == 0xffffffff) color = 0xff000001; + color++; + g2_set_color(color); + let x1: f32 = (texa[inda[i * 3 ] * 2 ]) * f; + let x2: f32 = (texa[inda[i * 3 + 1] * 2 ]) * f; + let x3: f32 = (texa[inda[i * 3 + 2] * 2 ]) * f; + let y1: f32 = (texa[inda[i * 3 ] * 2 + 1]) * f; + let y2: f32 = (texa[inda[i * 3 + 1] * 2 + 1]) * f; + let y3: f32 = (texa[inda[i * 3 + 2] * 2 + 1]) * f; + g2_fill_triangle(x1, y1, x2, y2, x3, y3); + } + g2_end(); +} + +function util_uv_cache_dilate_map() { + if (util_uv_dilatemap != null && (util_uv_dilatemap.width != config_get_texture_res_x() || util_uv_dilatemap.height != config_get_texture_res_y())) { + image_unload(util_uv_dilatemap); + util_uv_dilatemap = null; + util_uv_dilatemap_cached = false; + } + + if (util_uv_dilatemap_cached) return; + + if (util_uv_dilatemap == null) { + util_uv_dilatemap = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8); + } + + if (util_uv_pipe_dilate == null) { + util_uv_pipe_dilate = g4_pipeline_create(); + util_uv_pipe_dilate.vertex_shader = sys_get_shader("dilate_map.vert"); + util_uv_pipe_dilate.fragment_shader = sys_get_shader("dilate_map.frag"); + let vs: vertex_struct_t = g4_vertex_struct_create(); + ///if (krom_metal || krom_vulkan) + g4_vertex_struct_add(vs, "tex", vertex_data_t.I16_2X_NORM); + ///else + g4_vertex_struct_add(vs, "pos", vertex_data_t.I16_4X_NORM); + g4_vertex_struct_add(vs, "nor", vertex_data_t.I16_2X_NORM); + g4_vertex_struct_add(vs, "tex", vertex_data_t.I16_2X_NORM); + ///end + util_uv_pipe_dilate.input_layout = [vs]; + util_uv_pipe_dilate.depth_write = false; + util_uv_pipe_dilate.depth_mode = compare_mode_t.ALWAYS; + util_uv_pipe_dilate.color_attachments[0] = tex_format_t.R8; + g4_pipeline_compile(util_uv_pipe_dilate); + // dilateTexUnpack = getConstantLocation(pipeDilate, "texUnpack"); + } + + let mask: i32 = context_object_mask_used() ? SlotLayer.get_object_mask(context_raw.layer) : 0; + if (context_layer_filter_used()) mask = context_raw.layer_filter; + let geom: mesh_data_t = mask == 0 && context_raw.merged_object != null ? context_raw.merged_object.data : context_raw.paint_object.data; + g4_begin(util_uv_dilatemap); + g4_clear(0x00000000); + g4_set_pipeline(util_uv_pipe_dilate); + ///if (krom_metal || krom_vulkan) + g4_set_vertex_buffer(mesh_data_get(geom, [{name: "tex", data: "short2norm"}])); + ///else + g4_set_vertex_buffer(geom._.vertex_buffer); + ///end + g4_set_index_buffer(geom._.index_buffers[0]); + g4_draw(); + g4_end(); + util_uv_dilatemap_cached = true; + util_uv_dilate_bytes = null; +} + +function util_uv_cache_uv_island_map() { + util_uv_cache_dilate_map(); + if (util_uv_dilate_bytes == null) { + util_uv_dilate_bytes = image_get_pixels(util_uv_dilatemap); + } + util_render_pick_pos_nor_tex(); + let w: i32 = 2048; // config_get_texture_res_x() + let h: i32 = 2048; // config_get_texture_res_y() + let x: i32 = math_floor(context_raw.uvx_picked * w); + let y: i32 = math_floor(context_raw.uvy_picked * h); + let bytes: ArrayBuffer = new ArrayBuffer(w * h); + let view: DataView = new DataView(bytes); + let coords: coord_t[] = [{ x: x, y: y }]; + let r: i32 = math_floor(util_uv_dilatemap.width / w); + + let check = function (c: coord_t) { + if (c.x < 0 || c.x >= w || c.y < 0 || c.y >= h) return; + if (view.getUint8(c.y * w + c.x) == 255) return; + let dilate_view: DataView = new DataView(util_uv_dilate_bytes); + if (dilate_view.getUint8(c.y * r * util_uv_dilatemap.width + c.x * r) == 0) return; + view.setUint8(c.y * w + c.x, 255); + coords.push({ x: c.x + 1, y: c.y }); + coords.push({ x: c.x - 1, y: c.y }); + coords.push({ x: c.x, y: c.y + 1 }); + coords.push({ x: c.x, y: c.y - 1 }); + } + + while (coords.length > 0) { + check(coords.pop()); + } + + if (util_uv_uvislandmap != null) { + image_unload(util_uv_uvislandmap); + } + util_uv_uvislandmap = image_from_bytes(bytes, w, h, tex_format_t.R8); + util_uv_uvislandmap_cached = true; +} + +type coord_t = { + x?: i32; + y?: i32; +} + +///end diff --git a/base/Sources/viewport.ts b/base/Sources/viewport.ts index 4f6b32d0..ba377de6 100644 --- a/base/Sources/viewport.ts +++ b/base/Sources/viewport.ts @@ -3,7 +3,7 @@ function viewport_scale_to_bounds() { let po: mesh_object_t = context_raw.merged_object == null ? context_main_object() : context_raw.merged_object; let md: mesh_data_t = po.data; let aabb: vec4_t = mesh_data_calculate_aabb(md); - let r: f32 = Math.sqrt(aabb.x * aabb.x + aabb.y * aabb.y + aabb.z * aabb.z); + let r: f32 = math_sqrt(aabb.x * aabb.x + aabb.y * aabb.y + aabb.z * aabb.z); po = context_main_object(); po.base.transform.dim.x = aabb.x; po.base.transform.dim.y = aabb.y; @@ -60,8 +60,8 @@ function viewport_orbit(x: f32, y: f32) { function viewport_orbit_opposite() { let cam: camera_object_t = scene_camera; - let z: f32 = Math.abs(camera_object_look(cam).z) - 1.0; - (z < 0.0001 && z > -0.0001) ? viewport_orbit(0, Math.PI) : viewport_orbit(Math.PI, 0); + let z: f32 = math_abs(camera_object_look(cam).z) - 1.0; + (z < 0.0001 && z > -0.0001) ? viewport_orbit(0, math_pi()) : viewport_orbit(math_pi(), 0); } function viewport_zoom(f: f32) {