|
@@ -34,9 +34,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
var lights = [];
|
|
|
|
|
|
- var _webglObjects = {};
|
|
|
- var _webglObjectsImmediate = [];
|
|
|
-
|
|
|
var opaqueObjects = [];
|
|
|
var transparentObjects = [];
|
|
|
|
|
@@ -184,7 +181,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
resetGLState();
|
|
|
setDefaultGLState();
|
|
|
|
|
|
- _webglObjects = {};
|
|
|
+ objects.objects = {};
|
|
|
|
|
|
}, false);
|
|
|
|
|
@@ -211,7 +208,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
}
|
|
|
|
|
|
var extensions = new THREE.WebGLExtensions( _gl );
|
|
|
- var buffers = new THREE.WebGLBuffers( _gl, this.info, extensions, getBufferMaterial );
|
|
|
+ var objects = new THREE.WebGLObjects( _gl, this.info, extensions, getBufferMaterial );
|
|
|
|
|
|
extensions.get( 'OES_texture_float' );
|
|
|
extensions.get( 'OES_texture_float_linear' );
|
|
@@ -285,7 +282,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
// shadow map
|
|
|
|
|
|
- var shadowMap = new THREE.WebGLShadowMap( this, lights, _webglObjects, _webglObjectsImmediate );
|
|
|
+ var shadowMap = new THREE.WebGLShadowMap( this, lights, objects );
|
|
|
|
|
|
this.shadowMap = shadowMap;
|
|
|
|
|
@@ -607,30 +604,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
// Events
|
|
|
|
|
|
- var onObjectRemoved = function ( event ) {
|
|
|
-
|
|
|
- var object = event.target;
|
|
|
-
|
|
|
- object.traverse( function ( child ) {
|
|
|
-
|
|
|
- child.removeEventListener( 'remove', onObjectRemoved );
|
|
|
-
|
|
|
- removeObject( child );
|
|
|
-
|
|
|
- } );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- var onGeometryDispose = function ( event ) {
|
|
|
-
|
|
|
- var geometry = event.target;
|
|
|
-
|
|
|
- geometry.removeEventListener( 'dispose', onGeometryDispose );
|
|
|
-
|
|
|
- deallocateGeometry( geometry );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
var onTextureDispose = function ( event ) {
|
|
|
|
|
|
var texture = event.target;
|
|
@@ -668,82 +641,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
// Buffer deallocation
|
|
|
|
|
|
- var deallocateGeometry = function ( geometry ) {
|
|
|
-
|
|
|
- delete geometry.__webglInit;
|
|
|
-
|
|
|
- if ( geometry instanceof THREE.BufferGeometry ) {
|
|
|
-
|
|
|
- for ( var name in geometry.attributes ) {
|
|
|
-
|
|
|
- var attribute = geometry.attributes[ name ];
|
|
|
-
|
|
|
- if ( attribute.buffer !== undefined ) {
|
|
|
-
|
|
|
- _gl.deleteBuffer( attribute.buffer );
|
|
|
-
|
|
|
- delete attribute.buffer;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- _this.info.memory.geometries --;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- var geometryGroupsList = geometryGroups[ geometry.id ];
|
|
|
-
|
|
|
- if ( geometryGroupsList !== undefined ) {
|
|
|
-
|
|
|
- for ( var i = 0, l = geometryGroupsList.length; i < l; i ++ ) {
|
|
|
-
|
|
|
- var geometryGroup = geometryGroupsList[ i ];
|
|
|
-
|
|
|
- if ( geometryGroup.numMorphTargets !== undefined ) {
|
|
|
-
|
|
|
- for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
|
|
|
-
|
|
|
- _gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- delete geometryGroup.__webglMorphTargetsBuffers;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( geometryGroup.numMorphNormals !== undefined ) {
|
|
|
-
|
|
|
- for ( var m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
|
|
|
-
|
|
|
- _gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- delete geometryGroup.__webglMorphNormalsBuffers;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- buffers.delete( geometryGroup );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- delete geometryGroups[ geometry.id ];
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- buffers.delete( geometry );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // TOFIX: Workaround for deleted geometry being currently bound
|
|
|
-
|
|
|
- _currentGeometryProgram = '';
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
var deallocateTexture = function ( texture ) {
|
|
|
|
|
|
if ( texture.image && texture.image.__webglTextureCube ) {
|
|
@@ -1094,7 +991,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
if ( material.visible === false ) return;
|
|
|
|
|
|
- updateObject( object );
|
|
|
+ objects.update( object );
|
|
|
|
|
|
var program = setProgram( camera, lights, fog, material, object );
|
|
|
|
|
@@ -1499,7 +1396,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
if ( material.visible === false ) return;
|
|
|
|
|
|
- updateObject( object );
|
|
|
+ objects.update( object );
|
|
|
|
|
|
var program = setProgram( camera, lights, fog, material, object );
|
|
|
|
|
@@ -2043,9 +1940,9 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
// set matrices for immediate objects
|
|
|
|
|
|
- for ( var i = 0, il = _webglObjectsImmediate.length; i < il; i ++ ) {
|
|
|
+ for ( var i = 0, il = objects.objectsImmediate.length; i < il; i ++ ) {
|
|
|
|
|
|
- var webglObject = _webglObjectsImmediate[ i ];
|
|
|
+ var webglObject = objects.objectsImmediate[ i ];
|
|
|
var object = webglObject.object;
|
|
|
|
|
|
if ( object.visible ) {
|
|
@@ -2066,7 +1963,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial );
|
|
|
renderObjects( transparentObjects, camera, lights, fog, overrideMaterial );
|
|
|
- renderObjectsImmediate( _webglObjectsImmediate, '', camera, lights, fog, overrideMaterial );
|
|
|
+ renderObjectsImmediate( objects.objectsImmediate, '', camera, lights, fog, overrideMaterial );
|
|
|
|
|
|
} else {
|
|
|
|
|
@@ -2075,12 +1972,12 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
state.setBlending( THREE.NoBlending );
|
|
|
|
|
|
renderObjects( opaqueObjects, camera, lights, fog, null );
|
|
|
- renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog, null );
|
|
|
+ renderObjectsImmediate( objects.objectsImmediate, 'opaque', camera, lights, fog, null );
|
|
|
|
|
|
// transparent pass (back-to-front order)
|
|
|
|
|
|
renderObjects( transparentObjects, camera, lights, fog, null );
|
|
|
- renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog, null );
|
|
|
+ renderObjectsImmediate( objects.objectsImmediate, 'transparent', camera, lights, fog, null );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -2117,7 +2014,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- initObject( object );
|
|
|
+ objects.init( object );
|
|
|
|
|
|
if ( object instanceof THREE.Light ) {
|
|
|
|
|
@@ -2133,7 +2030,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- var webglObjects = _webglObjects[ object.id ];
|
|
|
+ var webglObjects = objects.objects[ object.id ];
|
|
|
|
|
|
if ( webglObjects && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {
|
|
|
|
|
@@ -2329,453 +2226,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
- function initObject( object ) {
|
|
|
-
|
|
|
- if ( object.__webglInit === undefined ) {
|
|
|
-
|
|
|
- object.__webglInit = true;
|
|
|
- object._modelViewMatrix = new THREE.Matrix4();
|
|
|
- object._normalMatrix = new THREE.Matrix3();
|
|
|
-
|
|
|
- object.addEventListener( 'removed', onObjectRemoved );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var geometry = object.geometry;
|
|
|
-
|
|
|
- if ( geometry === undefined ) {
|
|
|
-
|
|
|
- // ImmediateRenderObject
|
|
|
-
|
|
|
- } else if ( geometry.__webglInit === undefined ) {
|
|
|
-
|
|
|
- geometry.__webglInit = true;
|
|
|
- geometry.addEventListener( 'dispose', onGeometryDispose );
|
|
|
-
|
|
|
- if ( geometry instanceof THREE.BufferGeometry ) {
|
|
|
-
|
|
|
- _this.info.memory.geometries ++;
|
|
|
-
|
|
|
- } else if ( object instanceof THREE.Mesh ) {
|
|
|
-
|
|
|
- initGeometryGroups( object, geometry );
|
|
|
-
|
|
|
- } else if ( object instanceof THREE.Line ) {
|
|
|
-
|
|
|
- buffers.initLineBuffers( geometry, object );
|
|
|
-
|
|
|
- } else if ( object instanceof THREE.PointCloud ) {
|
|
|
-
|
|
|
- buffers.initPointCloudBuffers( geometry, object );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( object.__webglActive === undefined) {
|
|
|
-
|
|
|
- object.__webglActive = true;
|
|
|
-
|
|
|
- if ( object instanceof THREE.Mesh ) {
|
|
|
-
|
|
|
- if ( geometry instanceof THREE.BufferGeometry ) {
|
|
|
-
|
|
|
- addBuffer( _webglObjects, geometry, object );
|
|
|
-
|
|
|
- } else if ( geometry instanceof THREE.Geometry ) {
|
|
|
-
|
|
|
- var geometryGroupsList = geometryGroups[ geometry.id ];
|
|
|
-
|
|
|
- for ( var i = 0,l = geometryGroupsList.length; i < l; i ++ ) {
|
|
|
-
|
|
|
- addBuffer( _webglObjects, geometryGroupsList[ i ], object );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else if ( object instanceof THREE.Line || object instanceof THREE.PointCloud ) {
|
|
|
-
|
|
|
- addBuffer( _webglObjects, geometry, object );
|
|
|
-
|
|
|
- } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
|
|
|
-
|
|
|
- addBufferImmediate( _webglObjectsImmediate, object );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // Geometry splitting
|
|
|
-
|
|
|
- var geometryGroups = {};
|
|
|
- var geometryGroupCounter = 0;
|
|
|
-
|
|
|
- function makeGroups( geometry, usesFaceMaterial ) {
|
|
|
-
|
|
|
- var maxVerticesInGroup = extensions.get( 'OES_element_index_uint' ) ? 4294967296 : 65535;
|
|
|
-
|
|
|
- var groupHash, hash_map = {};
|
|
|
-
|
|
|
- var numMorphTargets = geometry.morphTargets.length;
|
|
|
- var numMorphNormals = geometry.morphNormals.length;
|
|
|
-
|
|
|
- var group;
|
|
|
- var groups = {};
|
|
|
- var groupsList = [];
|
|
|
-
|
|
|
- for ( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
|
|
|
-
|
|
|
- var face = geometry.faces[ f ];
|
|
|
- var materialIndex = usesFaceMaterial ? face.materialIndex : 0;
|
|
|
-
|
|
|
- if ( ! ( materialIndex in hash_map ) ) {
|
|
|
-
|
|
|
- hash_map[ materialIndex ] = { hash: materialIndex, counter: 0 };
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- groupHash = hash_map[ materialIndex ].hash + '_' + hash_map[ materialIndex ].counter;
|
|
|
-
|
|
|
- if ( ! ( groupHash in groups ) ) {
|
|
|
-
|
|
|
- group = {
|
|
|
- id: geometryGroupCounter ++,
|
|
|
- faces3: [],
|
|
|
- materialIndex: materialIndex,
|
|
|
- vertices: 0,
|
|
|
- numMorphTargets: numMorphTargets,
|
|
|
- numMorphNormals: numMorphNormals
|
|
|
- };
|
|
|
-
|
|
|
- groups[ groupHash ] = group;
|
|
|
- groupsList.push( group );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( groups[ groupHash ].vertices + 3 > maxVerticesInGroup ) {
|
|
|
-
|
|
|
- hash_map[ materialIndex ].counter += 1;
|
|
|
- groupHash = hash_map[ materialIndex ].hash + '_' + hash_map[ materialIndex ].counter;
|
|
|
-
|
|
|
- if ( ! ( groupHash in groups ) ) {
|
|
|
-
|
|
|
- group = {
|
|
|
- id: geometryGroupCounter ++,
|
|
|
- faces3: [],
|
|
|
- materialIndex: materialIndex,
|
|
|
- vertices: 0,
|
|
|
- numMorphTargets: numMorphTargets,
|
|
|
- numMorphNormals: numMorphNormals
|
|
|
- };
|
|
|
-
|
|
|
- groups[ groupHash ] = group;
|
|
|
- groupsList.push( group );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- groups[ groupHash ].faces3.push( f );
|
|
|
- groups[ groupHash ].vertices += 3;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return groupsList;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function initGeometryGroups( object, geometry ) {
|
|
|
-
|
|
|
- var material = object.material, addBuffers = false;
|
|
|
-
|
|
|
- if ( geometryGroups[ geometry.id ] === undefined || geometry.groupsNeedUpdate === true ) {
|
|
|
-
|
|
|
- delete _webglObjects[ object.id ];
|
|
|
-
|
|
|
- geometryGroups[ geometry.id ] = makeGroups( geometry, material instanceof THREE.MeshFaceMaterial );
|
|
|
-
|
|
|
- geometry.groupsNeedUpdate = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var geometryGroupsList = geometryGroups[ geometry.id ];
|
|
|
-
|
|
|
- // create separate VBOs per geometry chunk
|
|
|
-
|
|
|
- for ( var i = 0, il = geometryGroupsList.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- var geometryGroup = geometryGroupsList[ i ];
|
|
|
-
|
|
|
- // initialise VBO on the first access
|
|
|
-
|
|
|
- if ( geometryGroup.__webglVertexBuffer === undefined ) {
|
|
|
-
|
|
|
- buffers.initMeshBuffers( geometryGroup, object );
|
|
|
-
|
|
|
- geometry.verticesNeedUpdate = true;
|
|
|
- geometry.morphTargetsNeedUpdate = true;
|
|
|
- geometry.elementsNeedUpdate = true;
|
|
|
- geometry.uvsNeedUpdate = true;
|
|
|
- geometry.normalsNeedUpdate = true;
|
|
|
- geometry.tangentsNeedUpdate = true;
|
|
|
- geometry.colorsNeedUpdate = true;
|
|
|
-
|
|
|
- addBuffers = true;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- addBuffers = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( addBuffers || object.__webglActive === undefined ) {
|
|
|
-
|
|
|
- addBuffer( _webglObjects, geometryGroup, object );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- object.__webglActive = true;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function addBuffer( objlist, buffer, object ) {
|
|
|
-
|
|
|
- var id = object.id;
|
|
|
- objlist[id] = objlist[id] || [];
|
|
|
- objlist[id].push(
|
|
|
- {
|
|
|
- id: id,
|
|
|
- buffer: buffer,
|
|
|
- object: object,
|
|
|
- material: null,
|
|
|
- z: 0
|
|
|
- }
|
|
|
- );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- function addBufferImmediate( objlist, object ) {
|
|
|
-
|
|
|
- objlist.push(
|
|
|
- {
|
|
|
- id: null,
|
|
|
- object: object,
|
|
|
- opaque: null,
|
|
|
- transparent: null,
|
|
|
- z: 0
|
|
|
- }
|
|
|
- );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- // Objects updates
|
|
|
-
|
|
|
- function updateObject( object ) {
|
|
|
-
|
|
|
- var geometry = object.geometry;
|
|
|
-
|
|
|
- if ( geometry instanceof THREE.BufferGeometry ) {
|
|
|
-
|
|
|
- var attributes = geometry.attributes;
|
|
|
- var attributesKeys = geometry.attributesKeys;
|
|
|
-
|
|
|
- for ( var i = 0, l = attributesKeys.length; i < l; i ++ ) {
|
|
|
-
|
|
|
- var key = attributesKeys[ i ];
|
|
|
- var attribute = attributes[ key ];
|
|
|
- var bufferType = ( key === 'index' ) ? _gl.ELEMENT_ARRAY_BUFFER : _gl.ARRAY_BUFFER;
|
|
|
-
|
|
|
- var data = ( attribute instanceof THREE.InterleavedBufferAttribute ) ? attribute.data : attribute;
|
|
|
-
|
|
|
- if ( data.buffer === undefined ) {
|
|
|
-
|
|
|
- data.buffer = _gl.createBuffer();
|
|
|
- _gl.bindBuffer( bufferType, data.buffer );
|
|
|
-
|
|
|
- var usage = _gl.STATIC_DRAW;
|
|
|
-
|
|
|
- if ( data instanceof THREE.DynamicBufferAttribute
|
|
|
- || ( data instanceof THREE.InstancedBufferAttribute && data.dynamic === true )
|
|
|
- || ( data instanceof THREE.InterleavedBuffer && data.dynamic === true ) ) {
|
|
|
-
|
|
|
- usage = _gl.DYNAMIC_DRAW;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- _gl.bufferData( bufferType, data.array, usage );
|
|
|
-
|
|
|
- data.needsUpdate = false;
|
|
|
-
|
|
|
- } else if ( data.needsUpdate === true ) {
|
|
|
-
|
|
|
- _gl.bindBuffer( bufferType, data.buffer );
|
|
|
-
|
|
|
- if ( data.updateRange === undefined || data.updateRange.count === -1 ) { // Not using update ranges
|
|
|
-
|
|
|
- _gl.bufferSubData( bufferType, 0, data.array );
|
|
|
-
|
|
|
- } else if ( data.updateRange.count === 0 ) {
|
|
|
-
|
|
|
- THREE.error( 'THREE.WebGLRenderer.updateObject: using updateRange for THREE.DynamicBufferAttribute and marked as needsUpdate but count is 0, ensure you are using set methods or updating manually.' );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- _gl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,
|
|
|
- data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );
|
|
|
-
|
|
|
- data.updateRange.count = 0; // reset range
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- data.needsUpdate = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else if ( object instanceof THREE.Mesh ) {
|
|
|
-
|
|
|
- // check all geometry groups
|
|
|
-
|
|
|
- if ( geometry.groupsNeedUpdate === true ) {
|
|
|
-
|
|
|
- initGeometryGroups( object, geometry );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var geometryGroupsList = geometryGroups[ geometry.id ];
|
|
|
-
|
|
|
- for ( var i = 0, il = geometryGroupsList.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- var geometryGroup = geometryGroupsList[ i ];
|
|
|
- var material = getBufferMaterial( object, geometryGroup );
|
|
|
-
|
|
|
- var customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
|
|
|
-
|
|
|
- if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
|
|
|
- geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
|
|
|
- geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) {
|
|
|
-
|
|
|
- buffers.setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, ! geometry.dynamic, material );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- geometry.verticesNeedUpdate = false;
|
|
|
- geometry.morphTargetsNeedUpdate = false;
|
|
|
- geometry.elementsNeedUpdate = false;
|
|
|
- geometry.uvsNeedUpdate = false;
|
|
|
- geometry.normalsNeedUpdate = false;
|
|
|
- geometry.colorsNeedUpdate = false;
|
|
|
- geometry.tangentsNeedUpdate = false;
|
|
|
-
|
|
|
- material.attributes && clearCustomAttributes( material );
|
|
|
-
|
|
|
- } else if ( object instanceof THREE.Line ) {
|
|
|
-
|
|
|
- var material = getBufferMaterial( object, geometry );
|
|
|
- var customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
|
|
|
-
|
|
|
- if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || geometry.lineDistancesNeedUpdate || customAttributesDirty ) {
|
|
|
-
|
|
|
- buffers.setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- geometry.verticesNeedUpdate = false;
|
|
|
- geometry.colorsNeedUpdate = false;
|
|
|
- geometry.lineDistancesNeedUpdate = false;
|
|
|
-
|
|
|
- material.attributes && clearCustomAttributes( material );
|
|
|
-
|
|
|
- } else if ( object instanceof THREE.PointCloud ) {
|
|
|
-
|
|
|
- var material = getBufferMaterial( object, geometry );
|
|
|
- var customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
|
|
|
-
|
|
|
- if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || customAttributesDirty ) {
|
|
|
-
|
|
|
- buffers.setPointCloudBuffers( geometry, _gl.DYNAMIC_DRAW, object );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- geometry.verticesNeedUpdate = false;
|
|
|
- geometry.colorsNeedUpdate = false;
|
|
|
-
|
|
|
- material.attributes && clearCustomAttributes( material );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // Objects updates - custom attributes check
|
|
|
-
|
|
|
- function areCustomAttributesDirty( material ) {
|
|
|
-
|
|
|
- for ( var name in material.attributes ) {
|
|
|
-
|
|
|
- if ( material.attributes[ name ].needsUpdate ) return true;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function clearCustomAttributes( material ) {
|
|
|
-
|
|
|
- for ( var name in material.attributes ) {
|
|
|
-
|
|
|
- material.attributes[ name ].needsUpdate = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // Objects removal
|
|
|
-
|
|
|
- function removeObject( object ) {
|
|
|
-
|
|
|
- if ( object instanceof THREE.Mesh ||
|
|
|
- object instanceof THREE.PointCloud ||
|
|
|
- object instanceof THREE.Line ) {
|
|
|
-
|
|
|
- delete _webglObjects[ object.id ];
|
|
|
-
|
|
|
- } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
|
|
|
-
|
|
|
- removeInstances( _webglObjectsImmediate, object );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- delete object.__webglInit;
|
|
|
- delete object._modelViewMatrix;
|
|
|
- delete object._normalMatrix;
|
|
|
-
|
|
|
- delete object.__webglActive;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function removeInstances( objlist, object ) {
|
|
|
-
|
|
|
- for ( var o = objlist.length - 1; o >= 0; o -- ) {
|
|
|
-
|
|
|
- if ( objlist[ o ].object === object ) {
|
|
|
-
|
|
|
- objlist.splice( o, 1 );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
// Materials
|
|
|
|
|
|
var shaderIDs = {
|