Skip to content

Commit

Permalink
Fix memory leak when switching from first person view
Browse files Browse the repository at this point in the history
  • Loading branch information
danilosalvati committed Oct 24, 2016
1 parent d304ee2 commit 3d78ee9
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 14 deletions.
51 changes: 51 additions & 0 deletions src/components/viewer3d/three-memory-cleaner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
function disposeGeometry(geometry) {
geometry.dispose();
}

function disposeTexture(texture) {
if (!texture) {
return;
}
texture.dispose();
}

function disposeMultimaterial(material) {
if (!(material instanceof Three.MultiMaterial)) {
return;
}
material.materials.forEach(material => {
disposeMaterial(material);
});

}

function disposeMaterial(material) {
if (!(material instanceof Three.Material)) {
return;
}

disposeTexture(material.map);
material.dispose();
}

function disposeMesh(scene3D, mesh) {
if (!(mesh instanceof Three.Mesh || mesh instanceof Three.BoxHelper)) {
return;
}
scene3D.remove(mesh);
disposeGeometry(mesh.geometry);
disposeMultimaterial(mesh.material);
disposeMaterial(mesh.material);
}

export function disposeScene(scene3D) {
scene3D.traverse(child => {
disposeMesh(scene3D, child);
});
}

export function disposeObject(scene3D, object) {
object.traverse(child => {
disposeMesh(scene3D, child);
});
}
33 changes: 19 additions & 14 deletions src/components/viewer3d/viewer3d-first-person.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from 'react';
import ReactDOM from 'react-dom';
import Three from 'three';
import {parseData, updateScene} from './scene-creator';
import {disposeScene} from './three-memory-cleaner';
import diff from 'immutablediff';
import {initPointerLock} from "./pointer-lock-navigation";
import {firstPersonOnKeyDown, firstPersonOnKeyUp} from "./libs/first-person-controls";
Expand All @@ -17,9 +18,10 @@ export default class Viewer3DFirstPerson extends React.Component {
this.width = props.width;
this.height = props.height;
this.stopRendering = false;
this.renderer = window.__threeRenderer || new Three.WebGLRenderer();
window.__threeRenderer = this.renderer;
}


componentDidMount() {

/** Variables for movement control **/
Expand All @@ -42,9 +44,8 @@ export default class Viewer3DFirstPerson extends React.Component {
let sceneOnTop = new Three.Scene();

//RENDERER
let renderer = new Three.WebGLRenderer();
renderer.setClearColor(new Three.Color(0xffffff));
renderer.setSize(this.width, this.height);
this.renderer.setClearColor(new Three.Color(0xffffff));
this.renderer.setSize(this.width, this.height);

// LOAD DATA
let planData = parseData(data, editingActions, catalog);
Expand Down Expand Up @@ -82,7 +83,7 @@ export default class Viewer3DFirstPerson extends React.Component {

document.body.requestPointerLock();

this.controls = initPointerLock(camera, renderer.domElement);
this.controls = initPointerLock(camera, this.renderer.domElement);

/* Set user initial position */
let humanHeight = {length: 1.70, unit: 'm'};
Expand Down Expand Up @@ -157,12 +158,12 @@ export default class Viewer3DFirstPerson extends React.Component {

this.firstPersonMouseDown = (event) => {

console.log("I clicked in first person view!")

// First of all I check if controls are enabled

if (this.controls.enabled) {

console.log(this.renderer.info.memory.geometries, this.renderer.info.memory.textures, this.renderer.info.render);

event.preventDefault();

/* Per avere la direzione da assegnare al raycaster, chiamo il metodo getDirection di PointerLockControls,
Expand All @@ -184,8 +185,8 @@ export default class Viewer3DFirstPerson extends React.Component {
document.addEventListener('mousedown', this.firstPersonMouseDown, false);

// add the output of the renderer to the html element
canvasWrapper.appendChild(renderer.domElement);
renderer.autoClear = false;
canvasWrapper.appendChild(this.renderer.domElement);
this.renderer.autoClear = false;

let controls = this.controls;

Expand All @@ -208,10 +209,10 @@ export default class Viewer3DFirstPerson extends React.Component {

prevTime = time;

renderer.clear(); // clear buffers
renderer.render(scene3D, camera); // render scene 1
renderer.clearDepth(); // clear depth buffer
renderer.render(sceneOnTop, camera); // render scene 2
this.renderer.clear(); // clear buffers
this.renderer.render(scene3D, camera); // render scene 1
this.renderer.clearDepth(); // clear depth buffer
this.renderer.render(sceneOnTop, camera); // render scene 2

if (!this.stopRendering) {
requestAnimationFrame(render);
Expand All @@ -220,7 +221,6 @@ export default class Viewer3DFirstPerson extends React.Component {

render();

this.renderer = renderer;
this.camera = camera;
this.scene3D = scene3D;
this.sceneOnTop = sceneOnTop;
Expand All @@ -230,6 +230,11 @@ export default class Viewer3DFirstPerson extends React.Component {
componentWillUnmount() {
this.stopRendering = true;
document.removeEventListener('mousedown', this.firstPersonMouseDown);

disposeScene(this.scene3D);

this.scene3D = null;
this.planData = null;
}

componentWillReceiveProps(nextProps) {
Expand Down

0 comments on commit 3d78ee9

Please sign in to comment.