Skip to content

Commit

Permalink
Merge pull request #104 from Smithsonian/bug-fixes
Browse files Browse the repository at this point in the history
Bug fixes + Feature merge
  • Loading branch information
gjcope authored Sep 30, 2021
2 parents 5c0bcad + 0c807fd commit ecedef4
Show file tree
Hide file tree
Showing 31 changed files with 445 additions and 77 deletions.
2 changes: 1 addition & 1 deletion libs/ff-scene
51 changes: 40 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "voyager",
"version": "0.14.0",
"version": "0.14.1",
"description": "Smithsonian DPO Voyager - 3D Explorer and Tool Suite",
"scripts": {
"start": "npm run server",
Expand Down Expand Up @@ -65,6 +65,7 @@
"quill-image-resize-module": "^3.0.0",
"readable-stream": "^3.6.0",
"resolve-pathname": "^3.0.0",
"sanitize-html": "^2.5.1",
"stream-browserify": "^3.0.0",
"three": "^0.132.2",
"three-bmfont-text": "git+https://github.com/Smithsonian/three-bmfont-text.git#e611dac13d",
Expand Down
17 changes: 17 additions & 0 deletions source/client/annotations/CircleSprite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,23 @@ export default class CircleSprite extends AnnotationSprite
this.update();
}

dispose()
{
this.offset = null;
this.anchorMesh = null;
this.ringMesh = null;
this.ringGeometry = null;
this.ringMaterialA = null;
this.ringMaterialB = null;
this.markerGeometry = null;
this.markerMaterialA = null;
this.markerMaterialB = null;
this.markerA = null;
this.markerB = null;

super.dispose();
}

update()
{
const annotation = this.annotation.data;
Expand Down
1 change: 1 addition & 0 deletions source/client/annotations/ExtendedSprite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ class ExtendedAnnotation extends AnnotationElement

this.contentElement = this.createElement("div", null, this.wrapperElement);
this.contentElement.classList.add("sv-content");
this.contentElement.style.display = "none";
}

protected firstConnected()
Expand Down
39 changes: 34 additions & 5 deletions source/client/applications/ExplorerApplication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { EDerivativeQuality } from "client/schema/model";
import CVARManager from "client/components/CVARManager";
import { EUIElements } from "client/components/CVInterface";
import { EBackgroundStyle } from "client/schema/setup";
import CRenderer from "client/../../libs/ff-scene/source/components/CRenderer";

////////////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -188,6 +189,19 @@ Version: ${ENV_VERSION}
engine.pulse.start();
}

dispose()
{
// Clean up assuming a component disconnect means it won't be reconnected
this.assetReader.dispose();
this.documentProvider.activeComponent.clearNodeTree();
this.system.getMainComponent(CRenderer).views.forEach(view => view.dispose());
//this.documentProvider.activeComponent.setup.node.dispose();
//this.system.graph.clear();
this.documentProvider.activeComponent.setup.tape.dispose();
this.documentProvider.activeComponent.setup.floor.dispose();
this.documentProvider.activeComponent.setup.grid.dispose();
}

setBaseUrl(url: string)
{
this.assetManager.baseUrl = url;
Expand Down Expand Up @@ -281,24 +295,39 @@ Version: ${ENV_VERSION}
// first loading priority: document
props.document = props.root ? props.document : manager.getAssetName(props.document);
this.loadDocument(props.document, undefined, props.quality, props.uiMode)
.then(() => this.assetManager.ins.baseUrlValid.setValue(true))
.catch(error => Notification.show(`Failed to load document: ${error.message}`, "error"));
}
else if (props.model) {
// second loading priority: model
props.model = props.root ? props.model : manager.getAssetName(props.model);
this.loadModel(props.model, props.quality);

this.assetReader.getText(props.model) // make sure we have a valid model path
.then(() => {
this.loadModel(props.model, props.quality);
this.assetManager.ins.baseUrlValid.setValue(true);
})
.catch(error => Notification.show(`Bad Model Path: ${error.message}`, "error"));
}
else if (props.geometry) {
// third loading priority: geometry (plus optional color texture)
props.geometry = props.root ? props.geometry : manager.getAssetName(props.geometry);
props.texture = props.root ? props.texture : manager.getAssetName(props.texture);
props.occlusion = props.root ? props.occlusion : manager.getAssetName(props.occlusion);
props.normals = props.root ? props.normals : manager.getAssetName(props.normals);
this.loadGeometry(props.geometry, props.texture, props.occlusion, props.normals, props.quality);

this.assetReader.getText(props.geometry) // make sure we have a valid geometry path
.then(() => {
this.loadGeometry(props.geometry, props.texture, props.occlusion, props.normals, props.quality);
this.assetManager.ins.baseUrlValid.setValue(true);
})
.catch(error => Notification.show(`Bad Geometry Path: ${error.message}`, "error"));
}
else {
// if nothing else specified, try to read "document.svx.json" from the current folder
this.loadDocument("document.svx.json", undefined).catch(() => {});
else if (props.root) {
// if nothing else specified, try to read "scene.svx.json" from the current folder
this.loadDocument("scene.svx.json", undefined)
.then(() => this.assetManager.ins.baseUrlValid.setValue(true))
.catch(() => {});
}
}

Expand Down
32 changes: 18 additions & 14 deletions source/client/components/CVARManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,17 +175,17 @@ export default class CVARManager extends Component
}

