From d17677e2ff15ff037740545bc6f3fedc438f204a Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Mon, 30 Nov 2020 23:01:47 -0500 Subject: [PATCH] add new stack class --- src/kiri/stack.js | 218 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 src/kiri/stack.js diff --git a/src/kiri/stack.js b/src/kiri/stack.js new file mode 100644 index 00000000..f1733066 --- /dev/null +++ b/src/kiri/stack.js @@ -0,0 +1,218 @@ +/** Copyright Stewart Allen -- All Rights Reserved */ + +"use strict"; + +(function() { + + class Stack { + constructor(view) { + this.view = view.newGroup(); + this.slices = []; + this.freeMem = true; + } + + size() { + return this.slices.length; + } + + setVisible(newMin, newMax) { + for (let i=0, s=this.slices, len=s.length; i= newMin && i <= newMax; + } + } + + addLayers(layers) { + // each slice gets a group so the slice can be toggled efficiently + let group = this.view.newGroup(); + this.slices.push(group); + let map = this.renderLayers(layers, group); + // by default release memory after layers are rendered + if (this.freeMem) { + layers.init(); + } + // return map of layers to materials (so they can be toggled on/off) + return map; + } + + renderLayers(layers, group) { + const map = {} + for (const [label, layer] of Object.entries(layers.layers)) { + map[label] = this.renderLayer(layer, group); + } + return map; + } + + renderLayer(layer, group) { + function addPoly(vertices, poly) { + const points = poly.points, len = points.length; + for (let i=1; i m.visible = defstate); + for (let i=0; i { mat.push(newMat(c)) }); + } else { + mat.push(newMat(color)); + } + mat.forEach(m => m.visible = defstate); + const geo = new THREE.BufferGeometry(); + if (faces.toFloat32) { + geo.setAttribute('position', new THREE.BufferAttribute(faces.toFloat32(), 3)); + } else { + geo.setAttribute('position', new THREE.BufferAttribute(faces, 3)); + } + geo.computeFaceNormals(); + geo.computeVertexNormals(); + if (cface) { + cface.forEach((c, i) => geo.addGroup(c.start, c.count, i)); + } else { + geo.addGroup(0, Infinity, 0); + } + const mesh = new THREE.Mesh(geo, mat); + mesh.castShadow = true; + mesh.receiveShadow = true; + group.add(mesh); + mats.appendAll(mat); + } + if (paths.length) { + const mat = []; + if (cpath) { + cpath.forEach(c => { mat.push(newMat(c)) }); + } else { + mat.push(newMat(color)); + } + mat.forEach(m => m.visible = defstate); + // const mat = newMat(data); + paths.forEach((path, i) => { + const { index, faces, z, colors } = path; + const geo = new THREE.BufferGeometry(); + geo.setAttribute('position', new THREE.BufferAttribute(faces, 3)); + geo.setIndex(index); + geo.computeFaceNormals(); + geo.computeVertexNormals(); + if (cpath) { + cpath.forEach((c, i) => geo.addGroup(c.start, c.count, i)); + } else { + geo.addGroup(0, Infinity, 0); + } + const mesh = new THREE.Mesh(geo, mat); + mesh.position.z = z; + mesh.castShadow = true; + mesh.receiveShadow = true; + group.add(mesh); + }); + mats.appendAll(mat); + } + + mats.forEach(mat => mat.visible = defstate); + return mats; + } + } + + self.kiri.Stack = Stack; + + let shininess = 15, + specular = 0x444444, + emissive = 0x101010, + metalness = 0, + roughness = 0.3, + newMat = createPhongMaterial; + + function createLineMaterial(color, array) { + const opacity = color.opacity || 1; + const mat = new THREE.LineBasicMaterial({ + transparent: true, + opacity: opacity, + color: color.line + }); + if (array) { + array.push(mat); + } + return mat; + } + + function createStandardMaterial(color) { + return new THREE.MeshStandardMaterial({ + emissive, + roughness, + metalness, + transparent: color.opacity != 1, + opacity: color.opacity || 1, + color: color.face, + side: THREE.DoubleSide + }); + } + + function createPhongMaterial(color) { + return new THREE.MeshPhongMaterial({ + shininess, + specular, + transparent: color.opacity != 1, + opacity: color.opacity || 1, + color: color.face, + side: THREE.DoubleSide + }); + } + +})();