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': {