Skip to content

Commit

Permalink
Merge pull request #131 from Smithsonian/dev-bugfix
Browse files Browse the repository at this point in the history
Merging update branch
  • Loading branch information
gjcope authored May 2, 2022
2 parents 160996d + 7c0f0e8 commit fdd20e7
Show file tree
Hide file tree
Showing 25 changed files with 3,037 additions and 13,071 deletions.
9,471 changes: 2,572 additions & 6,899 deletions 3RD_PARTY_LICENSES.txt

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions docs/content/explorer/api/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ Methods for external control over camera properties and navigation.

| Name | Parameters | Description |
|-------------------------------|----------------------------------------------|----------------------------------------------|
| setCameraOrbit(yaw, pitch) | yaw, pitch: angle in degrees | Sets yaw and pitch of orbit navigation. |
| getCameraOrbit() | None | Returns an array [yaw, pitch] in radians. |
| setCameraOrbit(yaw, pitch) | yaw, pitch: angle in degrees | Sets yaw and pitch of orbit navigation. |
| getCameraOrbit() | None | Returns an array [yaw, pitch] in radians. |
| setCameraOffset(x, y, z) | x, y, z: coordinate in scene units | Sets offset of orbit navigation. |
| getCameraOffset() | None | Returns an array [x, y, z] in scene units. |

### Misc Methods

Expand All @@ -72,4 +74,5 @@ Methods for external control over camera properties and navigation.

| Name | Description |
|-------------------------------|------------------------------------------------------------------------|
| annotation-active | This event is fired when the active state of an annotation changes. event.detail will contain the ID of the activated annotation, or will be empty if no annotation is active.|
| annotation-active | This event is fired when the active state of an annotation changes. event.detail will contain the ID of the activated annotation, or will be empty if no annotation is active.|
| model-load | This event fires every time a model finishes loading. event.detail will contain the quality [(EDerivativeQuality)](https://github.com/Smithsonian/dpo-voyager/blob/master/source/client/schema/model.ts) of the loaded model. This will likely fire multiple times depending on the number of derivatives loaded and unloaded.|
2 changes: 1 addition & 1 deletion libs/ff-scene
2 changes: 1 addition & 1 deletion libs/ff-three
6,226 changes: 237 additions & 5,989 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"homepage": "https://github.com/Smithsonian/dpo-voyager#readme",
"dependencies": {
"ajv": "^8.6.2",
"buffer": "^6.0.3",
"client-zip": "^2.0.0",
"clone-deep": "^4.0.1",
"express": "^4.17.1",
Expand All @@ -58,20 +59,20 @@
"hotkeys-js": "^3.8.7",
"lit-element": "^2.5.1",
"lit-html": "^1.4.1",
"moment": "^2.27.0",
"moment": "^2.29.2",
"morgan": "^1.10.0",
"nodemon": "^2.0.12",
"postcss": "^8.3.6",
"process": "^0.11.10",
"quill": "^1.3.7",
"quill-image-resize-module": "^3.0.0",
"readable-stream": "^3.6.0",
"resolve-pathname": "^3.0.0",
"simple-dropzone": "^0.8.1",
"sanitize-html": "^2.5.1",
"simple-dropzone": "^0.8.1",
"stream-browserify": "^3.0.0",
"style-loader": "^3.3.1",
"three": "^0.137.5",
"three-bmfont-text": "git+https://github.com/Smithsonian/three-bmfont-text.git#e611dac13d",
"tinymce": "^6.0.1",
"toposort": "^2.0.2",
"webdav": "^4.7.0",
"webdav-server": "^2.6.2",
Expand All @@ -90,7 +91,6 @@
"handlebars-loader": "^1.7.1",
"html-webpack-plugin": "^5.3.2",
"license-checker": "^25.0.1",
"madge": "^5.0.1",
"mini-css-extract-plugin": "^2.2.0",
"mocha": "^9.2.0",
"node-sass": "^7.0.1",
Expand Down
13 changes: 8 additions & 5 deletions source/client/components/CVARManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export default class CVARManager extends Component
protected cachedView: RenderView = null;
protected cachedQuality: EDerivativeQuality = null;
protected cachedNearPlane: number = 0.0;
protected cachedFarPlane: number = 0.0;
protected xrCamera: PerspectiveCamera = null;
protected hitPlane: Mesh = null;
protected selectionRing: Mesh = null;
Expand Down Expand Up @@ -375,11 +376,12 @@ export default class CVARManager extends Component
const size = Math.max(_vector3.x / this.camera.aspect, _vector3.y);
const fovFactor = 1 / (2 * Math.tan(this.camera.fov * (180/Math.PI) * 0.5));
this.optimalCameraDistance = (_vector3b.z + size * fovFactor + _vector3.z * 0.75);*/

this.cachedNearPlane = this.camera.near;
if(Math.max(_vector3.x, _vector3.y, _vector3.z) < 0.5) {
this.camera.near = 0.01;
}
this.cachedFarPlane = this.camera.far;
// May want to set these to more dynamic values
this.vScene.activeCameraComponent.ins.near.setValue(0.01);
this.vScene.activeCameraComponent.ins.far.setValue(1000);
}

protected resetScene() {
Expand All @@ -392,7 +394,8 @@ export default class CVARManager extends Component
}
camera.position.set(0, 0, 0);
camera.rotation.set(0, 0, 0);
camera.near = this.cachedNearPlane;
this.vScene.activeCameraComponent.ins.near.setValue(this.cachedNearPlane);
this.vScene.activeCameraComponent.ins.far.setValue(this.cachedFarPlane);
camera.updateMatrix();

// reset lights
Expand Down
17 changes: 17 additions & 0 deletions source/client/components/CVMediaManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import CAssetManager, { IAssetOpenEvent, IFileInfo, IAssetTreeChangeEvent, IAsse
import Notification from "@ff/ui/Notification";
import CVStandaloneFileManager from "./CVStandaloneFileManager";
import CVAssetManager from "./CVAssetManager";
import resolvePathname from "resolve-pathname";

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

Expand Down Expand Up @@ -71,6 +72,22 @@ export default class CVMediaManager extends CAssetManager
});
}

