Skip to content
This repository has been archived by the owner on Jul 31, 2022. It is now read-only.

Commit

Permalink
Optional normals, auto vertex position merging #18 #19
Browse files Browse the repository at this point in the history
  • Loading branch information
xeolabs committed Jun 4, 2021
1 parent 2d0d77a commit a3d086a
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 8 deletions.
4 changes: 3 additions & 1 deletion src/XKTModel/XKTGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class XKTGeometry {
/**
* Non-compressed 3D vertex normals.
*
* Defined only for triangle primitives. Ignored for points and lines.
* Defined only for triangle primitives. Can be null if we want xeokit to auto-generate them. Ignored for points and lines.
*
* @type {Float32Array}
*/
Expand All @@ -87,6 +87,8 @@ class XKTGeometry {
*
* This array is later created from {@link XKTGeometry#normals} by {@link XKTModel#finalize}.
*
* Will be null if {@link XKTGeometry#normals} is also null.
*
* @type {Int8Array}
*/
this.normalsOctEncoded = null;
Expand Down
101 changes: 94 additions & 7 deletions src/XKTModel/XKTModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {XKTEntity} from './XKTEntity.js';
import {XKTTile} from './XKTTile.js';
import {KDNode} from "./KDNode.js";
import {XKTMetaObject} from "./XKTMetaObject.js";
import {mergeVertices} from "../lib/mergeVertices.js";

const tempVec4a = math.vec4([0, 0, 0, 1]);
const tempVec4b = math.vec4([0, 0, 0, 1]);
Expand Down Expand Up @@ -46,6 +47,75 @@ class XKTModel {
*/
constructor(cfg = {}) {

/**
* The model's ID, if available.
*
* Will be an empty string by default.
*
* @type {String}
*/
this.modelId = cfg.modelId || "";

/**
* The project ID, if available.
*
* Will be an empty string by default.
*
* @type {String}
*/
this.projectId = cfg.projectId || "";

/**
* The revision ID, if available.
*
* Will be an empty string by default.
*
* @type {String}
*/
this.revisionId = cfg.revisionId || "";

/**
* The model author, if available.
*
* Will be an empty string by default.
*
* @property author
* @type {String}
*/
this.author = cfg.author || "";

/**
* The date the model was created, if available.
*
* Will be an empty string by default.
*
* @property createdAt
* @type {String}
*/
this.createdAt = cfg.createdAt || "";

/**
* The application that created the model, if available.
*
* Will be an empty string by default.
*
* @property creatingApplication
* @type {String}
*/
this.creatingApplication = cfg.creatingApplication || "";

/**
* The model schema version, if available.
*
* In the case of IFC, this could be "IFC2x3" or "IFC4", for example.
*
* Will be an empty string by default.
*
* @property schema
* @type {String}
*/
this.schema = cfg.schema || "";

/**
*
* @type {Number|number}
Expand Down Expand Up @@ -190,7 +260,7 @@ class XKTModel {
}

if (this.metaObjects[params.metaObjectId]) {
// console.error("XKTMetaObject already exists with this ID: " + params.metaObjectId);
// console.error("XKTMetaObject already exists with this ID: " + params.metaObjectId);
return;
}

Expand All @@ -217,7 +287,7 @@ class XKTModel {
* @param {Number} params.geometryId Unique ID for the {@link XKTGeometry}.
* @param {String} params.primitiveType The type of {@link XKTGeometry}: "triangles", "lines" or "points".
* @param {Float64Array} params.positions Floating-point Local-space vertex positions for the {@link XKTGeometry}. Required for all primitive types.
* @param {Number[]} [params.normals] Floating-point vertex normals for the {@link XKTGeometry}. Required for triangles primitives. Ignored for points and lines.
* @param {Number[]} [params.normals] Floating-point vertex normals for the {@link XKTGeometry}. Only used with triangles primitives. Ignored for points and lines.
* @param {Number[]} [params.colors] Floating-point RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles.
* @param {Number[]} [params.colorsCompressed] Integer RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles.
* @param {Uint32Array} [params.indices] Indices for the {@link XKTGeometry}. Required for triangles and lines primitives. Ignored for points.
Expand Down Expand Up @@ -251,9 +321,6 @@ class XKTModel {
}

if (triangles) {
if (!params.normals) {
throw "Parameter expected for 'triangles' primitive: params.normals";
}
if (!params.indices) {
throw "Parameter expected for 'triangles' primitive: params.indices";
}
Expand Down Expand Up @@ -293,9 +360,10 @@ class XKTModel {
}

if (triangles) {
xktGeometryCfg.normals = new Float64Array(params.normals); // May modify in #finalize
if (params.normals) {
xktGeometryCfg.normals = new Float32Array(params.normals);
}
xktGeometryCfg.indices = params.indices;
xktGeometryCfg.edgeIndices = buildEdgeIndices(positions, params.indices, null, params.edgeThreshold || this.edgeThreshold || 10);
}

if (points) {
Expand All @@ -315,6 +383,25 @@ class XKTModel {
xktGeometryCfg.indices = params.indices;
}

if (triangles) {

if (!params.normals) {

// Building models often duplicate positions to allow face-aligned vertex normals; when we're not
// providing normals for a geometry, it becomes possible to merge duplicate vertex positions within it.

// TODO: Make vertex merging also merge normals?

const mergedPositions = [];
const mergedIndices = [];
mergeVertices(xktGeometryCfg.positions, xktGeometryCfg.indices, mergedPositions, mergedIndices);
xktGeometryCfg.positions = new Float64Array(mergedPositions);
xktGeometryCfg.indices = mergedIndices;
}

xktGeometryCfg.edgeIndices = buildEdgeIndices(xktGeometryCfg.positions, xktGeometryCfg.indices, null, params.edgeThreshold || this.edgeThreshold || 10);
}

const geometry = new XKTGeometry(xktGeometryCfg);

this.geometries[geometryId] = geometry;
Expand Down

0 comments on commit a3d086a

Please sign in to comment.