polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
212 lines (211 loc) • 6.48 kB
JavaScript
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;
}
}