grid-apps-cmms/src/kiri/codec.js

248 lines
6.7 KiB
JavaScript
Raw Normal View History

2020-06-03 22:39:30 -04:00
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
2017-04-18 22:22:29 -04:00
2017-04-18 17:09:33 -04:00
"use strict";
(function() {
if (self.kiri.codec) return;
2020-06-03 22:39:30 -04:00
const BASE = self.base, KIRI = self.kiri, handlers = {};
2017-04-18 17:09:33 -04:00
2020-06-16 11:08:50 -04:00
const codec = KIRI.codec = {
2017-04-18 17:09:33 -04:00
encode: encode,
decode: decode,
2020-06-16 11:08:50 -04:00
registerDecoder: registerDecoder,
allocFloat32Array: allocFloat32Array
2017-04-18 17:09:33 -04:00
};
2020-06-16 11:08:50 -04:00
function allocFloat32Array(len) {
2020-11-06 22:33:56 -05:00
if (Array.isArray(len)) {
return new Float32Array(len);
}
2020-06-16 11:08:50 -04:00
return new Float32Array(len);
}
2017-04-18 17:09:33 -04:00
function encode(o, state) {
state = state || {};
if (o === null) return null;
if (o === undefined) return undefined;
if (Array.isArray(o)) {
2020-06-03 22:39:30 -04:00
let arr = new Array(o.length), i=0;
2017-04-18 17:09:33 -04:00
while (i < o.length) arr[i] = encode(o[i++], state);
return arr;
}
switch (typeof(o)) {
case 'string':
case 'number':
return o;
case 'object':
if (o.encode) return o.encode(state);
return genOEncode(o, state);
}
return null;
}
function decode(o, state) {
state = state || {};
if (o === null) return null;
if (o === undefined) return undefined;
if (Array.isArray(o)) {
2020-06-03 22:39:30 -04:00
for (let i=0; i < o.length; i++) o[i] = decode(o[i],state);
2017-04-18 17:09:33 -04:00
return o;
}
switch (typeof(o)) {
case 'string':
case 'number':
return o;
case 'object':
if (o.type && handlers[o.type]) return handlers[o.type](o,state);
return genODecode(o, state);
}
return null;
}
function registerDecoder(type, handler) {
handlers[type] = handler;
}
function genOEncode(o, state) {
if (o instanceof Float32Array) return o;
2020-06-03 22:39:30 -04:00
let out = {};
for (let k in o) {
2017-04-18 17:09:33 -04:00
if (o.hasOwnProperty(k)) out[k] = encode(o[k], state);
}
return out;
}
function genODecode(o, state) {
if (o instanceof Float32Array) return o;
2020-06-03 22:39:30 -04:00
let out = {};
for (let k in o) {
2017-04-18 17:09:33 -04:00
if (o.hasOwnProperty(k)) out[k] = decode(o[k], state);
}
return out;
}
/** ******************************************************************
* Object CODEC Functions
******************************************************************* */
2020-06-03 22:39:30 -04:00
KIRI.Slice.prototype.encode = function(state) {
2017-04-18 17:09:33 -04:00
return {
type: 'slice',
z: this.z,
index: this.index,
render: encode(this.render, state)
2017-04-18 17:09:33 -04:00
};
};
registerDecoder('slice', function(v, state) {
2020-06-03 22:39:30 -04:00
let slice = KIRI.newSlice(v.z, state.mesh ? state.mesh.newGroup() : null);
2017-04-18 17:09:33 -04:00
slice.index = v.index;
slice.render = decode(v.render, state)
2017-04-18 17:09:33 -04:00
return slice;
});
KIRI.Render.prototype.encode = function(state) {
let enc = {
type: 'render',
layers: Object.keys(this.layers),
data: Object.values(this.layers).map(layer => { return {
polys: encode(layer.polys, state),
lines: encodePointArray(layer.lines, state),
2020-11-06 22:33:56 -05:00
faces: codec.allocFloat32Array(layer.faces),
2020-11-13 13:52:35 -05:00
cface: layer.cface,
2020-11-06 23:51:58 -05:00
color: layer.color,
paths: layer.paths,
cpath: layer.cpath,
off: layer.off
} })
};
return enc;
};
registerDecoder('render', function(v, state) {
let render = new KIRI.Render();
for (let i=0; i<v.layers.length; i++) {
render.layers[v.layers[i]] = {
polys: decode(v.data[i].polys, state),
2020-11-09 19:22:28 -05:00
cpoly: v.data[i].cpoly,
lines: decodePointArray(v.data[i].lines),
2020-11-06 22:33:56 -05:00
faces: v.data[i].faces,
2020-11-13 13:52:35 -05:00
cface: v.data[i].cface,
2020-11-06 23:51:58 -05:00
color: v.data[i].color,
paths: v.data[i].paths,
cpath: v.data[i].cpath,
off: v.data[i].off
};
}
return render;
});
2020-06-03 22:39:30 -04:00
KIRI.Top.prototype.encode = function(state) {
2017-04-18 17:09:33 -04:00
return {
type: 'top',
poly: encode(this.poly, state),
};
};
registerDecoder('top', function(v, state) {
2020-06-03 22:39:30 -04:00
let top = KIRI.newTop(decode(v.poly, state));
2017-04-18 17:09:33 -04:00
return top;
});
2020-05-06 14:04:43 -04:00
function encodePointArray(points, state) {
2017-04-18 17:09:33 -04:00
if (!points) return null;
2020-06-16 11:08:50 -04:00
let array = codec.allocFloat32Array(points.length * 3),
2017-04-18 17:09:33 -04:00
pos = 0;
points.forEach(function(point) {
2020-05-06 14:04:43 -04:00
if (state.rotate) {
if (state.centerz) {
point.z -= state.centerz;
}
let v = new THREE.Vector3(point.x, point.y, point.z);
v.applyMatrix4(state.rotate);
point = {x: v.x, y: v.y, z: v.z};
if (state.centerz) {
point.z += state.centerz;
}
if (state.movez) {
point.z -= state.movez;
}
}
2017-04-18 17:09:33 -04:00
array[pos++] = point.x;
array[pos++] = point.y;
array[pos++] = point.z;
});
return array;
}
function decodePointArray(array) {
if (!array) return null;
2020-06-03 22:39:30 -04:00
let vid = 0,
2017-04-18 17:09:33 -04:00
pid = 0,
points = new Array(array.length/3);
while (vid < array.length) {
2020-06-03 22:39:30 -04:00
points[pid++] = BASE.newPoint(array[vid++], array[vid++], array[vid++]);
2017-04-18 17:09:33 -04:00
}
return points;
}
2020-06-03 22:39:30 -04:00
BASE.Polygon.prototype.encode = function(state) {
2017-04-18 17:09:33 -04:00
if (!state.poly) state.poly = {};
2020-06-03 22:39:30 -04:00
let cached = state.poly[this.id];
2017-04-18 17:09:33 -04:00
if (cached) {
2020-11-09 19:22:28 -05:00
return { type: 'poly', ref: this.id };
2017-04-18 17:09:33 -04:00
}
state.poly[this.id] = this;
return {
type: 'poly',
id: this.id,
2020-05-06 14:04:43 -04:00
array: encodePointArray(this.points, state),
2017-04-18 17:09:33 -04:00
open: this.isOpen(),
inner: encode(this.inner, state),
parent: encode(this.parent, state),
2020-11-09 19:22:28 -05:00
depth: this.depth,
color: this.color
2017-04-18 17:09:33 -04:00
};
};
registerDecoder('poly', function(v, state) {
if (!state.poly) state.poly = {};
if (v.ref) return state.poly[v.ref];
2020-06-03 22:39:30 -04:00
let poly = BASE.newPolygon(),
2017-04-18 17:09:33 -04:00
vid = 0;
while (vid < v.array.length) {
2020-06-03 22:39:30 -04:00
poly.push(BASE.newPoint(v.array[vid++], v.array[vid++], v.array[vid++]));
2017-04-18 17:09:33 -04:00
}
poly.id = v.id;
poly.open = v.open;
state.poly[v.id] = poly;
poly.inner = decode(v.inner, state);
poly.parent = decode(v.parent, state);
poly.depth = v.depth;
2020-11-09 19:22:28 -05:00
poly.color = v.color;
2017-04-18 17:09:33 -04:00
return poly;
});
})();