提交 1f858e1c 编写于 作者: B Ben Houston

Merge branch 'dev' of git@github.com:mrdoob/three.js into sceneAnimations

......@@ -16622,10 +16622,17 @@ THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS
this.image = { data: data, width: width, height: height };
this.magFilter = magFilter !== undefined ? magFilter : THREE.NearestFilter;
this.minFilter = minFilter !== undefined ? minFilter : THREE.NearestFilter;
this.flipY = false;
this.generateMipmaps = false;
};
THREE.DataTexture.prototype = Object.create( THREE.Texture.prototype );
THREE.DataTexture.prototype.constructor = THREE.DataTexture;
// File:src/textures/VideoTexture.js
/**
......@@ -16959,7 +16966,9 @@ THREE.Line.prototype.raycast = ( function () {
if ( distSq > precisionSq ) continue;
var distance = ray.origin.distanceTo( interRay );
interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
var distance = raycaster.ray.origin.distanceTo( interRay );
if ( distance < raycaster.near || distance > raycaster.far ) continue;
......@@ -16994,7 +17003,9 @@ THREE.Line.prototype.raycast = ( function () {
if ( distSq > precisionSq ) continue;
var distance = ray.origin.distanceTo( interRay );
interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
var distance = raycaster.ray.origin.distanceTo( interRay );
if ( distance < raycaster.near || distance > raycaster.far ) continue;
......@@ -17025,8 +17036,10 @@ THREE.Line.prototype.raycast = ( function () {
var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
if ( distSq > precisionSq ) continue;
interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
var distance = ray.origin.distanceTo( interRay );
var distance = raycaster.ray.origin.distanceTo( interRay );
if ( distance < raycaster.near || distance > raycaster.far ) continue;
......@@ -17521,10 +17534,6 @@ THREE.Skeleton = function ( bones, boneInverses, useVertexTexture ) {
this.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel
this.boneTexture = new THREE.DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, THREE.RGBAFormat, THREE.FloatType );
this.boneTexture.minFilter = THREE.NearestFilter;
this.boneTexture.magFilter = THREE.NearestFilter;
this.boneTexture.generateMipmaps = false;
this.boneTexture.flipY = false;
} else {
......@@ -19741,15 +19750,12 @@ THREE.WebGLRenderer = function ( parameters ) {
pixelRatio = 1,
_precision = parameters.precision !== undefined ? parameters.precision : 'highp',
_alpha = parameters.alpha !== undefined ? parameters.alpha : false,
_depth = parameters.depth !== undefined ? parameters.depth : true,
_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
_logarithmicDepthBuffer = parameters.logarithmicDepthBuffer !== undefined ? parameters.logarithmicDepthBuffer : false,
_clearColor = new THREE.Color( 0x000000 ),
_clearAlpha = 0;
......@@ -19757,13 +19763,18 @@ THREE.WebGLRenderer = function ( parameters ) {
var lights = [];
var opaqueObjects = [];
var opaqueObjectsLastIndex = -1;
var transparentObjects = [];
var transparentObjectsLastIndex = -1;
var opaqueImmediateObjects = [];
var opaqueImmediateObjectsLastIndex = -1;
var transparentImmediateObjects = [];
var transparentImmediateObjectsLastIndex = -1;
var morphInfluences = new Float32Array( 8 );
var sprites = [];
var lensFlares = [];
......@@ -19928,11 +19939,7 @@ THREE.WebGLRenderer = function ( parameters ) {
}
if ( _logarithmicDepthBuffer ) {
extensions.get( 'EXT_frag_depth' );
}
var capabilities = new THREE.WebGLCapabilities( _gl, extensions, parameters );
var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
var properties = new THREE.WebGLProperties();
......@@ -19982,6 +19989,7 @@ THREE.WebGLRenderer = function ( parameters ) {
setDefaultGLState();
this.context = _gl;
this.capabilities = capabilities;
this.extensions = extensions;
this.state = state;
......@@ -19991,24 +19999,6 @@ THREE.WebGLRenderer = function ( parameters ) {
this.shadowMap = shadowMap;
// GPU capabilities
var _maxTextures = _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS );
var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
var _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE );
var _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
var _supportsVertexTextures = _maxVertexTextures > 0;
var _supportsBoneTextures = _supportsVertexTextures && extensions.get( 'OES_texture_float' );
var _maxPrecision = state.getMaxPrecision( _precision );
if ( _maxPrecision !== _precision ) {
console.warn( 'THREE.WebGLRenderer:', _precision, 'not supported, using', _maxPrecision, 'instead.' );
_precision = _maxPrecision;
}
// Plugins
......@@ -20063,7 +20053,7 @@ THREE.WebGLRenderer = function ( parameters ) {
this.getPrecision = function () {
return _precision;
return capabilities.precision;
};
......@@ -20345,7 +20335,7 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( newReferenceCount === 0 ) {
// the last meterial that has been using the program let
// the last material that has been using the program let
// go of it, so remove it from the (unordered) _programs
// set and deallocate the GL resource
......@@ -20868,17 +20858,23 @@ THREE.WebGLRenderer = function ( parameters ) {
lights.length = 0;
opaqueObjects.length = 0;
transparentObjects.length = 0;
opaqueObjectsLastIndex = -1;
transparentObjectsLastIndex = -1;
opaqueImmediateObjects.length = 0;
transparentImmediateObjects.length = 0;
opaqueImmediateObjectsLastIndex = -1;
transparentImmediateObjectsLastIndex = -1;
sprites.length = 0;
lensFlares.length = 0;
projectObject( scene );
opaqueObjects.length = opaqueObjectsLastIndex + 1;
transparentObjects.length = transparentObjectsLastIndex + 1;
opaqueImmediateObjects.length = opaqueImmediateObjectsLastIndex + 1;
transparentImmediateObjects.length = transparentImmediateObjectsLastIndex + 1;
if ( _this.sortObjects === true ) {
opaqueObjects.sort( painterSortStable );
......@@ -20958,40 +20954,84 @@ THREE.WebGLRenderer = function ( parameters ) {
function pushImmediateRenderItem( object ) {
var array, index;
// allocate the next position in the appropriate array
if ( object.material.transparent ) {
transparentImmediateObjects.push( object );
array = transparentImmediateObjects;
index = ++ transparentImmediateObjectsLastIndex;
} else {
opaqueImmediateObjects.push( object );
array = opaqueImmediateObjects;
index = ++ opaqueImmediateObjectsLastIndex;
}
// recycle existing position or grow the array
if ( index < array.length ) {
array[ index ] = object;
} else {
// assert( index === array.length );
array.push( object );
}
}
function pushRenderItem( object, geometry, material, z, group ) {
var renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
z: _vector3.z,
group: group
};
var array, index;
// allocate the next position in the appropriate array
if ( material.transparent ) {
transparentObjects.push( renderItem );
array = transparentObjects;
index = ++ transparentObjectsLastIndex;
} else {
opaqueObjects.push( renderItem );
array = opaqueObjects;
index = ++ opaqueObjectsLastIndex;
}
material.program = properties.get( material ).program; // TODO: Do this at compile time
// recycle existing render item or grow the array
var renderItem = array[ index ];
if ( renderItem !== undefined ) {
renderItem.id = object.id;
renderItem.object = object;
renderItem.geometry = geometry;
renderItem.material = material;
renderItem.z = _vector3.z;
renderItem.group = group;
} else {
renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
z: _vector3.z,
group: group
};
// assert( index === array.length );
array.push( renderItem );
}
}
......@@ -21152,11 +21192,11 @@ THREE.WebGLRenderer = function ( parameters ) {
var maxLightCount = allocateLights( lights );
var maxShadows = allocateShadows( lights );
var maxBones = allocateBones( object );
var precision = _precision;
var precision = capabilities.precision;
if ( material.precision !== null ) {
precision = state.getMaxPrecision( material.precision );
precision = capabilities.getMaxPrecision( material.precision );
if ( precision !== material.precision ) {
......@@ -21169,7 +21209,7 @@ THREE.WebGLRenderer = function ( parameters ) {
var parameters = {
precision: precision,
supportsVertexTextures: _supportsVertexTextures,
supportsVertexTextures: capabilities.vertexTextures,
map: !! material.map,
envMap: !! material.envMap,
......@@ -21193,11 +21233,11 @@ THREE.WebGLRenderer = function ( parameters ) {
flatShading: material.shading === THREE.FlatShading,
sizeAttenuation: material.sizeAttenuation,
logarithmicDepthBuffer: _logarithmicDepthBuffer,
logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,
skinning: material.skinning,
maxBones: maxBones,
useVertexTexture: _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture,
useVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,
morphTargets: material.morphTargets,
morphNormals: material.morphNormals,
......@@ -21336,6 +21376,7 @@ THREE.WebGLRenderer = function ( parameters ) {
}
materialProperties.program = program;
material.program = program;
var attributes = program.getAttributes();
......@@ -21463,7 +21504,7 @@ THREE.WebGLRenderer = function ( parameters ) {
_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera.projectionMatrix.elements );
if ( _logarithmicDepthBuffer ) {
if ( capabilities.logarithmicDepthBuffer ) {
_gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
......@@ -21522,7 +21563,7 @@ THREE.WebGLRenderer = function ( parameters ) {
}
if ( _supportsBoneTextures && object.skeleton && object.skeleton.useVertexTexture ) {
if ( capabilities.floatVertexTextures && object.skeleton && object.skeleton.useVertexTexture ) {
if ( p_uniforms.boneTexture !== undefined ) {
......@@ -21928,9 +21969,9 @@ THREE.WebGLRenderer = function ( parameters ) {
var textureUnit = _usedTextureUnits;
if ( textureUnit >= _maxTextures ) {
if ( textureUnit >= capabilities.maxTextures ) {
console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + _maxTextures );
console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
}
......@@ -22547,7 +22588,10 @@ THREE.WebGLRenderer = function ( parameters ) {
extension = extensions.get( 'EXT_texture_filter_anisotropic' );
if ( extension && texture.type !== THREE.FloatType && texture.type !== THREE.HalfFloatType ) {
if ( extension ) {
if ( texture.type === THREE.FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
if ( texture.type === THREE.HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;
if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
......@@ -22583,7 +22627,7 @@ THREE.WebGLRenderer = function ( parameters ) {
_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
texture.image = clampToMaxSize( texture.image, _maxTextureSize );
texture.image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
var image = texture.image,
isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
......@@ -22768,7 +22812,7 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( _this.autoScaleCubemaps && ! isCompressed && ! isDataTexture ) {
cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );
cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
} else {
......@@ -23231,7 +23275,7 @@ THREE.WebGLRenderer = function ( parameters ) {
function allocateBones ( object ) {
if ( _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {
if ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {
return 1024;
......@@ -23356,7 +23400,7 @@ THREE.WebGLRenderer = function ( parameters ) {
this.supportsVertexTextures = function () {
return _supportsVertexTextures;
return capabilities.vertexTextures;
};
......@@ -23747,6 +23791,76 @@ THREE.WebGLExtensions = function ( gl ) {
};
// File:src/renderers/webgl/WebGLCapabilities.js
THREE.WebGLCapabilities = function ( gl, extensions, parameters ) {
function getMaxPrecision( precision ) {
if ( precision === 'highp' ) {
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {
return 'highp';
}
precision = 'mediump';
}
if ( precision === 'mediump' ) {
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {
return 'mediump';
}
}
return 'lowp';
}
this.getMaxPrecision = getMaxPrecision;
this.precision = parameters.precision !== undefined ? parameters.precision : 'highp',
this.logarithmicDepthBuffer = parameters.logarithmicDepthBuffer !== undefined ? parameters.logarithmicDepthBuffer : false;
this.maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
this.maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
this.maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );
this.maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );
this.maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );
this.maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );
this.maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );
this.maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );
this.vertexTextures = this.maxVertexTextures > 0;
this.floatFragmentTextures = !! extensions.get( 'OES_texture_float' );
this.floatVertexTextures = this.vertexTextures && this.floatFragmentTextures;
var _maxPrecision = getMaxPrecision( this.precision );
if ( _maxPrecision !== this.precision ) {
console.warn( 'THREE.WebGLRenderer:', this.precision, 'not supported, using', _maxPrecision, 'instead.' );
this.precision = _maxPrecision;
}
if ( this.logarithmicDepthBuffer ) {
this.logarithmicDepthBuffer = !! extensions.get( 'EXT_frag_depth' );
}
};
// File:src/renderers/webgl/WebGLGeometries.js
/**
......@@ -24874,9 +24988,9 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
var groups = geometry.groups;
var materials = material.materials;
for ( var j = 0, jl = groups.length; j < jl; j ++ ) {
for ( var k = 0, kl = groups.length; k < kl; k ++ ) {
var group = groups[ j ];
var group = groups[ k ];
var groupMaterial = materials[ group.materialIndex ];
if ( groupMaterial.visible === true ) {
......@@ -25131,36 +25245,6 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) {
};
this.getMaxPrecision = function ( precision ) {
if ( precision === 'highp' ) {
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {
return 'highp';
}
precision = 'mediump';
}
if ( precision === 'mediump' ) {
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {
return 'mediump';
}
}
return 'lowp';
};
this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) {
if ( blending !== currentBlending ) {
......
此差异已折叠。
......@@ -71,7 +71,7 @@
<h3>[name]( [page:Vector3 origin], [page:Vector3 direction], [page:Float near], [page:Float far] ) {</h3>
<div>
[page:Vector3 origin] — The origin vector where the ray casts from.<br />
[page:Vector3 direction] — The direction vector that gives direction to the ray.<br />
[page:Vector3 direction] — The direction vector that gives direction to the ray. Should be normalized.<br />
[page:Float near] — All results returned are further away than near. Near can't be negative. Default value is 0.<br />
[page:Float far] — All results returned are closer then far. Far can't be lower then near . Default value is Infinity.
</div>
......@@ -109,7 +109,7 @@
<h3>[method:null set]( [page:Vector3 origin], [page:Vector3 direction] )</h3>
<div>
[page:Vector3 origin] — The origin vector where the ray casts from.<br />
[page:Vector3 direction] — The direction vector that gives direction to the ray.
[page:Vector3 direction] — The normalized direction vector that gives direction to the ray.
</div>
<div>
Updates the ray with a new origin and direction.
......
......@@ -16,26 +16,9 @@
<h2>Constructor</h2>
<h3>[name]([page:Float n11], [page:Float n12], [page:Float n13], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n31], [page:Float n32], [page:Float n33])</h3>
<h3>[name]()</h3>
<div>
n11 -- [page:Float] <br />
n12 -- [page:Float] <br />
n13 -- [page:Float] <br />
n21 -- [page:Float] <br />
n22 -- [page:Float] <br />
n23 -- [page:Float] <br />
n31 -- [page:Float] <br />
n32 -- [page:Float] <br />
n33 -- [page:Float]
</div>
<div>
Initialize the 3x3 matrix with a row-major sequence of values.<br/><br/>
n11, n12, n13,<br/>
n21, n22, n23,<br/>
n31, n32, n33<br/><br/>
If no values are sent the matrix will be initialized as an identity matrix.
Creates and initializes the 3x3 matrix to the identity matrix.
</div>
......@@ -44,7 +27,7 @@
<h3>[property:Float32Array elements]</h3>
<div>
Float32Array with column-major matrix values.
A column-major list of matrix values.
</div>
......@@ -60,13 +43,13 @@
array -- [page:Array] <br />
</div>
<div>
Transposes this matrix into the supplied array, and returns itself.
Transposes this matrix into the supplied array, and returns itself unchanged.
</div>
<h3>[method:Float determinant]()</h3>
<div>
Returns the matrix's determinant.
Computes and returns the determinant of this matrix.
</div>
<h3>[method:Matrix3 set]([page:Float n11], [page:Float n12], [page:Float n13], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n31], [page:Float n32], [page:Float n33]) [page:Matrix3 this]</h3>
......@@ -82,15 +65,15 @@
n33 -- [page:Float]
</div>
<div>
Set the 3x3 matrix values to the given row-major sequence of values.
Sets the 3x3 matrix values to the given row-major sequence of values.
</div>
<h3>[method:Matrix3 multiplyScalar]([page:Float scalar]) [page:Matrix3 this]</h3>
<h3>[method:Matrix3 multiplyScalar]([page:Float s]) [page:Matrix3 this]</h3>
<div>
scalar -- [page:Float]
</div>
<div>
Multiply every component of the matrix by a scalar value.
Multiplies every component of the matrix by the scalar value *s*.
</div>
<h3>[method:Array applyToVector3Array]([page:Array array])</h3>
......@@ -98,42 +81,42 @@
array -- An array in the form [vector1x, vector1y, vector1z, vector2x, vector2y, vector2z, ...]
</div>
<div>
Multiply (apply) this matrix to every vector3 in the array.
Multiplies (applies) this matrix to every vector3 in the array.
</div>
<h3>[method:Matrix3 getNormalMatrix]([page:Matrix4 matrix4]) [page:Matrix3 this]</h3>
<h3>[method:Matrix3 getNormalMatrix]([page:Matrix4 m]) [page:Matrix3 this]</h3>
<div>
matrix4 -- [page:Matrix4]
m -- [page:Matrix4]
</div>
<div>
Set this matrix as the normal matrix of the passed [page:Matrix4 matrix4]. The normal matrix is the inverse transpose of the matrix.
Sets this matrix as the normal matrix (upper left 3x3)of the passed [page:Matrix4 matrix4]. The normal matrix is the inverse transpose of the matrix *m*.
</div>
<h3>[method:Matrix3 getInverse]([page:Matrix4 matrix4], [page:Boolean throwOnInvertible]) [page:Matrix3 this]</h3>
<h3>[method:Matrix3 getInverse]([page:Matrix4 m], [page:Boolean throwOnInvertible]) [page:Matrix3 this]</h3>
<div>
matrix4 -- [page:Matrix4] <br />
m -- [page:Matrix4]<br />
throwOnInvertible -- [Page:Boolean] If true, throw an error if the matrix is invertible.
</div>
<div>
Set this matrix to the inverse of the passed matrix.
</div>
<h3>[method:Matrix3 copy]([page:Matrix3 matrix]) [page:Matrix3 this]</h3>
<h3>[method:Matrix3 copy]([page:Matrix3 m]) [page:Matrix3 this]</h3>
<div>
matrix -- [page:Matrix3]
m -- [page:Matrix4]
</div>
<div>
Copy the values of the passed matrix.
Copies the values of matrix *m* into this matrix.
</div>
<h3>[method:Matrix3 clone]()</h3>
<div>
Create a copy of the matrix.
Creates a copy of this matrix.
</div>
<h3>[method:Matrix3 identity]() [page:Matrix3 this]</h3>
<div>
Set as an identity matrix.<br/><br/>
Resets this matrix to identity.<br/><br/>
1, 0, 0<br/>
0, 1, 0<br/>
......
......@@ -39,10 +39,10 @@
<h2>Constructor</h2>
<h3>[name]( [page:Float n11], [page:Float n12], [page:Float n13], [page:Float n14], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n24], [page:Float n31], [page:Float n32], [page:Float n33], [page:Float n34], [page:Float n41], [page:Float n42], [page:Float n43], [page:Float n44] )</h3>
<h3>[name]()</h3>
<div>
Initialises the matrix with the supplied row-major values n11..n44, or just creates an identity matrix if no values are passed.
Creates and initializes the matrix to the identity matrix.
</div>
<h2>Properties</h2>
......@@ -64,7 +64,7 @@
<h3>[method:Matrix4 copy]( [page:Matrix4 m] ) [page:Matrix4 this]</h3>
<div>
Copies a matrix *m* into this matrix.
Copies the values of matrix *m* into this matrix.
</div>
<h3>[method:Matrix4 copyPosition]( [page:Matrix4 m] ) [page:Matrix4 this]</h3>
......@@ -72,12 +72,12 @@
Copies the translation component of the supplied matrix *m* into this matrix translation component.
</div>
<h3>[method:Matrix4 makeBasis]( [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]</h3>
<h3>[method:Matrix4 makeBasis]( [page:Vector3 xAxis], [page:Vector3 zAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]</h3>
<div>
Creates the basis matrix consisting of the three provided axis vectors. Returns the current matrix.
</div>
<h3>[method:Matrix4 extractBasis]( [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]</h3>
<h3>[method:Matrix4 extractBasis]( [page:Vector3 xAxis], [page:Vector3 zAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]</h3>
<div>
Extracts basis of into the three axis vectors provided. Returns the current matrix.
</div>
......@@ -110,12 +110,12 @@
<h3>[method:Matrix4 multiplyScalar]( [page:Float s] ) [page:Matrix4 this]</h3>
<div>
Multiplies this matrix by *s*.
Multiplies every component of the matrix by a scalar value *s*.
</div>
<h3>[method:Float determinant]()</h3>
<div>
Computes determinant of this matrix.<br />
Computes and returns the determinant of this matrix.<br />
Based on [link:http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm]
</div>
......@@ -142,7 +142,7 @@
<h3>[method:Matrix4 makeRotationFromEuler]( [page:Euler euler] ) [page:Matrix4 this]</h3>
<div>
euler — Rotation vector followed by order of rotations. Eg. "XYZ".
euler — Rotation vector followed by order of rotations, e.g., "XYZ".
</div>
<div>
Sets the rotation submatrix of this matrix to the rotation specified by Euler angles, the rest of the matrix is identity.<br />
......@@ -230,7 +230,7 @@
<h3>[method:Matrix4 clone]()</h3>
<div>
Clones this matrix.
Creates a copy of this matrix.
</div>
<h3>[method:Array applyToVector3Array]([page:Array a])</h3>
......@@ -238,12 +238,12 @@
array -- An array in the form [vector1x, vector1y, vector1z, vector2x, vector2y, vector2z, ...]
</div>
<div>
Multiply (apply) this matrix to every vector3 in the array.
Multiplies (applies) this matrix to every vector3 in the array.
</div>
<h3>[method:Float getMaxScaleOnAxis]()</h3>
<div>
Gets the max scale value of the 3 axes.
Gets the maximum scale value of the 3 axes.
</div>
<h2>Source</h2>
......
......@@ -112,6 +112,8 @@
<script src="js/Sidebar.Geometry.SphereGeometry.js"></script>
<script src="js/Sidebar.Geometry.TorusGeometry.js"></script>
<script src="js/Sidebar.Geometry.TorusKnotGeometry.js"></script>
<script src="../examples/js/geometries/TeapotBufferGeometry.js"></script>
<script src="js/Sidebar.Geometry.TeapotBufferGeometry.js"></script>
<script src="js/Sidebar.Material.js"></script>
<script src="js/Sidebar.Script.js"></script>
<script src="js/Toolbar.js"></script>
......
......@@ -7,6 +7,8 @@ var Loader = function ( editor ) {
var scope = this;
var signals = editor.signals;
this.texturePath = '';
this.loadFile = function ( file ) {
var filename = file.name;
......@@ -386,6 +388,8 @@ var Loader = function ( editor ) {
} else if ( data.metadata.type.toLowerCase() === 'geometry' ) {
var loader = new THREE.JSONLoader();
loader.setTexturePath( scope.texturePath );
var result = loader.parse( data );
var geometry = result.geometry;
......@@ -432,6 +436,8 @@ var Loader = function ( editor ) {
} else if ( data.metadata.type.toLowerCase() === 'object' ) {
var loader = new THREE.ObjectLoader();
loader.setTexturePath( scope.texturePath );
var result = loader.parse( data );
if ( result instanceof THREE.Scene ) {
......
......@@ -236,6 +236,34 @@ Menubar.Add = function ( editor ) {
} );
options.add( option );
// Teapot
var option = new UI.Panel();
option.setClass( 'option' );
option.setTextContent( 'Teapot' );
option.onClick( function () {
var size = 50;
var segments = 10;
var bottom = true;
var lid = true;
var body = true;
var fitLid = false;
var blinnScale = true;
var material = new THREE.MeshPhongMaterial();
material.side = 2;
var geometry = new THREE.TeapotBufferGeometry( size, segments, bottom, lid, body, fitLid, blinnScale );
var mesh = new THREE.Mesh( geometry, material );
mesh.name = 'Teapot ' + ( ++ meshCount );
editor.addObject( mesh );
editor.select( mesh );
} );
options.add( option );
// Sprite
var option = new UI.Panel();
......
/**
* @author tschw
*/
Sidebar.Geometry.TeapotBufferGeometry = function ( signals, object ) {
var container = new UI.Panel();
var parameters = object.geometry.parameters;
// size
var sizeRow = new UI.Panel();
var size = new UI.Number( parameters.size ).onChange( update );
sizeRow.add( new UI.Text( 'Size' ).setWidth( '90px' ) );
sizeRow.add( size );
container.add( sizeRow );
// segments
var segmentsRow = new UI.Panel();
var segments = new UI.Integer( parameters.segments ).setRange( 1, Infinity ).onChange( update );
segmentsRow.add( new UI.Text( 'Segments' ).setWidth( '90px' ) );
segmentsRow.add( segments );
container.add( segmentsRow );
// bottom
var bottomRow = new UI.Panel();
var bottom = new UI.Checkbox( parameters.bottom ).onChange( update );
bottomRow.add( new UI.Text( 'Bottom' ).setWidth( '90px' ) );
bottomRow.add( bottom );
container.add( bottomRow );
// lid
var lidRow = new UI.Panel();
var lid = new UI.Checkbox( parameters.lid ).onChange( update );
lidRow.add( new UI.Text( 'Lid' ).setWidth( '90px' ) );
lidRow.add( lid );
container.add( lidRow );
// body
var bodyRow = new UI.Panel();
var body = new UI.Checkbox( parameters.body ).onChange( update );
bodyRow.add( new UI.Text( 'Body' ).setWidth( '90px' ) );
bodyRow.add( body );
container.add( bodyRow );
// fitted lid
var fitLidRow = new UI.Panel();
var fitLid = new UI.Checkbox( parameters.fitLid ).onChange( update );
fitLidRow.add( new UI.Text( 'Fitted Lid' ).setWidth( '90px' ) );
fitLidRow.add( fitLid );
container.add( fitLidRow );
// blinn-sized
var blinnRow = new UI.Panel();
var blinn = new UI.Checkbox( parameters.blinn ).onChange( update );
blinnRow.add( new UI.Text( 'Blinn-scaled' ).setWidth( '90px' ) );
blinnRow.add( blinn );
container.add( blinnRow );
function update() {
object.geometry.dispose();
object.geometry = new THREE.TeapotBufferGeometry(
size.getValue(),
segments.getValue(),
bottom.getValue(),
lid.getValue(),
body.getValue(),
fitLid.getValue(),
blinn.getValue()
);
object.geometry.computeBoundingSphere();
signals.geometryChanged.dispatch( object );
}
return container;
}
......@@ -551,7 +551,7 @@ Sidebar.Material = function ( editor ) {
if ( objectHasUvs ) {
material.lightMap = specularMapEnabled ? materialLightMap.getValue() : null;
material.lightMap = lightMapEnabled ? materialLightMap.getValue() : null;
material.needsUpdate = true;
} else {
......@@ -683,7 +683,7 @@ Sidebar.Material = function ( editor ) {
};
function refreshUi(resetTextureSelectors) {
function refreshUi( resetTextureSelectors ) {
var material = currentObject.material;
......
......@@ -53,15 +53,15 @@ Viewport.Info = function ( editor ) {
} else if ( geometry instanceof THREE.BufferGeometry ) {
vertices += geometry.attributes.position.array.length / 3;
if ( geometry.index !== null ) {
if ( geometry.attributes.index !== undefined ) {
triangles += geometry.attributes.index.array.length / 3;
vertices += geometry.index.count * 3;
triangles += geometry.index.count;
} else {
triangles += geometry.attributes.position.array.length / 9;
vertices += geometry.attributes.position.count;
triangles += geometry.attributes.position.count / 3;
}
......
......@@ -381,6 +381,7 @@
"webgl_buffergeometry_lines_indexed",
"webgl_buffergeometry_particles",
"webgl_buffergeometry_rawshader",
"webgl_buffergeometry_teapot",
"webgl_buffergeometry_uint",
"webgl_custom_attributes",
"webgl_custom_attributes_lines",
......
......@@ -806,7 +806,7 @@
function onPointerHover( event ) {
if ( scope.object === undefined || _dragging === true ) return;
if ( scope.object === undefined || _dragging === true || ( event.button !== undefined && event.button !== 0 ) ) return;
var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
......@@ -834,7 +834,7 @@
function onPointerDown( event ) {
if ( scope.object === undefined || _dragging === true ) return;
if ( scope.object === undefined || _dragging === true || ( event.button !== undefined && event.button !== 0 ) ) return;
var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
......@@ -884,7 +884,7 @@
function onPointerMove( event ) {
if ( scope.object === undefined || scope.axis === null || _dragging === false ) return;
if ( scope.object === undefined || scope.axis === null || _dragging === false || ( event.button !== undefined && event.button !== 0 ) ) return;
var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
......@@ -1055,6 +1055,8 @@
function onPointerUp( event ) {
if ( event.button !== undefined && event.button !== 0 ) return;
if ( _dragging && ( scope.axis !== null ) ) {
mouseUpEvent.mode = _mode;
......
/**
* @author Eric Haines / http://erichaines.com/
*
* Tessellates the famous Utah teapot database by Martin Newell into triangles.
*
* THREE.TeapotBufferGeometry = function ( size, segments, bottom, lid, body, fitLid, blinn )
*
* defaults: size = 50, segments = 10, bottom = true, lid = true, body = true,
* fitLid = false, blinn = true
*
* size is a relative scale: I've scaled the teapot to fit vertically between -1 and 1.
* Think of it as a "radius".
* segments - number of line segments to subdivide each patch edge;
* 1 is possible but gives degenerates, so two is the real minimum.
* bottom - boolean, if true (default) then the bottom patches are added. Some consider
* adding the bottom heresy, so set this to "false" to adhere to the One True Way.
* lid - to remove the lid and look inside, set to true.
* body - to remove the body and leave the lid, set this and "bottom" to false.
* fitLid - the lid is a tad small in the original. This stretches it a bit so you can't
* see the teapot's insides through the gap.
* blinn - Jim Blinn scaled the original data vertically by dividing by about 1.3 to look
* nicer. If you want to see the original teapot, similar to the real-world model, set
* this to false. True by default.
* See http://en.wikipedia.org/wiki/File:Original_Utah_Teapot.jpg for the original
* real-world teapot (from http://en.wikipedia.org/wiki/Utah_teapot).
*
* Note that the bottom (the last four patches) is not flat - blame Frank Crow, not me.
*
* The teapot should normally be rendered as a double sided object, since for some
* patches both sides can be seen, e.g., the gap around the lid and inside the spout.
*
* Segments 'n' determines the number of triangles output.
* Total triangles = 32*2*n*n - 8*n [degenerates at the top and bottom cusps are deleted]
*
* size_factor # triangles
* 1 56
* 2 240
* 3 552
* 4 992
*
* 10 6320
* 20 25440
* 30 57360
*
* Code converted from my ancient SPD software, http://tog.acm.org/resources/SPD/
* Created for the Udacity course "Interactive Rendering", http://bit.ly/ericity
* Lesson: https://www.udacity.com/course/viewer#!/c-cs291/l-68866048/m-106482448
* YouTube video on teapot history: https://www.youtube.com/watch?v=DxMfblPzFNc
*
* See https://en.wikipedia.org/wiki/Utah_teapot for the history of the teapot
*
*/
/*global THREE */
THREE.TeapotBufferGeometry = function ( size, segments, bottom, lid, body, fitLid, blinn ) {
"use strict";
// 32 * 4 * 4 Bezier spline patches
var teapotPatches = [
/*rim*/
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
3,16,17,18,7,19,20,21,11,22,23,24,15,25,26,27,
18,28,29,30,21,31,32,33,24,34,35,36,27,37,38,39,
30,40,41,0,33,42,43,4,36,44,45,8,39,46,47,12,
/*body*/
12,13,14,15,48,49,50,51,52,53,54,55,56,57,58,59,
15,25,26,27,51,60,61,62,55,63,64,65,59,66,67,68,
27,37,38,39,62,69,70,71,65,72,73,74,68,75,76,77,
39,46,47,12,71,78,79,48,74,80,81,52,77,82,83,56,
56,57,58,59,84,85,86,87,88,89,90,91,92,93,94,95,
59,66,67,68,87,96,97,98,91,99,100,101,95,102,103,104,
68,75,76,77,98,105,106,107,101,108,109,110,104,111,112,113,
77,82,83,56,107,114,115,84,110,116,117,88,113,118,119,92,
/*handle*/
120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,
123,136,137,120,127,138,139,124,131,140,141,128,135,142,143,132,
132,133,134,135,144,145,146,147,148,149,150,151,68,152,153,154,
135,142,143,132,147,155,156,144,151,157,158,148,154,159,160,68,
/*spout*/
161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,
164,177,178,161,168,179,180,165,172,181,182,169,176,183,184,173,
173,174,175,176,185,186,187,188,189,190,191,192,193,194,195,196,
176,183,184,173,188,197,198,185,192,199,200,189,196,201,202,193,
/*lid*/
203,203,203,203,204,205,206,207,208,208,208,208,209,210,211,212,
203,203,203,203,207,213,214,215,208,208,208,208,212,216,217,218,
203,203,203,203,215,219,220,221,208,208,208,208,218,222,223,224,
203,203,203,203,221,225,226,204,208,208,208,208,224,227,228,209,
209,210,211,212,229,230,231,232,233,234,235,236,237,238,239,240,
212,216,217,218,232,241,242,243,236,244,245,246,240,247,248,249,
218,222,223,224,243,250,251,252,246,253,254,255,249,256,257,258,
224,227,228,209,252,259,260,229,255,261,262,233,258,263,264,237,
/*bottom*/
265,265,265,265,266,267,268,269,270,271,272,273,92,119,118,113,
265,265,265,265,269,274,275,276,273,277,278,279,113,112,111,104,
265,265,265,265,276,280,281,282,279,283,284,285,104,103,102,95,
265,265,265,265,282,286,287,266,285,288,289,270,95,94,93,92
] ;
var teapotVertices = [
1.4,0,2.4,
1.4,-0.784,2.4,
0.784,-1.4,2.4,
0,-1.4,2.4,
1.3375,0,2.53125,
1.3375,-0.749,2.53125,
0.749,-1.3375,2.53125,
0,-1.3375,2.53125,
1.4375,0,2.53125,
1.4375,-0.805,2.53125,
0.805,-1.4375,2.53125,
0,-1.4375,2.53125,
1.5,0,2.4,
1.5,-0.84,2.4,
0.84,-1.5,2.4,
0,-1.5,2.4,
-0.784,-1.4,2.4,
-1.4,-0.784,2.4,
-1.4,0,2.4,
-0.749,-1.3375,2.53125,
-1.3375,-0.749,2.53125,
-1.3375,0,2.53125,
-0.805,-1.4375,2.53125,
-1.4375,-0.805,2.53125,
-1.4375,0,2.53125,
-0.84,-1.5,2.4,
-1.5,-0.84,2.4,
-1.5,0,2.4,
-1.4,0.784,2.4,
-0.784,1.4,2.4,
0,1.4,2.4,
-1.3375,0.749,2.53125,
-0.749,1.3375,2.53125,
0,1.3375,2.53125,
-1.4375,0.805,2.53125,
-0.805,1.4375,2.53125,
0,1.4375,2.53125,
-1.5,0.84,2.4,
-0.84,1.5,2.4,
0,1.5,2.4,
0.784,1.4,2.4,
1.4,0.784,2.4,
0.749,1.3375,2.53125,
1.3375,0.749,2.53125,
0.805,1.4375,2.53125,
1.4375,0.805,2.53125,
0.84,1.5,2.4,
1.5,0.84,2.4,
1.75,0,1.875,
1.75,-0.98,1.875,
0.98,-1.75,1.875,
0,-1.75,1.875,
2,0,1.35,
2,-1.12,1.35,
1.12,-2,1.35,
0,-2,1.35,
2,0,0.9,
2,-1.12,0.9,
1.12,-2,0.9,
0,-2,0.9,
-0.98,-1.75,1.875,
-1.75,-0.98,1.875,
-1.75,0,1.875,
-1.12,-2,1.35,
-2,-1.12,1.35,
-2,0,1.35,
-1.12,-2,0.9,
-2,-1.12,0.9,
-2,0,0.9,
-1.75,0.98,1.875,
-0.98,1.75,1.875,
0,1.75,1.875,
-2,1.12,1.35,
-1.12,2,1.35,
0,2,1.35,
-2,1.12,0.9,
-1.12,2,0.9,
0,2,0.9,
0.98,1.75,1.875,
1.75,0.98,1.875,
1.12,2,1.35,
2,1.12,1.35,
1.12,2,0.9,
2,1.12,0.9,
2,0,0.45,
2,-1.12,0.45,
1.12,-2,0.45,
0,-2,0.45,
1.5,0,0.225,
1.5,-0.84,0.225,
0.84,-1.5,0.225,
0,-1.5,0.225,
1.5,0,0.15,
1.5,-0.84,0.15,
0.84,-1.5,0.15,
0,-1.5,0.15,
-1.12,-2,0.45,
-2,-1.12,0.45,
-2,0,0.45,
-0.84,-1.5,0.225,
-1.5,-0.84,0.225,
-1.5,0,0.225,
-0.84,-1.5,0.15,
-1.5,-0.84,0.15,
-1.5,0,0.15,
-2,1.12,0.45,
-1.12,2,0.45,
0,2,0.45,
-1.5,0.84,0.225,
-0.84,1.5,0.225,
0,1.5,0.225,
-1.5,0.84,0.15,
-0.84,1.5,0.15,
0,1.5,0.15,
1.12,2,0.45,
2,1.12,0.45,
0.84,1.5,0.225,
1.5,0.84,0.225,
0.84,1.5,0.15,
1.5,0.84,0.15,
-1.6,0,2.025,
-1.6,-0.3,2.025,
-1.5,-0.3,2.25,
-1.5,0,2.25,
-2.3,0,2.025,
-2.3,-0.3,2.025,
-2.5,-0.3,2.25,
-2.5,0,2.25,
-2.7,0,2.025,
-2.7,-0.3,2.025,
-3,-0.3,2.25,
-3,0,2.25,
-2.7,0,1.8,
-2.7,-0.3,1.8,
-3,-0.3,1.8,
-3,0,1.8,
-1.5,0.3,2.25,
-1.6,0.3,2.025,
-2.5,0.3,2.25,
-2.3,0.3,2.025,
-3,0.3,2.25,
-2.7,0.3,2.025,
-3,0.3,1.8,
-2.7,0.3,1.8,
-2.7,0,1.575,
-2.7,-0.3,1.575,
-3,-0.3,1.35,
-3,0,1.35,
-2.5,0,1.125,
-2.5,-0.3,1.125,
-2.65,-0.3,0.9375,
-2.65,0,0.9375,
-2,-0.3,0.9,
-1.9,-0.3,0.6,
-1.9,0,0.6,
-3,0.3,1.35,
-2.7,0.3,1.575,
-2.65,0.3,0.9375,
-2.5,0.3,1.125,
-1.9,0.3,0.6,
-2,0.3,0.9,
1.7,0,1.425,
1.7,-0.66,1.425,
1.7,-0.66,0.6,
1.7,0,0.6,
2.6,0,1.425,
2.6,-0.66,1.425,
3.1,-0.66,0.825,
3.1,0,0.825,
2.3,0,2.1,
2.3,-0.25,2.1,
2.4,-0.25,2.025,
2.4,0,2.025,
2.7,0,2.4,
2.7,-0.25,2.4,
3.3,-0.25,2.4,
3.3,0,2.4,
1.7,0.66,0.6,
1.7,0.66,1.425,
3.1,0.66,0.825,
2.6,0.66,1.425,
2.4,0.25,2.025,
2.3,0.25,2.1,
3.3,0.25,2.4,
2.7,0.25,2.4,
2.8,0,2.475,
2.8,-0.25,2.475,
3.525,-0.25,2.49375,
3.525,0,2.49375,
2.9,0,2.475,
2.9,-0.15,2.475,
3.45,-0.15,2.5125,
3.45,0,2.5125,
2.8,0,2.4,
2.8,-0.15,2.4,
3.2,-0.15,2.4,
3.2,0,2.4,
3.525,0.25,2.49375,
2.8,0.25,2.475,
3.45,0.15,2.5125,
2.9,0.15,2.475,
3.2,0.15,2.4,
2.8,0.15,2.4,
0,0,3.15,
0.8,0,3.15,
0.8,-0.45,3.15,
0.45,-0.8,3.15,
0,-0.8,3.15,
0,0,2.85,
0.2,0,2.7,
0.2,-0.112,2.7,
0.112,-0.2,2.7,
0,-0.2,2.7,
-0.45,-0.8,3.15,
-0.8,-0.45,3.15,
-0.8,0,3.15,
-0.112,-0.2,2.7,
-0.2,-0.112,2.7,
-0.2,0,2.7,
-0.8,0.45,3.15,
-0.45,0.8,3.15,
0,0.8,3.15,
-0.2,0.112,2.7,
-0.112,0.2,2.7,
0,0.2,2.7,
0.45,0.8,3.15,
0.8,0.45,3.15,
0.112,0.2,2.7,
0.2,0.112,2.7,
0.4,0,2.55,
0.4,-0.224,2.55,
0.224,-0.4,2.55,
0,-0.4,2.55,
1.3,0,2.55,
1.3,-0.728,2.55,
0.728,-1.3,2.55,
0,-1.3,2.55,
1.3,0,2.4,
1.3,-0.728,2.4,
0.728,-1.3,2.4,
0,-1.3,2.4,
-0.224,-0.4,2.55,
-0.4,-0.224,2.55,
-0.4,0,2.55,
-0.728,-1.3,2.55,
-1.3,-0.728,2.55,
-1.3,0,2.55,
-0.728,-1.3,2.4,
-1.3,-0.728,2.4,
-1.3,0,2.4,
-0.4,0.224,2.55,
-0.224,0.4,2.55,
0,0.4,2.55,
-1.3,0.728,2.55,
-0.728,1.3,2.55,
0,1.3,2.55,
-1.3,0.728,2.4,
-0.728,1.3,2.4,
0,1.3,2.4,
0.224,0.4,2.55,
0.4,0.224,2.55,
0.728,1.3,2.55,
1.3,0.728,2.55,
0.728,1.3,2.4,
1.3,0.728,2.4,
0,0,0,
1.425,0,0,
1.425,0.798,0,
0.798,1.425,0,
0,1.425,0,
1.5,0,0.075,
1.5,0.84,0.075,
0.84,1.5,0.075,
0,1.5,0.075,
-0.798,1.425,0,
-1.425,0.798,0,
-1.425,0,0,
-0.84,1.5,0.075,
-1.5,0.84,0.075,
-1.5,0,0.075,
-1.425,-0.798,0,
-0.798,-1.425,0,
0,-1.425,0,
-1.5,-0.84,0.075,
-0.84,-1.5,0.075,
0,-1.5,0.075,
0.798,-1.425,0,
1.425,-0.798,0,
0.84,-1.5,0.075,
1.5,-0.84,0.075
] ;
THREE.BufferGeometry.call( this );
this.type = 'TeapotBufferGeometry';
this.parameters = {
size: size,
segments: segments,
bottom: bottom,
lid: lid,
body: body,
fitLid: fitLid,
blinn: blinn
};
size = size || 50;
// number of segments per patch
segments = segments !== undefined ? Math.max( 2, Math.floor( segments ) || 10 ) : 10;
// which parts should be visible
bottom = bottom === undefined ? true : bottom;
lid = lid === undefined ? true : lid;
body = body === undefined ? true : body;
// Should the lid be snug? It's not traditional, so off by default
fitLid = fitLid === undefined ? false : fitLid;
// Jim Blinn scaled the teapot down in size by about 1.3 for
// some rendering tests. He liked the new proportions that he kept
// the data in this form. The model was distributed with these new
// proportions and became the norm. Trivia: comparing images of the
// real teapot and the computer model, the ratio for the bowl of the
// real teapot is more like 1.25, but since 1.3 is the traditional
// value given, we use it here.
var blinnScale = 1.3;
blinn = blinn === undefined ? true : blinn;
// scale the size to be the real scaling factor
var maxHeight = 3.15 * ( blinn ? 1 : blinnScale );
var maxHeight2 = maxHeight / 2;
var trueSize = size / maxHeight2;
// Number of elements depends on what is needed. Subtract degenerate
// triangles at tip of bottom and lid out in advance.
var numTriangles = bottom ? ( 8 * segments - 4 ) * segments : 0;
numTriangles += lid ? ( 16 * segments - 4 ) * segments : 0;
numTriangles += body ? 40 * segments * segments : 0;
var indices = new Uint32Array( numTriangles * 3 );
var numVertices = bottom ? 4 : 0;
numVertices += lid ? 8 : 0;
numVertices += body ? 20 : 0;
numVertices *= ( segments + 1 ) * ( segments + 1 );
var vertices = new Float32Array( numVertices * 3 );
var normals = new Float32Array( numVertices * 3 );
var uvs = new Float32Array( numVertices * 2 );
// Bezier form
var ms = new THREE.Matrix4();
ms.set( -1.0, 3.0, -3.0, 1.0,
3.0, -6.0, 3.0, 0.0,
-3.0, 3.0, 0.0, 0.0,
1.0, 0.0, 0.0, 0.0 ) ;
var g = [];
var i, r, c;
var sp = [];
var tp = [];
var dsp = [];
var dtp = [];
// M * G * M matrix, sort of see
// http://www.cs.helsinki.fi/group/goa/mallinnus/curves/surfaces.html
var mgm = [];
var vert = [];
var sdir = [];
var tdir = [];
var norm = new THREE.Vector3();
var tcoord;
var sstep, tstep;
var vertPerRow, eps;
var s, t, sval, tval, p, dsval, dtval;
var normOut = new THREE.Vector3();
var v1, v2, v3, v4;
var gmx = new THREE.Matrix4();
var tmtx = new THREE.Matrix4();
var vsp = new THREE.Vector4();
var vtp = new THREE.Vector4();
var vdsp = new THREE.Vector4();
var vdtp = new THREE.Vector4();
var vsdir = new THREE.Vector3();
var vtdir = new THREE.Vector3();
var mst = ms.clone();
mst.transpose();
// internal function: test if triangle has any matching vertices;
// if so, don't save triangle, since it won't display anything.
var notDegenerate = function ( vtx1, vtx2, vtx3 ) {
// if any vertex matches, return false
return ! ( ( ( vertices[ vtx1 * 3 ] === vertices[ vtx2 * 3 ] ) &&
( vertices[ vtx1 * 3 + 1 ] === vertices[ vtx2 * 3 + 1 ] ) &&
( vertices[ vtx1 * 3 + 2 ] === vertices[ vtx2 * 3 + 2 ] ) ) ||
( ( vertices[ vtx1 * 3 ] === vertices[ vtx3 * 3 ] ) &&
( vertices[ vtx1 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] ) &&
( vertices[ vtx1 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ) ) ||
( ( vertices[ vtx2 * 3 ] === vertices[ vtx3 * 3 ] ) &&
( vertices[ vtx2 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] ) &&
( vertices[ vtx2 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ) ) );
};
for ( i = 0; i < 3; i ++ )
{
mgm[ i ] = new THREE.Matrix4();
}
var minPatches = body ? 0 : 20;
var maxPatches = bottom ? 32 : 28;
vertPerRow = segments + 1;
eps = 0.0000001;
var surfCount = 0;
var vertCount = 0;
var normCount = 0;
var uvCount = 0;
var indexCount = 0;
for ( var surf = minPatches ; surf < maxPatches ; surf ++ ) {
// lid is in the middle of the data, patches 20-27,
// so ignore it for this part of the loop if the lid is not desired
if ( lid || ( surf < 20 || surf >= 28 ) ) {
// get M * G * M matrix for x,y,z
for ( i = 0 ; i < 3 ; i ++ ) {
// get control patches
for ( r = 0 ; r < 4 ; r ++ ) {
for ( c = 0 ; c < 4 ; c ++ ) {
// transposed
g[ c * 4 + r ] = teapotVertices[ teapotPatches[ surf * 16 + r * 4 + c ] * 3 + i ] ;
// is the lid to be made larger, and is this a point on the lid
// that is X or Y?
if ( fitLid && ( surf >= 20 && surf < 28 ) && ( i !== 2 ) ) {
// increase XY size by 7.7%, found empirically. I don't
// increase Z so that the teapot will continue to fit in the
// space -1 to 1 for Y (Y is up for the final model).
g[ c * 4 + r ] *= 1.077;
}
// Blinn "fixed" the teapot by dividing Z by blinnScale, and that's the
// data we now use. The original teapot is taller. Fix it:
if ( ! blinn && ( i === 2 ) ) {
g[ c * 4 + r ] *= blinnScale;
}
}
}
gmx.set( g[ 0 ], g[ 1 ], g[ 2 ], g[ 3 ], g[ 4 ], g[ 5 ], g[ 6 ], g[ 7 ], g[ 8 ], g[ 9 ], g[ 10 ], g[ 11 ], g[ 12 ], g[ 13 ], g[ 14 ], g[ 15 ] );
tmtx.multiplyMatrices( gmx, ms );
mgm[ i ].multiplyMatrices( mst, tmtx );
}
// step along, get points, and output
for ( sstep = 0 ; sstep <= segments ; sstep ++ ) {
s = sstep / segments;
for ( tstep = 0 ; tstep <= segments ; tstep ++ ) {
t = tstep / segments;
// point from basis
// get power vectors and their derivatives
for ( p = 4, sval = tval = 1.0 ; p -- ; ) {
sp[ p ] = sval ;
tp[ p ] = tval ;
sval *= s ;
tval *= t ;
if ( p === 3 ) {
dsp[ p ] = dtp[ p ] = 0.0 ;
dsval = dtval = 1.0 ;
} else {
dsp[ p ] = dsval * ( 3 - p ) ;
dtp[ p ] = dtval * ( 3 - p ) ;
dsval *= s ;
dtval *= t ;
}
}
vsp.fromArray( sp );
vtp.fromArray( tp );
vdsp.fromArray( dsp );
vdtp.fromArray( dtp );
// do for x,y,z
for ( i = 0 ; i < 3 ; i ++ ) {
// multiply power vectors times matrix to get value
tcoord = vsp.clone();
tcoord.applyMatrix4( mgm[ i ] );
vert[ i ] = tcoord.dot( vtp );
// get s and t tangent vectors
tcoord = vdsp.clone();
tcoord.applyMatrix4( mgm[ i ] );
sdir[ i ] = tcoord.dot( vtp ) ;
tcoord = vsp.clone();
tcoord.applyMatrix4( mgm[ i ] );
tdir[ i ] = tcoord.dot( vdtp ) ;
}
// find normal
vsdir.fromArray( sdir );
vtdir.fromArray( tdir );
norm.crossVectors( vtdir, vsdir );
norm.normalize();
// if X and Z length is 0, at the cusp, so point the normal up or down, depending on patch number
if ( vert[ 0 ] === 0 && vert[ 1 ] === 0 )
{
// if above the middle of the teapot, normal points up, else down
normOut.set( 0, vert[ 2 ] > maxHeight2 ? 1 : - 1, 0 );
}
else
{
// standard output: rotate on X axis
normOut.set( norm.x, norm.z, - norm.y );
}
// store it all
vertices[ vertCount ++ ] = trueSize * vert[ 0 ];
vertices[ vertCount ++ ] = trueSize * ( vert[ 2 ] - maxHeight2 );
vertices[ vertCount ++ ] = - trueSize * vert[ 1 ];
normals[ normCount ++ ] = normOut.x;
normals[ normCount ++ ] = normOut.y;
normals[ normCount ++ ] = normOut.z;
uvs[ uvCount ++ ] = 1 - t;
uvs[ uvCount ++ ] = 1 - s;
}
}
// save the faces
for ( sstep = 0 ; sstep < segments ; sstep ++ ) {
for ( tstep = 0 ; tstep < segments ; tstep ++ ) {
v1 = surfCount * vertPerRow * vertPerRow + sstep * vertPerRow + tstep;
v2 = v1 + 1;
v3 = v2 + vertPerRow;
v4 = v1 + vertPerRow;
// Normals and UVs cannot be shared. Without clone(), you can see the consequences
// of sharing if you call geometry.applyMatrix( matrix ).
if ( notDegenerate ( v1, v2, v3 ) ) {
indices[ indexCount ++ ] = v1;
indices[ indexCount ++ ] = v2;
indices[ indexCount ++ ] = v3;
}
if ( notDegenerate ( v1, v3, v4 ) ) {
indices[ indexCount ++ ] = v1;
indices[ indexCount ++ ] = v3;
indices[ indexCount ++ ] = v4;
}
}
}
// increment only if a surface was used
surfCount ++;
}
}
this.addIndex( new THREE.BufferAttribute( indices, 1 ) );
this.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
this.computeBoundingSphere();
};
THREE.TeapotBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
THREE.TeapotBufferGeometry.prototype.constructor = THREE.TeapotBufferGeometry;
THREE.TeapotBufferGeometry.prototype.clone = function () {
var bufferGeometry = new THREE.TeapotBufferGeometry(
this.parameters.size,
this.parameters.segments,
this.parameters.bottom,
this.parameters.lid,
this.parameters.body,
this.parameters.fitLid,
this.parameters.blinn
);
return bufferGeometry;
};
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - teapot buffer geometry</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #fff;
font-family: Monospace;
font-size: 13px;
text-align: center;
font-weight: bold;
background-color: #000;
margin: 0px;
overflow: hidden;
}
#info {
position: relative;
margin: 0 auto -2.1em;
top: 0px;
width: 550px;
padding: 5px;
z-index:100;
}
a { color: blue; }
</style>
</head>
<body>
<div id="info">
<a href="http://threejs.org" target="_blank">three.js</a> - the Utah Teapot from the <a href="https://www.udacity.com/course/interactive-3d-graphics--cs291">Udacity Interactive 3D Graphics course</a>
</div>
<script src="../build/three.min.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/Detector.js"></script>
<script src='js/libs/dat.gui.min.js'></script>
<script src='js/geometries/TeapotBufferGeometry.js'></script>
<script>
////////////////////////////////////////////////////////////////////////////////
// Utah/Newell Teapot demo
////////////////////////////////////////////////////////////////////////////////
/*global THREE, Detector, container, dat, window */
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var camera, scene, sceneCube, renderer;
var cameraControls;
var effectController;
var teapotSize = 400;
var ambientLight, light;
var skybox;
var tess = -1; // force initialization
var bBottom ;
var bLid;
var bBody;
var bFitLid;
var bNonBlinn;
var shading;
var wireMaterial, flatMaterial, gouraudMaterial, phongMaterial, texturedMaterial, reflectiveMaterial;
var teapot;
// allocate these just once
var diffuseColor = new THREE.Color();
var specularColor = new THREE.Color();
init();
render();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var canvasWidth = window.innerWidth;
var canvasHeight = window.innerHeight;
// CAMERA
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 80000 );
camera.position.set( -600, 550, 1300 );
// LIGHTS
ambientLight = new THREE.AmbientLight( 0x333333 ); // 0.2
light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 );
// direction is set in GUI
// RENDERER
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( canvasWidth, canvasHeight );
renderer.setClearColor( 0xAAAAAA );
renderer.gammaInput = true;
renderer.gammaOutput = true;
container.appendChild( renderer.domElement );
// EVENTS
window.addEventListener( 'resize', onWindowResize, false );
// CONTROLS
cameraControls = new THREE.OrbitControls( camera, renderer.domElement );
cameraControls.target.set( 0, 0, 0 );
cameraControls.addEventListener( 'change', render );
// TEXTURE MAP
var textureMap = THREE.ImageUtils.loadTexture( 'textures/UV_Grid_Sm.jpg' );
textureMap.wrapS = textureMap.wrapT = THREE.RepeatWrapping;
textureMap.anisotropy = 16;
// REFLECTION MAP
var path = "textures/cube/skybox/";
var urls = [ path + "px.jpg", path + "nx.jpg",
path + "py.jpg", path + "ny.jpg",
path + "pz.jpg", path + "nz.jpg" ];
var textureCube = THREE.ImageUtils.loadTextureCube( urls );
// MATERIALS
var materialColor = new THREE.Color();
materialColor.setRGB( 1.0, 1.0, 1.0 );
wireMaterial = new THREE.MeshBasicMaterial( { color: 0xFFFFFF, wireframe: true } ) ;
flatMaterial = new THREE.MeshPhongMaterial( { color: materialColor, specular: 0x0, shading: THREE.FlatShading, side: THREE.DoubleSide } );
gouraudMaterial = new THREE.MeshLambertMaterial( { color: materialColor, shading: THREE.SmoothShading, side: THREE.DoubleSide } );
phongMaterial = new THREE.MeshPhongMaterial( { color: materialColor, shading: THREE.SmoothShading, side: THREE.DoubleSide } );
texturedMaterial = new THREE.MeshPhongMaterial( { color: materialColor, map: textureMap, shading: THREE.SmoothShading, side: THREE.DoubleSide } );
reflectiveMaterial = new THREE.MeshPhongMaterial( { color: materialColor, envMap: textureCube, shading: THREE.SmoothShading, side: THREE.DoubleSide } );
// SKYBOX
var shader = THREE.ShaderLib[ "cube" ];
shader.uniforms[ "tCube" ].value = textureCube;
var skyboxMaterial = new THREE.ShaderMaterial( {
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
depthWrite: false,
side: THREE.BackSide
} );
skybox = new THREE.Mesh( new THREE.BoxGeometry( 5000, 5000, 5000 ), skyboxMaterial );
// skybox scene - keep camera centered here
sceneCube = new THREE.Scene();
sceneCube.add( skybox );
// scene itself
scene = new THREE.Scene();
scene.add( ambientLight );
scene.add( light );
// GUI
setupGui();
}
// EVENT HANDLERS
function onWindowResize() {
var canvasWidth = window.innerWidth;
var canvasHeight = window.innerHeight;
renderer.setSize( canvasWidth, canvasHeight );
camera.aspect = canvasWidth / canvasHeight;
camera.updateProjectionMatrix();
render();
}
function setupGui() {
effectController = {
shininess: 40.0,
ka: 0.17,
kd: 0.51,
ks: 0.2,
metallic: true,
hue: 0.121,
saturation: 0.73,
lightness: 0.66,
lhue: 0.04,
lsaturation: 0.01, // non-zero so that fractions will be shown
llightness: 1.0,
// bizarrely, if you initialize these with negative numbers, the sliders
// will not show any decimal places.
lx: 0.32,
ly: 0.39,
lz: 0.7,
newTess: 15,
bottom: true,
lid: true,
body: true,
fitLid: false,
nonblinn: false,
newShading: "glossy"
};
var h;
var gui = new dat.GUI();
// material (attributes)
h = gui.addFolder( "Material control" );
h.add( effectController, "shininess", 1.0, 400.0, 1.0 ).name( "shininess" ).onChange( render );
h.add( effectController, "kd", 0.0, 1.0, 0.025 ).name( "diffuse strength" ).onChange( render );
h.add( effectController, "ks", 0.0, 1.0, 0.025 ).name( "specular strength" ).onChange( render );
h.add( effectController, "metallic" ).onChange( render );
// material (color)
h = gui.addFolder( "Material color" );
h.add( effectController, "hue", 0.0, 1.0, 0.025 ).name( "hue" ).onChange( render );
h.add( effectController, "saturation", 0.0, 1.0, 0.025 ).name( "saturation" ).onChange( render );
h.add( effectController, "lightness", 0.0, 1.0, 0.025 ).name( "lightness" ).onChange( render );
// light (point)
h = gui.addFolder( "Lighting" );
h.add( effectController, "lhue", 0.0, 1.0, 0.025 ).name( "hue" ).onChange( render );
h.add( effectController, "lsaturation", 0.0, 1.0, 0.025 ).name( "saturation" ).onChange( render );
h.add( effectController, "llightness", 0.0, 1.0, 0.025 ).name( "lightness" ).onChange( render );
h.add( effectController, "ka", 0.0, 1.0, 0.025 ).name( "ambient" ).onChange( render );
// light (directional)
h = gui.addFolder( "Light direction" );
h.add( effectController, "lx", -1.0, 1.0, 0.025 ).name( "x" ).onChange( render );
h.add( effectController, "ly", -1.0, 1.0, 0.025 ).name( "y" ).onChange( render );
h.add( effectController, "lz", -1.0, 1.0, 0.025 ).name( "z" ).onChange( render );
h = gui.addFolder( "Tessellation control" );
h.add( effectController, "newTess", [ 2, 3, 4, 5, 6, 8, 10, 15, 20, 30, 40, 50 ] ).name( "Tessellation Level" ).onChange( render );
h.add( effectController, "lid" ).name( "display lid" ).onChange( render );
h.add( effectController, "body" ).name( "display body" ).onChange( render );
h.add( effectController, "bottom" ).name( "display bottom" ).onChange( render );
h.add( effectController, "fitLid" ).name( "snug lid" ).onChange( render );
h.add( effectController, "nonblinn" ).name( "original scale" ).onChange( render );
// shading
h = gui.add( effectController, "newShading", [ "wireframe", "flat", "smooth", "glossy", "textured", "reflective" ] ).name( "Shading" ).onChange( render );
}
//
function render() {
if ( effectController.newTess !== tess ||
effectController.bottom !== bBottom ||
effectController.lid !== bLid ||
effectController.body !== bBody ||
effectController.fitLid !== bFitLid ||
effectController.nonblinn !== bNonBlinn ||
effectController.newShading !== shading )
{
tess = effectController.newTess;
bBottom = effectController.bottom;
bLid = effectController.lid;
bBody = effectController.body;
bFitLid = effectController.fitLid;
bNonBlinn = effectController.nonblinn;
shading = effectController.newShading;
createNewTeapot();
}
// We're a bit lazy here. We could check to see if any material attributes changed and update
// only if they have. But, these calls are cheap enough and this is just a demo.
phongMaterial.shininess = effectController.shininess;
texturedMaterial.shininess = effectController.shininess;
diffuseColor.setHSL( effectController.hue, effectController.saturation, effectController.lightness );
if ( effectController.metallic )
{
// make colors match to give a more metallic look
specularColor.copy( diffuseColor );
}
else
{
// more of a plastic look
specularColor.setRGB( 1, 1, 1 );
}
diffuseColor.multiplyScalar( effectController.kd );
flatMaterial.color.copy( diffuseColor );
gouraudMaterial.color.copy( diffuseColor );
phongMaterial.color.copy( diffuseColor );
texturedMaterial.color.copy( diffuseColor );
specularColor.multiplyScalar( effectController.ks );
phongMaterial.specular.copy( specularColor );
texturedMaterial.specular.copy( specularColor );
// Ambient's actually controlled by the light for this demo
ambientLight.color.setHSL( effectController.hue, effectController.saturation, effectController.lightness * effectController.ka );
light.position.set( effectController.lx, effectController.ly, effectController.lz );
light.color.setHSL( effectController.lhue, effectController.lsaturation, effectController.llightness );
// skybox is rendered separately, so that it is always behind the teapot.
if ( shading === "reflective" )
{
// clear to skybox
renderer.autoClear = false;
skybox.position.copy( camera.position );
renderer.render( sceneCube, camera );
}
else
{
// clear to regular background color
renderer.autoClear = true;
}
renderer.render( scene, camera );
}
// Whenever the teapot changes, the scene is rebuilt from scratch (not much to it).
function createNewTeapot() {
if ( teapot !== undefined ) {
teapot.geometry.dispose();
scene.remove( teapot );
}
var teapotGeometry = new THREE.TeapotBufferGeometry( teapotSize,
tess,
effectController.bottom,
effectController.lid,
effectController.body,
effectController.fitLid,
! effectController.nonblinn );
teapot = new THREE.Mesh(
teapotGeometry,
shading === "wireframe" ? wireMaterial : (
shading === "flat" ? flatMaterial : (
shading === "smooth" ? gouraudMaterial : (
shading === "glossy" ? phongMaterial : (
shading === "textured" ? texturedMaterial : reflectiveMaterial ) ) ) ) ); // if no match, pick Phong
scene.add( teapot );
}
</script>
</body>
</html>
......@@ -97,7 +97,9 @@ THREE.Line.prototype.raycast = ( function () {
if ( distSq > precisionSq ) continue;
var distance = ray.origin.distanceTo( interRay );
interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
var distance = raycaster.ray.origin.distanceTo( interRay );
if ( distance < raycaster.near || distance > raycaster.far ) continue;
......@@ -132,7 +134,9 @@ THREE.Line.prototype.raycast = ( function () {
if ( distSq > precisionSq ) continue;
var distance = ray.origin.distanceTo( interRay );
interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
var distance = raycaster.ray.origin.distanceTo( interRay );
if ( distance < raycaster.near || distance > raycaster.far ) continue;
......@@ -163,8 +167,10 @@ THREE.Line.prototype.raycast = ( function () {
var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
if ( distSq > precisionSq ) continue;
interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
var distance = ray.origin.distanceTo( interRay );
var distance = raycaster.ray.origin.distanceTo( interRay );
if ( distance < raycaster.near || distance > raycaster.far ) continue;
......
......@@ -19,15 +19,12 @@ THREE.WebGLRenderer = function ( parameters ) {
pixelRatio = 1,
_precision = parameters.precision !== undefined ? parameters.precision : 'highp',
_alpha = parameters.alpha !== undefined ? parameters.alpha : false,
_depth = parameters.depth !== undefined ? parameters.depth : true,
_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
_logarithmicDepthBuffer = parameters.logarithmicDepthBuffer !== undefined ? parameters.logarithmicDepthBuffer : false,
_clearColor = new THREE.Color( 0x000000 ),
_clearAlpha = 0;
......@@ -35,13 +32,18 @@ THREE.WebGLRenderer = function ( parameters ) {
var lights = [];
var opaqueObjects = [];
var opaqueObjectsLastIndex = -1;
var transparentObjects = [];
var transparentObjectsLastIndex = -1;
var opaqueImmediateObjects = [];
var opaqueImmediateObjectsLastIndex = -1;
var transparentImmediateObjects = [];
var transparentImmediateObjectsLastIndex = -1;
var morphInfluences = new Float32Array( 8 );
var sprites = [];
var lensFlares = [];
......@@ -206,11 +208,7 @@ THREE.WebGLRenderer = function ( parameters ) {
}
if ( _logarithmicDepthBuffer ) {
extensions.get( 'EXT_frag_depth' );
}
var capabilities = new THREE.WebGLCapabilities( _gl, extensions, parameters );
var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
var properties = new THREE.WebGLProperties();
......@@ -260,6 +258,7 @@ THREE.WebGLRenderer = function ( parameters ) {
setDefaultGLState();
this.context = _gl;
this.capabilities = capabilities;
this.extensions = extensions;
this.state = state;
......@@ -269,24 +268,6 @@ THREE.WebGLRenderer = function ( parameters ) {
this.shadowMap = shadowMap;
// GPU capabilities
var _maxTextures = _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS );
var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
var _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE );
var _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
var _supportsVertexTextures = _maxVertexTextures > 0;
var _supportsBoneTextures = _supportsVertexTextures && extensions.get( 'OES_texture_float' );
var _maxPrecision = state.getMaxPrecision( _precision );
if ( _maxPrecision !== _precision ) {
console.warn( 'THREE.WebGLRenderer:', _precision, 'not supported, using', _maxPrecision, 'instead.' );
_precision = _maxPrecision;
}
// Plugins
......@@ -341,7 +322,7 @@ THREE.WebGLRenderer = function ( parameters ) {
this.getPrecision = function () {
return _precision;
return capabilities.precision;
};
......@@ -623,7 +604,7 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( newReferenceCount === 0 ) {
// the last meterial that has been using the program let
// the last material that has been using the program let
// go of it, so remove it from the (unordered) _programs
// set and deallocate the GL resource
......@@ -1146,17 +1127,23 @@ THREE.WebGLRenderer = function ( parameters ) {
lights.length = 0;
opaqueObjects.length = 0;
transparentObjects.length = 0;
opaqueObjectsLastIndex = -1;
transparentObjectsLastIndex = -1;
opaqueImmediateObjects.length = 0;
transparentImmediateObjects.length = 0;
opaqueImmediateObjectsLastIndex = -1;
transparentImmediateObjectsLastIndex = -1;
sprites.length = 0;
lensFlares.length = 0;
projectObject( scene );
opaqueObjects.length = opaqueObjectsLastIndex + 1;
transparentObjects.length = transparentObjectsLastIndex + 1;
opaqueImmediateObjects.length = opaqueImmediateObjectsLastIndex + 1;
transparentImmediateObjects.length = transparentImmediateObjectsLastIndex + 1;
if ( _this.sortObjects === true ) {
opaqueObjects.sort( painterSortStable );
......@@ -1236,36 +1223,82 @@ THREE.WebGLRenderer = function ( parameters ) {
function pushImmediateRenderItem( object ) {
var array, index;
// allocate the next position in the appropriate array
if ( object.material.transparent ) {
transparentImmediateObjects.push( object );
array = transparentImmediateObjects;
index = ++ transparentImmediateObjectsLastIndex;
} else {
opaqueImmediateObjects.push( object );
array = opaqueImmediateObjects;
index = ++ opaqueImmediateObjectsLastIndex;
}
// recycle existing position or grow the array
if ( index < array.length ) {
array[ index ] = object;
} else {
// assert( index === array.length );
array.push( object );
}
}
function pushRenderItem( object, geometry, material, z, group ) {
var renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
z: _vector3.z,
group: group
};
var array, index;
// allocate the next position in the appropriate array
if ( material.transparent ) {
transparentObjects.push( renderItem );
array = transparentObjects;
index = ++ transparentObjectsLastIndex;
} else {
opaqueObjects.push( renderItem );
array = opaqueObjects;
index = ++ opaqueObjectsLastIndex;
}
// recycle existing render item or grow the array
var renderItem = array[ index ];
if ( renderItem !== undefined ) {
renderItem.id = object.id;
renderItem.object = object;
renderItem.geometry = geometry;
renderItem.material = material;
renderItem.z = _vector3.z;
renderItem.group = group;
} else {
renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
z: _vector3.z,
group: group
};
// assert( index === array.length );
array.push( renderItem );
}
......@@ -1428,11 +1461,11 @@ THREE.WebGLRenderer = function ( parameters ) {
var maxLightCount = allocateLights( lights );
var maxShadows = allocateShadows( lights );
var maxBones = allocateBones( object );
var precision = _precision;
var precision = capabilities.precision;
if ( material.precision !== null ) {
precision = state.getMaxPrecision( material.precision );
precision = capabilities.getMaxPrecision( material.precision );
if ( precision !== material.precision ) {
......@@ -1445,7 +1478,7 @@ THREE.WebGLRenderer = function ( parameters ) {
var parameters = {
precision: precision,
supportsVertexTextures: _supportsVertexTextures,
supportsVertexTextures: capabilities.vertexTextures,
map: !! material.map,
envMap: !! material.envMap,
......@@ -1469,11 +1502,11 @@ THREE.WebGLRenderer = function ( parameters ) {
flatShading: material.shading === THREE.FlatShading,
sizeAttenuation: material.sizeAttenuation,
logarithmicDepthBuffer: _logarithmicDepthBuffer,
logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,
skinning: material.skinning,
maxBones: maxBones,
useVertexTexture: _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture,
useVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,
morphTargets: material.morphTargets,
morphNormals: material.morphNormals,
......@@ -1740,7 +1773,7 @@ THREE.WebGLRenderer = function ( parameters ) {
_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera.projectionMatrix.elements );
if ( _logarithmicDepthBuffer ) {
if ( capabilities.logarithmicDepthBuffer ) {
_gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
......@@ -1799,7 +1832,7 @@ THREE.WebGLRenderer = function ( parameters ) {
}
if ( _supportsBoneTextures && object.skeleton && object.skeleton.useVertexTexture ) {
if ( capabilities.floatVertexTextures && object.skeleton && object.skeleton.useVertexTexture ) {
if ( p_uniforms.boneTexture !== undefined ) {
......@@ -2205,9 +2238,9 @@ THREE.WebGLRenderer = function ( parameters ) {
var textureUnit = _usedTextureUnits;
if ( textureUnit >= _maxTextures ) {
if ( textureUnit >= capabilities.maxTextures ) {
console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + _maxTextures );
console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
}
......@@ -2824,7 +2857,10 @@ THREE.WebGLRenderer = function ( parameters ) {
extension = extensions.get( 'EXT_texture_filter_anisotropic' );
if ( extension && texture.type !== THREE.FloatType && texture.type !== THREE.HalfFloatType ) {
if ( extension ) {
if ( texture.type === THREE.FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
if ( texture.type === THREE.HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;
if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
......@@ -2860,7 +2896,7 @@ THREE.WebGLRenderer = function ( parameters ) {
_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
texture.image = clampToMaxSize( texture.image, _maxTextureSize );
texture.image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
var image = texture.image,
isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
......@@ -3045,7 +3081,7 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( _this.autoScaleCubemaps && ! isCompressed && ! isDataTexture ) {
cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );
cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
} else {
......@@ -3508,7 +3544,7 @@ THREE.WebGLRenderer = function ( parameters ) {
function allocateBones ( object ) {
if ( _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {
if ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {
return 1024;
......@@ -3633,7 +3669,7 @@ THREE.WebGLRenderer = function ( parameters ) {
this.supportsVertexTextures = function () {
return _supportsVertexTextures;
return capabilities.vertexTextures;
};
......
THREE.WebGLCapabilities = function ( gl, extensions, parameters ) {
function getMaxPrecision( precision ) {
if ( precision === 'highp' ) {
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {
return 'highp';
}
precision = 'mediump';
}
if ( precision === 'mediump' ) {
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {
return 'mediump';
}
}
return 'lowp';
}
this.getMaxPrecision = getMaxPrecision;
this.precision = parameters.precision !== undefined ? parameters.precision : 'highp',
this.logarithmicDepthBuffer = parameters.logarithmicDepthBuffer !== undefined ? parameters.logarithmicDepthBuffer : false;
this.maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
this.maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
this.maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );
this.maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );
this.maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );
this.maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );
this.maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );
this.maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );
this.vertexTextures = this.maxVertexTextures > 0;
this.floatFragmentTextures = !! extensions.get( 'OES_texture_float' );
this.floatVertexTextures = this.vertexTextures && this.floatFragmentTextures;
var _maxPrecision = getMaxPrecision( this.precision );
if ( _maxPrecision !== this.precision ) {
console.warn( 'THREE.WebGLRenderer:', this.precision, 'not supported, using', _maxPrecision, 'instead.' );
this.precision = _maxPrecision;
}
if ( this.logarithmicDepthBuffer ) {
this.logarithmicDepthBuffer = !! extensions.get( 'EXT_frag_depth' );
}
};
......@@ -209,9 +209,9 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
var groups = geometry.groups;
var materials = material.materials;
for ( var j = 0, jl = groups.length; j < jl; j ++ ) {
for ( var k = 0, kl = groups.length; k < kl; k ++ ) {
var group = groups[ j ];
var group = groups[ k ];
var groupMaterial = materials[ group.materialIndex ];
if ( groupMaterial.visible === true ) {
......
......@@ -142,36 +142,6 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) {
};
this.getMaxPrecision = function ( precision ) {
if ( precision === 'highp' ) {
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {
return 'highp';
}
precision = 'mediump';
}
if ( precision === 'mediump' ) {
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {
return 'mediump';
}
}
return 'lowp';
};
this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) {
if ( blending !== currentBlending ) {
......
......@@ -3,22 +3,13 @@
*/
THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy ) {
if ( magFilter === undefined ) {
magFilter = THREE.NearestFilter;
}
if ( minFilter === undefined ) {
minFilter = THREE.NearestFilter;
}
THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
this.image = { data: data, width: width, height: height };
this.magFilter = magFilter !== undefined ? magFilter : THREE.NearestFilter;
this.minFilter = minFilter !== undefined ? minFilter : THREE.NearestFilter;
this.flipY = false;
this.generateMipmaps = false;
......@@ -26,4 +17,4 @@ THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS
};
THREE.DataTexture.prototype = Object.create( THREE.Texture.prototype );
THREE.DataTexture.prototype.constructor = THREE.DataTexture;
\ No newline at end of file
THREE.DataTexture.prototype.constructor = THREE.DataTexture;
......@@ -170,6 +170,7 @@
"src/renderers/webgl/WebGLBufferRenderer.js",
"src/renderers/webgl/WebGLIndexedBufferRenderer.js",
"src/renderers/webgl/WebGLExtensions.js",
"src/renderers/webgl/WebGLCapabilities.js",
"src/renderers/webgl/WebGLGeometries.js",
"src/renderers/webgl/WebGLObjects.js",
"src/renderers/webgl/WebGLProgram.js",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册