THREE.WebGLRenderer.ParticleRenderer = function ( lowlevelrenderer, info ) { THREE.WebGLRenderer.Object3DRenderer.call( this, lowlevelrenderer, info ); }; THREE.WebGLRenderer.ParticleRenderer.prototype = Object.create( THREE.WebGLRenderer.Object3DRenderer.prototype ); THREE.extend( THREE.WebGLRenderer.ParticleRenderer.prototype, { createBuffers: function ( geometry ) { var renderer = this.renderer; geometry.__webglVertexBuffer = renderer.createBuffer(); geometry.__webglColorBuffer = renderer.createBuffer(); this.info.memory.geometries ++; }, initBuffers: function ( geometry, object ) { var nvertices = geometry.vertices.length; geometry.__vertexArray = new Float32Array( nvertices * 3 ); geometry.__colorArray = new Float32Array( nvertices * 3 ); geometry.__sortArray = []; geometry.__webglParticleCount = nvertices; this.initCustomAttributes ( geometry, object ); }, setBuffers: function ( geometry, object , projectionScreenMatrix ) { var renderer = this.renderer; var v, c, vertex, offset, index, color, vertices = geometry.vertices, vl = vertices.length, colors = geometry.colors, cl = colors.length, vertexArray = geometry.__vertexArray, colorArray = geometry.__colorArray, sortArray = geometry.__sortArray, dirtyVertices = geometry.verticesNeedUpdate, dirtyElements = geometry.elementsNeedUpdate, dirtyColors = geometry.colorsNeedUpdate, customAttributes = geometry.__webglCustomAttributesList, i, il, a, ca, cal, value, customAttribute; var _projScreenMatrixPS = THREE.WebGLRenderer.ParticleRenderer._m1, _vector3 = THREE.WebGLRenderer.ParticleRenderer._v1; if ( object.sortParticles ) { _projScreenMatrixPS.multiplyMatrices( projectionScreenMatrix, object.matrixWorld ); for ( v = 0; v < vl; v ++ ) { vertex = vertices[ v ]; _vector3.copy( vertex ); _vector3.applyProjection(_projScreenMatrixPS); sortArray[ v ] = [ _vector3.z, v ]; } sortArray.sort( this.numericalSort ); for ( v = 0; v < vl; v ++ ) { vertex = vertices[ sortArray[v][1] ]; offset = v * 3; vertexArray[ offset ] = vertex.x; vertexArray[ offset + 1 ] = vertex.y; vertexArray[ offset + 2 ] = vertex.z; } for ( c = 0; c < cl; c ++ ) { offset = c * 3; color = colors[ sortArray[c][1] ]; colorArray[ offset ] = color.r; colorArray[ offset + 1 ] = color.g; colorArray[ offset + 2 ] = color.b; } if ( customAttributes ) { for ( i = 0, il = customAttributes.length; i < il; i ++ ) { customAttribute = customAttributes[ i ]; if ( ! ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) ) continue; offset = 0; cal = customAttribute.value.length; if ( customAttribute.size === 1 ) { for ( ca = 0; ca < cal; ca ++ ) { index = sortArray[ ca ][ 1 ]; customAttribute.array[ ca ] = customAttribute.value[ index ]; } } else if ( customAttribute.size === 2 ) { for ( ca = 0; ca < cal; ca ++ ) { index = sortArray[ ca ][ 1 ]; value = customAttribute.value[ index ]; customAttribute.array[ offset ] = value.x; customAttribute.array[ offset + 1 ] = value.y; offset += 2; } } else if ( customAttribute.size === 3 ) { if ( customAttribute.type === "c" ) { for ( ca = 0; ca < cal; ca ++ ) { index = sortArray[ ca ][ 1 ]; value = customAttribute.value[ index ]; customAttribute.array[ offset ] = value.r; customAttribute.array[ offset + 1 ] = value.g; customAttribute.array[ offset + 2 ] = value.b; offset += 3; } } else { for ( ca = 0; ca < cal; ca ++ ) { index = sortArray[ ca ][ 1 ]; value = customAttribute.value[ index ]; customAttribute.array[ offset ] = value.x; customAttribute.array[ offset + 1 ] = value.y; customAttribute.array[ offset + 2 ] = value.z; offset += 3; } } } else if ( customAttribute.size === 4 ) { for ( ca = 0; ca < cal; ca ++ ) { index = sortArray[ ca ][ 1 ]; value = customAttribute.value[ index ]; customAttribute.array[ offset ] = value.x; customAttribute.array[ offset + 1 ] = value.y; customAttribute.array[ offset + 2 ] = value.z; customAttribute.array[ offset + 3 ] = value.w; offset += 4; } } } } } else { if ( dirtyVertices ) { for ( v = 0; v < vl; v ++ ) { vertex = vertices[ v ]; offset = v * 3; vertexArray[ offset ] = vertex.x; vertexArray[ offset + 1 ] = vertex.y; vertexArray[ offset + 2 ] = vertex.z; } } if ( dirtyColors ) { for ( c = 0; c < cl; c ++ ) { color = colors[ c ]; offset = c * 3; colorArray[ offset ] = color.r; colorArray[ offset + 1 ] = color.g; colorArray[ offset + 2 ] = color.b; } } if ( customAttributes ) { for ( i = 0, il = customAttributes.length; i < il; i ++ ) { customAttribute = customAttributes[ i ]; if ( customAttribute.needsUpdate && ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices") ) { cal = customAttribute.value.length; offset = 0; if ( customAttribute.size === 1 ) { for ( ca = 0; ca < cal; ca ++ ) { customAttribute.array[ ca ] = customAttribute.value[ ca ]; } } else if ( customAttribute.size === 2 ) { for ( ca = 0; ca < cal; ca ++ ) { value = customAttribute.value[ ca ]; customAttribute.array[ offset ] = value.x; customAttribute.array[ offset + 1 ] = value.y; offset += 2; } } else if ( customAttribute.size === 3 ) { if ( customAttribute.type === "c" ) { for ( ca = 0; ca < cal; ca ++ ) { value = customAttribute.value[ ca ]; customAttribute.array[ offset ] = value.r; customAttribute.array[ offset + 1 ] = value.g; customAttribute.array[ offset + 2 ] = value.b; offset += 3; } } else { for ( ca = 0; ca < cal; ca ++ ) { value = customAttribute.value[ ca ]; customAttribute.array[ offset ] = value.x; customAttribute.array[ offset + 1 ] = value.y; customAttribute.array[ offset + 2 ] = value.z; offset += 3; } } } else if ( customAttribute.size === 4 ) { for ( ca = 0; ca < cal; ca ++ ) { value = customAttribute.value[ ca ]; customAttribute.array[ offset ] = value.x; customAttribute.array[ offset + 1 ] = value.y; customAttribute.array[ offset + 2 ] = value.z; customAttribute.array[ offset + 3 ] = value.w; offset += 4; } } } } } } if ( dirtyVertices || object.sortParticles ) { renderer.setDynamicArrayBuffer(geometry.__webglVertexBuffer,vertexArray); } if ( dirtyColors || object.sortParticles ) { renderer.setDynamicArrayBuffer(geometry.__webglColorBuffer,colorArray); } if ( customAttributes ) { for ( i = 0, il = customAttributes.length; i < il; i ++ ) { customAttribute = customAttributes[ i ]; if ( customAttribute.needsUpdate || object.sortParticles ) { renderer.setDynamicArrayBuffer(customAttribute.buffer,customAttribute.array); } } } } } ); THREE.WebGLRenderer.ParticleRenderer._m1 = new THREE.Matrix4(); THREE.WebGLRenderer.ParticleRenderer._v1 = new THREE.Vector3();