protected launchWebXR() {
const renderer = this.renderer.views[0].renderer;
const sceneComponent = this.vScene = this.renderer.activeSceneComponent;
const camera = this.camera = sceneComponent.activeCamera;
const renderer = this.renderer?.views[0].renderer;
const sceneComponent = this.vScene = this.renderer?.activeSceneComponent;
const camera = this.camera = sceneComponent?.activeCamera;
this.cameraParent = camera.parent;
const setup = this.setup = this.getSystemComponent(CVSetup); //this.documentProvider.outs.activeDocument.value.setup;

if(!setup) {
return false;
}

const models = this.sceneNode.getGraphComponents(CVModel2);
const models = this.sceneNode?.getGraphComponents(CVModel2);
const derivative = models[0] ? models[0].derivatives.get(EDerivativeUsage.Web3D, EDerivativeQuality.AR) : null;

if(derivative) {
Expand Down Expand Up @@ -279,6 +279,9 @@ export default class CVARManager extends Component
this.inputSource = null;
this.xrCamera = null;
this.cachedView = null;
this.vScene = null;
this.cachedView = null;
this.camera = null;

const session = this.session;
if(session) {
Expand Down Expand Up @@ -466,15 +469,16 @@ export default class CVARManager extends Component
protected render = (timestamp, frame) => {
this.frame = frame;
const renderer = this.renderer.views[0].renderer;
const {camera, xrCamera} = this;
const {camera, xrCamera, refSpace, initialHitTestSource, vScene, sceneNode,
shadow, lastFrameTime} = this;

if(!frame || !frame.getViewerPose(this.refSpace!)) {
if(!frame || !frame.getViewerPose(refSpace!)) {
return;
}

// Get xr camera from Three.js to set local camera properties. TODO: More efficient use of xrcamera
if(!xrCamera && this.session) {
const xrCameraArray : ArrayCamera = renderer.xr.getCamera(this.camera) as ArrayCamera;
const xrCameraArray : ArrayCamera = renderer.xr.getCamera(camera) as ArrayCamera;
this.xrCamera = xrCameraArray.cameras[0];
return;
}
Expand All @@ -487,10 +491,10 @@ export default class CVARManager extends Component
}

// center model in front of camera while trying for initial placement
if (this.initialHitTestSource != null && xrCamera) {
const scene = this.vScene.scene;
if (initialHitTestSource != null && xrCamera) {
const scene = vScene.scene;
const {position} = scene;
const radius = this.sceneNode.outs.boundingRadius.value * 2.0 + xrCamera.near; // Math.abs(this.optimalCameraDistance);
const radius = sceneNode.outs.boundingRadius.value * 2.0 + xrCamera.near; // Math.abs(this.optimalCameraDistance);

const e = xrCamera.matrixWorld.elements;
position.set(-e[ 8 ], -e[ 9 ], -e[ 10 ]).normalize();
Expand All @@ -510,7 +514,7 @@ export default class CVARManager extends Component

if(this.outs.isPlaced.value) {
// update selection ring opacity
const deltaT = timestamp - this.lastFrameTime;
const deltaT = timestamp - lastFrameTime;
this.updateOpacity(deltaT, this.targetOpacity);
this.lastFrameTime = timestamp;
}
Expand All @@ -522,12 +526,12 @@ export default class CVARManager extends Component
gl.clear(gl.DEPTH_BUFFER_BIT);
gl.depthMask(true);

if(this.shadow.needsUpdate) {
if(shadow.needsUpdate) {
renderer.shadowMap.needsUpdate = true;
this.shadow.needsUpdate = false;
shadow.needsUpdate = false;
}

renderer.render( this.vScene.scene, this.camera );
renderer.render( vScene.scene, camera );
}

// adapted from model-viewer
Expand Down
19 changes: 7 additions & 12 deletions source/client/components/CVAnnotationView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,17 +329,6 @@ export default class CVAnnotationView extends CObject3D
this.language.addLanguage(ELanguageType[key]);
});

// set webgl2 for circle annotations
for (const key in this._annotations) {
const annotation = this._annotations[key];
if(annotation.get("style") === "Circle") {
const sprite = this._sprites[annotation.id] as CircleSprite;
if (sprite) {
sprite.isWebGL2 = this.renderer.views[0].renderer.capabilities.isWebGL2;
}
}
}

this.changed = true;
}

Expand Down Expand Up @@ -481,16 +470,22 @@ export default class CVAnnotationView extends CObject3D
protected createSprite(annotation: Annotation)
{
this.removeSprite(annotation);
const isCircle = annotation.data.style === "Circle";

// TODO: Combine when font loading is centralized
const sprite = annotation.data.style === "Circle" ? AnnotationFactory.createInstance(annotation, "Circle", this.assetReader) : AnnotationFactory.createInstance(annotation);
const sprite = isCircle ? AnnotationFactory.createInstance(annotation, "Circle", this.assetReader) : AnnotationFactory.createInstance(annotation);

sprite.addEventListener("click", this.onSpriteClick);
sprite.addEventListener("link", this.onSpriteLink);

this._sprites[annotation.id] = sprite;
this.object3D.add(sprite);
this.registerPickableObject3D(sprite, true);

// set webgl2 for circle annotations
if (isCircle) {
(sprite as CircleSprite).isWebGL2 = this.renderer.views[0].renderer.capabilities.isWebGL2;
}
}

protected removeSprite(annotation: Annotation)
Expand Down
Loading

0 comments on commit ecedef4

Please sign in to comment.