Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: COXP-3500 Reset camera issue in Box3D #47

Merged
merged 14 commits into from
Apr 5, 2017
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const X_REP_HINT_VIDEO_MP4 = '[mp4]';
// whenever a file in that third party directory is updated
export const DOC_STATIC_ASSETS_VERSION = '0.114.0';
export const MEDIA_STATIC_ASSETS_VERSION = '0.112.0';
export const MODEL3D_STATIC_ASSETS_VERSION = '0.112.0';
export const MODEL3D_STATIC_ASSETS_VERSION = '0.114.0';
export const SWF_STATIC_ASSETS_VERSION = '0.112.0';
export const TEXT_STATIC_ASSETS_VERSION = '0.114.0';

Expand Down
15 changes: 0 additions & 15 deletions src/lib/viewers/box3d/Box3dRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ class Box3DRenderer extends EventEmitter {
super();

this.containerEl = containerEl;
// Instances and assets created, that are not scene default entities, are
// tracked for cleanup during recycling of box3d runtime
this.assets = [];
this.vrEnabled = false;
this.vrGamepads = [];
this.box3d = null;
Expand Down Expand Up @@ -125,18 +122,6 @@ class Box3DRenderer extends EventEmitter {
return this.box3d ? this.box3d.getObjectById('CAMERA_ID') : null;
}

/**
* Get the current aspect ratio of the preview area.
*
* @private
* @return {number} Aspect ratio of the preview area
*/
getAspect() {
const width = this.containerEl.clientWidth;
const height = this.containerEl.clientHeight;
return width / height;
}

/**
* Get the scene object.
*
Expand Down
11 changes: 0 additions & 11 deletions src/lib/viewers/box3d/__tests__/Box3dRenderer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,6 @@ describe('lib/viewers/box3d/Box3dRenderer', () => {
});
});

describe('getAspect()', () => {
it('should return aspect ratio of container element', () => {
renderer.containerEl = {
clientWidth: 5,
clientHeight: 10
};

expect(renderer.getAspect()).to.equal(0.5);
});
});

describe('getScene()', () => {
it('should return the scene prefab that exists in the Box3D runtime', () => {
renderer.box3d = {
Expand Down
46 changes: 7 additions & 39 deletions src/lib/viewers/box3d/model3d/Model3dRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,18 +145,17 @@ class Model3dRenderer extends Box3DRenderer {
renderModes.setAttribute('shapeTexture', 'MAT_CAP_TEX');

return this.box3d.addRemoteEntities(assetUrl)
.then((entities) => this.setupScene(entities), () => this.onUnsupportedRepresentation());
.then(() => this.setupScene(), () => this.onUnsupportedRepresentation());
}

/**
* Setup scene ground visualization grid, optimize materials for rendering, and create prefabs to
* create the scene with.
*
* @private
* @param {Box3DEntity[]} entities - A list of Box3DEntities to add to the scene and render.
* @return {void}
*/
setupScene(entities) {
setupScene() {
const scene = this.getScene();
if (!scene) {
return;
Expand All @@ -166,14 +165,6 @@ class Model3dRenderer extends Box3DRenderer {
this.createPrefabInstances();
this.addHelpersToScene();
scene.when('load', () => this.onSceneLoad());

// Make sure we add ALL assets to the asset list to destroy
entities.forEach((entity) => {
if (entity.id === entity.parentAssetId) {
const asset = this.box3d.getAssetById(entity.id);
this.assets.push(asset);
}
});
}

/**
Expand Down Expand Up @@ -311,15 +302,13 @@ class Model3dRenderer extends Box3DRenderer {

// Set the origin point (so that we always point at the center of the model when the camera reloads)
orbitController.originPoint.copy(center);
orbitController.setPivotPosition(center);
orbitController.reset();
const distance = PREVIEW_CAMERA_ORBIT_DISTANCE_FACTOR * Math.max(Math.max(maxDimension.x, maxDimension.y), maxDimension.z);
orbitController.setOrbitDistance(distance);
}

/** @inheritdoc */
onSceneLoad() {
this.reset();

// Reset the skeleton visualization.
this.resetSkeletons();

Expand Down Expand Up @@ -536,18 +525,6 @@ class Model3dRenderer extends Box3DRenderer {
*/
cleanupScene() {
this.cleanupHelpers();

if (this.instance) {
this.instance.destroy();
this.instance = null;
}

this.assets.forEach((asset) => {
asset.destroy();
});

this.assets.length = 0;

this.resetSkeletons();
}

Expand Down Expand Up @@ -589,29 +566,20 @@ class Model3dRenderer extends Box3DRenderer {
return;
}

const aspect = this.getAspect();

switch (projection) {
case CAMERA_PROJECTION_ORTHOGRAPHIC:
camera.setProperties({
top: 0.5,
bottom: -0.5,
left: -0.5 * aspect,
right: 0.5 * aspect,
cameraType: 'orthographic'
});
camera.setProperty('cameraType', 'orthographic');
break;

case CAMERA_PROJECTION_PERSPECTIVE:
camera.setProperties({
aspect,
cameraType: 'perspective'
});
camera.setProperty('cameraType', 'perspective');
break;

default:
break;
}

this.resetView();
}

/**
Expand Down
114 changes: 18 additions & 96 deletions src/lib/viewers/box3d/model3d/__tests__/Model3dRenderer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,8 @@ describe('lib/viewers/box3d/model3d/Model3dRenderer', () => {
});

it('should setup the scene via setupScene() if it can successfully load the model', (done) => {
const entities = [];
renderMock.expects('setupScene').withArgs(entities);
sandbox.mock(renderer.box3d).expects('addRemoteEntities').returns(Promise.resolve(entities));
renderMock.expects('setupScene').called;
sandbox.mock(renderer.box3d).expects('addRemoteEntities').returns(Promise.resolve());
renderer.loadBox3dFile('').then(() => done());
});

Expand Down Expand Up @@ -242,39 +241,6 @@ describe('lib/viewers/box3d/model3d/Model3dRenderer', () => {
sandbox.mock(scene).expects('when').withArgs('load');
renderer.setupScene([]);
});

it('should track ONLY the asset entities added to the scene, for cleanup later', () => {
const one = {
id: '1',
parentAssetId: '1',
destroy: () => {}
};
const two = {
id: '2',
parentAssetId: '2',
destroy: () => {}
};
const fail = {
id: '3',
parentAssetId: 'another_entity',
destroy: () => {}
};
const entities = [one, two, fail];
sandbox.stub(renderer.box3d, 'getAssetById', (id) => {
switch (id) {
case '1':
return one;
case '2':
return two;
default:
return undefined;
}
});
sandbox.stub(renderer, 'getScene').returns(scene);
renderer.setupScene(entities);

expect(renderer.assets).to.deep.equal([one, two]);
});
});

describe('optimizeMaterials()', () => {
Expand Down Expand Up @@ -532,8 +498,8 @@ describe('lib/viewers/box3d/model3d/Model3dRenderer', () => {
sandbox.stub(THREE.Vector3.prototype, 'applyMatrix4');
orbitComp = {
originPoint: new THREE.Vector3(),
setPivotPosition: () => {},
setOrbitDistance: () => {}
setOrbitDistance: () => {},
reset: () => {}
};
camera = {
getComponentByScriptId: () => {}
Expand Down Expand Up @@ -586,11 +552,9 @@ describe('lib/viewers/box3d/model3d/Model3dRenderer', () => {
renderer.resetView();
});

it('should set the pivot point of the orbitController component to the center of the model', () => {
const center = new THREE.Vector3(9, 9, 9);
it('should call the reset method of the orbitController component', () => {
sandbox.mock(camera).expects('getComponentByScriptId').returns(orbitComp);
sandbox.mock(renderer.instance).expects('getCenter').returns(center);
sandbox.mock(orbitComp).expects('setPivotPosition').withArgs(center);
sandbox.mock(orbitComp).expects('reset');
renderer.resetView();
});

Expand All @@ -599,7 +563,6 @@ describe('lib/viewers/box3d/model3d/Model3dRenderer', () => {
sandbox.mock(orbitComp).expects('setOrbitDistance');
sandbox.mock(camera).expects('getComponentByScriptId').returns(orbitComp);
sandbox.mock(renderer.instance).expects('getCenter').returns(center);
sandbox.mock(orbitComp).expects('setPivotPosition').withArgs(center);
renderer.resetView();
});
});
Expand Down Expand Up @@ -632,12 +595,6 @@ describe('lib/viewers/box3d/model3d/Model3dRenderer', () => {
videos.length = 0;
});

it('should reset the scene via reset()', () => {
sandbox.stub(Promise, 'all').returns({ then: () => {} });
renderMock.expects('reset');
renderer.onSceneLoad();
});

it('should collect all assets that are loading', () => {
sandbox.stub(Promise, 'all').returns({ then: () => {} });
const anim = {
Expand Down Expand Up @@ -1104,25 +1061,6 @@ describe('lib/viewers/box3d/model3d/Model3dRenderer', () => {
renderer.cleanupScene();
});

it('should destroy the model instance if it exists', () => {
const inst = {
destroy: sandbox.stub()
};
renderer.instance = inst;
renderer.cleanupScene();
expect(inst.destroy).to.be.called;
expect(renderer.instance).to.not.exist;
});

it('should destroy all assets that were tracked', () => {
const asset = {
destroy: sandbox.stub()
};
renderer.assets.push(asset);
renderer.cleanupScene();
expect(asset.destroy).to.be.called;
});

it('should invoke resetSkeletons()', () => {
sandbox.mock(renderer).expects('resetSkeletons');
renderer.cleanupScene();
Expand Down Expand Up @@ -1159,57 +1097,41 @@ describe('lib/viewers/box3d/model3d/Model3dRenderer', () => {
let camera;
beforeEach(() => {
camera = {
setProperties: () => {}
setProperty: () => {},
getProperty: () => { return 'perspective'; }
};
});

it('should do nothing if no camera is present', () => {
it('should not throw error if no camera is present', () => {
const mock = sandbox.mock(renderer);
mock.expects('getAspect').never();
mock.expects('getCamera').returns(undefined);
renderer.setCameraProjection(CAMERA_PROJECTION_PERSPECTIVE);
});

it('should get the aspect ratio of the camera for operations', () => {
const mock = sandbox.mock(renderer);
mock.expects('getAspect');
mock.expects('getCamera').returns(camera);
renderer.setCameraProjection(CAMERA_PROJECTION_PERSPECTIVE);
expect(renderer.setCameraProjection(CAMERA_PROJECTION_PERSPECTIVE)).to.not.throw;
});

it('should set the perspective properties of the camera if perspective mode is selected', (done) => {
sandbox.stub(renderer, 'getCamera').returns(camera);
sandbox.stub(renderer, 'getAspect').returns(2);
sandbox.stub(camera, 'setProperties', (props) => {
expect(props).to.deep.equal({
aspect: 2,
cameraType: 'perspective'
});
sandbox.stub(camera, 'setProperty', (prop, value) => {
expect(prop).to.equal('cameraType');
expect(value).to.equal('perspective');
done();
});
renderer.setCameraProjection(CAMERA_PROJECTION_PERSPECTIVE);
});

it('should set the orthographic properties of the camera if ortho mode is selected', (done) => {
sandbox.stub(renderer, 'getCamera').returns(camera);
sandbox.stub(renderer, 'getAspect').returns(2);
sandbox.stub(camera, 'setProperties', (props) => {
expect(props).to.deep.equal({
top: 0.5,
bottom: -0.5,
left: -1,
right: 1,
cameraType: 'orthographic'
});
sandbox.stub(camera, 'setProperty', (prop, value) => {
expect(prop).to.equal('cameraType');
expect(value).to.equal('orthographic');
done();
});
renderer.setCameraProjection(CAMERA_PROJECTION_ORTHOGRAPHIC);
});

it('should do nothing for unrecognized projection type', () => {
sandbox.stub(renderer, 'getCamera').returns(camera);
sandbox.stub(renderer, 'getAspect').returns(2);
sandbox.mock(camera).expects('setProperties').never();
sandbox.stub(renderer, 'resetView');
sandbox.mock(camera).expects('setProperty').never();
renderer.setCameraProjection('weak_perspective_projection');
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/third-party/model3d/0.112.0/box3d-runtime.min.js

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions src/third-party/model3d/0.114.0/box3d-runtime.min.js

Large diffs are not rendered by default.