uploadFile(name: string, blob: Blob, folder: IAssetEntry): Promise<any>
{
const filename = decodeURI(name);
const url = resolvePathname(folder.info.path + filename, this.rootUrl);

if(this.standaloneFileManager) {
this.standaloneFileManager.addFile(CVMediaManager.articleFolder + "/" + filename, [blob]);
this.refresh();
return Promise.resolve();
}
else {
const params: RequestInit = { method: "PUT", credentials: "include", body: new File([blob], filename) };
return fetch(url, params).then(() => this.refresh());
}
}

refresh()
{
const standaloneManager = this.standaloneFileManager;
Expand Down
19 changes: 16 additions & 3 deletions source/client/components/CVModel2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ const _box = new Box3();
export interface ITagUpdateEvent extends ITypedEvent<"tag-update">
{
}
export interface IModelLoadEvent extends ITypedEvent<"model-load">
{
quality: EDerivativeQuality;
}

/**
* Graph component rendering a model or model part.
Expand Down Expand Up @@ -364,8 +368,13 @@ export default class CVModel2 extends CObject3D
this._boxFrame = new (Box3Helper as any)(boundingBox, "#009cde");
this.addObject3D(this._boxFrame);
this._boxFrame.updateMatrixWorld(true);


const setup = this.getGraphComponent(CVSetup);
if(setup.navigation.ins.autoZoom.value) {
setup.navigation.ins.zoomExtents.set();
}
outs.updated.set();
this.updateUnitScale();
}

if (data.derivatives) {
Expand Down Expand Up @@ -566,7 +575,7 @@ export default class CVModel2 extends CObject3D
*/
protected autoLoad(quality: EDerivativeQuality): Promise<void>
{
const sequence = [];
const sequence : Derivative[] = [];

const lowestQualityDerivative = this.derivatives.select(EDerivativeUsage.Web3D, EDerivativeQuality.Thumb);
if (lowestQualityDerivative) {
Expand All @@ -585,7 +594,7 @@ export default class CVModel2 extends CObject3D

// load sequence of derivatives one by one
return sequence.reduce((promise, derivative) => {
return promise.then(() => this.loadDerivative(derivative));
return promise.then(() => { this.loadDerivative(derivative)});
}, Promise.resolve());
}

Expand Down Expand Up @@ -627,6 +636,7 @@ export default class CVModel2 extends CObject3D
}

// update bounding box based on loaded derivative
this._localBoundingBox.makeEmpty();
helpers.computeLocalBoundingBox(derivative.model, this._localBoundingBox);
this.outs.updated.set();

Expand Down Expand Up @@ -669,6 +679,9 @@ export default class CVModel2 extends CObject3D
const overlayOptions = ["None"];
overlayOptions.push(...derivative.findAssets(EAssetType.Image).filter(image => image.data.mapType === EMapType.Zone).map(image => image.data.uri));
this.ins.overlayMap.setOptions(overlayOptions);

this.emit<IModelLoadEvent>({ type: "model-load", quality: derivative.data.quality });
//this.getGraphComponent(CVSetup).navigation.ins.zoomExtents.set();
})
.catch(error => Notification.show(`Failed to load model derivative: ${error.message}`));
}
Expand Down
28 changes: 11 additions & 17 deletions source/client/components/CVOrbitNavigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,10 @@ export default class CVOrbitNavigation extends CObject3D
this.system.on<ITriggerEvent>("wheel", this.onTrigger, this);

