UNPKG

polygonjs-engine

Version:

node-based webgl 3D engine https://polygonjs.com

212 lines (211 loc) 6.48 kB
import {Vector4 as Vector42} from "three/src/math/Vector4"; import {Vector3 as Vector32} from "three/src/math/Vector3"; import {Vector2 as Vector22} from "three/src/math/Vector2"; import {CoreAttribute} from "./Attribute"; import {CoreEntity} from "./Entity"; import {CoreType} from "../Type"; const ATTRIB_NAMES = { POSITION: "position", NORMAL: "normal" }; var ComponentName; (function(ComponentName2) { ComponentName2["x"] = "x"; ComponentName2["y"] = "y"; ComponentName2["z"] = "z"; ComponentName2["w"] = "w"; ComponentName2["r"] = "r"; ComponentName2["g"] = "g"; ComponentName2["b"] = "b"; })(ComponentName || (ComponentName = {})); const COMPONENT_INDICES = { x: 0, y: 1, z: 2, w: 3, r: 0, g: 1, b: 2 }; const PTNUM = "ptnum"; const DOT = "."; export class CorePoint extends CoreEntity { constructor(_core_geometry, _index) { super(_index); this._core_geometry = _core_geometry; this._geometry = this._core_geometry.geometry(); } core_geometry() { return this._core_geometry; } geometry() { return this._geometry = this._geometry || this._core_geometry.geometry(); } attribSize(name) { name = CoreAttribute.remap_name(name); return this._geometry.getAttribute(name).itemSize; } hasAttrib(name) { const remapped_name = CoreAttribute.remap_name(name); return this._core_geometry.hasAttrib(remapped_name); } attribValue(name, target) { if (name === PTNUM) { return this.index(); } else { let component_name = null; let component_index = null; if (name[name.length - 2] === DOT) { component_name = name[name.length - 1]; component_index = COMPONENT_INDICES[component_name]; name = name.substring(0, name.length - 2); } const remaped_name = CoreAttribute.remap_name(name); const attrib = this._geometry.getAttribute(remaped_name); if (attrib) { const {array} = attrib; if (this._core_geometry.isAttribIndexed(remaped_name)) { return this.indexedAttribValue(remaped_name); } else { const size = attrib.itemSize; const start_index = this._index * size; if (component_index == null) { switch (size) { case 1: return array[start_index]; break; case 2: target = target || new Vector22(); target.fromArray(array, start_index); return target; break; case 3: target = target || new Vector32(); target.fromArray(array, start_index); return target; break; case 4: target = target || new Vector42(); target.fromArray(array, start_index); return target; break; default: throw `size not valid (${size})`; } } else { switch (size) { case 1: return array[start_index]; break; default: return array[start_index + component_index]; } } } } else { const message = `attrib ${name} not found. availables are: ${Object.keys(this._geometry.attributes || {}).join(",")}`; console.warn(message); throw message; } } } indexedAttribValue(name) { const value_index = this.attribValueIndex(name); return this._core_geometry.userDataAttrib(name)[value_index]; } stringAttribValue(name) { return this.indexedAttribValue(name); } attribValueIndex(name) { if (this._core_geometry.isAttribIndexed(name)) { return this._geometry.getAttribute(name).array[this._index]; } else { return -1; } } isAttribIndexed(name) { return this._core_geometry.isAttribIndexed(name); } position(target) { const {array} = this._geometry.getAttribute(ATTRIB_NAMES.POSITION); if (target) { return target.fromArray(array, this._index * 3); } else { this._position = this._position || new Vector32(); return this._position.fromArray(array, this._index * 3); } } setPosition(new_position) { this.setAttribValueVector3(ATTRIB_NAMES.POSITION, new_position); } normal() { const {array} = this._geometry.getAttribute(ATTRIB_NAMES.NORMAL); this._normal = this._normal || new Vector32(); return this._normal.fromArray(array, this._index * 3); } setNormal(new_normal) { return this.setAttribValueVector3(ATTRIB_NAMES.NORMAL, new_normal); } setAttribValue(name, value) { if (value == null) { return; } if (name == null) { throw "Point.set_attrib_value requires a name"; } const attrib = this._geometry.getAttribute(name); const array = attrib.array; const attrib_size = attrib.itemSize; if (CoreType.isArray(value)) { for (let i = 0; i < attrib_size; i++) { array[this._index * attrib_size + i] = value[i]; } return; } switch (attrib_size) { case 1: array[this._index] = value; break; case 2: const v2 = value; array[this._index * 2 + 0] = v2.x; array[this._index * 2 + 1] = v2.y; break; case 3: const is_color = value.r != null; if (is_color) { const col = value; array[this._index * 3 + 0] = col.r; array[this._index * 3 + 1] = col.g; array[this._index * 3 + 2] = col.b; } else { const v3 = value; array[this._index * 3 + 0] = v3.x; array[this._index * 3 + 1] = v3.y; array[this._index * 3 + 2] = v3.z; } break; default: console.warn(`Point.set_attrib_value does not yet allow attrib size ${attrib_size}`); throw `attrib size ${attrib_size} not implemented`; } } setAttribValueVector3(name, value) { if (value == null) { return; } if (name == null) { throw "Point.set_attrib_value requires a name"; } const attrib = this._geometry.getAttribute(name); const array = attrib.array; const i = this._index * 3; array[i] = value.x; array[i + 1] = value.y; array[i + 2] = value.z; } setAttribIndex(name, new_value_index) { const array = this._geometry.getAttribute(name).array; return array[this._index] = new_value_index; } }