cables_dev/cables/src/core/cg/cg_geom.js
- // import { vec2, vec3 } from "gl-matrix";
- import { Logger } from "cables-shared-client";
- import { UTILS } from "../utils.js";
- import { BoundingBox } from "./cg_boundingbox.js";
-
- /**
- * a geometry contains all information about a mesh, vertices, texturecoordinates etc. etc.
- * @namespace external:CGL#Geometry
- * @param {String} name
- * @class
- * @example
- * // create a triangle with all attributes
- * const geom=new Geometry("triangle"),
- *
- * geom.vertices = [
- * 0.0, sizeH.get(), 0.0,
- * -sizeW.get(), -sizeH.get(), 0.0,
- * sizeW.get(), -sizeH.get(), 0.0 ];
- *
- * geom.vertexNormals = [
- * 0.0, 0.0, 1.0,
- * 0.0, 0.0, 1.0,
- * 0.0, 0.0, 1.0 ];
- *
- * geom.tangents = [
- * 1,0,0,
- * 1,0,0,
- * 1,0,0 ];
- *
- * geom.biTangents = [
- * 0,1,0,
- * 0,1,0,
- * 0,1,0 ];
- *
- * geom.texCoords = [
- * 0.5, 0.0,
- * 1.0, 1.0,
- * 0.0, 1.0, ];
- *
- * geom.verticesIndices = [
- * 0, 1, 2 ];
- *
- */
- const Geometry = function (name)
- {
- this.name = name || "unknown";
- this._log = new Logger("cgl_geometry");
-
- this.faceVertCount = 3;
- this.glPrimitive = null;
- this._attributes = {};
-
- this._vertices = [];
- this.verticesIndices = [];
-
- this.isGeometry = true;
-
- this.morphTargets = [];
-
- Object.defineProperty(this, "vertices", {
- get()
- {
- return this._vertices;
- },
- set(v)
- {
- this.setVertices(v);
- },
- });
-
- Object.defineProperty(this, "texCoords", {
- get()
- {
- const att = this.getAttribute("texCoords");
- if (!att) return [];
- return att.data;
- },
- set(v)
- {
- this.setAttribute("texCoords", v, 2);
- },
- });
-
- Object.defineProperty(this, "vertexNormals", {
- get()
- {
- const att = this.getAttribute("vertexNormals");
- if (!att) return [];
- return att.data;
- },
- set(v)
- {
- this.setAttribute("vertexNormals", v, 3);
- },
- });
-
- Object.defineProperty(this, "tangents", {
- get()
- {
- const att = this.getAttribute("tangents");
- if (!att) return [];
- return att.data;
- },
- set(v)
- {
- this.setAttribute("tangents", v, 3);
- },
- });
-
- Object.defineProperty(this, "biTangents", {
- get()
- {
- const att = this.getAttribute("biTangents");
- if (!att) return [];
- return att.data;
- },
- set(v)
- {
- this.setAttribute("biTangents", v, 3);
- },
- });
-
- Object.defineProperty(this, "vertexColors", {
- get()
- {
- const att = this.getAttribute("vertexColors");
- if (!att) return [];
- return att.data;
- },
- set(v)
- {
- this.setAttribute("vertexColors", v, 4);
- },
- });
- };
-
- /**
- * @function clear
- * @memberof Geometry
- * @instance
- * @description clear all buffers/set them to length 0
- */
- Geometry.prototype.clear = function ()
- {
- this._vertices = new Float32Array([]);
- this.verticesIndices = [];
- this.texCoords = new Float32Array([]);
- this.vertexNormals = new Float32Array([]);
- this.tangents = [];
- this.biTangents = [];
- this._attributes = {};
- };
-
-
-
- /**
- * @function getAttributes
- @memberof Geometry
- * @instance
- * @return {Array<Object>} returns array of attribute objects
- */
- Geometry.prototype.getAttributes = function ()
- {
- return this._attributes;
- };
-
- /**
- * @function getAttribute
- * @memberof Geometry
- * @instance
- * @param {String} name
- * @return {Object}
- */
- Geometry.prototype.getAttribute = function (name)
- {
- for (const i in this._attributes)
- {
- if (this._attributes[i].name == name) return this._attributes[i];
- }
- return null;
- };
-
- /**
- * @function setAttribute
- * @description create an attribute
- * @memberof Geometry
- * @instance
- * @param {String} name
- * @param {Array} arr
- * @param {Number} itemSize
- */
- Geometry.prototype.setAttribute = function (name, arr, itemSize)
- {
- let attrType = "";
- if (!itemSize || itemSize > 4)
- {
- console.log("itemsize wrong?", itemSize, name);
- this._log.stack("itemsize");
-
- itemSize = 3;
- }
-
- if (itemSize == 1) attrType = "float";
- else if (itemSize == 2) attrType = "vec2";
- else if (itemSize == 3) attrType = "vec3";
- else if (itemSize == 4) attrType = "vec4";
-
-
- const attr = {
- "name": name,
- "data": arr,
- "itemSize": itemSize,
- "type": attrType,
- };
-
- this._attributes[name] = attr;
- };
-
- Geometry.prototype.copyAttribute = function (name, newgeom)
- {
- const attr = this.getAttribute(name);
- newgeom.setAttribute(name, new Float32Array(attr.data), attr.itemSize);
- };
-
-
- /**
- * @function setVertices
- * @memberof Geometry
- * @instance
- * @description set vertices
- * @param {Array|Float32Array} arr [x,y,z,x,y,z,...]
- */
- Geometry.prototype.setVertices = function (arr)
- {
- if (arr instanceof Float32Array) this._vertices = arr;
- else this._vertices = new Float32Array(arr);
- };
-
- /**
- * @function setTexCoords
- * @memberof Geometry
- * @instance
- * @description set texcoords
- * @param {Array|Float32Array} arr [u,v,u,v,...]
- */
- Geometry.prototype.setTexCoords = function (arr)
- {
- if (arr instanceof Float32Array) this.texCoords = arr;
- else this.texCoords = new Float32Array(arr);
- };
-
- // Geometry.prototype.testIndices = function ()
- // {
- // var foundError = false;
- // for (var i = 0; i < this.verticesIndices.length; i++)
- // {
- // if (this.verticesIndices[i * 3 + 0] >= this._vertices.length / 3 || this.verticesIndices[i * 3 + 1] >= this._vertices.length / 3 || this.verticesIndices[i * 3 + 2] >= this._vertices.length / 3)
- // {
- // foundError = true;
- // console.log("index error!");
- // }
- // }
- // };
-
- // deprecated
- Geometry.prototype.calcNormals = function (smooth)
- {
- const options = { "smooth": smooth };
- this.calculateNormals(options);
- };
-
- /**
- * @function flipNormals
- * @memberof Geometry
- * @param x
- * @param y
- * @param z
- * @description flip normals
- */
- Geometry.prototype.flipNormals = function (x, y, z)
- {
- let vec = vec3.create();
-
- if (x == undefined)x = 1;
- if (y == undefined)y = 1;
- if (z == undefined)z = 1;
-
-
- for (let i = 0; i < this.vertexNormals.length; i += 3)
- {
- vec3.set(vec,
- this.vertexNormals[i + 0],
- this.vertexNormals[i + 1],
- this.vertexNormals[i + 2]);
-
- vec[0] *= -x;
- vec[1] *= -y;
- vec[2] *= -z;
-
- vec3.normalize(vec, vec);
-
- this.vertexNormals[i + 0] = vec[0];
- this.vertexNormals[i + 1] = vec[1];
- this.vertexNormals[i + 2] = vec[2];
- }
- };
-
- Geometry.prototype.getNumTriangles = function ()
- {
- if (this.verticesIndices && this.verticesIndices.length) return this.verticesIndices.length / 3;
- return this.vertices.length / 3;
- };
-
-
- /**
- * @function flipVertDir
- * @memberof Geometry
- * @description flip order of vertices in geom faces
- */
- Geometry.prototype.flipVertDir = function ()
- {
- const newInd = [];
- newInd.length = this.verticesIndices.length;
- for (let i = 0; i < this.verticesIndices.length; i += 3)
- {
- newInd[i] = this.verticesIndices[i + 2];
- newInd[i + 1] = this.verticesIndices[i + 1];
- newInd[i + 2] = this.verticesIndices[i];
- }
- this.verticesIndices = newInd;
- };
-
-
- Geometry.prototype.setPointVertices = function (verts)
- {
- if (verts.length % 3 !== 0)
- {
- this._log.error("SetPointVertices: Array must be multiple of three.");
- return;
- }
-
- if (!(verts instanceof Float32Array)) this.vertices = new Float32Array(verts);
- else this.vertices = verts;
-
- if (!(this.texCoords instanceof Float32Array)) this.texCoords = new Float32Array((verts.length / 3) * 2);
-
- // this.texCoords.length=verts.length/3*2;
- this.verticesIndices.length = verts.length / 3;
- // this.verticesIndices=[];
-
- for (let i = 0; i < verts.length / 3; i++)
- {
- this.verticesIndices[i] = i;
- this.texCoords[i * 2] = 0;
- this.texCoords[i * 2 + 1] = 0;
- }
- };
-
- /**
- * merge a different geometry into the this geometry
- * @function merge
- * @param {Geometry} geom
- * @memberof Geometry
- * @instance
- */
- Geometry.prototype.merge = function (geom)
- {
- if (!geom) return;
-
- if (this.isIndexed() != geom.isIndexed())
- {
- if (this.isIndexed())
- {
- this.unIndex(false, true);
- }
- if (geom.isIndexed())
- {
- const g = geom.copy();
- g.unIndex(false, true);
- geom = g;
- }
- }
-
- const oldIndizesLength = this.verticesIndices.length;
- const vertLength = this._vertices.length / 3;
-
- this.verticesIndices.length += geom.verticesIndices.length;
- for (let i = 0; i < geom.verticesIndices.length; i++)
- this.verticesIndices[oldIndizesLength + i] = geom.verticesIndices[i] + vertLength;
-
- this.vertices = UTILS.float32Concat(this._vertices, geom.vertices);
- this.texCoords = UTILS.float32Concat(this.texCoords, geom.texCoords);
- this.vertexNormals = UTILS.float32Concat(this.vertexNormals, geom.vertexNormals);
- this.tangents = UTILS.float32Concat(this.tangents, geom.tangents);
- this.biTangents = UTILS.float32Concat(this.biTangents, geom.biTangents);
- };
-
- /**
- * a copy of the geometry
- * @function copy
- * @memberof Geometry
- * @instance
- */
- Geometry.prototype.copy = function ()
- {
- const geom = new Geometry(this.name + " copy");
- geom.faceVertCount = this.faceVertCount;
- geom.glPrimitive = this.glPrimitive;
-
- geom.setVertices(this._vertices.slice(0));
-
- if (this.verticesIndices)
- {
- geom.verticesIndices.length = this.verticesIndices.length;
- for (let i = 0; i < this.verticesIndices.length; i++) geom.verticesIndices[i] = this.verticesIndices[i];
- }
-
- for (let i in this._attributes) this.copyAttribute(i, geom);
-
- geom.morphTargets.length = this.morphTargets.length;
- for (let i = 0; i < this.morphTargets.length; i++) geom.morphTargets[i] = this.morphTargets[i];
-
- return geom;
- };
-
- /**
- * Calculaten normals
- * @function calculateNormals
- * @memberof Geometry
- * @param options
- * @instance
- */
- Geometry.prototype.calculateNormals = function (options)
- {
- // todo: should check angle of normals to get edges https://community.khronos.org/t/calculating-accurate-vertex-normals/28152
- options = options || {};
- if (options.smooth === false) this.unIndex();
-
- const u = vec3.create();
- const v = vec3.create();
- const n = vec3.create();
-
- function calcNormal(triangle)
- {
- vec3.subtract(u, triangle[0], triangle[1]);
- vec3.subtract(v, triangle[0], triangle[2]);
- vec3.cross(n, u, v);
- vec3.normalize(n, n);
-
- if (options && options.forceZUp)
- {
- if (n[2] < 0)
- {
- n[0] *= -1;
- n[1] *= -1;
- n[2] *= -1;
- }
- }
- return n;
- }
-
- this.getVertexVec = function (which)
- {
- const vec = [0, 0, 0];
- vec[0] = this.vertices[which * 3 + 0];
- vec[1] = this.vertices[which * 3 + 1];
- vec[2] = this.vertices[which * 3 + 2];
- return vec;
- };
-
- if (!(this.vertexNormals instanceof Float32Array) || this.vertexNormals.length != this.vertices.length) this.vertexNormals = new Float32Array(this.vertices.length);
-
- for (let i = 0; i < this.vertices.length; i++)
- {
- this.vertexNormals[i] = 0;
- }
-
- if (!this.isIndexed())
- {
- const norms = [];
- for (let i = 0; i < this.vertices.length; i += 9)
- {
- const triangle = [[this.vertices[i + 0], this.vertices[i + 1], this.vertices[i + 2]], [this.vertices[i + 3], this.vertices[i + 4], this.vertices[i + 5]], [this.vertices[i + 6], this.vertices[i + 7], this.vertices[i + 8]]];
- const nn = calcNormal(triangle);
- norms.push(nn[0], nn[1], nn[2], nn[0], nn[1], nn[2], nn[0], nn[1], nn[2]);
- }
- this.vertexNormals = norms;
- }
- else
- {
- const faceNormals = [];
-
- faceNormals.length = Math.floor(this.verticesIndices.length / 3);
-
- for (let i = 0; i < this.verticesIndices.length; i += 3)
- {
- const triangle = [this.getVertexVec(this.verticesIndices[i + 0]), this.getVertexVec(this.verticesIndices[i + 1]), this.getVertexVec(this.verticesIndices[i + 2])];
-
- faceNormals[i / 3] = calcNormal(triangle);
-
- this.vertexNormals[this.verticesIndices[i + 0] * 3 + 0] += faceNormals[i / 3][0];
- this.vertexNormals[this.verticesIndices[i + 0] * 3 + 1] += faceNormals[i / 3][1];
- this.vertexNormals[this.verticesIndices[i + 0] * 3 + 2] += faceNormals[i / 3][2];
-
- this.vertexNormals[this.verticesIndices[i + 1] * 3 + 0] += faceNormals[i / 3][0];
- this.vertexNormals[this.verticesIndices[i + 1] * 3 + 1] += faceNormals[i / 3][1];
- this.vertexNormals[this.verticesIndices[i + 1] * 3 + 2] += faceNormals[i / 3][2];
-
- this.vertexNormals[this.verticesIndices[i + 2] * 3 + 0] += faceNormals[i / 3][0];
- this.vertexNormals[this.verticesIndices[i + 2] * 3 + 1] += faceNormals[i / 3][1];
- this.vertexNormals[this.verticesIndices[i + 2] * 3 + 2] += faceNormals[i / 3][2];
- }
-
-
- for (let i = 0; i < this.verticesIndices.length; i += 3) // faces
- {
- for (let k = 0; k < 3; k++) // triangles
- {
- const vv = [this.vertexNormals[this.verticesIndices[i + k] * 3 + 0], this.vertexNormals[this.verticesIndices[i + k] * 3 + 1], this.vertexNormals[this.verticesIndices[i + k] * 3 + 2]];
- vec3.normalize(vv, vv);
- this.vertexNormals[this.verticesIndices[i + k] * 3 + 0] = vv[0];
- this.vertexNormals[this.verticesIndices[i + k] * 3 + 1] = vv[1];
- this.vertexNormals[this.verticesIndices[i + k] * 3 + 2] = vv[2];
- }
- }
- }
- };
-
- /**
- * Calculates tangents & bitangents with the help of uv-coordinates. Adapted from
- * Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”.
- * Terathon Software 3D Graphics Library.
- * https://fenix.tecnico.ulisboa.pt/downloadFile/845043405449073/Tangent%20Space%20Calculation.pdf
- *
- * @function calcTangentsBitangents
- * @memberof Geometry
- * @instance
- */
- Geometry.prototype.calcTangentsBitangents = function ()
- {
- if (!this.vertices.length)
- {
- // this._log.error("Cannot calculate tangents/bitangents without vertices.");
- return;
- }
- if (!this.vertexNormals.length)
- {
- // this._log.error("Cannot calculate tangents/bitangents without normals.");
- return;
- }
- if (!this.texCoords.length)
- {
- // console.warn("No texcoords. Replacing with default values [0, 0].");
- const texCoordLength = (this.vertices.length / 3) * 2;
- this.texCoords = new Float32Array(texCoordLength);
- for (let i = 0; i < texCoordLength; i += 1) this.texCoords[i] = 0;
- }
- if (!this.verticesIndices || !this.verticesIndices.length)
- {
- // this._log.error("Cannot calculate tangents/bitangents without vertex indices.");
- return;
- }
- // this code assumes that we have three indices per triangle
- if (this.verticesIndices.length % 3 !== 0)
- {
- this._log.error("Vertex indices mismatch!");
- return;
- }
-
- const triangleCount = this.verticesIndices.length / 3;
- const vertexCount = this.vertices.length / 3;
-
- this.tangents = new Float32Array(this.vertexNormals.length);
- this.biTangents = new Float32Array(this.vertexNormals.length);
-
- // temporary buffers
- const tempVertices = [];
- tempVertices.length = vertexCount * 2;
- const v1 = vec3.create();
- const v2 = vec3.create();
- const v3 = vec3.create();
-
- const w1 = vec2.create();
- const w2 = vec2.create();
- const w3 = vec2.create();
-
- const sdir = vec3.create();
- const tdir = vec3.create();
-
- // for details on calculation, see article referenced above
- for (let tri = 0; tri < triangleCount; tri += 1)
- {
- // indices of the three vertices for a triangle
- const i1 = this.verticesIndices[tri * 3];
- const i2 = this.verticesIndices[tri * 3 + 1];
- const i3 = this.verticesIndices[tri * 3 + 2];
-
- // vertex position as vec3
- vec3.set(v1, this.vertices[i1 * 3], this.vertices[i1 * 3 + 1], this.vertices[i1 * 3 + 2]);
- vec3.set(v2, this.vertices[i2 * 3], this.vertices[i2 * 3 + 1], this.vertices[i2 * 3 + 2]);
- vec3.set(v3, this.vertices[i3 * 3], this.vertices[i3 * 3 + 1], this.vertices[i3 * 3 + 2]);
-
- // texture coordinate as vec2
- vec2.set(w1, this.texCoords[i1 * 2], this.texCoords[i1 * 2 + 1]);
- vec2.set(w2, this.texCoords[i2 * 2], this.texCoords[i2 * 2 + 1]);
- vec2.set(w3, this.texCoords[i3 * 2], this.texCoords[i3 * 2 + 1]);
-
- const x1 = v2[0] - v1[0];
- const x2 = v3[0] - v1[0];
- const y1 = v2[1] - v1[1];
- const y2 = v3[1] - v1[1];
- const z1 = v2[2] - v1[2];
- const z2 = v3[2] - v1[2];
-
- const s1 = w2[0] - w1[0];
- const s2 = w3[0] - w1[0];
- const t1 = w2[1] - w1[1];
- const t2 = w3[1] - w1[1];
-
- const r = 1.0 / (s1 * t2 - s2 * t1);
-
- vec3.set(sdir, (t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
- vec3.set(tdir, (s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
-
- tempVertices[i1] = sdir;
- tempVertices[i2] = sdir;
- tempVertices[i3] = sdir;
-
- tempVertices[i1 + vertexCount] = tdir;
- tempVertices[i2 + vertexCount] = tdir;
- tempVertices[i3 + vertexCount] = tdir;
- }
-
- const normal = vec3.create();
- const tempVert = vec3.create();
- const tan = vec3.create();
- const bitan = vec3.create();
- const temp1 = vec3.create();
- const temp2 = vec3.create();
- const crossPd = vec3.create();
- const normalized = vec3.create();
-
- for (let vert = 0; vert < vertexCount; vert += 1)
- {
- // NOTE: some meshes don't have index 0 - n in their indexbuffer, if this is the case, skip calculation of this vertex
- if (!tempVertices[vert]) continue;
-
- vec3.set(normal, this.vertexNormals[vert * 3], this.vertexNormals[vert * 3 + 1], this.vertexNormals[vert * 3 + 2]);
- vec3.set(tempVert, tempVertices[vert][0], tempVertices[vert][1], tempVertices[vert][2]);
-
- // Gram-Schmidt orthagonalize
- const _dp = vec3.dot(normal, tempVert);
- vec3.scale(temp1, normal, _dp);
- vec3.subtract(temp2, tempVert, temp1);
-
- vec3.normalize(normalized, temp2);
- vec3.cross(crossPd, normal, tempVert);
-
- // const intermDot = vec3.dot(crossPd, tempVertices[vert + vertexCount]);
- const w = 1.0;// intermDot < 0.0 ? -1.0 : 1.0;
-
- vec3.scale(tan, normalized, 1 / w);
- vec3.cross(bitan, normal, tan);
-
- this.tangents[vert * 3 + 0] = tan[0];
- this.tangents[vert * 3 + 1] = tan[1];
- this.tangents[vert * 3 + 2] = tan[2];
- this.biTangents[vert * 3 + 0] = bitan[0];
- this.biTangents[vert * 3 + 1] = bitan[1];
- this.biTangents[vert * 3 + 2] = bitan[2];
- }
- };
-
- Geometry.prototype.isIndexed = function ()
- {
- if (this._vertices.length == 0) return true;
- return this.verticesIndices.length != 0;
- };
-
- /**
- * @function unIndex
- * @memberof Geometry
- * @instance
- * @description remove all vertex indizes, vertices array will contain 3*XYZ for every triangle
- * @param {boolean} reIndex
- * @param {boolean} dontCalcNormals
- */
- Geometry.prototype.unIndex = function (reIndex, dontCalcNormals)
- {
- const newVerts = [];
- const newIndizes = [];
- let count = 0;
-
- for (let j in this._attributes)
- {
- const attr = this._attributes[j];
- let na = [];
-
- for (let i = 0; i < this.verticesIndices.length; i += 3)
- {
- for (let s = 0; s < 3; s++)
- {
- if (attr.itemSize == 3)
- na.push(
- attr.data[this.verticesIndices[i + s] * 3 + 0],
- attr.data[this.verticesIndices[i + s] * 3 + 1],
- attr.data[this.verticesIndices[i + s] * 3 + 2]);
- else if (attr.itemSize == 4)
- na.push(
- attr.data[this.verticesIndices[i + s] * 4 + 0],
- attr.data[this.verticesIndices[i + s] * 4 + 1],
- attr.data[this.verticesIndices[i + s] * 4 + 2],
- attr.data[this.verticesIndices[i + s] * 4 + 3]);
- else if (attr.itemSize == 2)
- na.push(
- attr.data[this.verticesIndices[i + s] * 2 + 0],
- attr.data[this.verticesIndices[i + s] * 2 + 1]);
- else if (attr.itemSize == 1)
- na.push(
- attr.data[this.verticesIndices[i + s]]);
- else console.log("unknown attr", attr);
- }
- }
- this.setAttribute(attr.name, na, attr.itemSize);
- }
-
- for (let i = 0; i < this.verticesIndices.length; i += 3)
- {
- newVerts.push(
- this.vertices[this.verticesIndices[i + 0] * 3 + 0],
- this.vertices[this.verticesIndices[i + 0] * 3 + 1],
- this.vertices[this.verticesIndices[i + 0] * 3 + 2]);
-
- newIndizes.push(count);
- count++;
-
- newVerts.push(
- this.vertices[this.verticesIndices[i + 1] * 3 + 0],
- this.vertices[this.verticesIndices[i + 1] * 3 + 1],
- this.vertices[this.verticesIndices[i + 1] * 3 + 2]);
-
- newIndizes.push(count);
- count++;
-
- newVerts.push(
- this.vertices[this.verticesIndices[i + 2] * 3 + 0],
- this.vertices[this.verticesIndices[i + 2] * 3 + 1],
- this.vertices[this.verticesIndices[i + 2] * 3 + 2]);
-
- newIndizes.push(count);
- count++;
- }
-
- this.vertices = newVerts;
-
- this.verticesIndices = [];
- if (reIndex) this.verticesIndices = newIndizes;
-
- if (!dontCalcNormals) this.calculateNormals();
- };
-
- Geometry.prototype.calcBarycentric = function ()
- {
- let barycentrics = [];
- barycentrics.length = this.vertices.length;
- for (let i = 0; i < this.vertices.length; i++) barycentrics[i] = 0;
-
- let count = 0;
- for (let i = 0; i < this.vertices.length; i += 3)
- {
- barycentrics[i + count] = 1;
- count++;
- if (count == 3) count = 0;
- }
-
- this.setAttribute("attrBarycentric", barycentrics, 3);
- };
-
- Geometry.prototype.getBounds = function ()
- {
- return new BoundingBox(this);
- };
-
- Geometry.prototype.center = function (x, y, z)
- {
- if (x === undefined)
- {
- x = true;
- y = true;
- z = true;
- }
-
- let i = 0;
- const bounds = this.getBounds();
- const offset = [bounds.minX + (bounds.maxX - bounds.minX) / 2, bounds.minY + (bounds.maxY - bounds.minY) / 2, bounds.minZ + (bounds.maxZ - bounds.minZ) / 2];
-
- for (i = 0; i < this.vertices.length; i += 3)
- {
- if (this.vertices[i + 0] == this.vertices[i + 0])
- {
- if (x) this.vertices[i + 0] -= offset[0];
- if (y) this.vertices[i + 1] -= offset[1];
- if (z) this.vertices[i + 2] -= offset[2];
- }
- }
-
- return offset;
- };
-
- Geometry.prototype.mapTexCoords2d = function ()
- {
- const bounds = this.getBounds();
- const num = this.vertices.length / 3;
-
- this.texCoords = new Float32Array(num * 2);
-
- for (let i = 0; i < num; i++)
- {
- const vertX = this.vertices[i * 3 + 0];
- const vertY = this.vertices[i * 3 + 1];
- this.texCoords[i * 2 + 0] = vertX / (bounds.maxX - bounds.minX) + 0.5;
- this.texCoords[i * 2 + 1] = 1.0 - vertY / (bounds.maxY - bounds.minY) + 0.5;
- }
- };
-
-
- Geometry.prototype.getInfoOneLine = function ()
- {
- let txt = "";
- if (this.faceVertCount == 3 && this.verticesIndices)txt += this.verticesIndices.length / 3;
- else txt += 0;
-
- txt += " tris ";
-
- if (this.vertices)txt += this.vertices.length / 3;
- else txt += 0;
-
- txt += " verts";
-
- return txt;
- };
-
- Geometry.prototype.getInfo = function ()
- {
- const info = {};
-
- if (this.faceVertCount == 3 && this.verticesIndices)info.numFaces = this.verticesIndices.length / 3;
- else info.numFaces = 0;
-
- if (this.verticesIndices && this.verticesIndices.length)info.indices = this.verticesIndices.length;
-
- if (this.vertices)info.numVerts = this.vertices.length / 3;
- else info.numVerts = 0;
-
- if (this.vertexNormals) info.numNormals = this.vertexNormals.length / 3;
- else info.numNormals = 0;
-
- if (this.texCoords) info.numTexCoords = this.texCoords.length / 2;
- else info.numTexCoords = 0;
-
- if (this.tangents) info.numTangents = this.tangents.length / 3;
- else info.numTangents = 0;
-
- if (this.biTangents) info.numBiTangents = this.biTangents.length / 3;
- else info.numBiTangents = 0;
-
- if (this.biTangents) info.numBiTangents = this.biTangents.length / 3;
- else info.numBiTangents = 0;
-
- if (this.vertexColors) info.numVertexColors = this.vertexColors.length / 4;
- else info.numVertexColors = 0;
-
- if (this.getAttributes()) info.numAttribs = Object.keys(this.getAttributes()).length;
- else info.numAttribs = 0;
-
- info.isIndexed = this.isIndexed();
-
- return info;
- };
-
- // -----------------
-
- // TODO : rewritwe circle op
- Geometry.buildFromFaces = function (arr, name, optimize)
- {
- const vertices = [];
- const verticesIndices = [];
-
- for (let i = 0; i < arr.length; i += 3)
- {
- const a = arr[i + 0];
- const b = arr[i + 1];
- const c = arr[i + 2];
- const face = [-1, -1, -1];
-
- if (optimize)
- for (let iv = 0; iv < vertices.length; iv += 3)
- {
- if (vertices[iv + 0] == a[0] && vertices[iv + 1] == a[1] && vertices[iv + 2] == a[2]) face[0] = iv / 3;
- if (vertices[iv + 0] == b[0] && vertices[iv + 1] == b[1] && vertices[iv + 2] == b[2]) face[1] = iv / 3;
- if (vertices[iv + 0] == c[0] && vertices[iv + 1] == c[1] && vertices[iv + 2] == c[2]) face[2] = iv / 3;
- }
-
- if (face[0] == -1)
- {
- vertices.push(a[0], a[1], a[2]);
- face[0] = (vertices.length - 1) / 3;
- }
-
- if (face[1] == -1)
- {
- vertices.push(b[0], b[1], b[2]);
- face[1] = (vertices.length - 1) / 3;
- }
-
- if (face[2] == -1)
- {
- vertices.push(c[0], c[1], c[2]);
- face[2] = (vertices.length - 1) / 3;
- }
-
- verticesIndices.push(parseInt(face[0], 10));
- verticesIndices.push(parseInt(face[1], 10));
- verticesIndices.push(parseInt(face[2], 10));
- }
-
- const geom = new Geometry(name);
- geom.name = name;
- geom.vertices = vertices;
- geom.verticesIndices = verticesIndices;
-
- return geom;
- };
-
-
- export { Geometry };