disable hdr
This commit is contained in:
parent
85562d5406
commit
d610fd0f08
2 changed files with 531 additions and 467 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
viewer/package-lock.json
|
||||
viewer/web/viewer/render.mjs
|
||||
|
|
@ -1,20 +1,19 @@
|
|||
// (C) buildingSMART International
|
||||
// published under MIT license
|
||||
|
||||
import { ComposedObject } from './composed-object';
|
||||
import { IfcxFile } from '../ifcx-core/schema/schema-helper';
|
||||
import { compose3 } from './compose-flattened';
|
||||
import * as THREE from 'three';
|
||||
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
||||
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
|
||||
import { PCDLoader } from 'three/addons/loaders/PCDLoader.js';
|
||||
import { ComposedObject } from "./composed-object";
|
||||
import { IfcxFile } from "../ifcx-core/schema/schema-helper";
|
||||
import { compose3 } from "./compose-flattened";
|
||||
import * as THREE from "three";
|
||||
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
|
||||
import { RGBELoader } from "three/addons/loaders/RGBELoader.js";
|
||||
import { PCDLoader } from "three/addons/loaders/PCDLoader.js";
|
||||
|
||||
let controls, renderer, scene, camera;
|
||||
type datastype = [string, IfcxFile][];
|
||||
let datas: datastype = [];
|
||||
let autoCamera = true;
|
||||
|
||||
|
||||
let objectMap: { [path: string]: any } = {};
|
||||
let domMap: { [path: string]: HTMLElement } = {};
|
||||
let primMap: { [path: string]: ComposedObject } = {};
|
||||
|
|
@ -24,7 +23,6 @@ let rootPrim: ComposedObject | null = null;
|
|||
let selectedObject: any = null;
|
||||
let selectedDom: HTMLElement | null = null;
|
||||
|
||||
|
||||
let raycaster = new THREE.Raycaster();
|
||||
let mouse = new THREE.Vector2();
|
||||
|
||||
|
|
@ -46,21 +44,27 @@ async function init() {
|
|||
rimLight.position.set(0, 8, -10);
|
||||
scene.add(rimLight);
|
||||
|
||||
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
|
||||
camera = new THREE.PerspectiveCamera(
|
||||
75,
|
||||
window.innerWidth / window.innerHeight,
|
||||
0.1,
|
||||
100,
|
||||
);
|
||||
|
||||
camera.up.set(0, 0, 1);
|
||||
camera.position.set(50, 50, 50);
|
||||
camera.lookAt(0, 0, 0);
|
||||
|
||||
const nd = document.querySelector('.viewport');
|
||||
const nd = document.querySelector(".viewport");
|
||||
renderer = new THREE.WebGLRenderer({
|
||||
alpha: true,
|
||||
logarithmicDepthBuffer: true
|
||||
logarithmicDepthBuffer: true,
|
||||
});
|
||||
|
||||
// for GLTF PBR rendering, create environment map using PMREMGenerator:
|
||||
// see https://threejs.org/docs/#api/en/extras/PMREMGenerator
|
||||
|
||||
/*
|
||||
const pmremGenerator = new THREE.PMREMGenerator(renderer);
|
||||
pmremGenerator.compileEquirectangularShader();
|
||||
new RGBELoader()
|
||||
|
|
@ -75,6 +79,7 @@ async function init() {
|
|||
texture.dispose();
|
||||
pmremGenerator.dispose();
|
||||
});
|
||||
*/
|
||||
|
||||
//@ts-ignore
|
||||
renderer.setSize(nd.offsetWidth, nd.offsetHeight);
|
||||
|
|
@ -85,24 +90,20 @@ async function init() {
|
|||
controls.dampingFactor = 0.25;
|
||||
|
||||
nd!.appendChild(renderer.domElement);
|
||||
renderer.domElement.addEventListener('click', onCanvasClick);
|
||||
renderer.domElement.addEventListener("click", onCanvasClick);
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
function HasAttr(node: ComposedObject | undefined, attrName: string)
|
||||
{
|
||||
function HasAttr(node: ComposedObject | undefined, attrName: string) {
|
||||
if (!node || !node.attributes) return false;
|
||||
return !!node.attributes[attrName];
|
||||
}
|
||||
|
||||
function FindChildWithAttr(node: ComposedObject | undefined, attrName: string)
|
||||
{
|
||||
function FindChildWithAttr(node: ComposedObject | undefined, attrName: string) {
|
||||
if (!node || !node.children) return undefined;
|
||||
for (let i = 0; i < node.children.length; i++)
|
||||
{
|
||||
if (HasAttr(node.children[i], attrName))
|
||||
{
|
||||
for (let i = 0; i < node.children.length; i++) {
|
||||
if (HasAttr(node.children[i], attrName)) {
|
||||
return node.children[i];
|
||||
}
|
||||
}
|
||||
|
|
@ -132,7 +133,7 @@ function setHighlight(obj: any, highlight: boolean) {
|
|||
function selectPath(path: string | null) {
|
||||
if (!path) {
|
||||
if (selectedObject) setHighlight(selectedObject, false);
|
||||
if (selectedDom) selectedDom.classList.remove('selected');
|
||||
if (selectedDom) selectedDom.classList.remove("selected");
|
||||
selectedObject = null;
|
||||
selectedDom = null;
|
||||
return;
|
||||
|
|
@ -142,12 +143,12 @@ function selectPath(path: string | null) {
|
|||
setHighlight(selectedObject, false);
|
||||
}
|
||||
if (selectedDom) {
|
||||
selectedDom.classList.remove('selected');
|
||||
selectedDom.classList.remove("selected");
|
||||
}
|
||||
selectedObject = objectMap[path] || null;
|
||||
selectedDom = domMap[path] || null;
|
||||
if (selectedObject) setHighlight(selectedObject, true);
|
||||
if (selectedDom) selectedDom.classList.add('selected');
|
||||
if (selectedDom) selectedDom.classList.add("selected");
|
||||
}
|
||||
|
||||
function onCanvasClick(event) {
|
||||
|
|
@ -167,20 +168,19 @@ function onCanvasClick(event) {
|
|||
}
|
||||
selectPath(path);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
selectPath(null);
|
||||
}
|
||||
}
|
||||
|
||||
function tryCreateMeshGltfMaterial(path: ComposedObject[]) {
|
||||
|
||||
// check for PBR defined by the gltf::material schema
|
||||
for (let p of path) {
|
||||
if (!p.attributes) {
|
||||
continue;
|
||||
}
|
||||
const pbrMetallicRoughness = p.attributes["gltf::material::pbrMetallicRoughness"];
|
||||
const pbrMetallicRoughness =
|
||||
p.attributes["gltf::material::pbrMetallicRoughness"];
|
||||
const normalTexture = p.attributes["gltf::material::normalTexture"];
|
||||
const occlusionTexture = p.attributes["gltf::material::occlusionTexture"];
|
||||
const emissiveTexture = p.attributes["gltf::material::emissiveTexture"];
|
||||
|
|
@ -188,7 +188,16 @@ function tryCreateMeshGltfMaterial(path: ComposedObject[]) {
|
|||
const alphaMode = p.attributes["gltf::material::alphaMode"];
|
||||
const alphaCutoff = p.attributes["gltf::material::alphaCutoff"];
|
||||
const doubleSided = p.attributes["gltf::material::doubleSided"];
|
||||
if (!pbrMetallicRoughness && !normalTexture && !occlusionTexture && !emissiveTexture && !emissiveFactor && !alphaMode && !alphaCutoff && !doubleSided) {
|
||||
if (
|
||||
!pbrMetallicRoughness &&
|
||||
!normalTexture &&
|
||||
!occlusionTexture &&
|
||||
!emissiveTexture &&
|
||||
!emissiveFactor &&
|
||||
!alphaMode &&
|
||||
!alphaCutoff &&
|
||||
!doubleSided
|
||||
) {
|
||||
// if none of the gltf::material properties are defined, we don't use pbr rendering, but default to the bsi::ifc::presentation definitions
|
||||
continue;
|
||||
}
|
||||
|
|
@ -209,7 +218,11 @@ function tryCreateMeshGltfMaterial(path: ComposedObject[]) {
|
|||
if (pbrMetallicRoughness) {
|
||||
let baseColorFactor = pbrMetallicRoughness["baseColorFactor"];
|
||||
if (baseColorFactor) {
|
||||
material.color = new THREE.Color(baseColorFactor[0], baseColorFactor[1], baseColorFactor[2]);
|
||||
material.color = new THREE.Color(
|
||||
baseColorFactor[0],
|
||||
baseColorFactor[1],
|
||||
baseColorFactor[2],
|
||||
);
|
||||
}
|
||||
|
||||
let metallicFactor = pbrMetallicRoughness["metallicFactor"];
|
||||
|
|
@ -222,24 +235,26 @@ function tryCreateMeshGltfMaterial(path: ComposedObject[]) {
|
|||
material.roughness = roughnessFactor;
|
||||
}
|
||||
}
|
||||
material.envMap = envMap
|
||||
material.needsUpdate = true
|
||||
material.envMap = envMap;
|
||||
material.needsUpdate = true;
|
||||
material.envMapRotation = new THREE.Euler(0.5 * Math.PI, 0, 0);
|
||||
// console.log(material)
|
||||
return material;
|
||||
}
|
||||
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function createMaterialFromParent(path: ComposedObject[]) {
|
||||
let material = {
|
||||
color: new THREE.Color(0.6, 0.6, 0.6),
|
||||
transparent: false,
|
||||
opacity: 1
|
||||
opacity: 1,
|
||||
};
|
||||
for (let p of path) {
|
||||
const color = p.attributes ? p.attributes["bsi::ifc::presentation::diffuseColor"] : null;
|
||||
const color = p.attributes
|
||||
? p.attributes["bsi::ifc::presentation::diffuseColor"]
|
||||
: null;
|
||||
if (color) {
|
||||
material.color = new THREE.Color(...color);
|
||||
const opacity = p.attributes["bsi::ifc::presentation::opacity"];
|
||||
|
|
@ -254,7 +269,9 @@ function createMaterialFromParent(path: ComposedObject[]) {
|
|||
}
|
||||
|
||||
function createCurveFromJson(path: ComposedObject[]) {
|
||||
let points = new Float32Array(path[0].attributes["usd::usdgeom::basiscurves::points"].flat());
|
||||
let points = new Float32Array(
|
||||
path[0].attributes["usd::usdgeom::basiscurves::points"].flat(),
|
||||
);
|
||||
const geometry = new THREE.BufferGeometry();
|
||||
geometry.setAttribute("position", new THREE.BufferAttribute(points, 3));
|
||||
|
||||
|
|
@ -266,20 +283,23 @@ function createCurveFromJson(path: ComposedObject[]) {
|
|||
}
|
||||
|
||||
function createMeshFromJson(path: ComposedObject[]) {
|
||||
let points = new Float32Array(path[0].attributes["usd::usdgeom::mesh::points"].flat());
|
||||
let indices = new Uint16Array(path[0].attributes["usd::usdgeom::mesh::faceVertexIndices"]);
|
||||
let points = new Float32Array(
|
||||
path[0].attributes["usd::usdgeom::mesh::points"].flat(),
|
||||
);
|
||||
let indices = new Uint16Array(
|
||||
path[0].attributes["usd::usdgeom::mesh::faceVertexIndices"],
|
||||
);
|
||||
|
||||
const geometry = new THREE.BufferGeometry();
|
||||
geometry.setAttribute("position", new THREE.BufferAttribute(points, 3));
|
||||
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
|
||||
geometry.computeVertexNormals();
|
||||
|
||||
|
||||
var meshMaterial;
|
||||
|
||||
let gltfPbrMaterial = tryCreateMeshGltfMaterial(path);
|
||||
if (gltfPbrMaterial) {
|
||||
meshMaterial = gltfPbrMaterial
|
||||
meshMaterial = gltfPbrMaterial;
|
||||
// console.log(meshMaterial)
|
||||
} else {
|
||||
const m = createMaterialFromParent(path);
|
||||
|
|
@ -305,7 +325,10 @@ function createPointsFromJsonPcdBase64(path: ComposedObject[]) {
|
|||
return points;
|
||||
}
|
||||
|
||||
function createPoints(geometry: THREE.BufferGeometry, withColors: boolean): THREE.Points {
|
||||
function createPoints(
|
||||
geometry: THREE.BufferGeometry,
|
||||
withColors: boolean,
|
||||
): THREE.Points {
|
||||
const material = new THREE.PointsMaterial();
|
||||
material.sizeAttenuation = false;
|
||||
material.fog = true;
|
||||
|
|
@ -321,13 +344,21 @@ function createPoints(geometry: THREE.BufferGeometry, withColors: boolean): THRE
|
|||
function createPointsFromJsonArray(path: ComposedObject[]) {
|
||||
const geometry = new THREE.BufferGeometry();
|
||||
|
||||
const positions = new Float32Array(path[0].attributes["points::array::positions"].flat());
|
||||
geometry.setAttribute("position", new THREE.Float32BufferAttribute(positions, 3));
|
||||
const positions = new Float32Array(
|
||||
path[0].attributes["points::array::positions"].flat(),
|
||||
);
|
||||
geometry.setAttribute(
|
||||
"position",
|
||||
new THREE.Float32BufferAttribute(positions, 3),
|
||||
);
|
||||
|
||||
const colors = path[0].attributes["points::array::colors"];
|
||||
if (colors) {
|
||||
const colors_ = new Float32Array(colors.flat());
|
||||
geometry.setAttribute("color", new THREE.Float32BufferAttribute(colors_, 3));
|
||||
geometry.setAttribute(
|
||||
"color",
|
||||
new THREE.Float32BufferAttribute(colors_, 3),
|
||||
);
|
||||
}
|
||||
return createPoints(geometry, colors);
|
||||
}
|
||||
|
|
@ -336,8 +367,7 @@ function base64ToArrayBuffer(str): ArrayBuffer | undefined {
|
|||
let binary;
|
||||
try {
|
||||
binary = atob(str);
|
||||
}
|
||||
catch(e) {
|
||||
} catch (e) {
|
||||
throw new Error("base64 encoded string is invalid");
|
||||
}
|
||||
const bytes = new Uint8Array(binary.length);
|
||||
|
|
@ -356,14 +386,20 @@ function createPointsFromJsonPositionBase64(path: ComposedObject[]) {
|
|||
return null;
|
||||
}
|
||||
const positions = new Float32Array(positions_bytes!);
|
||||
geometry.setAttribute("position", new THREE.Float32BufferAttribute(positions, 3));
|
||||
geometry.setAttribute(
|
||||
"position",
|
||||
new THREE.Float32BufferAttribute(positions, 3),
|
||||
);
|
||||
|
||||
const colors_base64 = path[0].attributes["points::base64::colors"];
|
||||
if (colors_base64) {
|
||||
const colors_bytes = base64ToArrayBuffer(colors_base64);
|
||||
if (colors_bytes) {
|
||||
const colors = new Float32Array(colors_bytes!);
|
||||
geometry.setAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
|
||||
geometry.setAttribute(
|
||||
"color",
|
||||
new THREE.Float32BufferAttribute(colors, 3),
|
||||
);
|
||||
}
|
||||
}
|
||||
return createPoints(geometry, colors_base64);
|
||||
|
|
@ -372,31 +408,23 @@ function createPointsFromJsonPositionBase64(path: ComposedObject[]) {
|
|||
function traverseTree(path: ComposedObject[], parent, pathMapping) {
|
||||
const node = path[0];
|
||||
let elem: any = new THREE.Group();
|
||||
if (HasAttr(node, "usd::usdgeom::visibility::visibility"))
|
||||
{
|
||||
if (node.attributes["usd::usdgeom::visibility::visibility"] === 'invisible') {
|
||||
if (HasAttr(node, "usd::usdgeom::visibility::visibility")) {
|
||||
if (
|
||||
node.attributes["usd::usdgeom::visibility::visibility"] === "invisible"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (HasAttr(node, "usd::usdgeom::mesh::points"))
|
||||
{
|
||||
} else if (HasAttr(node, "usd::usdgeom::mesh::points")) {
|
||||
elem = createMeshFromJson(path);
|
||||
}
|
||||
else if (HasAttr(node, "usd::usdgeom::basiscurves::points"))
|
||||
{
|
||||
} else if (HasAttr(node, "usd::usdgeom::basiscurves::points")) {
|
||||
elem = createCurveFromJson(path);
|
||||
}
|
||||
// point cloud data types:
|
||||
else if (HasAttr(node, "pcd::base64"))
|
||||
{
|
||||
else if (HasAttr(node, "pcd::base64")) {
|
||||
elem = createPointsFromJsonPcdBase64(path);
|
||||
}
|
||||
else if (HasAttr(node, "points::array::positions"))
|
||||
{
|
||||
} else if (HasAttr(node, "points::array::positions")) {
|
||||
elem = createPointsFromJsonArray(path);
|
||||
}
|
||||
else if (HasAttr(node, "points::base64::positions"))
|
||||
{
|
||||
} else if (HasAttr(node, "points::base64::positions")) {
|
||||
elem = createPointsFromJsonPositionBase64(path);
|
||||
}
|
||||
|
||||
|
|
@ -404,15 +432,22 @@ function traverseTree(path: ComposedObject[], parent, pathMapping) {
|
|||
primMap[node.name] = node;
|
||||
elem.userData.path = node.name;
|
||||
|
||||
for (let path of Object.entries(node.attributes || {}).filter(([k, _]) => k.startsWith('__internal_')).map(([_, v]) => v)) {
|
||||
(pathMapping[String(path)] = pathMapping[String(path)] || []).push(node.name);
|
||||
for (let path of Object.entries(node.attributes || {})
|
||||
.filter(([k, _]) => k.startsWith("__internal_"))
|
||||
.map(([_, v]) => v)) {
|
||||
(pathMapping[String(path)] = pathMapping[String(path)] || []).push(
|
||||
node.name,
|
||||
);
|
||||
}
|
||||
|
||||
parent.add(elem);
|
||||
if (path.length > 1) {
|
||||
elem.matrixAutoUpdate = false;
|
||||
|
||||
let matrixNode = node.attributes && node.attributes['usd::xformop::transform'] ? node.attributes['usd::xformop::transform'].flat() : null;
|
||||
let matrixNode =
|
||||
node.attributes && node.attributes["usd::xformop::transform"]
|
||||
? node.attributes["usd::xformop::transform"].flat()
|
||||
: null;
|
||||
if (matrixNode) {
|
||||
let matrix = new THREE.Matrix4();
|
||||
//@ts-ignore
|
||||
|
|
@ -422,22 +457,24 @@ function traverseTree(path: ComposedObject[], parent, pathMapping) {
|
|||
}
|
||||
}
|
||||
|
||||
(node.children || []).forEach(child => traverseTree([child, ...path], elem || parent, pathMapping));
|
||||
(node.children || []).forEach((child) =>
|
||||
traverseTree([child, ...path], elem || parent, pathMapping),
|
||||
);
|
||||
}
|
||||
|
||||
function encodeHtmlEntities(str) {
|
||||
const div = document.createElement('div');
|
||||
const div = document.createElement("div");
|
||||
div.textContent = str;
|
||||
return div.innerHTML;
|
||||
};
|
||||
}
|
||||
|
||||
const icons = {
|
||||
'usd::usdgeom::mesh::points': 'deployed_code',
|
||||
'usd::usdgeom::basiscurves::points': 'line_curve',
|
||||
'usd::usdshade::material::outputs::surface.connect': 'line_style',
|
||||
'pcd::base64': 'grain',
|
||||
'points::array::positions': 'grain',
|
||||
'points::base64::positions': 'grain',
|
||||
"usd::usdgeom::mesh::points": "deployed_code",
|
||||
"usd::usdgeom::basiscurves::points": "line_curve",
|
||||
"usd::usdshade::material::outputs::surface.connect": "line_style",
|
||||
"pcd::base64": "grain",
|
||||
"points::array::positions": "grain",
|
||||
"points::base64::positions": "grain",
|
||||
};
|
||||
|
||||
function handleClick(prim, pathMapping, root) {
|
||||
|
|
@ -446,27 +483,37 @@ function handleClick(prim, pathMapping, root) {
|
|||
container.innerHTML = "";
|
||||
const table = document.createElement("table");
|
||||
table.setAttribute("border", "0");
|
||||
const entries = [["name", prim.name], ...Object.entries(prim.attributes).filter(([k, _]) => !k.startsWith('__internal_'))];
|
||||
const entries = [
|
||||
["name", prim.name],
|
||||
...Object.entries(prim.attributes).filter(
|
||||
([k, _]) => !k.startsWith("__internal_"),
|
||||
),
|
||||
];
|
||||
const format = (value) => {
|
||||
if (Array.isArray(value)) {
|
||||
let N = document.createElement('span');
|
||||
N.appendChild(document.createTextNode('('));
|
||||
let N = document.createElement("span");
|
||||
N.appendChild(document.createTextNode("("));
|
||||
let first = true;
|
||||
for (let n of value.map(format)) {
|
||||
if (!first) {
|
||||
N.appendChild(document.createTextNode(','));
|
||||
N.appendChild(document.createTextNode(","));
|
||||
}
|
||||
N.appendChild(n);
|
||||
first = false;
|
||||
}
|
||||
N.appendChild(document.createTextNode(')'));
|
||||
N.appendChild(document.createTextNode(")"));
|
||||
return N;
|
||||
} else if (typeof value === "object") {
|
||||
const ks = Object.keys(value);
|
||||
if (ks.length == 1 && ks[0] === 'ref' && pathMapping[value.ref] && pathMapping[value.ref].length == 1) {
|
||||
let a = document.createElement('a');
|
||||
if (
|
||||
ks.length == 1 &&
|
||||
ks[0] === "ref" &&
|
||||
pathMapping[value.ref] &&
|
||||
pathMapping[value.ref].length == 1
|
||||
) {
|
||||
let a = document.createElement("a");
|
||||
let resolvedRefAsPath = pathMapping[value.ref][0];
|
||||
a.setAttribute('href', '#');
|
||||
a.setAttribute("href", "#");
|
||||
a.textContent = resolvedRefAsPath;
|
||||
a.onclick = () => {
|
||||
let prim = null;
|
||||
|
|
@ -476,12 +523,12 @@ function handleClick(prim, pathMapping, root) {
|
|||
} else {
|
||||
(n.children || []).forEach(recurse);
|
||||
}
|
||||
}
|
||||
};
|
||||
recurse(root);
|
||||
if (prim) {
|
||||
handleClick(prim, pathMapping, root);
|
||||
}
|
||||
}
|
||||
};
|
||||
return a;
|
||||
} else {
|
||||
return document.createTextNode(JSON.stringify(value));
|
||||
|
|
@ -504,12 +551,18 @@ function handleClick(prim, pathMapping, root) {
|
|||
}
|
||||
}
|
||||
|
||||
function buildDomTree(prim, node, pathMapping, root=null) {
|
||||
const elem = document.createElement('div');
|
||||
function buildDomTree(prim, node, pathMapping, root = null) {
|
||||
const elem = document.createElement("div");
|
||||
let span;
|
||||
elem.appendChild(document.createTextNode(prim.name ? prim.name.split('/').reverse()[0] : 'root'));
|
||||
elem.appendChild(span = document.createElement('span'));
|
||||
Object.entries(icons).forEach(([k, v]) => span.innerText += (prim.attributes || {})[k] ? v : ' ');
|
||||
elem.appendChild(
|
||||
document.createTextNode(
|
||||
prim.name ? prim.name.split("/").reverse()[0] : "root",
|
||||
),
|
||||
);
|
||||
elem.appendChild((span = document.createElement("span")));
|
||||
Object.entries(icons).forEach(
|
||||
([k, v]) => (span.innerText += (prim.attributes || {})[k] ? v : " "),
|
||||
);
|
||||
span.className = "material-symbols-outlined";
|
||||
domMap[prim.name] = elem as HTMLElement;
|
||||
elem.dataset.path = prim.name;
|
||||
|
|
@ -519,14 +572,16 @@ function buildDomTree(prim, node, pathMapping, root=null) {
|
|||
evt.stopPropagation();
|
||||
};
|
||||
node.appendChild(elem);
|
||||
(prim.children || []).forEach(p => buildDomTree(p, elem, pathMapping, root || prim));
|
||||
(prim.children || []).forEach((p) =>
|
||||
buildDomTree(p, elem, pathMapping, root || prim),
|
||||
);
|
||||
}
|
||||
|
||||
export async function composeAndRender() {
|
||||
if (scene) {
|
||||
// @todo does this actually free up resources?
|
||||
// retain only the lights
|
||||
scene.children = scene.children.filter(n => n instanceof THREE.Light);
|
||||
scene.children = scene.children.filter((n) => n instanceof THREE.Light);
|
||||
}
|
||||
|
||||
objectMap = {};
|
||||
|
|
@ -535,14 +590,14 @@ export async function composeAndRender() {
|
|||
currentPathMapping = null;
|
||||
rootPrim = null;
|
||||
|
||||
document.querySelector('.tree')!.innerHTML = '';
|
||||
document.querySelector(".tree")!.innerHTML = "";
|
||||
|
||||
if (datas.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tree: null | ComposedObject = null;
|
||||
let dataArray = datas.map(arr => arr[1]);
|
||||
let dataArray = datas.map((arr) => arr[1]);
|
||||
|
||||
tree = await compose3(dataArray as IfcxFile[]);
|
||||
if (!tree) {
|
||||
|
|
@ -551,7 +606,7 @@ export async function composeAndRender() {
|
|||
}
|
||||
|
||||
if (!scene) {
|
||||
await init()
|
||||
await init();
|
||||
}
|
||||
|
||||
let pathMapping = {};
|
||||
|
|
@ -563,9 +618,16 @@ export async function composeAndRender() {
|
|||
const boundingBox = new THREE.Box3();
|
||||
boundingBox.setFromObject(scene);
|
||||
if (!boundingBox.isEmpty()) {
|
||||
let avg = boundingBox.min.clone().add(boundingBox.max).multiplyScalar(0.5);
|
||||
let avg = boundingBox.min
|
||||
.clone()
|
||||
.add(boundingBox.max)
|
||||
.multiplyScalar(0.5);
|
||||
let ext = boundingBox.max.clone().sub(boundingBox.min).length();
|
||||
camera.position.copy(avg.clone().add(new THREE.Vector3(1,1,1).normalize().multiplyScalar(ext)));
|
||||
camera.position.copy(
|
||||
avg
|
||||
.clone()
|
||||
.add(new THREE.Vector3(1, 1, 1).normalize().multiplyScalar(ext)),
|
||||
);
|
||||
camera.far = ext * 3;
|
||||
camera.updateProjectionMatrix();
|
||||
controls.target.copy(avg);
|
||||
|
|
@ -576,17 +638,17 @@ export async function composeAndRender() {
|
|||
}
|
||||
}
|
||||
|
||||
buildDomTree(tree, document.querySelector('.tree'), pathMapping);
|
||||
buildDomTree(tree, document.querySelector(".tree"), pathMapping);
|
||||
animate();
|
||||
}
|
||||
|
||||
function createLayerDom() {
|
||||
document.querySelector('.layers div')!.innerHTML = '';
|
||||
document.querySelector(".layers div")!.innerHTML = "";
|
||||
datas.forEach(([name, _], index) => {
|
||||
const elem = document.createElement('div');
|
||||
const elem = document.createElement("div");
|
||||
elem.appendChild(document.createTextNode(name));
|
||||
['\u25B3', '\u25BD', '\u00D7'].reverse().forEach((lbl, cmd) => {
|
||||
const btn = document.createElement('span');
|
||||
["\u25B3", "\u25BD", "\u00D7"].reverse().forEach((lbl, cmd) => {
|
||||
const btn = document.createElement("span");
|
||||
btn.onclick = (evt) => {
|
||||
evt.stopPropagation();
|
||||
if (cmd === 2) {
|
||||
|
|
@ -603,11 +665,11 @@ function createLayerDom() {
|
|||
// TODO: await this
|
||||
composeAndRender();
|
||||
createLayerDom();
|
||||
}
|
||||
};
|
||||
btn.appendChild(document.createTextNode(lbl));
|
||||
elem.appendChild(btn);
|
||||
});
|
||||
document.querySelector('.layers div')!.appendChild(elem);
|
||||
document.querySelector(".layers div")!.appendChild(elem);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue