diff --git a/app.js b/app.js index f65154b4..1b2a8fb7 100644 --- a/app.js +++ b/app.js @@ -290,6 +290,7 @@ const script = { "ext/pngjs", "license", "ext/clip2", + "ext/earcut", "add/array", "add/three", "add/class", diff --git a/src/kiri/codec.js b/src/kiri/codec.js index e69214d6..a9d19d3d 100644 --- a/src/kiri/codec.js +++ b/src/kiri/codec.js @@ -16,6 +16,9 @@ }; function allocFloat32Array(len) { + if (Array.isArray(len)) { + return new Float32Array(len); + } return new Float32Array(len); } @@ -121,7 +124,7 @@ data: Object.values(this.layers).map(layer => { return { polys: encode(layer.polys, state), lines: encodePointArray(layer.lines, state), - faces: encodePointArray(layer.faces, state), + faces: codec.allocFloat32Array(layer.faces), color: layer.color } }) }; @@ -134,7 +137,7 @@ render.layers[v.layers[i]] = { polys: decode(v.data[i].polys, state), lines: decodePointArray(v.data[i].lines), - faces: decodePointArray(v.data[i].faces), + faces: v.data[i].faces, color: v.data[i].color }; } diff --git a/src/kiri/render.js b/src/kiri/render.js index ed9a5ee5..ce5b6a91 100644 --- a/src/kiri/render.js +++ b/src/kiri/render.js @@ -3,18 +3,29 @@ "use strict"; (function() { + const KIRI = self.kiri, BASE = self.base, POLY = BASE.polygons; + class Render { constructor() { this.layers = {}; } - setLayer(layer, color) { + setLayer(layer, colors) { let layers = this.layers; + if (typeof(colors) === 'number') { + colors = { + line: color, + face: color + }; + } this.current = layers[layer] = layers[layer] || { lines: [], polys: [], faces: [], - color: color || 0 + color: colors || { + line: 0, + face: 0 + } }; return this; } @@ -44,6 +55,33 @@ } return this; } + + addFlat(polys, options) { + let opts = options || {}; + let offset = opts.offset || 1; + if (Array.isArray(polys)) { + polys = POLY.flatten(polys, [], true); + } else { + polys = POLY.flatten([polys], [], true); + } + if (!polys.length) { + return; + } + const z = polys[0].getZ(), faces = this.current.faces; + polys.forEach(poly => { + let exp = []; + POLY.offset([poly], offset/2, { z, outs: exp, flat: true }); + POLY.offset([poly], -offset/2, { z, outs: exp, flat: true }); + if (opts.outline) { + this.addPolys(exp.clone()); + } + POLY.nest(exp).forEach((poly,i) => { + poly.earcut().forEach(ep => { + ep.forEachPoint(p => { faces.push(p.x, p.y, p.z) }); + }); + }); + }); + } } self.kiri.Render = Render; diff --git a/src/mode/cam/client.js b/src/mode/cam/client.js index db617d89..a84bc5fe 100644 --- a/src/mode/cam/client.js +++ b/src/mode/cam/client.js @@ -46,18 +46,39 @@ } for (const [layer, data] of Object.entries(render.layers)) { - const mat = new THREE.LineBasicMaterial({ color: data.color }); - const geo = new THREE.Geometry(), vertices = geo.vertices; - const polys = data.polys; - for (let i=0, il=polys.length; i