提交 df513e04 编写于 作者: A alteredq

Transplanted simple hierarchy system from WebGLRenderer2 into WebGLRenderer.

Work in progress.

As with static objects, faster with OpenGL (34 -> 38 fps) and slower with ANGLE (30 -> 27 fps).
上级 04cae716
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -30,7 +30,7 @@
<span id="rwebgl" class="button">WebGL renderer</span>
<br/>
<p>Models by <a href="http://sketchup.google.com/3dwarehouse/details?mid=2c6fd128fca34052adc5f5b98d513da1">Reallusion<a>
<p>Models by <a href="http://sketchup.google.com/3dwarehouse/details?mid=2c6fd128fca34052adc5f5b98d513da1">Reallusion</a>
<a href="http://sketchup.google.com/3dwarehouse/details?mid=f526cc4abf7cb68d76cab47c765b7255">iClone</a>.
<p>Using a modified version of <a href="http://github.com/alteredq/three.js">Three.js</a> by mrdoob.
......
......@@ -4,13 +4,14 @@
THREE.Object3D = function () {
this.id = THREE.Object3DCounter.value ++;
this.id = THREE.Object3DCounter.value ++; // TODO: Probably not needed?
this.position = new THREE.Vector3();
this.rotation = new THREE.Vector3();
this.scale = new THREE.Vector3( 1, 1, 1 );
this.matrix = new THREE.Matrix4();
this.matrixWorld = new THREE.Matrix4();
this.rotationMatrix = new THREE.Matrix4();
this.tmpMatrix = new THREE.Matrix4();
......@@ -19,35 +20,53 @@ THREE.Object3D = function () {
this.autoUpdateMatrix = true;
this.visible = true;
this.children = [];
};
THREE.Object3D.prototype = {
updateMatrix: function () {
addChild: function ( object ) {
var p = this.position, r = this.rotation, s = this.scale, m = this.tmpMatrix;
var i = this.children.indexOf( object );
this.matrix.setTranslation( p.x, p.y, p.z );
if ( i === -1 ) {
this.rotationMatrix.setRotX( r.x );
this.children.push( object );
if ( r.y != 0 ) {
m.setRotY( r.y );
this.rotationMatrix.multiplySelf( m );
}
if ( r.z != 0 ) {
m.setRotZ( r.z );
this.rotationMatrix.multiplySelf( m );
}
},
removeChild: function ( object ) {
this.matrix.multiplySelf( this.rotationMatrix );
var i = this.children.indexOf( object );
if ( i !== -1 ) {
this.children.splice( i, 1 );
if ( s.x != 0 || s.y != 0 || s.z != 0 ) {
m.setScale( s.x, s.y, s.z );
this.matrix.multiplySelf( m );
}
},
updateMatrix: function () {
var p = this.position, r = this.rotation, s = this.scale,
matrix = this.matrix, rotationMatrix = this.rotationMatrix,
tmpMatrix = this.tmpMatrix;
matrix.setTranslation( p.x, p.y, p.z );
rotationMatrix.setRotX( r.x );
if ( r.y != 0 ) rotationMatrix.multiplySelf( tmpMatrix.setRotY( r.y ) );
if ( r.z != 0 ) rotationMatrix.multiplySelf( tmpMatrix.setRotZ( r.z ) );
matrix.multiplySelf( rotationMatrix );
if ( s.x != 0 || s.y != 0 || s.z != 0 ) matrix.multiplySelf( tmpMatrix.setScale( s.x, s.y, s.z ) );
}
};
......
......@@ -87,14 +87,14 @@ THREE.WebGLRenderer = function ( parameters ) {
};
this.setClearColorHex = function( hex, alpha ) {
this.setClearColorHex = function ( hex, alpha ) {
var color = new THREE.Color( hex );
_gl.clearColor( color.r, color.g, color.b, alpha );
};
this.setClearColor = function( color, alpha ) {
this.setClearColor = function ( color, alpha ) {
_gl.clearColor( color.r, color.g, color.b, alpha );
......@@ -186,21 +186,21 @@ THREE.WebGLRenderer = function ( parameters ) {
};
this.createParticleBuffers = function( geometry ) {
function createParticleBuffers ( geometry ) {
geometry.__webGLVertexBuffer = _gl.createBuffer();
geometry.__webGLColorBuffer = _gl.createBuffer();
};
this.createLineBuffers = function( geometry ) {
function createLineBuffers ( geometry ) {
geometry.__webGLVertexBuffer = _gl.createBuffer();
geometry.__webGLColorBuffer = _gl.createBuffer();
};
this.createMeshBuffers = function( geometryChunk ) {
function createMeshBuffers ( geometryChunk ) {
geometryChunk.__webGLVertexBuffer = _gl.createBuffer();
geometryChunk.__webGLNormalBuffer = _gl.createBuffer();
......@@ -214,7 +214,7 @@ THREE.WebGLRenderer = function ( parameters ) {
};
this.initLineBuffers = function( geometry ) {
function initLineBuffers ( geometry ) {
var nvertices = geometry.vertices.length;
......@@ -225,7 +225,7 @@ THREE.WebGLRenderer = function ( parameters ) {
};
this.initParticleBuffers = function( geometry ) {
function initParticleBuffers ( geometry ) {
var nvertices = geometry.vertices.length;
......@@ -238,7 +238,7 @@ THREE.WebGLRenderer = function ( parameters ) {
};
this.initMeshBuffers = function( geometryChunk, object ) {
function initMeshBuffers ( geometryChunk, object ) {
var f, fl, nvertices = 0, ntris = 0, nlines = 0,
obj_faces = object.geometry.faces,
......@@ -284,7 +284,7 @@ THREE.WebGLRenderer = function ( parameters ) {
};
this.setMeshBuffers = function ( geometryChunk, object, hint ) {
function setMeshBuffers ( geometryChunk, object, hint ) {
var f, fl, fi, face, vertexNormals, faceNormal, normal,
uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
......@@ -735,7 +735,7 @@ THREE.WebGLRenderer = function ( parameters ) {
};
this.setLineBuffers = function( geometry, hint ) {
function setLineBuffers ( geometry, hint ) {
var v, c, vertex, offset,
vertices = geometry.vertices,
......@@ -789,7 +789,7 @@ THREE.WebGLRenderer = function ( parameters ) {
};
this.setParticleBuffers = function( geometry, hint, object, camera ) {
function setParticleBuffers ( geometry, hint, object, camera ) {
var v, c, vertex, offset,
vertices = geometry.vertices,
......@@ -809,7 +809,7 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( object.sortParticles ) {
_projScreenMatrix.multiplySelf( object.matrix );
_projScreenMatrix.multiplySelf( object.matrixWorld );
for ( v = 0; v < vl; v++ ) {
......@@ -1446,6 +1446,23 @@ THREE.WebGLRenderer = function ( parameters ) {
};
function updateChildren( object ) {
var i, l, child, children = object.children;
for ( i = 0, l = children.length; i < l; i ++ ) {
child = children[ i ];
child.autoUpdateMatrix && child.updateMatrix();
child.matrixWorld.multiply( object.matrixWorld, child.matrix );
updateChildren( child );
}
};
this.render = function( scene, camera, renderTarget, clear ) {
var i, program, opaque, transparent,
......@@ -1453,7 +1470,7 @@ THREE.WebGLRenderer = function ( parameters ) {
lights = scene.lights,
fog = scene.fog,
ol;
camera.autoUpdateMatrix && camera.updateMatrix();
camera.matrix.flattenToArray( _viewMatrixArray );
......@@ -1481,26 +1498,38 @@ THREE.WebGLRenderer = function ( parameters ) {
webGLObject = scene.__webGLObjects[ o ];
object = webGLObject.object;
if ( object.visible && ( ! ( object instanceof THREE.Mesh ) || isInFrustum( object ) ) ) {
if ( object.visible ) {
if( object.autoUpdateMatrix ) {
object.updateMatrix();
object.matrix.flattenToArray( object._objectMatrixArray );
if ( webGLObject.root ) {
object.autoUpdateMatrix && object.updateMatrix();
object.matrixWorld.copy( object.matrix );
updateChildren( object );
}
if ( ! ( object instanceof THREE.Mesh ) || isInFrustum( object ) ) {
object.matrixWorld.flattenToArray( object._objectMatrixArray );
setupMatrices( object, camera );
unrollBufferMaterials( webGLObject );
webGLObject.render = true;
this.setupMatrices( object, camera );
unrollBufferMaterials( webGLObject );
webGLObject.render = true;
} else {
webGLObject.render = false;
}
} else {
webGLObject.render = false;
}
}
......@@ -1517,11 +1546,12 @@ THREE.WebGLRenderer = function ( parameters ) {
if( object.autoUpdateMatrix ) {
object.updateMatrix();
object.matrix.flattenToArray( object._objectMatrixArray );
object.matrixWorld.copy( object.matrix );
object.matrixWorld.flattenToArray( object._objectMatrixArray );
}
this.setupMatrices( object, camera );
setupMatrices( object, camera );
unrollImmediateBufferMaterials( webGLObject );
......@@ -1640,7 +1670,7 @@ THREE.WebGLRenderer = function ( parameters ) {
}
}
// Generate mipmap if we're using any kind of mipmap filtering
if ( renderTarget && renderTarget.min_filter !== THREE.NearestFilter && renderTarget.min_filter !== THREE.LinearFilter ) {
......@@ -1651,168 +1681,197 @@ THREE.WebGLRenderer = function ( parameters ) {
};
this.initWebGLObjects = function( scene, camera ) {
function addChildren( scene, object ) {
var i, l, children = object.children;
for ( i = 0, l = children.length; i < l; i ++ ) {
function add_buffer( objmap, id, buffer, object ) {
child = children[ i ];
if ( objmap[ id ] == undefined ) {
addObject( scene, child, false );
addChildren( scene, child );
}
scene.__webGLObjects.push( { buffer: buffer, object: object,
opaque: { list: [], count: 0 },
transparent: { list: [], count: 0 }
} );
objmap[ id ] = 1;
};
}
function addObject( scene, object, root ) {
var g, geometry, geometryChunk, objmap;
geometry = object.geometry;
if ( scene.__webGLObjectsMap[ object.id ] == undefined ) {
};
scene.__webGLObjectsMap[ object.id ] = {};
object._modelViewMatrix = new THREE.Matrix4();
object._normalMatrixArray = new Float32Array( 9 );
object._modelViewMatrixArray = new Float32Array( 16 );
object._objectMatrixArray = new Float32Array( 16 );
object.matrix.flattenToArray( object._objectMatrixArray );
function add_buffer_immediate( objmap, id, object ) {
}
if ( objmap[ id ] == undefined ) {
objmap = scene.__webGLObjectsMap[ object.id ];
objlist = scene.__webGLObjects;
scene.__webGLObjectsImmediate.push( { object: object,
opaque: { list: [], count: 0 },
transparent: { list: [], count: 0 }
} );
objmap[ id ] = 1;
if ( object instanceof THREE.Mesh ) {
}
// create separate VBOs per geometry chunk
};
for ( g in geometry.geometryChunks ) {
var o, ol, object, g, geometry, geometryChunk, objmap;
geometryChunk = geometry.geometryChunks[ g ];
if ( !scene.__webGLObjects ) {
// initialise VBO on the first access
scene.__webGLObjects = [];
scene.__webGLObjectsMap = {};
if( ! geometryChunk.__webGLVertexBuffer ) {
scene.__webGLObjectsImmediate = [];
createMeshBuffers( geometryChunk );
initMeshBuffers( geometryChunk, object );
}
geometry.__dirtyVertices = true;
geometry.__dirtyElements = true;
geometry.__dirtyUvs = true;
geometry.__dirtyNormals = true;
geometry.__dirtyTangents = true;
geometry.__dirtyColors = true;
for ( o = 0, ol = scene.objects.length; o < ol; o++ ) {
}
object = scene.objects[ o ];
geometry = object.geometry;
if( geometry.__dirtyVertices || geometry.__dirtyElements ||
geometry.__dirtyUvs || geometry.__dirtyNormals ||
geometry.__dirtyColors || geometry.__dirtyTangents ) {
if ( scene.__webGLObjectsMap[ object.id ] == undefined ) {
setMeshBuffers( geometryChunk, object, _gl.DYNAMIC_DRAW );
scene.__webGLObjectsMap[ object.id ] = {};
object._modelViewMatrix = new THREE.Matrix4();
object._normalMatrixArray = new Float32Array( 9 );
object._modelViewMatrixArray = new Float32Array( 16 );
object._objectMatrixArray = new Float32Array( 16 );
object.matrix.flattenToArray( object._objectMatrixArray );
}
}
// create separate wrapper per each use of VBO
objmap = scene.__webGLObjectsMap[ object.id ];
add_buffer( objlist, objmap, g, geometryChunk, object, root );
if ( object instanceof THREE.Mesh ) {
}
// create separate VBOs per geometry chunk
geometry.__dirtyVertices = false;
geometry.__dirtyElements = false;
geometry.__dirtyUvs = false;
geometry.__dirtyNormals = false;
geometry.__dirtyTangents = false;
geometry.__dirtyColors = false;
for ( g in geometry.geometryChunks ) {
} else if ( object instanceof THREE.Line ) {
geometryChunk = geometry.geometryChunks[ g ];
if( ! geometry.__webGLVertexBuffer ) {
// initialise VBO on the first access
createLineBuffers( geometry );
initLineBuffers( geometry );
if( ! geometryChunk.__webGLVertexBuffer ) {
geometry.__dirtyVertices = true;
geometry.__dirtyColors = true;
this.createMeshBuffers( geometryChunk );
this.initMeshBuffers( geometryChunk, object );
}
geometry.__dirtyVertices = true;
geometry.__dirtyElements = true;
geometry.__dirtyUvs = true;
geometry.__dirtyNormals = true;
geometry.__dirtyTangents = true;
geometry.__dirtyColors = true;
if( geometry.__dirtyVertices || geometry.__dirtyColors ) {
}
setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
if( geometry.__dirtyVertices || geometry.__dirtyElements ||
geometry.__dirtyUvs || geometry.__dirtyNormals ||
geometry.__dirtyColors || geometry.__dirtyTangents ) {
}
this.setMeshBuffers( geometryChunk, object, _gl.DYNAMIC_DRAW );
add_buffer( objlist, objmap, 0, geometry, object, root );
}
geometry.__dirtyVertices = false;
geometry.__dirtyColors = false;
// create separate wrapper per each use of VBO
} else if ( object instanceof THREE.ParticleSystem ) {
add_buffer( objmap, g, geometryChunk, object );
if( ! geometry.__webGLVertexBuffer ) {
}
createParticleBuffers( geometry );
initParticleBuffers( geometry );
geometry.__dirtyVertices = false;
geometry.__dirtyElements = false;
geometry.__dirtyUvs = false;
geometry.__dirtyNormals = false;
geometry.__dirtyTangents = false;
geometry.__dirtyColors = false;
geometry.__dirtyVertices = true;
geometry.__dirtyColors = true;
}
} else if ( object instanceof THREE.Line ) {
if( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles ) {
setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object, camera );
if( ! geometry.__webGLVertexBuffer ) {
}
this.createLineBuffers( geometry );
this.initLineBuffers( geometry );
add_buffer( objlist, objmap, 0, geometry, object, root );
geometry.__dirtyVertices = true;
geometry.__dirtyColors = true;
geometry.__dirtyVertices = false;
geometry.__dirtyColors = false;
}
} else if ( object instanceof THREE.MarchingCubes ) {
add_buffer_immediate( scene.__webGLObjectsImmediate, objmap, 0, object, root );
}/*else if ( object instanceof THREE.Particle ) {
if( geometry.__dirtyVertices || geometry.__dirtyColors ) {
}*/
};
this.setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
function add_buffer( objlist, objmap, id, buffer, object, root ) {
}
if ( objmap[ id ] == undefined ) {
add_buffer( objmap, 0, geometry, object );
objlist.push( { buffer: buffer, object: object,
opaque: { list: [], count: 0 },
transparent: { list: [], count: 0 },
root: root
} );
objmap[ id ] = 1;
geometry.__dirtyVertices = false;
geometry.__dirtyColors = false;
}
} else if ( object instanceof THREE.ParticleSystem ) {
};
if( ! geometry.__webGLVertexBuffer ) {
function add_buffer_immediate( objlist, objmap, id, object, root ) {
this.createParticleBuffers( geometry );
this.initParticleBuffers( geometry );
if ( objmap[ id ] == undefined ) {
geometry.__dirtyVertices = true;
geometry.__dirtyColors = true;
}
objlist.push( { object: object,
opaque: { list: [], count: 0 },
transparent: { list: [], count: 0 },
root: root
} );
objmap[ id ] = 1;
if( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles ) {
}
this.setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object, camera );
};
this.initWebGLObjects = function( scene, camera ) {
}
var o, ol, object;
add_buffer( objmap, 0, geometry, object );
if ( !scene.__webGLObjects ) {
geometry.__dirtyVertices = false;
geometry.__dirtyColors = false;
scene.__webGLObjects = [];
scene.__webGLObjectsMap = {};
} else if ( object instanceof THREE.MarchingCubes ) {
add_buffer_immediate( objmap, 0, object );
}/*else if ( object instanceof THREE.Particle ) {
scene.__webGLObjectsImmediate = [];
}*/
}
for ( o = 0, ol = scene.objects.length; o < ol; o++ ) {
object = scene.objects[ o ];
addObject( scene, object, true );
addChildren( scene, object );
}
};
......@@ -1835,9 +1894,9 @@ THREE.WebGLRenderer = function ( parameters ) {
};
this.setupMatrices = function ( object, camera ) {
function setupMatrices ( object, camera ) {
object._modelViewMatrix.multiplyToArray( camera.matrix, object.matrix, object._modelViewMatrixArray );
object._modelViewMatrix.multiplyToArray( camera.matrix, object.matrixWorld, object._modelViewMatrixArray );
object._normalMatrix = THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册