diff --git a/pwapp.js b/pwapp.js index b4f307b..cdbff6b 100644 --- a/pwapp.js +++ b/pwapp.js @@ -1,4 +1,4 @@ -const version = '0.2.1'; +const version = '0.2.2'; const cacheName = `ogzeditor-${version}`; const assetsToCache = [ '/OGZ-Editor/index.html', diff --git a/scripts/examples/ogzeditor_default.js b/scripts/examples/ogzeditor_default.js index 85b0838..ceacab0 100644 --- a/scripts/examples/ogzeditor_default.js +++ b/scripts/examples/ogzeditor_default.js @@ -5,11 +5,10 @@ Maps can be loaded in your client by performing the following steps: 1. Place the .OGZ files in the packages/base folder of your Sauerbraten or in the media/map of your Tesseract. 2. Use the /coop command or the /map command followed by the name of the .OGZ file in the game console to load the map. */ - // Modify the functions below to change the aspects of the .OGZ file: const TODAY_DATE = new Date().toLocaleDateString(); mapvars({ - "maptitle": `\f8Untitled Map by OGZ Editor \f5(${TODAY_DATE})`, + "maptitle": `\f8Untitled Map by OGZ Editor \f2(${TODAY_DATE})\n\f5salatielsauer.github.io/OGZ-Editor/`, "skyboxcolour": [0, 0, 0] }); @@ -22,7 +21,7 @@ entities([ You can use helper functions to generate arrays and objects: ogzeditor.ground(texture) // returns an [array] containing four 512x512 cubes with given texture. ogzeditor.cube(x, y, z, texture, gridpower) // returns an {object} containing a single cube with given properties. -ogzeditor.text(text, x, y, z, texture, gridpower, rotate) // returns an [array] containing cubes that form a given text. +ogzeditor.text(text, x, y, z, texture, gridpower, yaw, pitch, roll) // returns an [array] containing cubes that form a given text. */ const RANDOM_TEXTURE = () => Math.round(Math.random()*1704); geometry(()=>{ @@ -30,10 +29,11 @@ geometry(()=>{ let gridpower = 3; for (let i = 0; i <= 5; i += 1) { cubes.push(ogzeditor.cube(512, 512, 512 + (1 << gridpower)*i, RANDOM_TEXTURE(), gridpower)); // tower of cubes - cubes.push(ogzeditor.sphere(350, 412, 630, 0, RANDOM_TEXTURE(), 32-(1 << gridpower)*i)); // spheres within spheres + cubes.push(ogzeditor.sphere(350, 390, 630, 0, RANDOM_TEXTURE(), 32-(1 << gridpower)*i)); // spheres within spheres } - cubes.push({x: 512, y: 512, z: 512, g: 1, af: 1377, vcolor: [1, 0, 1], vscroll: [0.001, 0]}); - cubes.push(ogzeditor.text(`OGZ Editor\n${TODAY_DATE}`, 400, 412, 630, 1704, 2)); - cubes.push(ogzeditor.text(`this is an editable text :)`, 400, 412, 560, RANDOM_TEXTURE(), 0)); + cubes.push(ogzeditor.text(`^f0>^f1OGZ Editor\n^f0>^f3${TODAY_DATE}`, 400, 390, 630, 1460, 2)); + cubes.push(ogzeditor.text(`^f7this is an ^f0editable ^f~text\n^f~with ^f0>^f1c^f2o^f3l^f4o^f5r^f6s^f8< ^f~support! ^f8:)`, 400, 390, 560, 1462, 0)); + cubes.push(_addKleinBottle(512, 600, 800, 1, 1711, 32, 64, 128)); + cubes.push(ogzeditor.text(`^f7Klein Bottle`, 650, 512, 920, 1462, 2, 180, -30)); return cubes; }); \ No newline at end of file diff --git a/scripts/examples/ogzeditor_heightmap.js b/scripts/examples/ogzeditor_heightmap.js index 0a62ba6..f6dacdd 100644 --- a/scripts/examples/ogzeditor_heightmap.js +++ b/scripts/examples/ogzeditor_heightmap.js @@ -14,5 +14,5 @@ mapvars({ entities([]); // draws image with index A, quality B, at position CxDxE with gridpower F. -// G, H and I are related to the image orientation, J is the heightmap max height. -geometry(() => ogzeditor.image(0, 50, 512, 512, 512, 1, 0, 0, 0, 3)); \ No newline at end of file +// G (yaw), H (pitch) and I (roll) are related to the image orientation, J is the heightmap max height. +geometry(() => ogzeditor.image(0, 50, 512, 512, 512, 1, 0, 90, 0, 3)); \ No newline at end of file diff --git a/scripts/examples/ogzeditor_mri_helper.js b/scripts/examples/ogzeditor_mri_helper.js new file mode 100644 index 0000000..7376a17 --- /dev/null +++ b/scripts/examples/ogzeditor_mri_helper.js @@ -0,0 +1,17 @@ + +// This preset uses the image helper to draw a sequence of images on different layers. +// You can upload MRI (Magnetic Resonance Imaging) sequences to reconstruct the model in-game. +// example: https://i.imgur.com/UtRFtHB.gif + +mapvars({ + 'skyboxcolour': [0, 0, 0], + 'skylight': [255, 255, 255], + 'maptitle': 'OGZ Editor MRI Helper example', + 'mapsize': 1024 +}); + +entities([]); + +geometry(() => ogzeditor.image([0, ogzeditor.asset.frames.length], 35, 512, 512, 0, 0, 0, 90, 0, 1, 2, true, 3, (colors, position) => { + return (colors.heightValue >= 5); +})); \ No newline at end of file diff --git a/scripts/examples/ogzeditor_subtractive_geometry.js b/scripts/examples/ogzeditor_subtractive_geometry.js new file mode 100644 index 0000000..a4f345f --- /dev/null +++ b/scripts/examples/ogzeditor_subtractive_geometry.js @@ -0,0 +1,40 @@ + +// This preset starts with full geometry and selectively removes chunks to create structured patterns. + +mapvars({ + "maptitle": `\f8*thirdevermap*`, + "skyboxcolour": [0, 0, 0], + "ambient": [1, 1, 1], + "mapsize": 2048 +}); + +const ents = [{x: 1120, y: 1120, z: 900, t: 3, at0: 135}]; + +geometry(()=>{ + let cubes = []; + ogzeditor.loopmap(1024, 9, (x, y, z) => cubes.push({x, y, z, g: 9, tp: 2, ft: 3, rt: 4, lf: 5, bk: 6, dn: 7})); + + ogzeditor.loopmap(1024, 7, (x, y, z, i) => { + if (i%2) { + cubes.push({x, y, z, g: 7, t: 1}); + ents.push({x, y, z: z+5, t: 1, at0: 200, at1: z/(i/90), at2: y/(i/90), at3: x/10}); + } + }); + + ogzeditor.loopmap(1024, 6, (x, y, z, i) => { + if (i%2) cubes.push({x, y, z, g: 6, t: 1}); + }); + + ogzeditor.loopmap(1024, 6, (x, y, z, i) => { + if ((x+y+z)/3 % 2 ) cubes.push({x, y, z, g: 6, t: 1}); + }); + + ogzeditor.loopmap(1024, 5, (x, y, z, i) => { + if ((x+y+z)/3 % 2 && i%2 ) { + cubes.push({x, y, z, g: 5, t: 1}); + } + }); + return cubes; +}); + +entities(ents); \ No newline at end of file diff --git a/scripts/examples/ogzeditor_textrotation.js b/scripts/examples/ogzeditor_textrotation.js new file mode 100644 index 0000000..5e9bb74 --- /dev/null +++ b/scripts/examples/ogzeditor_textrotation.js @@ -0,0 +1,22 @@ + + +mapvars({ + "maptitle": `\f8Simple Text Yaw/Pitch/Roll rotation.`, + "skyboxcolour": [0, 0, 0] +}); + +entities([ + {x: 512, y: 650, z: 512, t: 3, at0: 180} +]); + +geometry(()=>{ + let cubes = ogzeditor.ground(6); + let color = 0; + for (let i = 0; i < 19; i++) { + // texts can be rotated on 3 axes: yaw, pitch and roll. + cubes.push(ogzeditor.text(`^f${color}----^f~OGZ Editor----`, 512+(i*5), 512-(i*5), 600-i, 1462, 1, 0, i*10, i*10)) + color = color == 8 ? 0 : color+1; + } + + return cubes; +}); \ No newline at end of file diff --git a/scripts/ogzeditor_presets.js b/scripts/ogzeditor_presets.js index 8b0905b..65a20d6 100644 --- a/scripts/ogzeditor_presets.js +++ b/scripts/ogzeditor_presets.js @@ -6,11 +6,29 @@ const ogzeditor_presets = [ "file": "scripts/examples/ogzeditor_default.js" }, { - "name": "MRI Gif Extractor", + "name": "Text 3D Rotation", + "author": "SalatielSauer", + "url": "https://github.com/SalatielSauer/", + "file": "scripts/examples/ogzeditor_textrotation.js" + }, + { + "name": "Subtractive Geometry", + "author": "SalatielSauer", + "url": "https://github.com/SalatielSauer/", + "file": "scripts/examples/ogzeditor_subtractive_geometry.js" + }, + { + "name": "MRI GIF Extractor (no-helper)", "author": "SalatielSauer", "url": "https://github.com/SalatielSauer/", "file": "scripts/examples/ogzeditor_mri.js" }, + { + "name": "MRI GIF Extractor (helper)", + "author": "SalatielSauer", + "url": "https://github.com/SalatielSauer/", + "file": "scripts/examples/ogzeditor_mri_helper.js" + }, { "name": "Simple 2D Image (no-helper)", "author": "SalatielSauer", @@ -73,22 +91,27 @@ const helpers_descriptions = { params: ['centerX', 'centerY', 'centerZ', 'gridpower', 'texture', 'radius', 'segments', 'rings'] }, 'ogzeditor.text': { - comment: 'Adds a text to the map.', - params: ['text', 'startX', 'startY', 'startZ', 'texture', 'gridpower', 'rotate'] + comment: 'Adds a text to the map, supports color markers (^fN) and 3D rotation (yaw, pitch, roll).', + params: ['text', 'startX', 'startY', 'startZ', 'texture', 'gridpower', 'yaw', 'pitch', 'roll'], + details: { + 0: `Predefined colors can be chosen with the ^fN marker, where N is a number from 0 to 8.\nExample: '^f2hello ^f8world'` + } }, 'ogzeditor.loopmap': { - comment: 'Loops over every position with a given gridpower, returns x y z values as callback', + comment: 'Loops over every position with a given gridpower, returns x y z i values as callback.
⚠️This will crash easily if you set the gridpower too low.', params: ['worldSize', 'gridpower', 'callback'] }, 'ogzeditor.image': { - comment: 'Adds one or more flat images with optional heightmap support, also allows changing orientation.
Use the Upload button to add assets.', - params: ['assetID', 'quality', 'startX', 'startY', 'startZ', 'gridpower', 'yaw', 'layout', 'direction', 'heightmap'], + comment: 'Adds one or more flat images with optional heightmap support, also allows changing 3D orientation.
Use the Upload button to add assets.', + params: ['assetID', 'quality', 'startX', 'startY', 'startZ', 'gridpower', 'yaw', 'pitch', 'roll', 'heightmap', 'direction', 'localPivot', 'layerOffset', 'callback'], details: { 0: 'Either an integer or an array containing the [start, end] of a range (for multiple frames)', - 1: 'An integer between 10 and 100', - 7: '0 = horizontal (XY plane), 1 = vertical (XZ plane), 2 = vertical (YZ plane)', - 8: '0 = extend along X, 1 = extend along Y, 2 = extend along Z (up)', - 9: 'The maximum height to be applied from the pixel brightness (multiplied by 16), 0 to disable.' + 1: 'A resolution percentage between 5 and 100', + 9: 'The maximum height to be applied from the pixel brightness (multiplied by 16), 0 to disable.', + 10: 'Direction to place next frames: 0 = right, 1 = left, 2 = up, 3 = down, 4 = front, 5 = back', + 11: 'Use local position for rotation (1) or start position (0).', + 12: 'Defines the distance between subsequent frames.', + 13: 'The callback is executed at each pixel of each frame, contains parameters ({r, g, b, a, brightness, heightValue, width, height}, {x, y, z, i}),\nYou can skip a pixel by returning false in the callback.\nYou can return an array [r, g, b, a] to replace the pixel color in the callback.' } }, 'ogzeditor.cubeRoom': {