this.assetManager.outs.completed.on("value", this.onLoadingCompleted, this);
this.sceneNode.outs.boundingBox.on("value", this.onBoundsUpdate, this);
}

dispose()
{
this.sceneNode.outs.boundingBox.off("value", this.onBoundsUpdate, this);
this.assetManager.outs.completed.off("value", this.onLoadingCompleted, this);

this.system.off<IPointerEvent>(["pointer-down", "pointer-up", "pointer-move"], this.onPointer, this);
Expand Down Expand Up @@ -166,14 +164,6 @@ export default class CVOrbitNavigation extends CObject3D
orbit.setValue(_orientationPresets[preset.getValidatedValue()].slice());
}

// zoom extents
if (camera && ins.zoomExtents.changed) {
const scene = this.getGraphComponent(CVScene);
this._modelBoundingBox = scene.outs.boundingBox.value;
controller.zoomExtents(this._modelBoundingBox);
cameraComponent.ins.zoom.set();
}

// include lights
if (ins.lightsFollowCamera.changed) {
const lightTransform = this.getLightTransform();
Expand Down Expand Up @@ -205,6 +195,17 @@ export default class CVOrbitNavigation extends CObject3D
controller.maxOffset.fromArray(maxOffset.value);
}

// zoom extents
if (camera && ins.zoomExtents.changed /*&& !this.assetManager.loadingManager.isBusy*/) {
const scene = this.getGraphComponent(CVScene);
if(scene.models.some(model => model.outs.updated.changed)) {
scene.update(null);
}
this._modelBoundingBox = scene.outs.boundingBox.value;
controller.zoomExtents(this._modelBoundingBox);
cameraComponent.ins.zoom.set();
}

return true;
}

Expand Down Expand Up @@ -364,11 +365,4 @@ export default class CVOrbitNavigation extends CObject3D
this.ins.zoomExtents.set();
}
}

protected onBoundsUpdate()
{
if (this.ins.autoZoom.value) {
this.ins.zoomExtents.set();
}
}
}
35 changes: 21 additions & 14 deletions source/client/components/CVScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,27 +203,34 @@ export default class CVScene extends CVNode

protected updateCameras()
{
// Only dynamically update near/far planes when we are editing a scene
if(!!this.system.getComponent("CVStoryApplication", true)) {
if(this.setup.navigation.ins.autoZoom.value) {
this.setup.navigation.ins.offset.once("value", this.updateCameraHelper);
}
else {
this.updateCameraHelper();
}
// Make sure max zoom is less than far plane.
if(this.setup.navigation.ins.autoZoom.value) {
this.setup.navigation.ins.offset.once("value", this.updateCameraHelper);
}
else {
this.updateCameraHelper();
}
}

protected updateCameraHelper = () =>
{
this.cameras.forEach(camera => {
const navOffset = this.setup.navigation.ins.offset.value;
const orbitRadius = _vec3.set(navOffset[0], navOffset[1], navOffset[2]).length()
const navOffset = this.setup.navigation.ins.offset.value;
const orbitRadius = _vec3.set(navOffset[0], navOffset[1], navOffset[2]).length();

if(!this.system.getComponent("CVStoryApplication", true)) {
const maxOffset = 2 * Math.max(orbitRadius, this.outs.boundingRadius.value);
const currOffset = this.setup.navigation.ins.maxOffset.value;
const zOffset = navOffset[2] < currOffset[2] ? Math.min(currOffset[2], maxOffset) : maxOffset;
this.setup.navigation.ins.maxOffset.setValue([currOffset[0], currOffset[1], zOffset]);
}

const far = 3 * Math.max(orbitRadius, this.outs.boundingRadius.value);
this.cameras.forEach(camera => {
const far = 4 * Math.max(orbitRadius, this.outs.boundingRadius.value);
const near = far / 1000.0;
camera.ins.far.setValue(far);
camera.ins.near.setValue(near);
if(far < camera.ins.far.value || camera.ins.far.value < 2*this.setup.navigation.ins.maxOffset.value[2]) {
camera.ins.far.setValue(far);
camera.ins.near.setValue(near);
}
});
}
}
7 changes: 7 additions & 0 deletions source/client/components/CVStandaloneFileManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ export default class CVStandaloneFileManager extends Component

this.rootMap[filename] = rootPath;
this.fileMap[uri] = new File(data, filename);

if(this.runtimeURLs[uri]) {
this.runtimeURLs[uri] = null;
}
}

deleteFile(uri: string)
Expand Down Expand Up @@ -198,6 +202,9 @@ export default class CVStandaloneFileManager extends Component
const baseURL = this.rootMap[filename] + filename;
const normalizedURL = baseURL.startsWith("/") ? baseURL.substr(1) : baseURL; // strip potential leading slash

if(this.runtimeURLs[normalizedURL]) {
return this.runtimeURLs[normalizedURL];
}
if(this.fileMap[normalizedURL]) {
const bloburl = URL.createObjectURL( this.fileMap[normalizedURL] );
this.runtimeURLs[normalizedURL] = bloburl;
Expand Down
8 changes: 7 additions & 1 deletion source/client/components/CVViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import CRenderer from "@ff/scene/components/CRenderer";
import { EShaderMode, IViewer, TShaderMode } from "client/schema/setup";
import { EDerivativeQuality } from "client/schema/model";

import CVModel2 from "./CVModel2";
import CVModel2, { IModelLoadEvent } from "./CVModel2";
import CVAnnotationView, { IAnnotationClickEvent, ITagUpdateEvent } from "./CVAnnotationView";
import CVAnalytics from "./CVAnalytics";
import CVLanguageManager from "./CVLanguageManager";
Expand Down Expand Up @@ -277,9 +277,11 @@ export default class CVViewer extends Component

if (event.add) {
component.on<ITagUpdateEvent>("tag-update", this.refreshTagCloud, this);
component.on<IModelLoadEvent>("model-load", this.onModelLoad, this);
}
else if (event.remove) {
component.off<ITagUpdateEvent>("tag-update", this.refreshTagCloud, this);
component.off<IModelLoadEvent>("model-load", this.onModelLoad, this);
}
}

Expand Down Expand Up @@ -309,4 +311,8 @@ export default class CVViewer extends Component
component.off<ITagUpdateEvent>("tag-update", this.refreshTagCloud, this);
}
}

protected onModelLoad(event: IModelLoadEvent) {
this.rootElement.dispatchEvent(new CustomEvent('model-load', { detail: EDerivativeQuality[event.quality] }));
}
}
1 change: 1 addition & 0 deletions source/client/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ declare module '!raw-loader!*' {
}

declare module "*.scss";
declare module "*.css";

// Webpack constant: build version
declare const ENV_VERSION: string;
Expand Down
18 changes: 9 additions & 9 deletions source/client/nodes/NVScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ export default class NVScene extends NVNode

this.scene.fromDocument(document, scene);

// serialize additional scene components
if (isFinite(scene.meta)) {
this.meta.fromDocument(document, scene);
pathMap.set(`meta/${scene.meta}`, this.meta);
}
if (isFinite(scene.setup)) {
this.setup.fromDocument(document, sceneIndex, pathMap);
}

// serialize node tree
const nodeIndices = scene.nodes;
if (nodeIndices) {
Expand All @@ -60,15 +69,6 @@ export default class NVScene extends NVNode
childNode.fromDocument(document, nodeIndex, pathMap);
});
}

// serialize additional scene components
if (isFinite(scene.meta)) {
this.meta.fromDocument(document, scene);
pathMap.set(`meta/${scene.meta}`, this.meta);
}
if (isFinite(scene.setup)) {
this.setup.fromDocument(document, sceneIndex, pathMap);
}
}

toDocument(document: IDocument, pathMap: Map<Component, string>, components?: INodeComponents): number
Expand Down
Loading

0 comments on commit fdd20e7

Please sign in to comment.