├── .idea └── .name ├── README.md ├── Three.js ├── cameras ├── Camera.js ├── CubeCamera.js ├── OrthographicCamera.js └── PerspectiveCamera.js ├── core ├── BufferAttribute.js ├── BufferGeometry.js ├── Clock.js ├── EventDispatcher.js ├── Face3.js ├── Face4.js ├── Geometry.js ├── Object3D.js ├── Projector.js └── Raycaster.js ├── lights ├── AmbientLight.js ├── AreaLight.js ├── DirectionalLight.js ├── HemisphereLight.js ├── Light.js ├── PointLight.js └── SpotLight.js ├── materials ├── LineBasicMaterial.js ├── LineDashedMaterial.js ├── Material.js ├── MeshBasicMaterial.js ├── MeshDepthMaterial.js ├── MeshFaceMaterial.js ├── MeshLambertMaterial.js ├── MeshNormalMaterial.js ├── MeshPhongMaterial.js ├── PointCloudMaterial.js ├── RawShaderMaterial.js ├── ShaderMaterial.js └── SpriteMaterial.js ├── math ├── Box2.js ├── Box3.js ├── Color.js ├── Euler.js ├── Frustum.js ├── Line3.js ├── Math.js ├── Matrix3.js ├── Matrix4.js ├── Plane.js ├── Quaternion.js ├── Ray.js ├── Sphere.js ├── Spline.js ├── Triangle.js ├── Vector2.js ├── Vector3.js └── Vector4.js ├── objects ├── Line.js ├── Mesh.js └── PointCloud.js ├── renderers ├── WebGLRenderTarget.js ├── WebGLRenderTargetCube.js ├── WebGLRenderer.js ├── shaders │ ├── ShaderChunk.js │ ├── ShaderLib.js │ ├── UniformsLib.js │ └── UniformsUtils.js └── webgl │ ├── WebGLExtensions.js │ ├── WebGLProgram.js │ ├── WebGLShader.js │ └── plugins │ ├── LensFlarePlugin.js │ ├── ShadowMapPlugin.js │ └── SpritePlugin.js ├── scenes ├── Fog.js ├── FogExp2.js └── Scene.js └── textures └── Texture.js /.idea/.name: -------------------------------------------------------------------------------- 1 | ThreeJS-Notes -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ThreeJS-Notes 2 | 对ThreeJS的中文注释,可以使用JSDOC可以自动生成说明文档 3 | 部分内容参照omni360同学已经写过的注释,https://github.com/omni360/three.js.sourcecode 4 | 5 | -------------------------------------------------------------------------------- /cameras/Camera.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author mikael emtinger / http://gomo.se/ 4 | * @author WestLangley / http://github.com/WestLangley 5 | */ 6 | /** 7 | * @classdesc 相机基类 8 | * @constructor 9 | * @extends {THREE.Object3D} 10 | */ 11 | THREE.Camera = function () { 12 | 13 | THREE.Object3D.call( this ); 14 | /** 15 | * @default 16 | * @type {string} 17 | */ 18 | this.type = 'Camera'; 19 | /** 20 | * @desc 这是matrixWorld的逆矩阵,matrixWorld包含相机在世界坐标系的变换矩阵 21 | * @type {THREE.Matrix4} 22 | */ 23 | this.matrixWorldInverse = new THREE.Matrix4(); 24 | /** 25 | * @desc 相机设置属性projectionMatrix,包含相机的投影矩阵 26 | * @type {THREE.Matrix4} 27 | */ 28 | this.projectionMatrix = new THREE.Matrix4(); 29 | 30 | }; 31 | /** 32 | * @desc 相机对象从THREE.Objec3D的原型继承所有属性方法 33 | * @type {THREE.Object3D} 34 | */ 35 | THREE.Camera.prototype = Object.create( THREE.Object3D.prototype ); 36 | /** 37 | * @function 38 | * @desc 获取世界坐标系内的四元数参数 39 | * @param {THREE.Quaternion} optionalTarget 40 | * @return {THREE.Quaternion} 41 | */ 42 | THREE.Camera.prototype.getWorldDirection = function () { 43 | 44 | var quaternion = new THREE.Quaternion(); 45 | 46 | return function ( optionalTarget ) { 47 | 48 | var result = optionalTarget || new THREE.Vector3(); 49 | 50 | this.getWorldQuaternion( quaternion ); 51 | 52 | return result.set( 0, 0, - 1 ).applyQuaternion( quaternion ); 53 | 54 | } 55 | 56 | }(); 57 | /** 58 | * @function 59 | * @desc 用来旋转相机对象,并将对象面对空间中的点(参数vector) 60 | * @param {THREE.Vector3} vector 61 | */ 62 | THREE.Camera.prototype.lookAt = function () { 63 | 64 | // This routine does not support cameras with rotated and/or translated parent(s) 65 | 66 | var m1 = new THREE.Matrix4(); 67 | 68 | return function ( vector ) { 69 | 70 | m1.lookAt( this.position, vector, this.up ); 71 | 72 | this.quaternion.setFromRotationMatrix( m1 ); 73 | 74 | }; 75 | 76 | }(); 77 | /** 78 | * @desc 克隆相机 79 | * @param {THREE.Camera} camera 80 | * @returns {THREE.Camera} 81 | */ 82 | THREE.Camera.prototype.clone = function ( camera ) { 83 | 84 | if ( camera === undefined ) camera = new THREE.Camera(); 85 | 86 | THREE.Object3D.prototype.clone.call( this, camera ); 87 | 88 | camera.matrixWorldInverse.copy( this.matrixWorldInverse ); 89 | camera.projectionMatrix.copy( this.projectionMatrix ); 90 | 91 | return camera; 92 | }; 93 | -------------------------------------------------------------------------------- /cameras/CubeCamera.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Camera for rendering cube maps 3 | * - renders scene into axis-aligned cube 4 | * 5 | * @author alteredq / http://alteredqualia.com/ 6 | */ 7 | /** 8 | * @classdesc 立方体投影相机 9 | * @desc 根据 near, far, cubeResolution 生成立方体投影相机 10 | * @constructor 11 | * @param {float} near 相对于深度剪切面的近的距离,必须为正数,可选参数,如果未指定,初始化为0.1 12 | * @param {float} far 相对于深度剪切面的远的距离,必须为正数,可选参数,如果未指定,初始化为2000 13 | * @param {float} cubeResolution 14 | * @extends {THREE.Camera} 15 | */ 16 | THREE.CubeCamera = function ( near, far, cubeResolution ) { //garreet 17 | 18 | THREE.Object3D.call( this ); 19 | 20 | this.type = 'CubeCamera'; 21 | 22 | var fov = 90, aspect = 1; 23 | 24 | var cameraPX = new THREE.PerspectiveCamera( fov, aspect, near, far ); 25 | cameraPX.up.set( 0, - 1, 0 ); 26 | cameraPX.lookAt( new THREE.Vector3( 1, 0, 0 ) ); 27 | this.add( cameraPX ); 28 | 29 | var cameraNX = new THREE.PerspectiveCamera( fov, aspect, near, far ); 30 | cameraNX.up.set( 0, - 1, 0 ); 31 | cameraNX.lookAt( new THREE.Vector3( - 1, 0, 0 ) ); 32 | this.add( cameraNX ); 33 | 34 | var cameraPY = new THREE.PerspectiveCamera( fov, aspect, near, far ); 35 | cameraPY.up.set( 0, 0, 1 ); 36 | cameraPY.lookAt( new THREE.Vector3( 0, 1, 0 ) ); 37 | this.add( cameraPY ); 38 | 39 | var cameraNY = new THREE.PerspectiveCamera( fov, aspect, near, far ); 40 | cameraNY.up.set( 0, 0, - 1 ); 41 | cameraNY.lookAt( new THREE.Vector3( 0, - 1, 0 ) ); 42 | this.add( cameraNY ); 43 | 44 | var cameraPZ = new THREE.PerspectiveCamera( fov, aspect, near, far ); 45 | cameraPZ.up.set( 0, - 1, 0 ); 46 | cameraPZ.lookAt( new THREE.Vector3( 0, 0, 1 ) ); 47 | this.add( cameraPZ ); 48 | 49 | var cameraNZ = new THREE.PerspectiveCamera( fov, aspect, near, far ); 50 | cameraNZ.up.set( 0, - 1, 0 ); 51 | cameraNZ.lookAt( new THREE.Vector3( 0, 0, - 1 ) ); 52 | this.add( cameraNZ ); 53 | 54 | this.renderTarget = new THREE.WebGLRenderTargetCube( cubeResolution, cubeResolution, { format: THREE.RGBFormat, magFilter: THREE.LinearFilter, minFilter: THREE.LinearFilter } ); 55 | 56 | this.updateCubeMap = function ( renderer, scene ) { 57 | 58 | var renderTarget = this.renderTarget; 59 | var generateMipmaps = renderTarget.generateMipmaps; 60 | 61 | renderTarget.generateMipmaps = false; 62 | 63 | renderTarget.activeCubeFace = 0; 64 | renderer.render( scene, cameraPX, renderTarget ); 65 | 66 | renderTarget.activeCubeFace = 1; 67 | renderer.render( scene, cameraNX, renderTarget ); 68 | 69 | renderTarget.activeCubeFace = 2; 70 | renderer.render( scene, cameraPY, renderTarget ); 71 | 72 | renderTarget.activeCubeFace = 3; 73 | renderer.render( scene, cameraNY, renderTarget ); 74 | 75 | renderTarget.activeCubeFace = 4; 76 | renderer.render( scene, cameraPZ, renderTarget ); 77 | 78 | renderTarget.generateMipmaps = generateMipmaps; 79 | 80 | renderTarget.activeCubeFace = 5; 81 | renderer.render( scene, cameraNZ, renderTarget ); 82 | 83 | }; 84 | 85 | }; 86 | 87 | THREE.CubeCamera.prototype = Object.create( THREE.Object3D.prototype ); 88 | -------------------------------------------------------------------------------- /cameras/OrthographicCamera.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | /** 5 | * @classdesc 正交投影相机 6 | * @desc 根据 left, right, top, bottom, near, far 生成正交投影相 7 | * @constructor 8 | * @param {float} left 垂直平面的左侧坐标位置 9 | * @param {float} right 垂直平面的右侧坐标位置 10 | * @param {float} top 垂直平面的顶部坐标位置 11 | * @param {float} bottom 垂直平面的底部坐标位置 12 | * @param {float} near 相对于深度剪切面的近的距离,必须为正数,可选参数,如果未指定,初始化为0.1 13 | * @param {float} far 相对于深度剪切面的远的距离,必须为正数,可选参数,如果未指定,初始化为2000 14 | * @extends {THREE.Camera} 15 | */ 16 | THREE.OrthographicCamera = function ( left, right, top, bottom, near, far ) { 17 | 18 | THREE.Camera.call( this ); 19 | /** 20 | * @default 21 | * @type {string} 22 | */ 23 | this.type = 'OrthographicCamera'; 24 | /** 25 | * @desc 缩放级别 26 | * @default 27 | * @type {float} 28 | */ 29 | this.zoom = 1; 30 | /** 31 | * @desc 垂直平面的左侧坐标位置 32 | * @type {float} 33 | */ 34 | this.left = left; 35 | /** 36 | * @desc 垂直平面的右侧坐标位置 37 | * @type {float} 38 | */ 39 | this.right = right; 40 | /** 41 | * @desc 垂直平面的顶部坐标位置 42 | * @type {float} 43 | */ 44 | this.top = top; 45 | /** 46 | * @desc 垂直平面的底部坐标位置 47 | * @type {float} 48 | */ 49 | this.bottom = bottom; 50 | /** 51 | * @desc 指明相对于深度剪切面的近的距离,必须为正数,可选参数,如果未指定,初始化为0.1 52 | * @default 0.1 53 | * @type {float} 54 | */ 55 | this.near = ( near !== undefined ) ? near : 0.1; 56 | /** 57 | * @desc 指明相对于深度剪切面的近的距离,必须为正数,可选参数,如果未指定,初始化为0.1 58 | * @default 2000 59 | * @type {float} 60 | */ 61 | this.far = ( far !== undefined ) ? far : 2000; 62 | 63 | this.updateProjectionMatrix(); 64 | 65 | }; 66 | /** 67 | * @desc 正交相机对象从THREE.Camera的原型继承所有属性方法 68 | * @type {THREE.Camera} 69 | */ 70 | THREE.OrthographicCamera.prototype = Object.create( THREE.Camera.prototype ); 71 | 72 | /** 73 | * @desc 返回正交投影相机的可视边界的矩阵 74 | */ 75 | THREE.OrthographicCamera.prototype.updateProjectionMatrix = function () { 76 | 77 | var dx = ( this.right - this.left ) / ( 2 * this.zoom ); 78 | var dy = ( this.top - this.bottom ) / ( 2 * this.zoom ); 79 | var cx = ( this.right + this.left ) / 2; 80 | var cy = ( this.top + this.bottom ) / 2; 81 | 82 | this.projectionMatrix.makeOrthographic( cx - dx, cx + dx, cy + dy, cy - dy, this.near, this.far ); 83 | 84 | }; 85 | 86 | /** 87 | * @desc 克隆正交相机对象 88 | * @returns {THREE.OrthographicCamera} 89 | */ 90 | THREE.OrthographicCamera.prototype.clone = function () { 91 | 92 | var camera = new THREE.OrthographicCamera(); 93 | 94 | THREE.Camera.prototype.clone.call( this, camera ); 95 | 96 | camera.zoom = this.zoom; 97 | 98 | camera.left = this.left; 99 | camera.right = this.right; 100 | camera.top = this.top; 101 | camera.bottom = this.bottom; 102 | 103 | camera.near = this.near; 104 | camera.far = this.far; 105 | 106 | camera.projectionMatrix.copy( this.projectionMatrix ); 107 | 108 | return camera; 109 | }; 110 | -------------------------------------------------------------------------------- /cameras/PerspectiveCamera.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author greggman / http://games.greggman.com/ 4 | * @author zz85 / http://www.lab4games.net/zz85/blog 5 | */ 6 | /** 7 | * @classdesc 透视投影相机 8 | * @desc 根据 fov, aspect, near, far 生成透视投影相机 9 | * @constructor 10 | * @param {float} fov 相机的可视角度,可选参数,如果未指定,初始化为50 11 | * @param {float} aspect 相机可视范围的长宽比,可选参数,如果未指定,初始化为1 12 | * @param {float} near 相对于深度剪切面的近的距离,必须为正数,可选参数,如果未指定,初始化为0.1 13 | * @param {float} far 相对于深度剪切面的远的距离,必须为正数,可选参数,如果未指定,初始化为2000 14 | * @extends {THREE.Camera} 15 | */ 16 | THREE.PerspectiveCamera = function ( fov, aspect, near, far ) { 17 | 18 | THREE.Camera.call( this ); 19 | /** 20 | * @default 21 | * @type {string} 22 | */ 23 | this.type = 'PerspectiveCamera'; 24 | 25 | /** 26 | * @desc 缩放比例 27 | * @default 28 | * @type {float} 29 | */ 30 | this.zoom = 1; 31 | /** 32 | * @desc 相机的可视角度,可选参数 33 | * @default 50 34 | * @type {float} 35 | */ 36 | this.fov = fov !== undefined ? fov : 50; 37 | /** 38 | * @desc 相机可视范围的长宽比 39 | * @default 1 40 | * @type {float} 41 | */ 42 | this.aspect = aspect !== undefined ? aspect : 1; 43 | /** 44 | * @desc 相对于深度剪切面的近的距离 45 | * @default 0.1 46 | * @type {float} 47 | */ 48 | this.near = near !== undefined ? near : 0.1; 49 | /** 50 | * @desc 相对于深度剪切面的远的距离 51 | * @default 2000 52 | * @type {float} 53 | */ 54 | this.far = far !== undefined ? far : 2000; 55 | 56 | this.updateProjectionMatrix(); 57 | 58 | }; 59 | /** 60 | * @desc 透视相机对象从THREE.Camera的原型继承所有属性方法 61 | * @type {THREE.Camera} 62 | */ 63 | THREE.PerspectiveCamera.prototype = Object.create( THREE.Camera.prototype ); 64 | 65 | 66 | /** 67 | * Uses Focal Length (in mm) to estimate and set FOV 68 | * 35mm (fullframe) camera is used if frame size is not specified; 69 | * Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html 70 | * 使用焦距(单位毫米)设置相机时,如果画幅大小没有指定,默认使用FOV(视野)35mm(全画幅)相机 71 | */ 72 | /** 73 | * @desc 焦距 focalLength, 画幅大小 frameHeight 更新透视投影相机的视野 74 | * @param {float} focalLength 焦距 75 | * @param {float} frameHeight 画幅大小 76 | */ 77 | THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, frameHeight ) { 78 | 79 | if ( frameHeight === undefined ) frameHeight = 24; 80 | 81 | this.fov = 2 * THREE.Math.radToDeg( Math.atan( frameHeight / ( focalLength * 2 ) ) ); 82 | this.updateProjectionMatrix(); 83 | 84 | }; 85 | 86 | 87 | /** 88 | * Sets an offset in a larger frustum. This is useful for multi-window or 89 | * multi-monitor/multi-machine setups. 90 | * 为一个大的平截头体设置视口偏移,这个方法在多显示器,多台机器,显示器矩阵上应用非常有效 91 | * For example, if you have 3x2 monitors and each monitor is 1920x1080 and 92 | * the monitors are in grid like this 93 | * 比如,你有3x2 个显示器,每个显示器的分辨率是1920x1080,组成的显示器矩阵向下面的网格 94 | * +---+---+---+ 95 | * | A | B | C | 96 | * +---+---+---+ 97 | * | D | E | F | 98 | * +---+---+---+ 99 | * 100 | * then for each monitor you would call it like this 101 | * 然后,你可以向下面这样为每台显示器调用setOffset()方法,让每个显示器显示画布的一部分 102 | * var w = 1920; 103 | * var h = 1080; 104 | * var fullWidth = w * 3; 105 | * var fullHeight = h * 2; 106 | * 107 | * --A-- 108 | * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); 109 | * --B-- 110 | * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); 111 | * --C-- 112 | * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); 113 | * --D-- 114 | * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); 115 | * --E-- 116 | * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); 117 | * --F-- 118 | * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); 119 | * 120 | * Note there is no reason monitors have to be the same size or in a grid. 121 | * 注意,有可能,这些显示器不是同样的尺寸.所以你可以根据需要设置你想要的各种方式 122 | */ 123 | /** 124 | * 一个大的平截头体设置视口偏移,这个方法在多显示器,多台机器,显示器矩阵上应用非常有效 125 | * @param {number} fullWidth 一个超大的摄像机场景的总宽度 126 | * @param {number} fullHeight 一个超大的摄像机场景的总高度 127 | * @param {number} x 当前摄像机左上角点的x坐标在网格内的起始点 128 | * @param {number} y 当前摄像机左上角点的y坐标在网格内的起始点 129 | * @param {number} width 当前摄像机的宽度 130 | * @param {number} height 当前摄像机的高度 131 | */ 132 | THREE.PerspectiveCamera.prototype.setViewOffset = function ( fullWidth, fullHeight, x, y, width, height ) { 133 | /** 134 | * @memberof THREE.PerspectiveCamera 135 | * @type {number} 136 | */ 137 | this.fullWidth = fullWidth; 138 | /** 139 | * @memberof THREE.PerspectiveCamera 140 | * @type {number} 141 | */ 142 | this.fullHeight = fullHeight; 143 | /** 144 | * @memberof THREE.PerspectiveCamera 145 | * @type {number} 146 | */ 147 | this.x = x; 148 | /** 149 | * @memberof THREE.PerspectiveCamera 150 | * @type {number} 151 | */ 152 | this.y = y; 153 | /** 154 | * @memberof THREE.PerspectiveCamera 155 | * @type {number} 156 | */ 157 | this.width = width; 158 | /** 159 | * @memberof THREE.PerspectiveCamera 160 | * @type {number} 161 | */ 162 | this.height = height; 163 | 164 | this.updateProjectionMatrix(); 165 | 166 | }; 167 | 168 | /** 169 | * @desc 返回透视投影相机的可视边界的矩阵.当相机的参数被更改后,必须调用此参数 170 | */ 171 | THREE.PerspectiveCamera.prototype.updateProjectionMatrix = function () { 172 | 173 | var fov = THREE.Math.radToDeg( 2 * Math.atan( Math.tan( THREE.Math.degToRad( this.fov ) * 0.5 ) / this.zoom ) ); 174 | 175 | if ( this.fullWidth ) { 176 | 177 | var aspect = this.fullWidth / this.fullHeight; 178 | var top = Math.tan( THREE.Math.degToRad( fov * 0.5 ) ) * this.near; 179 | var bottom = - top; 180 | var left = aspect * bottom; 181 | var right = aspect * top; 182 | var width = Math.abs( right - left ); 183 | var height = Math.abs( top - bottom ); 184 | 185 | this.projectionMatrix.makeFrustum( 186 | left + this.x * width / this.fullWidth, 187 | left + ( this.x + this.width ) * width / this.fullWidth, 188 | top - ( this.y + this.height ) * height / this.fullHeight, 189 | top - this.y * height / this.fullHeight, 190 | this.near, 191 | this.far 192 | ); 193 | 194 | } else { 195 | 196 | this.projectionMatrix.makePerspective( fov, this.aspect, this.near, this.far ); 197 | 198 | } 199 | 200 | }; 201 | /** 202 | * @desc 克隆透视投影矩阵 203 | * @returns {THREE.PerspectiveCamera} 204 | */ 205 | THREE.PerspectiveCamera.prototype.clone = function () { 206 | 207 | var camera = new THREE.PerspectiveCamera(); 208 | 209 | THREE.Camera.prototype.clone.call( this, camera ); 210 | 211 | camera.zoom = this.zoom; 212 | 213 | camera.fov = this.fov; 214 | camera.aspect = this.aspect; 215 | camera.near = this.near; 216 | camera.far = this.far; 217 | 218 | camera.projectionMatrix.copy( this.projectionMatrix ); 219 | 220 | return camera; 221 | 222 | }; 223 | -------------------------------------------------------------------------------- /core/BufferAttribute.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | 5 | /** 6 | * @classdesc 属性对象类 7 | * @desc 存储于bufferGeometry相关联的属性数据 8 | * @param {array} array 属性数组 9 | * @param {number} itemSize 数组元素尺寸 10 | * @constructor 11 | */ 12 | THREE.BufferAttribute = function ( array, itemSize ) { 13 | /** 14 | * @desc 属性数组 15 | * @type {array} 16 | */ 17 | this.array = array; 18 | /** 19 | * @desc 数组元素尺寸 20 | * @type {number} 21 | */ 22 | this.itemSize = itemSize; 23 | /** 24 | * @desc 是否需要更新标识 25 | * @type {boolean} 26 | */ 27 | this.needsUpdate = false; 28 | 29 | }; 30 | 31 | THREE.BufferAttribute.prototype = { 32 | 33 | constructor: THREE.BufferAttribute, 34 | /** 35 | * @desc 获得数组长度 36 | * @returns {number} 37 | */ 38 | get length () { 39 | 40 | return this.array.length; 41 | 42 | }, 43 | /** 44 | * @desc 拷贝数组 45 | * @param {number} index1 目标数组起始索引 46 | * @param {THREE.BufferAttribute} attribute 源数组 47 | * @param {number} index2 源数组起始索引 48 | */ 49 | copyAt: function ( index1, attribute, index2 ) { 50 | 51 | index1 *= this.itemSize; 52 | index2 *= attribute.itemSize; 53 | 54 | for ( var i = 0, l = this.itemSize; i < l; i ++ ) { 55 | 56 | this.array[ index1 + i ] = attribute.array[ index2 + i ]; 57 | 58 | } 59 | 60 | }, 61 | /** 62 | * @desc 重新设置BufferAttribute的属性数组 63 | * @param {THREE.BufferAttribute.array} value 属性数组 64 | * @returns {THREE.BufferAttribute} 65 | */ 66 | set: function ( value ) { 67 | 68 | this.array.set( value ); 69 | 70 | return this; 71 | 72 | }, 73 | /** 74 | * @desc 重新设置含有3个属性相的BufferAttribute属性数组的第一个分量
75 | * setX方法中,属性数组的长度是属性相的长度乘以属性的个数
76 | * 比如要存放100个点的坐标,坐标有3个属性相,那么属性数组的长度是300,如果想改变第30个点的x坐标就将index设为30 77 | * @param {number} index 属性数组的索引 78 | * @param {number} x 属性数组的第一个分量的值 79 | * @returns {THREE.BufferAttribute} 80 | */ 81 | setX: function ( index, x ) { 82 | 83 | this.array[ index * this.itemSize ] = x; 84 | 85 | return this; 86 | 87 | }, 88 | /** 89 | * @desc 重新设置含有3个属性相的BufferAttribute属性数组的第二个分量
90 | * @param {number} index 属性数组的索引 91 | * @param {number} y 属性数组的第二个分量的值 92 | * @returns {THREE.BufferAttribute} 93 | */ 94 | setY: function ( index, y ) { 95 | 96 | this.array[ index * this.itemSize + 1 ] = y; 97 | 98 | return this; 99 | 100 | }, 101 | /** 102 | * @desc 重新设置含有3个属性相的BufferAttribute属性数组的第三个分量
103 | * @param {number} index 属性数组的索引 104 | * @param {number} z 属性数组的第三个分量的值 105 | * @returns {THREE.BufferAttribute} 106 | */ 107 | setZ: function ( index, z ) { 108 | 109 | this.array[ index * this.itemSize + 2 ] = z; 110 | 111 | return this; 112 | 113 | }, 114 | /** 115 | * @desc 重新设置含有3个属性相的BufferAttribute属性数组的第1,2个分量
116 | * @param {number} index 属性数组的索引 117 | * @param {number} x 属性数组的第1个分量的值 118 | * @param {number} y 属性数组的第2个分量的值 119 | * @returns {THREE.BufferAttribute} 120 | */ 121 | setXY: function ( index, x, y ) { 122 | 123 | index *= this.itemSize; 124 | 125 | this.array[ index ] = x; 126 | this.array[ index + 1 ] = y; 127 | 128 | return this; 129 | 130 | }, 131 | /** 132 | * @desc 重新设置含有3个属性相的BufferAttribute属性数组的第1,2,3个分量
133 | * @param {number} index 属性数组的索引 134 | * @param {number} x 属性数组的第1个分量的值 135 | * @param {number} y 属性数组的第2个分量的值 136 | * @param {number} z 属性数组的第3个分量的值 137 | * @returns {THREE.BufferAttribute} 138 | */ 139 | setXYZ: function ( index, x, y, z ) { 140 | 141 | index *= this.itemSize; 142 | 143 | this.array[ index ] = x; 144 | this.array[ index + 1 ] = y; 145 | this.array[ index + 2 ] = z; 146 | 147 | return this; 148 | 149 | }, 150 | /** 151 | * @desc 重新设置含有4个属性相的BufferAttribute属性数组的第1,2,3,4个分量
152 | * @param {number} index 属性数组的索引 153 | * @param {number} x 属性数组的第1个分量的值 154 | * @param {number} y 属性数组的第2个分量的值 155 | * @param {number} z 属性数组的第3个分量的值 156 | * @param {number} w 属性数组的第4个分量的值 157 | * @returns {THREE.BufferAttribute} 158 | */ 159 | setXYZW: function ( index, x, y, z, w ) { 160 | 161 | index *= this.itemSize; 162 | 163 | this.array[ index ] = x; 164 | this.array[ index + 1 ] = y; 165 | this.array[ index + 2 ] = z; 166 | this.array[ index + 3 ] = w; 167 | 168 | return this; 169 | 170 | }, 171 | /** 172 | * @desc 克隆属性对象 173 | * @returns {THREE.BufferAttribute} 174 | */ 175 | clone: function () { 176 | 177 | return new THREE.BufferAttribute( new this.array.constructor( this.array ), this.itemSize ); 178 | 179 | } 180 | 181 | }; 182 | 183 | // 184 | /********************************************************************************** 185 | ****下面这些方法是定义不同数据类型的属性,已经在新版本中删除,这里保留是为了向后兼容. 186 | ***********************************************************************************/ 187 | THREE.Int8Attribute = function ( data, itemSize ) { 188 | 189 | console.warn( 'THREE.Int8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); 190 | return new THREE.BufferAttribute( data, itemSize ); 191 | 192 | }; 193 | 194 | THREE.Uint8Attribute = function ( data, itemSize ) { 195 | 196 | console.warn( 'THREE.Uint8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); 197 | return new THREE.BufferAttribute( data, itemSize ); 198 | 199 | }; 200 | 201 | THREE.Uint8ClampedAttribute = function ( data, itemSize ) { 202 | 203 | console.warn( 'THREE.Uint8ClampedAttribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); 204 | return new THREE.BufferAttribute( data, itemSize ); 205 | 206 | 207 | }; 208 | 209 | THREE.Int16Attribute = function ( data, itemSize ) { 210 | 211 | console.warn( 'THREE.Int16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); 212 | return new THREE.BufferAttribute( data, itemSize ); 213 | 214 | }; 215 | 216 | THREE.Uint16Attribute = function ( data, itemSize ) { 217 | 218 | console.warn( 'THREE.Uint16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); 219 | return new THREE.BufferAttribute( data, itemSize ); 220 | 221 | }; 222 | 223 | THREE.Int32Attribute = function ( data, itemSize ) { 224 | 225 | console.warn( 'THREE.Int32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); 226 | return new THREE.BufferAttribute( data, itemSize ); 227 | 228 | }; 229 | 230 | THREE.Uint32Attribute = function ( data, itemSize ) { 231 | 232 | console.warn( 'THREE.Uint32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); 233 | return new THREE.BufferAttribute( data, itemSize ); 234 | 235 | }; 236 | 237 | THREE.Float32Attribute = function ( data, itemSize ) { 238 | 239 | console.warn( 'THREE.Float32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); 240 | return new THREE.BufferAttribute( data, itemSize ); 241 | 242 | }; 243 | 244 | THREE.Float64Attribute = function ( data, itemSize ) { 245 | 246 | console.warn( 'THREE.Float64Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); 247 | return new THREE.BufferAttribute( data, itemSize ); 248 | 249 | }; 250 | -------------------------------------------------------------------------------- /core/Clock.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | /** 6 | * @classdesc 时钟类 7 | * @desc 用来记录时间等功能 8 | * @param {boolean} autoStart 是否自动启动,默认为启动 9 | * @constructor 10 | */ 11 | THREE.Clock = function ( autoStart ) { 12 | 13 | /** 14 | * @desc 是否自动启动 15 | * @default true 16 | * @type {boolean} 17 | */ 18 | this.autoStart = ( autoStart !== undefined ) ? autoStart : true; 19 | /** 20 | * @desc 启动时间 21 | * @default 0 22 | * @type {number} 23 | */ 24 | this.startTime = 0; 25 | /** 26 | * @desc 上一次时间 27 | * @default 0 28 | * @type {number} 29 | */ 30 | this.oldTime = 0; 31 | /** 32 | * @desc 运行时间 33 | * @default 0 34 | * @type {number} 35 | */ 36 | this.elapsedTime = 0; 37 | /** 38 | * @desc 是否正在运行 39 | * @default false 40 | * @type {boolean} 41 | */ 42 | this.running = false; 43 | 44 | }; 45 | 46 | THREE.Clock.prototype = { 47 | 48 | constructor: THREE.Clock, 49 | /** 50 | * @desc 开始记录时间,获得开始的时间截 51 | */ 52 | start: function () { 53 | 54 | this.startTime = self.performance !== undefined && self.performance.now !== undefined 55 | ? self.performance.now() 56 | : Date.now(); 57 | 58 | this.oldTime = this.startTime; 59 | this.running = true; 60 | }, 61 | /** 62 | * @desc 停止记录时间,获得结束的时间截 63 | */ 64 | stop: function () { 65 | 66 | this.getElapsedTime(); 67 | this.running = false; 68 | 69 | }, 70 | /** 71 | * @desc 返回从oldTimed到stop之间的时间长度,以秒为单位 72 | * @returns {number} 秒为单位 73 | */ 74 | getElapsedTime: function () { 75 | 76 | this.getDelta(); 77 | return this.elapsedTime; 78 | 79 | }, 80 | /** 81 | * @desc 获oldTimed到现在的时间差值,以秒为单位 82 | * @returns {number} 秒为单位 83 | */ 84 | getDelta: function () { 85 | 86 | var diff = 0; 87 | 88 | if ( this.autoStart && ! this.running ) { 89 | 90 | this.start(); 91 | 92 | } 93 | 94 | if ( this.running ) { 95 | 96 | var newTime = self.performance !== undefined && self.performance.now !== undefined 97 | ? self.performance.now() 98 | : Date.now(); 99 | 100 | diff = 0.001 * ( newTime - this.oldTime ); 101 | this.oldTime = newTime; 102 | 103 | this.elapsedTime += diff; 104 | 105 | } 106 | 107 | return diff; 108 | 109 | } 110 | 111 | }; 112 | -------------------------------------------------------------------------------- /core/EventDispatcher.js: -------------------------------------------------------------------------------- 1 | /** 2 | * https://github.com/mrdoob/eventdispatcher.js/ 3 | */ 4 | /** 5 | * @classdesc 事件调度类 6 | * @desc 用来管理侦听函数,被嵌入Object3D对象之上.当Object3D发生事件时,这个方法就会自动被触发.
7 | * 可以通过调用调度该事件的对象的 addEventListener() 方法来注册函数以处理运行时事件 8 | * @constructor 9 | */ 10 | THREE.EventDispatcher = function () {} 11 | 12 | THREE.EventDispatcher.prototype = { 13 | 14 | constructor: THREE.EventDispatcher, 15 | /** 16 | * @desc 将当前基类绑定到参数Object对象之上,将基类的方法添加到object对象内 17 | * @param {THREE.Object3D} object 18 | */ 19 | apply: function ( object ) { 20 | 21 | object.addEventListener = THREE.EventDispatcher.prototype.addEventListener; 22 | object.hasEventListener = THREE.EventDispatcher.prototype.hasEventListener; 23 | object.removeEventListener = THREE.EventDispatcher.prototype.removeEventListener; 24 | object.dispatchEvent = THREE.EventDispatcher.prototype.dispatchEvent; 25 | 26 | }, 27 | /** 28 | * @desc 使用 EventDispatcher 对象注册事件侦听器对象,以使侦听器能够接收事件通知 29 | * @param {String} type 事件类型 30 | * @param {requestCallback} listener 监听回调函数 31 | */ 32 | addEventListener: function ( type, listener ) { 33 | 34 | if ( this._listeners === undefined ) this._listeners = {}; 35 | 36 | var listeners = this._listeners; 37 | 38 | if ( listeners[ type ] === undefined ) { 39 | 40 | listeners[ type ] = []; 41 | 42 | } 43 | 44 | if ( listeners[ type ].indexOf( listener ) === - 1 ) { 45 | 46 | listeners[ type ].push( listener ); 47 | 48 | } 49 | 50 | }, 51 | /** 52 | * @desc 检查 EventDispatcher 对象是否为特定事件类型注册了任何侦听器 53 | * @param {String} type 事件类型 54 | * @param {requestCallback} listener 55 | * @returns {boolean} 监听回调函数 56 | */ 57 | hasEventListener: function ( type, listener ) { 58 | 59 | if ( this._listeners === undefined ) return false; 60 | 61 | var listeners = this._listeners; 62 | 63 | if ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) { 64 | 65 | return true; 66 | 67 | } 68 | 69 | return false; 70 | 71 | }, 72 | 73 | /** 74 | * @desc 从 EventDispatcher 对象中删除为特定事件类型注册了任何侦听器 75 | * @param {String} type 事件类型 76 | * @param {requestCallback} listener 77 | */ 78 | removeEventListener: function ( type, listener ) { 79 | 80 | if ( this._listeners === undefined ) return; 81 | 82 | var listeners = this._listeners; 83 | var listenerArray = listeners[ type ]; 84 | 85 | if ( listenerArray !== undefined ) { 86 | 87 | var index = listenerArray.indexOf( listener ); 88 | 89 | if ( index !== - 1 ) { 90 | 91 | listenerArray.splice( index, 1 ); 92 | 93 | } 94 | 95 | } 96 | 97 | }, 98 | /** 99 | * @desc 将事件调度到事件流中
100 | * 事件目标是对其调用 dispatchEvent() 方法的 EventDispatcher 对象
101 | * 如果正在重新调度事件,则会自动创建此事件的一个克隆
102 | * 在调度了事件后,其 target 属性将无法更改,因此您必须创建此事件的一个新副本以能够重新调度 103 | * @param event 事件 104 | */ 105 | dispatchEvent: function ( event ) { 106 | 107 | if ( this._listeners === undefined ) return; 108 | 109 | var listeners = this._listeners; 110 | var listenerArray = listeners[ event.type ]; 111 | 112 | if ( listenerArray !== undefined ) { 113 | 114 | event.target = this; 115 | 116 | var array = []; 117 | var length = listenerArray.length; 118 | 119 | for ( var i = 0; i < length; i ++ ) { 120 | 121 | array[ i ] = listenerArray[ i ]; 122 | 123 | } 124 | 125 | for ( var i = 0; i < length; i ++ ) { 126 | 127 | array[ i ].call( this, event ); 128 | 129 | } 130 | 131 | } 132 | 133 | } 134 | 135 | }; 136 | -------------------------------------------------------------------------------- /core/Face3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | */ 5 | /** 6 | * @classdesc 三角面对象类(三维空间内) 7 | * @param {THREE.Vector3} a 三角面角点a的索引 8 | * @param {THREE.Vector3} b 三角面角点b的索引 9 | * @param {THREE.Vector3} c 三角面角点c的索引 10 | * @param {THREE.Vector3[]} normal 三角面法线向量,或顶点法线向量数组 11 | * @param {THREE.Color[]} color 三角面颜色值,或顶点颜色值数组 12 | * @param {number[]} materialIndex 材质索引数组 13 | * @example 用法: 创建一个颜色为0xffaa00,0x00aaff,0x00ffaa的a,b,c三点组成的,法线指向normal,材质索引为0的三角面对象
14 | * var a=0,b=1,c=2;
15 | * var normal1 = new THREE.Vector3( 0, 1, 0 ), normal2 = new THREE.Vector3( 0, 1, 0 ), normal3 = new THREE.Vector3( 0, 1, 0 );
16 | * normal = new Array(normal1,normal2,normal3);
17 | * var color1 = new THREE.Color( 0xffaa00 ), color2 = new THREE.Color( 0x00aaff ), color3 = new THREE.Color( 0x00ffaa );
18 | * var color = new Array(color1,color2,color3);
19 | * var face = new THREE.Face3( a, b, c, normal, color, 0 );
20 | * 创建一个颜色为0xffaa00,0x00aaff,0x00ffaa的a,b,c三点组成的,法线指向normal,材质索引为0的三角面对象 21 | * @constructor 22 | */ 23 | THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) { 24 | 25 | /** 26 | * @desc 顶点a 27 | * @type {THREE.Vector3} 28 | */ 29 | this.a = a; 30 | /** 31 | * @desc 顶点b 32 | * @type {THREE.Vector3} 33 | */ 34 | this.b = b; 35 | /** 36 | * @desc 顶点c 37 | * @type {THREE.Vector3} 38 | */ 39 | this.c = c; 40 | 41 | /** 42 | * @desc 面法线 43 | * @type {THREE.Vector3} 44 | */ 45 | this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3(); 46 | /** 47 | * @desc 顶点法线 48 | * @type {THREE.Vector3[]} 49 | */ 50 | this.vertexNormals = normal instanceof Array ? normal : []; 51 | 52 | /** 53 | * @desc 面颜色 54 | * @type {THREE.Color} 55 | */ 56 | this.color = color instanceof THREE.Color ? color : new THREE.Color(); 57 | /** 58 | * @desc 顶点颜色 59 | * @type {THREE.Color[]} 60 | */ 61 | this.vertexColors = color instanceof Array ? color : []; 62 | 63 | /** 64 | * @desc 顶点正切数组 65 | * @type {Array} 66 | */ 67 | this.vertexTangents = []; 68 | 69 | /** 70 | * @desc 三角面的材质索引 71 | * @type {number} 72 | */ 73 | this.materialIndex = materialIndex !== undefined ? materialIndex : 0; 74 | 75 | }; 76 | 77 | THREE.Face3.prototype = { 78 | 79 | constructor: THREE.Face3, 80 | /** 81 | * @desc 克隆三角面对象 82 | * @returns {THREE.Face3} 83 | */ 84 | clone: function () { 85 | 86 | var face = new THREE.Face3( this.a, this.b, this.c ); 87 | 88 | face.normal.copy( this.normal ); 89 | face.color.copy( this.color ); 90 | 91 | face.materialIndex = this.materialIndex; 92 | 93 | for ( var i = 0, il = this.vertexNormals.length; i < il; i ++ ) { 94 | 95 | face.vertexNormals[ i ] = this.vertexNormals[ i ].clone(); 96 | 97 | } 98 | 99 | for ( var i = 0, il = this.vertexColors.length; i < il; i ++ ) { 100 | 101 | face.vertexColors[ i ] = this.vertexColors[ i ].clone(); 102 | 103 | } 104 | 105 | for ( var i = 0, il = this.vertexTangents.length; i < il; i ++ ) { 106 | 107 | face.vertexTangents[ i ] = this.vertexTangents[ i ].clone(); 108 | 109 | } 110 | 111 | return face; 112 | 113 | } 114 | 115 | }; 116 | -------------------------------------------------------------------------------- /core/Face4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | /** 5 | * @classdesc 四角面对象类(四维空间内) 6 | * @ignore 7 | */ 8 | THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) { 9 | 10 | console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ) 11 | return new THREE.Face3( a, b, c, normal, color, materialIndex ); 12 | 13 | }; 14 | -------------------------------------------------------------------------------- /core/Projector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | /** 5 | * @ignore 6 | * @constructor 7 | */ 8 | THREE.Projector = function () { 9 | 10 | console.warn( 'THREE.Projector has been moved to /examples/renderers/Projector.js.' ); 11 | 12 | this.projectVector = function ( vector, camera ) { 13 | 14 | console.warn( 'THREE.Projector: .projectVector() is now vector.project().' ); 15 | vector.project( camera ); 16 | 17 | }; 18 | 19 | this.unprojectVector = function ( vector, camera ) { 20 | 21 | console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); 22 | vector.unproject( camera ); 23 | 24 | }; 25 | 26 | this.pickingRay = function ( vector, camera ) { 27 | 28 | console.error( 'THREE.Projector: .pickingRay() has been removed.' ); 29 | 30 | }; 31 | 32 | }; 33 | -------------------------------------------------------------------------------- /core/Raycaster.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author bhouston / http://exocortex.com/ 4 | * @author stephomi / http://stephaneginier.com/ 5 | */ 6 | 7 | ( function ( THREE ) { 8 | /** 9 | * @classdesc 射线拾取对象 10 | * @param {THREE.Vector3} origin 射线起点 11 | * @param {THREE.Vector3} direction 射线方向 12 | * @param {float} near 最近距离 13 | * @param {float} far 最远距离 14 | * @constructor 15 | */ 16 | THREE.Raycaster = function ( origin, direction, near, far ) { 17 | /** 18 | * @desc 射线 19 | * @type {THREE.Ray} 20 | */ 21 | this.ray = new THREE.Ray( origin, direction ); 22 | // direction is assumed to be normalized (for accurate distance calculations) 23 | /** 24 | * @desc 最近距离 25 | * @default 0 26 | * @type {float} 27 | */ 28 | this.near = near || 0; 29 | /** 30 | * @desc 最远距离 31 | * @default Infinity 32 | * @type {float} 33 | */ 34 | this.far = far || Infinity; 35 | /** 36 | * @desc 拾取结果 37 | * @type {*} 38 | */ 39 | this.params = { 40 | Sprite: {}, 41 | Mesh: {}, 42 | PointCloud: { threshold: 1 }, 43 | LOD: {}, 44 | Line: {} 45 | }; 46 | 47 | }; 48 | /** 49 | * @desc 距离降序排序方法 50 | * @param {THREE.Object3D} a 51 | * @param {THREE.Object3D} b 52 | * @returns {float} 53 | */ 54 | var descSort = function ( a, b ) { 55 | 56 | return a.distance - b.distance; 57 | 58 | }; 59 | /** 60 | * @desc 插入对象 61 | * @param {THREE.Object3D} object 62 | * @param {THREE.Raycaster} raycaster 63 | * @param {*} intersects 拾取结果对象数组,结果添加至数组 64 | * @param {boolean} recursive 是否递归判断子对象 65 | */ 66 | var intersectObject = function ( object, raycaster, intersects, recursive ) { 67 | 68 | object.raycast( raycaster, intersects ); 69 | 70 | if ( recursive === true ) { 71 | 72 | var children = object.children; 73 | 74 | for ( var i = 0, l = children.length; i < l; i ++ ) { 75 | 76 | intersectObject( children[ i ], raycaster, intersects, true ); 77 | 78 | } 79 | 80 | } 81 | 82 | }; 83 | 84 | // 85 | 86 | THREE.Raycaster.prototype = { 87 | 88 | constructor: THREE.Raycaster, 89 | /** 90 | * @desc 拾取精度 91 | * @default 92 | * @type {float} 93 | */ 94 | precision: 0.0001, 95 | /** 96 | * @desc 线的精度 97 | * @default 98 | * @type {float} 99 | */ 100 | linePrecision: 1, 101 | /** 102 | * @desc 设置拾取对象 103 | * @param {THREE.Ray} origin 射线起点 104 | * @param {THREE.Vector3} direction 射线方向 105 | */ 106 | set: function ( origin, direction ) { 107 | 108 | this.ray.set( origin, direction ); 109 | // direction is assumed to be normalized (for accurate distance calculations) 110 | 111 | }, 112 | /** 113 | * @desc 拾取相交判断 114 | * @param {THREE.Object3D} object 需要判断对象 115 | * @param {boolean} recursive 是否递归 116 | * @returns {*} 被拾取对象数组 117 | */ 118 | intersectObject: function ( object, recursive ) { 119 | 120 | var intersects = []; 121 | 122 | intersectObject( object, this, intersects, recursive ); 123 | 124 | intersects.sort( descSort ); 125 | 126 | return intersects; 127 | 128 | }, 129 | /** 130 | * @desc 拾取相交判断 131 | * @param {THREE.Object3D} objects 需要判断对象数组 132 | * @param {boolean} recursive 是否递归 133 | * @returns {*} 被拾取对象数组 134 | */ 135 | intersectObjects: function ( objects, recursive ) { 136 | 137 | var intersects = []; 138 | 139 | if ( objects instanceof Array === false ) { 140 | 141 | console.log( 'THREE.Raycaster.intersectObjects: objects is not an Array.' ); 142 | return intersects; 143 | 144 | } 145 | 146 | for ( var i = 0, l = objects.length; i < l; i ++ ) { 147 | 148 | intersectObject( objects[ i ], this, intersects, recursive ); 149 | 150 | } 151 | 152 | intersects.sort( descSort ); 153 | 154 | return intersects; 155 | 156 | } 157 | 158 | }; 159 | 160 | }( THREE ) ); 161 | -------------------------------------------------------------------------------- /lights/AmbientLight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | /** 5 | * @classdesc 环境光对象 6 | * @param {THREE.Color} color 环境光的颜色 7 | * @extends {THREE.Light} 8 | * @constructor 9 | */ 10 | THREE.AmbientLight = function ( color ) { 11 | 12 | THREE.Light.call( this, color ); 13 | /** 14 | * @default 15 | * @type {string} 16 | */ 17 | this.type = 'AmbientLight'; 18 | 19 | }; 20 | /** 21 | * @desc AmbientLight对象从THREE.Light的原型继承所有属性方法 22 | * @type {THREE.Light} 23 | */ 24 | THREE.AmbientLight.prototype = Object.create( THREE.Light.prototype ); 25 | /** 26 | * @desc AmbientLight克隆函数 27 | * @returns {THREE.AmbientLight} 28 | */ 29 | THREE.AmbientLight.prototype.clone = function () { 30 | 31 | var light = new THREE.AmbientLight(); 32 | 33 | THREE.Light.prototype.clone.call( this, light ); 34 | 35 | return light; 36 | 37 | }; 38 | -------------------------------------------------------------------------------- /lights/AreaLight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author MPanknin / http://www.redplant.de/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | */ 5 | /** 6 | * @classdesc 面光,区域光对象 7 | * @desc 区域光和其他光源不同,是一种二维面积光源,他的亮度不仅和强度有关,而且还和他的面积大小有关.
8 | * 通过变换灯光的width,height,normal属性,区域光可以模拟窗户射入光线 9 | * @param {THREE.Color} color 环境光的颜色 10 | * @param {float} intensity 灯光的强度,默认是1 11 | * @extends {THREE.Light} 12 | * @example var light = new THREE.AreaLight(0xff0000,1); //创建平面灯光对象
13 | * light.position.set(50,50,30); //设置位置
14 | * light.rotation.set(-0.3,0.3,0.002); //设置角度
15 | * light.width = 10; //设置宽度
16 | * light.height = 1; //设置高度
17 | * scene.add(lignt); //加入场景 18 | * @constructor 19 | */ 20 | THREE.AreaLight = function ( color, intensity ) { 21 | 22 | THREE.Light.call( this, color ); 23 | /** 24 | * @default 25 | * @type {string} 26 | */ 27 | this.type = 'AreaLight'; 28 | 29 | /** 30 | * @desc 面法线
31 | * 可以设置或者获得面光的单位向量,确认灯光照射面正确.这是在局部空间计算. 32 | * @default ( 0, - 1, 0 ) 33 | * @type {THREE.Vector3} 34 | */ 35 | this.normal = new THREE.Vector3( 0, - 1, 0 ); 36 | /** 37 | * @desc 灯光的方向 38 | * @default ( 1, 0, 0 ) 39 | * @type {THREE.Vector3} 40 | */ 41 | this.right = new THREE.Vector3( 1, 0, 0 ); 42 | /** 43 | * @desc 灯光的强度 44 | * @default ( 1, 0, 0 ) 45 | * @type {THREE.Vector3} 46 | */ 47 | this.intensity = ( intensity !== undefined ) ? intensity : 1; 48 | /** 49 | * @desc 区域光的宽度,初始化为1.0 50 | * @default 51 | * @type {float} 52 | */ 53 | this.width = 1.0; 54 | /** 55 | * @desc 区域光的宽度,初始化为1.0 56 | * @default 57 | * @type {float} 58 | */ 59 | this.height = 1.0; 60 | //WebGL是通过光强乘以衰减系数来计算衰减光照的, 61 | //attenuation (衰减系数) = 1`/ (this.constantAttenuation + this.distance * this.linearAttenuation + this.quadraticAttenuation * this.distance * this.distance ) 62 | /** 63 | * @desc 常量衰减系数,系数值越大,衰变越快 64 | * @default 65 | * @type {float} 66 | */ 67 | this.constantAttenuation = 1.5; 68 | /** 69 | * @desc 线性衰减系数,系数值越大,衰变越快 70 | * @default 71 | * @type {float} 72 | */ 73 | this.linearAttenuation = 0.5; 74 | /** 75 | * @desc 衰减平方系数,系数值越大,衰变越快 76 | * @default 77 | * @type {float} 78 | */ 79 | this.quadraticAttenuation = 0.1; 80 | 81 | }; 82 | /** 83 | * @desc AreaLight对象从THREE.Light的原型继承所有属性方法 84 | * @type {THREE.Light} 85 | */ 86 | THREE.AreaLight.prototype = Object.create( THREE.Light.prototype ); 87 | 88 | -------------------------------------------------------------------------------- /lights/DirectionalLight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | */ 5 | /** 6 | * @classdesc 平行光源对象 7 | * @desc 平行光支持阴影 8 | * @param {THREE.Color} color 平行光的颜色属性 9 | * @param {float} intensity 平行光的强度,默认是1 10 | * @extends {THREE.Light} 11 | * @constructor 12 | */ 13 | THREE.DirectionalLight = function ( color, intensity ) { 14 | 15 | THREE.Light.call( this, color ); 16 | /** 17 | * @default 18 | * @type {string} 19 | */ 20 | this.type = 'DirectionalLight'; 21 | /** 22 | * @desc 灯光的位置属性初始化为,0,1,0 23 | */ 24 | this.position.set( 0, 1, 0 ); 25 | /** 26 | * @desc 创建一个目标点对象,目标点对象是一个Object3D对象 27 | * @type {THREE.Object3D} 28 | */ 29 | this.target = new THREE.Object3D(); 30 | /** 31 | * desc 灯光的强度
32 | * (光线的密度,默认为1。因为RGB的三个值均在0~255之间,
33 | * 不能反映出光照的强度变化,光照越强,物体表面就更明亮。) 34 | * @default 1 35 | * @type {float} 36 | */ 37 | this.intensity = ( intensity !== undefined ) ? intensity : 1; 38 | /** 39 | * @desc 是否对于所有表面都会逐像元地计算其在光照方向上是否被遮挡,这会消耗大量的计算 40 | * @default 41 | * @type {boolean} 42 | */ 43 | this.castShadow = false; 44 | /** 45 | * @desc 控制是否只产生阴影而不“照亮”物体 46 | * @default 47 | * @type {boolean} 48 | */ 49 | this.onlyShadow = false; 50 | 51 | // 52 | /** 53 | * @desc 平截头体近端,定义一个范围(平截头体),不计算在范围之外的物体的阴影 54 | * @default 55 | * @type {float} 56 | */ 57 | this.shadowCameraNear = 50; 58 | /** 59 | * @desc 平截头体远端,定义一个范围(平截头体),不计算在范围之外的物体的阴影 60 | * @default 61 | * @type {float} 62 | */ 63 | this.shadowCameraFar = 5000; 64 | /** 65 | * @desc 相机左侧距离,不计算在范围之外的物体的阴影 66 | * @default 67 | * @type {float} 68 | */ 69 | this.shadowCameraLeft = - 500; 70 | /** 71 | * @desc 相机右侧距离,不计算在范围之外的物体的阴影 72 | * @default 73 | * @type {float} 74 | */ 75 | this.shadowCameraRight = 500; 76 | /** 77 | * @desc 相机上侧距离,不计算在范围之外的物体的阴影 78 | * @default 79 | * @type {float} 80 | */ 81 | this.shadowCameraTop = 500; 82 | /** 83 | * @desc 相机下侧距离,不计算在范围之外的物体的阴影 84 | * @default 85 | * @type {float} 86 | */ 87 | this.shadowCameraBottom = - 500; 88 | /** 89 | * @desc 会在场景中显示灯光的框架,方便调试 90 | * @default 91 | * @type {boolean} 92 | */ 93 | this.shadowCameraVisible = false; 94 | /** 95 | * @desc 阴影贴图的偏移 96 | * @default 97 | * @type {float} 98 | */ 99 | this.shadowBias = 0; 100 | /** 101 | * @desc 阴影对物体亮度的影响 102 | * @default 103 | * @type {float} 104 | */ 105 | this.shadowDarkness = 0.5; 106 | /** 107 | * @desc 阴影贴图宽度 108 | * @default 109 | * @type {float} 110 | */ 111 | this.shadowMapWidth = 512; 112 | /** 113 | * @desc 阴影贴图高度 114 | * @default 115 | * @type {float} 116 | */ 117 | this.shadowMapHeight = 512; 118 | 119 | // 120 | /** 121 | * @desc 是否支持阴影级联 122 | * @default 123 | * @type {boolean} 124 | */ 125 | this.shadowCascade = false; 126 | /** 127 | * @desc 阴影级联偏移距离 128 | * @default ( 0, 0, - 1000 ) 129 | * @type {THREE.Vector3} 130 | */ 131 | this.shadowCascadeOffset = new THREE.Vector3( 0, 0, - 1000 ); 132 | /** 133 | * @desc 当使用2个阴影级联时,整个阴影距离内,默认被分为两块,靠近观察者较小的块和远处较大的块 134 | * @default 135 | * @type {number} 136 | */ 137 | this.shadowCascadeCount = 2; 138 | /** 139 | * @desc 阴影级联偏移数组 140 | * @default 141 | * @type {number[]} 142 | */ 143 | this.shadowCascadeBias = [ 0, 0, 0 ]; 144 | /** 145 | * @desc 阴影级联宽度数组 146 | * @default 147 | * @type {number[]} 148 | */ 149 | this.shadowCascadeWidth = [ 512, 512, 512 ]; 150 | /** 151 | * @desc 阴影级联高度数组 152 | * @default 153 | * @type {number[]} 154 | */ 155 | this.shadowCascadeHeight = [ 512, 512, 512 ]; 156 | /** 157 | * @desc 阴影级联近处 158 | * @default 159 | * @type {number[]} 160 | */ 161 | this.shadowCascadeNearZ = [ - 1.000, 0.990, 0.998 ]; 162 | /** 163 | * @desc 阴影级联远处 164 | * @default 165 | * @type {number[]} 166 | */ 167 | this.shadowCascadeFarZ = [ 0.990, 0.998, 1.000 ]; 168 | /** 169 | * @desc 阴影级联数组 170 | * @type {Array} 171 | */ 172 | this.shadowCascadeArray = []; 173 | 174 | // 175 | 176 | /** 177 | * @desc 指定阴影贴图 178 | * @default 179 | * @type {null} 180 | */ 181 | this.shadowMap = null; 182 | /** 183 | * @desc 指定阴影贴图大小 184 | * @default 185 | * @type {number} 186 | */ 187 | this.shadowMapSize = null; 188 | /** 189 | * @desc 指定阴影相机 190 | * @default 191 | * @type {THREE.Camera} 192 | */ 193 | this.shadowCamera = null; 194 | /** 195 | * @desc 指定阴影矩阵 196 | * @default 197 | * @type {THREE.Matrix4} 198 | */ 199 | this.shadowMatrix = null; 200 | 201 | }; 202 | /** 203 | * @desc DirectionalLight对象从THREE.Light的原型继承所有属性方法 204 | * @type {THREE.Light} 205 | */ 206 | THREE.DirectionalLight.prototype = Object.create( THREE.Light.prototype ); 207 | /** 208 | * @desc DirectionalLight克隆函数 209 | * @returns {THREE.DirectionalLight} 210 | */ 211 | THREE.DirectionalLight.prototype.clone = function () { 212 | 213 | var light = new THREE.DirectionalLight(); 214 | 215 | THREE.Light.prototype.clone.call( this, light ); 216 | 217 | light.target = this.target.clone(); 218 | 219 | light.intensity = this.intensity; 220 | 221 | light.castShadow = this.castShadow; 222 | light.onlyShadow = this.onlyShadow; 223 | 224 | // 225 | 226 | light.shadowCameraNear = this.shadowCameraNear; 227 | light.shadowCameraFar = this.shadowCameraFar; 228 | 229 | light.shadowCameraLeft = this.shadowCameraLeft; 230 | light.shadowCameraRight = this.shadowCameraRight; 231 | light.shadowCameraTop = this.shadowCameraTop; 232 | light.shadowCameraBottom = this.shadowCameraBottom; 233 | 234 | light.shadowCameraVisible = this.shadowCameraVisible; 235 | 236 | light.shadowBias = this.shadowBias; 237 | light.shadowDarkness = this.shadowDarkness; 238 | 239 | light.shadowMapWidth = this.shadowMapWidth; 240 | light.shadowMapHeight = this.shadowMapHeight; 241 | 242 | // 243 | 244 | light.shadowCascade = this.shadowCascade; 245 | 246 | light.shadowCascadeOffset.copy( this.shadowCascadeOffset ); 247 | light.shadowCascadeCount = this.shadowCascadeCount; 248 | 249 | light.shadowCascadeBias = this.shadowCascadeBias.slice( 0 ); 250 | light.shadowCascadeWidth = this.shadowCascadeWidth.slice( 0 ); 251 | light.shadowCascadeHeight = this.shadowCascadeHeight.slice( 0 ); 252 | 253 | light.shadowCascadeNearZ = this.shadowCascadeNearZ.slice( 0 ); 254 | light.shadowCascadeFarZ = this.shadowCascadeFarZ.slice( 0 ); 255 | 256 | return light; 257 | 258 | }; 259 | -------------------------------------------------------------------------------- /lights/HemisphereLight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | /** 5 | * @classdesc 半球光对象 6 | * @desc HemisphereLight类是在场景中创建半球光,就是天光效果
7 | * 经常用在室外,将各个位置的物体都照亮,室内的光线大多是方向性的
8 | * 半球光不支持阴影 9 | * @param {THREE.Color} skyColor 半球光的颜色(天光的颜色) 10 | * @param {THREE.Color} groundColor 半球光的地面颜色 11 | * @param {float} intensity 灯光的强度,默认是1 12 | * @extends {THREE.Light} 13 | * @constructor 14 | */ 15 | THREE.HemisphereLight = function ( skyColor, groundColor, intensity ) { 16 | 17 | THREE.Light.call( this, skyColor ); 18 | /** 19 | * @default 20 | * @type {string} 21 | */ 22 | this.type = 'HemisphereLight'; 23 | 24 | /** 25 | * @desc 灯光初始化位置为(0,100,0) 26 | */ 27 | this.position.set( 0, 100, 0 ); 28 | 29 | /** 30 | * @desc 半球光的地面颜色 31 | * @type {THREE.Color} 32 | */ 33 | this.groundColor = new THREE.Color( groundColor ); 34 | /** 35 | * @desc 灯光的强度 36 | * @default 1 37 | * @type {number} 38 | */ 39 | this.intensity = ( intensity !== undefined ) ? intensity : 1; 40 | 41 | }; 42 | /** 43 | * @desc HemisphereLight对象从THREE.Light的原型继承所有属性方法 44 | * @type {THREE.Light} 45 | */ 46 | THREE.HemisphereLight.prototype = Object.create( THREE.Light.prototype ); 47 | /** 48 | * @desc HemisphereLight克隆函数 49 | * @returns {THREE.HemisphereLight} 50 | */ 51 | THREE.HemisphereLight.prototype.clone = function () { 52 | 53 | var light = new THREE.HemisphereLight(); 54 | 55 | THREE.Light.prototype.clone.call( this, light ); 56 | 57 | light.groundColor.copy( this.groundColor ); 58 | light.intensity = this.intensity; 59 | 60 | return light; 61 | 62 | }; 63 | -------------------------------------------------------------------------------- /lights/Light.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | */ 5 | /** 6 | * @classdesc 灯光对象的抽象基类 7 | * @desc 在WebGL的三维空间中,存在点光源PointLight和聚光灯SpotLight两种类型,还有作为点光源的一种特例
8 | * 平行光DirectionLight,和环境光AmbientLight.在3D场景中,基本上是这几种光源的组合,创建各种各样的效果 9 | * @param {THREE.Color} color 灯光颜色值 10 | * @extends {THREE.Object3D} 11 | * @constructor 12 | */ 13 | THREE.Light = function ( color ) { 14 | 15 | THREE.Object3D.call( this ); 16 | /** 17 | * @default 18 | * @type {string} 19 | */ 20 | this.type = 'Light'; 21 | 22 | /** 23 | * @desc //设置灯光的颜色属性 24 | * @type {THREE.Color} 25 | */ 26 | this.color = new THREE.Color( color ); 27 | 28 | }; 29 | /** 30 | * @desc Light对象从THREE.Objec3D的原型继承所有属性方法 31 | * @type {THREE.Object3D} 32 | */ 33 | THREE.Light.prototype = Object.create( THREE.Object3D.prototype ); 34 | /** 35 | * @desc Light克隆函数 36 | * @param {THREE.Light} light 37 | * @returns {THREE.Light} 38 | */ 39 | THREE.Light.prototype.clone = function ( light ) { 40 | 41 | if ( light === undefined ) light = new THREE.Light(); 42 | 43 | THREE.Object3D.prototype.clone.call( this, light ); 44 | 45 | light.color.copy( this.color ); 46 | 47 | return light; 48 | 49 | }; 50 | -------------------------------------------------------------------------------- /lights/PointLight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | /** 5 | * @classdesc 点光源对象 6 | * @desc 点光源目前不支持阴影 7 | * @param {THREE.Color} color 点光源颜色 8 | * @param {float} intensity 光的强度,默认是1 9 | * @param {float} distance 光的长度,从光的position位置,开始衰减,衰减到distance的长度,默认是0 10 | * @extends {THREE.Light} 11 | * @example var light = new THREE.PointLight(0xff0000,1,100);
12 | * light.position.set(50,50,30); //设置位置
13 | * scene.add(lignt); //加入场景
14 | * @constructor 15 | */ 16 | THREE.PointLight = function ( color, intensity, distance ) { 17 | 18 | THREE.Light.call( this, color ); 19 | /** 20 | * @default 21 | * @type {string} 22 | */ 23 | this.type = 'PointLight'; 24 | /** 25 | * @desc 光的强度 26 | * @default 1 27 | * @type {float} 28 | */ 29 | this.intensity = ( intensity !== undefined ) ? intensity : 1; 30 | /** 31 | * @desc 光的长度 32 | * @default 0 33 | * @type {float} 34 | */ 35 | this.distance = ( distance !== undefined ) ? distance : 0; 36 | 37 | }; 38 | /** 39 | * @desc PointLight对象从THREE.Light的原型继承所有属性方法 40 | * @type {THREE.Light} 41 | */ 42 | THREE.PointLight.prototype = Object.create( THREE.Light.prototype ); 43 | /** 44 | * @desc PointLight克隆函数 45 | * @returns {THREE.PointLight} 46 | */ 47 | THREE.PointLight.prototype.clone = function () { 48 | 49 | var light = new THREE.PointLight(); 50 | 51 | THREE.Light.prototype.clone.call( this, light ); 52 | 53 | light.intensity = this.intensity; 54 | light.distance = this.distance; 55 | 56 | return light; 57 | 58 | }; 59 | -------------------------------------------------------------------------------- /lights/SpotLight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | /** 5 | * @classdesc 聚光灯光源对象 6 | * @desc 根据设置灯光的颜属性color, 强度属性intensity,距离属性 distance,灯光的照射角度 angle,衰减速度 exponent 创建聚光灯光源(射灯)
7 | * SpotLight类型灯光实现了阴影,但是需要在场景中使用MeshLambertMaterial或者MeshPhongMaterial 8 | * @param {THREE.Color} color 灯光的颜色属性 9 | * @param {float} intensity 灯光的强度,默认是1 10 | * @param {float} distance 灯光的长度属性,从灯光的position位置,开始衰减,衰减到distance的长度,默认是0 11 | * @param {float} angle 聚光灯的灯光照射角度属性,单位是弧度,默认是60度角的弧度 12 | * @param {float} exponent 聚光灯的从照射点的衰减速度属性,默认是10 13 | * @extends {THREE.Light} 14 | * @example var light = new THREE.SpotLight(0xff0000,1,100,Math.PI /2,5); //创建灯光对象
15 | * light.position.set(50,50,30); //设置位置
16 | * light.castShadow = true; //开启阴影
17 | * light.shadowMapWidth = 1024; //阴影贴图宽度设置为1024像素
18 | * light.shadowMapHeight = 1024; //阴影贴图高度设置为1024像素
19 | * light.shadowCameraNear = 500; //阴影的平截头体区域near属性
20 | * light.shadowCameraFar = 4000; //阴影的平截头体区域far属性
21 | * light.shadowCameraFov = 30; //阴影的平截头体区域fov属性
22 | * scene.add(lignt); //加入场景 23 | * @constructor 24 | */ 25 | THREE.SpotLight = function ( color, intensity, distance, angle, exponent ) { 26 | 27 | THREE.Light.call( this, color ); 28 | /** 29 | * @default 30 | * @type {string} 31 | */ 32 | this.type = 'SpotLight'; 33 | /** 34 | * @desc 灯光的位置属性初始化为,0,1,0 35 | */ 36 | this.position.set( 0, 1, 0 ); 37 | /** 38 | * @desc 创建一个目标点对象,目标点对象是一个Object3D对象 39 | * @type {THREE.Object3D} 40 | */ 41 | this.target = new THREE.Object3D(); 42 | /** 43 | * desc 灯光的强度
44 | * (光线的密度,默认为1。因为RGB的三个值均在0~255之间,
45 | * 不能反映出光照的强度变化,光照越强,物体表面就更明亮。) 46 | * @default 1 47 | * @type {float} 48 | */ 49 | this.intensity = ( intensity !== undefined ) ? intensity : 1; 50 | /** 51 | * desc 灯光的长度度
52 | * 如果不指定,初始化为1.
53 | * (衰减距离,默认值为0,光照无衰减;如果是非0值,光照会从position位置
54 | * (实际上是position所处的那个平面)开始衰减,衰减到distance距离之后,光照强度intensity为0) 55 | * @default 0 56 | * @type {float} 57 | */ 58 | this.distance = ( distance !== undefined ) ? distance : 0; 59 | /** 60 | * desc 聚光灯的灯光照射角度属性
61 | * 单位是弧度,默认是60度角的弧度 62 | * @default Math.PI / 3 63 | * @type {float} 64 | */ 65 | this.angle = ( angle !== undefined ) ? angle : Math.PI / 3; 66 | /** 67 | * desc 光灯的从照射点的衰减速度指数 68 | * @default 10 69 | * @type {float} 70 | */ 71 | this.exponent = ( exponent !== undefined ) ? exponent : 10; 72 | /** 73 | * @desc 是否对于所有表面都会逐像元地计算其在光照方向上是否被遮挡,这会消耗大量的计算 74 | * @default 75 | * @type {boolean} 76 | */ 77 | this.castShadow = false; 78 | /** 79 | * @desc 控制是否只产生阴影而不“照亮”物体 80 | * @default 81 | * @type {boolean} 82 | */ 83 | this.onlyShadow = false; 84 | 85 | // 86 | /** 87 | * @desc 平截头体近端,定义一个范围(平截头体),不计算在范围之外的物体的阴影 88 | * @default 89 | * @type {float} 90 | */ 91 | this.shadowCameraNear = 50; 92 | /** 93 | * @desc 平截头体远端,定义一个范围(平截头体),不计算在范围之外的物体的阴影 94 | * @default 95 | * @type {float} 96 | */ 97 | this.shadowCameraFar = 5000; 98 | /** 99 | * @desc 平截头体视野,定义一个范围(平截头体),不计算在范围之外的物体的阴影 100 | * @default 101 | * @type {float} 102 | */ 103 | this.shadowCameraFov = 50; 104 | /** 105 | * @desc 会在场景中显示灯光的框架,方便调试 106 | * @default 107 | * @type {boolean} 108 | */ 109 | this.shadowCameraVisible = false; 110 | /** 111 | * @desc 阴影贴图的偏移 112 | * @default 113 | * @type {float} 114 | */ 115 | this.shadowBias = 0; 116 | /** 117 | * @desc 阴影对物体亮度的影响 118 | * @default 119 | * @type {float} 120 | */ 121 | this.shadowDarkness = 0.5; 122 | /** 123 | * @desc 阴影贴图宽度 124 | * @default 125 | * @type {float} 126 | */ 127 | this.shadowMapWidth = 512; 128 | /** 129 | * @desc 阴影贴图高度 130 | * @default 131 | * @type {float} 132 | */ 133 | this.shadowMapHeight = 512; 134 | 135 | // 136 | /** 137 | * @desc 指定阴影贴图 138 | * @default 139 | * @type {null} 140 | */ 141 | this.shadowMap = null; 142 | /** 143 | * @desc 指定阴影贴图大小 144 | * @default 145 | * @type {number} 146 | */ 147 | this.shadowMapSize = null; 148 | /** 149 | * @desc 指定阴影相机 150 | * @default 151 | * @type {THREE.Camera} 152 | */ 153 | this.shadowCamera = null; 154 | /** 155 | * @desc 指定阴影矩阵 156 | * @default 157 | * @type {THREE.Matrix4} 158 | */ 159 | this.shadowMatrix = null; 160 | 161 | }; 162 | /** 163 | * @desc SpotLight对象从THREE.Light的原型继承所有属性方法 164 | * @type {THREE.Light} 165 | */ 166 | THREE.SpotLight.prototype = Object.create( THREE.Light.prototype ); 167 | /** 168 | * @desc SpotLight克隆函数 169 | * @returns {THREE.SpotLight} 170 | */ 171 | THREE.SpotLight.prototype.clone = function () { 172 | 173 | var light = new THREE.SpotLight(); 174 | 175 | THREE.Light.prototype.clone.call( this, light ); 176 | 177 | light.target = this.target.clone(); 178 | 179 | light.intensity = this.intensity; 180 | light.distance = this.distance; 181 | light.angle = this.angle; 182 | light.exponent = this.exponent; 183 | 184 | light.castShadow = this.castShadow; 185 | light.onlyShadow = this.onlyShadow; 186 | 187 | // 188 | 189 | light.shadowCameraNear = this.shadowCameraNear; 190 | light.shadowCameraFar = this.shadowCameraFar; 191 | light.shadowCameraFov = this.shadowCameraFov; 192 | 193 | light.shadowCameraVisible = this.shadowCameraVisible; 194 | 195 | light.shadowBias = this.shadowBias; 196 | light.shadowDarkness = this.shadowDarkness; 197 | 198 | light.shadowMapWidth = this.shadowMapWidth; 199 | light.shadowMapHeight = this.shadowMapHeight; 200 | 201 | return light; 202 | 203 | }; 204 | -------------------------------------------------------------------------------- /materials/LineBasicMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | * 5 | * parameters = { 6 | * color: , 7 | * opacity: , 8 | * 9 | * blending: THREE.NormalBlending, 10 | * depthTest: , 11 | * depthWrite: , 12 | * 13 | * linewidth: , 14 | * linecap: "round", 15 | * linejoin: "round", 16 | * 17 | * vertexColors: 18 | * 19 | * fog: 20 | * } 21 | */ 22 | /** 23 | * @classdesc 线线型材质 24 | * @desc 据参数parameters创建线段的线线型材质,参数为JSON格式的属性参数 25 | * @param {String} parameters 材质参数 26 | * @extends {THREE.Material} 27 | * @constructor 28 | */ 29 | THREE.LineBasicMaterial = function ( parameters ) { 30 | 31 | THREE.Material.call( this ); 32 | /** 33 | * @default 'LineBasicMaterial' 34 | * @type {string} 35 | */ 36 | this.type = 'LineBasicMaterial'; 37 | /** 38 | * @desc 线材质颜色 39 | * @default 0xffffff 白色 40 | * @type {THREE.Color} 41 | */ 42 | this.color = new THREE.Color( 0xffffff ); 43 | /** 44 | * @desc 线的宽度 45 | * @default 46 | * @type {float} 47 | */ 48 | this.linewidth = 1; 49 | /** 50 | * @desc 线头类型 "round" 圆角 "butt" 平角 "square" 方角 51 | * @default "round" 圆角 52 | * @type {string} 53 | */ 54 | this.linecap = 'round'; 55 | /** 56 | * @desc 线连接类型 "bevel" 斜角 "round" 圆角 "miter" 尖角 57 | * @default "round" 圆角 58 | * @type {string} 59 | */ 60 | this.linejoin = 'round'; 61 | /** 62 | * @desc 线顶点颜色 63 | * @default THREE.NoColors 64 | * @type {number} 65 | */ 66 | this.vertexColors = THREE.NoColors; 67 | /** 68 | * @desc 雾效 69 | * @default 70 | * @type {boolean} 71 | */ 72 | this.fog = true; 73 | 74 | this.setValues( parameters ); 75 | 76 | }; 77 | /** 78 | * @desc LineBasicMaterial对象从THREE.Material的原型继承所有属性方法 79 | * @type {THREE.Material} 80 | */ 81 | THREE.LineBasicMaterial.prototype = Object.create( THREE.Material.prototype ); 82 | 83 | /** 84 | * @desc 线材质的克隆函数 85 | * @returns {THREE.LineBasicMaterial} 86 | */ 87 | THREE.LineBasicMaterial.prototype.clone = function () { 88 | 89 | var material = new THREE.LineBasicMaterial(); 90 | 91 | THREE.Material.prototype.clone.call( this, material ); 92 | 93 | material.color.copy( this.color ); 94 | 95 | material.linewidth = this.linewidth; 96 | material.linecap = this.linecap; 97 | material.linejoin = this.linejoin; 98 | 99 | material.vertexColors = this.vertexColors; 100 | 101 | material.fog = this.fog; 102 | 103 | return material; 104 | 105 | }; 106 | -------------------------------------------------------------------------------- /materials/LineDashedMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * parameters = { 5 | * color: , 6 | * opacity: , 7 | * 8 | * blending: THREE.NormalBlending, 9 | * depthTest: , 10 | * depthWrite: , 11 | * 12 | * linewidth: , 13 | * 14 | * scale: , 15 | * dashSize: , 16 | * gapSize: , 17 | * 18 | * vertexColors: 19 | * 20 | * fog: 21 | * } 22 | */ 23 | /** 24 | * @classdesc 虚线线型材质 25 | * @desc 据参数parameters创建线段的线线型材质,参数为JSON格式的属性参数 26 | * @param {String} parameters 材质参数 27 | * @extends {THREE.Material} 28 | * @constructor 29 | */ 30 | THREE.LineDashedMaterial = function ( parameters ) { 31 | 32 | THREE.Material.call( this ); 33 | /** 34 | * @default 'LineDashedMaterial' 35 | * @type {string} 36 | */ 37 | this.type = 'LineDashedMaterial'; 38 | /** 39 | * @desc 线材质颜色 40 | * @default 0xffffff 白色 41 | * @type {THREE.Color} 42 | */ 43 | this.color = new THREE.Color( 0xffffff ); 44 | /** 45 | * @desc 线的宽度 46 | * @default 47 | * @type {float} 48 | */ 49 | this.linewidth = 1; 50 | /** 51 | * @desc 虚线的线型比例属性 52 | * @default 53 | * @type {float} 54 | */ 55 | this.scale = 1; 56 | /** 57 | * @desc 虚线(点化线),线段的长度 58 | * @default 59 | * @type {float} 60 | */ 61 | this.dashSize = 3; 62 | /** 63 | * @desc 虚线(点化线)的线段间距长度 64 | * @default 65 | * @type {float} 66 | */ 67 | this.gapSize = 1; 68 | /** 69 | * @desc 线顶点颜色 70 | * @default THREE.NoColors 71 | * @type {number} 72 | */ 73 | this.vertexColors = false; 74 | /** 75 | * @desc 雾效 76 | * @default 77 | * @type {boolean} 78 | */ 79 | this.fog = true; 80 | 81 | this.setValues( parameters ); 82 | 83 | }; 84 | /** 85 | * @desc LineDashedMaterial对象从THREE.Material的原型继承所有属性方法 86 | * @type {THREE.Material} 87 | */ 88 | THREE.LineDashedMaterial.prototype = Object.create( THREE.Material.prototype ); 89 | /** 90 | * @desc 虚线材质的克隆函数 91 | * @returns {THREE.LineDashedMaterial} 92 | */ 93 | THREE.LineDashedMaterial.prototype.clone = function () { 94 | 95 | var material = new THREE.LineDashedMaterial(); 96 | 97 | THREE.Material.prototype.clone.call( this, material ); 98 | 99 | material.color.copy( this.color ); 100 | 101 | material.linewidth = this.linewidth; 102 | 103 | material.scale = this.scale; 104 | material.dashSize = this.dashSize; 105 | material.gapSize = this.gapSize; 106 | 107 | material.vertexColors = this.vertexColors; 108 | 109 | material.fog = this.fog; 110 | 111 | return material; 112 | 113 | }; 114 | -------------------------------------------------------------------------------- /materials/Material.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | */ 5 | /** 6 | * @classdesc 材质对象 7 | * @desc Material是材质对象的抽象基类,当创建材质时都从这个类继承
8 | * Material对象的功能函数采用定义构造的函数原型对象来实现
9 | * 简单的说就是物体看起来是什么质地。材质可以看成是材料和质感的结合。
10 | * 在渲染程式中,它是表面各可视属性的结合,这些可视属性是指表面的色彩、纹理、光滑度、透明度、反射率、折射率、发光度等。 11 | * @constructor 12 | */ 13 | THREE.Material = function () { 14 | 15 | Object.defineProperty( this, 'id', { value: THREE.MaterialIdCount ++ } ); 16 | /** 17 | * @desc 材质唯一ID 18 | */ 19 | this.uuid = THREE.Math.generateUUID(); 20 | 21 | /** 22 | * @desc 材质名称 23 | * @default 24 | * @type {string} 25 | */ 26 | this.name = ''; 27 | /** 28 | * @desc 材质类型 29 | * @default 30 | * @type {string} 31 | */ 32 | this.type = 'Material'; 33 | /** 34 | * @desc 材质的单双面
35 | * THREE.FrontSide 材质只附着正面
36 | * THREE.BackSide 材质只附着背面
37 | * THREE.DoubleSide 模型双面都附着材质 38 | * @default THREE.FrontSide 39 | * @type {number} 40 | */ 41 | this.side = THREE.FrontSide; 42 | /** 43 | * @desc 材质透明度,(0.0 ,1.0)只有在 transparent = true 才使用
44 | * 透明是渲染像素时,待渲染值与已存在值共同作用计算出渲染后像素值,达到混合的效果 45 | * @type {float} 46 | */ 47 | this.opacity = 1; 48 | /** 49 | * @desc 是否支持材质透明 50 | * @type {boolean} 51 | */ 52 | this.transparent = false; 53 | /** 54 | * @desc 材质混合方式 55 | * @default THREE.NormalBlending; 56 | * @type {number} 57 | */ 58 | this.blending = THREE.NormalBlending; 59 | /** 60 | * @desc 混合颜色的源颜色因子 61 | * @default THREE.SrcAlphaFactor 62 | * @type {number} 63 | */ 64 | this.blendSrc = THREE.SrcAlphaFactor; 65 | /** 66 | * @desc 混合颜色的目标颜色因子 67 | * @default THREE.OneMinusSrcAlphaFactor 68 | * @type {number} 69 | */ 70 | this.blendDst = THREE.OneMinusSrcAlphaFactor; 71 | /** 72 | * @desc 混合方程式 73 | * @default THREE.AddEquation 相加 74 | * @type {number} 75 | */ 76 | this.blendEquation = THREE.AddEquation; 77 | /** 78 | * @desc 深度测试,默认为true,如果设置为false,在场景中远处的对象不被近处的对象遮挡 79 | * @default 80 | * @type {boolean} 81 | */ 82 | this.depthTest = true; 83 | /** 84 | * @desc 允许或禁止向深度缓冲区写入数据,默认为true,指定是否允许向深度缓冲区写入数据 85 | * @default 86 | * @type {boolean} 87 | */ 88 | this.depthWrite = true; 89 | /** 90 | * @desc 多边形位移,当两个面共面时,会出现十分难看的z - fighting 问题
91 | * 要解决此问题可以使用, Polygon Offset 92 | * @default 93 | * @type {boolean} 94 | */ 95 | this.polygonOffset = false; 96 | /** 97 | * @desc 多边形位移因子 98 | * @default 99 | * @type {number} 100 | */ 101 | this.polygonOffsetFactor = 0; 102 | /** 103 | * @desc 多边形位移单位 104 | * @default 105 | * @type {number} 106 | */ 107 | this.polygonOffsetUnits = 0; 108 | /** 109 | * @desc alpha测试,取值范围0.0-1.0 110 | * @default 111 | * @type {float} 112 | */ 113 | this.alphaTest = 0; 114 | /** 115 | * @desc 当三角面之间产生间距,发生图形走样时
116 | * 填充像素,确保图形保真,消除走样.通常取值范围在0.0=1.0之间 117 | * @default 118 | * @type {float} 119 | */ 120 | this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer 121 | /** 122 | * @desc 是否可见 123 | * @default 124 | * @type {boolean} 125 | */ 126 | this.visible = true; 127 | /** 128 | * @desc //当设置为true时,标记材质已经更新. 129 | * @default 130 | * @type {boolean} 131 | */ 132 | this.needsUpdate = true; 133 | 134 | }; 135 | 136 | THREE.Material.prototype = { 137 | 138 | constructor: THREE.Material, 139 | /** 140 | * @desc 通过参数values设置材质对象的属性.values参数的格式为
141 | * values = { 142 | * color: , 143 | * opacity: , 144 | * map: new THREE.Texture( ), 145 | * 146 | * lightMap: new THREE.Texture( ), 147 | * 148 | * specularMap: new THREE.Texture( ), 149 | * 150 | * alphaMap: new THREE.Texture( ), 151 | * 152 | * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ), 153 | * combine: THREE.Multiply, 154 | * reflectivity: , 155 | * refractionRatio: , 156 | * 157 | * shading: THREE.SmoothShading, 158 | * blending: THREE.NormalBlending, 159 | * depthTest: , 160 | * depthWrite: , 161 | * 162 | * wireframe: , 163 | * wireframeLinewidth: , 164 | * 165 | * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, 166 | * 167 | * skinning: , 168 | * morphTargets: , 169 | * 170 | * fog: 171 | * } 172 | * @param {*} values 材质属性 173 | * @return {THREE.Material} 174 | */ 175 | setValues: function ( values ) { 176 | 177 | if ( values === undefined ) return; 178 | 179 | //遍历values中的键值,并一一赋值给当前材质对象. 180 | for ( var key in values ) { 181 | 182 | var newValue = values[ key ]; 183 | 184 | if ( newValue === undefined ) { 185 | 186 | console.warn( "THREE.Material: '" + key + "' parameter is undefined." ); 187 | continue; 188 | 189 | } 190 | 191 | if ( key in this ) { 192 | 193 | var currentValue = this[ key ]; 194 | 195 | if ( currentValue instanceof THREE.Color ) { 196 | 197 | currentValue.set( newValue ); 198 | 199 | } else if ( currentValue instanceof THREE.Vector3 && newValue instanceof THREE.Vector3 ) { 200 | 201 | currentValue.copy( newValue ); 202 | 203 | } else if ( key == 'overdraw' ) { 204 | 205 | // ensure overdraw is backwards-compatable with legacy boolean type 206 | this[ key ] = Number( newValue ); 207 | 208 | } else { 209 | 210 | this[ key ] = newValue; 211 | 212 | } 213 | 214 | } 215 | 216 | } 217 | 218 | }, 219 | /** 220 | * @desc 将材质转换为JSON格式
221 | * 包含了多种材质格式的转换方法 222 | */ 223 | toJSON: function () { 224 | 225 | var output = { 226 | metadata: { 227 | version: 4.2, 228 | type: 'material', 229 | generator: 'MaterialExporter' 230 | }, 231 | uuid: this.uuid, 232 | type: this.type 233 | }; 234 | 235 | if ( this.name !== "" ) output.name = this.name; 236 | 237 | if ( this instanceof THREE.MeshBasicMaterial ) { 238 | 239 | output.color = this.color.getHex(); 240 | if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors; 241 | if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; 242 | if ( this.side !== THREE.FrontSide ) output.side = this.side; 243 | 244 | } else if ( this instanceof THREE.MeshLambertMaterial ) { 245 | 246 | output.color = this.color.getHex(); 247 | output.ambient = this.ambient.getHex(); 248 | output.emissive = this.emissive.getHex(); 249 | if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors; 250 | if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; 251 | if ( this.side !== THREE.FrontSide ) output.side = this.side; 252 | 253 | } else if ( this instanceof THREE.MeshPhongMaterial ) { 254 | 255 | output.color = this.color.getHex(); 256 | output.ambient = this.ambient.getHex(); 257 | output.emissive = this.emissive.getHex(); 258 | output.specular = this.specular.getHex(); 259 | output.shininess = this.shininess; 260 | if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors; 261 | if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; 262 | if ( this.side !== THREE.FrontSide ) output.side = this.side; 263 | 264 | } else if ( this instanceof THREE.MeshNormalMaterial ) { 265 | 266 | if ( this.shading !== THREE.FlatShading ) output.shading = this.shading; 267 | if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; 268 | if ( this.side !== THREE.FrontSide ) output.side = this.side; 269 | 270 | } else if ( this instanceof THREE.MeshDepthMaterial ) { 271 | 272 | if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; 273 | if ( this.side !== THREE.FrontSide ) output.side = this.side; 274 | 275 | } else if ( this instanceof THREE.ShaderMaterial ) { 276 | 277 | output.uniforms = this.uniforms; 278 | output.vertexShader = this.vertexShader; 279 | output.fragmentShader = this.fragmentShader; 280 | 281 | } else if ( this instanceof THREE.SpriteMaterial ) { 282 | 283 | output.color = this.color.getHex(); 284 | 285 | } 286 | 287 | if ( this.opacity < 1 ) output.opacity = this.opacity; 288 | if ( this.transparent !== false ) output.transparent = this.transparent; 289 | if ( this.wireframe !== false ) output.wireframe = this.wireframe; 290 | 291 | return output; 292 | 293 | }, 294 | /** 295 | * @desc 克隆材质 296 | * @param {THREE.Material} material 297 | * @returns {THREE.Material} 298 | */ 299 | clone: function ( material ) { 300 | 301 | if ( material === undefined ) material = new THREE.Material(); 302 | 303 | material.name = this.name; 304 | 305 | material.side = this.side; 306 | 307 | material.opacity = this.opacity; 308 | material.transparent = this.transparent; 309 | 310 | material.blending = this.blending; 311 | 312 | material.blendSrc = this.blendSrc; 313 | material.blendDst = this.blendDst; 314 | material.blendEquation = this.blendEquation; 315 | 316 | material.depthTest = this.depthTest; 317 | material.depthWrite = this.depthWrite; 318 | 319 | material.polygonOffset = this.polygonOffset; 320 | material.polygonOffsetFactor = this.polygonOffsetFactor; 321 | material.polygonOffsetUnits = this.polygonOffsetUnits; 322 | 323 | material.alphaTest = this.alphaTest; 324 | 325 | material.overdraw = this.overdraw; 326 | 327 | material.visible = this.visible; 328 | 329 | return material; 330 | 331 | }, 332 | /** 333 | * @desc 材质的销毁函数 334 | */ 335 | dispose: function () { 336 | 337 | this.dispatchEvent( { type: 'dispose' } ); 338 | 339 | } 340 | 341 | }; 342 | 343 | //EventDispatcher方法应用到当前Material对象. 344 | THREE.EventDispatcher.prototype.apply( THREE.Material.prototype ); 345 | /** 346 | * @memberof THREE 347 | * @desc 全局材质对象数目 348 | * @type {number} 349 | */ 350 | THREE.MaterialIdCount = 0; 351 | -------------------------------------------------------------------------------- /materials/MeshBasicMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | * 5 | * parameters = { 6 | * color: , 7 | * opacity: , 8 | * map: new THREE.Texture( ), 9 | * 10 | * lightMap: new THREE.Texture( ), 11 | * 12 | * specularMap: new THREE.Texture( ), 13 | * 14 | * alphaMap: new THREE.Texture( ), 15 | * 16 | * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ), 17 | * combine: THREE.Multiply, 18 | * reflectivity: , 19 | * refractionRatio: , 20 | * 21 | * shading: THREE.SmoothShading, 22 | * blending: THREE.NormalBlending, 23 | * depthTest: , 24 | * depthWrite: , 25 | * 26 | * wireframe: , 27 | * wireframeLinewidth: , 28 | * 29 | * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, 30 | * 31 | * skinning: , 32 | * morphTargets: , 33 | * 34 | * fog: 35 | * } 36 | */ 37 | /** 38 | * @classdesc mesh(网格)的基本材质材质 39 | * @desc 据参数parameters创建线段的线线型材质,参数为JSON格式的属性参数 40 | * @param {String} parameters 材质参数 41 | * @extends {THREE.Material} 42 | * @constructor 43 | */ 44 | THREE.MeshBasicMaterial = function ( parameters ) { 45 | 46 | THREE.Material.call( this ); 47 | /** 48 | * @default 'MeshBasicMaterial' 49 | * @type {string} 50 | */ 51 | this.type = 'MeshBasicMaterial'; 52 | /** 53 | * @desc 材质颜色 54 | * @default 0xffffff 白色 55 | * @type {THREE.Color} 56 | */ 57 | this.color = new THREE.Color( 0xffffff ); // emissive 58 | /** 59 | * @desc 纹理贴图 60 | * @default 61 | * @type {THREE.Texture} 62 | */ 63 | this.map = null; 64 | /** 65 | * @desc 光照贴图 66 | * @default 67 | * @type {THREE.Texture} 68 | */ 69 | this.lightMap = null; 70 | /** 71 | * @desc 高光贴图 72 | * @default 73 | * @type {THREE.Texture} 74 | */ 75 | this.specularMap = null; 76 | /** 77 | * @desc 透明贴图 78 | * @default 79 | * @type {THREE.Texture} 80 | */ 81 | this.alphaMap = null; 82 | /** 83 | * @desc 环境贴图 84 | * @default 85 | * @type {THREE.Texture} 86 | */ 87 | this.envMap = null; 88 | /** 89 | * @desc 材质混合模式 90 | * @default THREE.MultiplyOperation 91 | * @type {number} 92 | */ 93 | this.combine = THREE.MultiplyOperation; 94 | /** 95 | * @desc 反射率 96 | * @default 97 | * @type {float} 98 | */ 99 | this.reflectivity = 1; 100 | /** 101 | * @desc 折射率 102 | * @default 103 | * @type {float} 104 | */ 105 | this.refractionRatio = 0.98; 106 | /** 107 | * @desc 雾效,默认开启 108 | * @default 109 | * @type {boolean} 110 | */ 111 | this.fog = true; 112 | /** 113 | * @desc 着色方式
114 | * THREE.SmoothShading平滑着色:用多种颜色进行绘制
115 | * 每个顶点都是单独进行处理的,各顶点和各图元之间采用均匀插值。 116 | * @default 117 | * @type {number} 118 | */ 119 | this.shading = THREE.SmoothShading; 120 | /** 121 | * @desc 是否以线框方式渲染几何体 122 | * @default 123 | * @type {boolean} 124 | */ 125 | this.wireframe = false; 126 | /** 127 | * @desc 线框宽度 128 | * @default 129 | * @type {float} 130 | */ 131 | this.wireframeLinewidth = 1; 132 | /** 133 | * @desc 线框端点类型,参照LineBasicMaterial的定义 134 | * @default 'round' 135 | * @type {string} 136 | */ 137 | this.wireframeLinecap = 'round'; 138 | /** 139 | * @desc 线框连接类型,参照LineBasicMaterial的定义 140 | * @default 'round' 141 | * @type {string} 142 | */ 143 | this.wireframeLinejoin = 'round'; 144 | /** 145 | * @desc 材质顶点颜色 146 | * @default THREE.NoColors 147 | * @type {number} 148 | */ 149 | this.vertexColors = THREE.NoColors; 150 | /** 151 | * @desc 材质是否使用蒙皮 152 | * @default 153 | * @type {boolean} 154 | */ 155 | this.skinning = false; 156 | /** 157 | * @desc 材质是否设定目标变形动画 158 | * @default 159 | * @type {boolean} 160 | */ 161 | this.morphTargets = false; 162 | 163 | this.setValues( parameters ); 164 | 165 | }; 166 | /** 167 | * @desc MeshBasicMaterial对象从THREE.Material的原型继承所有属性方法 168 | * @type {THREE.Material} 169 | */ 170 | THREE.MeshBasicMaterial.prototype = Object.create( THREE.Material.prototype ); 171 | /** 172 | * @desc 面材质的克隆函数 173 | * @returns {THREE.MeshBasicMaterial} 174 | */ 175 | THREE.MeshBasicMaterial.prototype.clone = function () { 176 | 177 | var material = new THREE.MeshBasicMaterial(); 178 | 179 | THREE.Material.prototype.clone.call( this, material ); 180 | 181 | material.color.copy( this.color ); 182 | 183 | material.map = this.map; 184 | 185 | material.lightMap = this.lightMap; 186 | 187 | material.specularMap = this.specularMap; 188 | 189 | material.alphaMap = this.alphaMap; 190 | 191 | material.envMap = this.envMap; 192 | material.combine = this.combine; 193 | material.reflectivity = this.reflectivity; 194 | material.refractionRatio = this.refractionRatio; 195 | 196 | material.fog = this.fog; 197 | 198 | material.shading = this.shading; 199 | 200 | material.wireframe = this.wireframe; 201 | material.wireframeLinewidth = this.wireframeLinewidth; 202 | material.wireframeLinecap = this.wireframeLinecap; 203 | material.wireframeLinejoin = this.wireframeLinejoin; 204 | 205 | material.vertexColors = this.vertexColors; 206 | 207 | material.skinning = this.skinning; 208 | material.morphTargets = this.morphTargets; 209 | 210 | return material; 211 | 212 | }; 213 | -------------------------------------------------------------------------------- /materials/MeshDepthMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | * 5 | * parameters = { 6 | * opacity: , 7 | * 8 | * blending: THREE.NormalBlending, 9 | * depthTest: , 10 | * depthWrite: , 11 | * 12 | * wireframe: , 13 | * wireframeLinewidth: 14 | * } 15 | */ 16 | /** 17 | * @classdesc mesh(网格)的网格深度材质 18 | * @desc 基于相机远近裁切面自动变换亮度(明暗度)的mesh(网格)的材质
19 | * 离相机越近,材质越亮(白),离相机越远,材质越暗(黑) 20 | * @param {String} parameters 材质参数 21 | * @extends {THREE.Material} 22 | * @constructor 23 | */ 24 | THREE.MeshDepthMaterial = function ( parameters ) { 25 | 26 | THREE.Material.call( this ); 27 | /** 28 | * @default 'MeshDepthMaterial' 29 | * @type {string} 30 | */ 31 | this.type = 'MeshDepthMaterial'; 32 | /** 33 | * @desc 定义材质是否设定目标变形动画 34 | * @default 35 | * @type {boolean} 36 | */ 37 | this.morphTargets = false; 38 | /** 39 | * @desc 是否使用线框模式 40 | * @default 41 | * @type {boolean} 42 | */ 43 | this.wireframe = false; 44 | /** 45 | * @default 线框宽度 46 | * @default 47 | * @type {number} 48 | */ 49 | this.wireframeLinewidth = 1; 50 | 51 | this.setValues( parameters ); 52 | 53 | }; 54 | /** 55 | * @desc MeshDepthMaterial对象从THREE.Material的原型继承所有属性方法 56 | * @type {THREE.Material} 57 | */ 58 | THREE.MeshDepthMaterial.prototype = Object.create( THREE.Material.prototype ); 59 | /** 60 | * @desc MeshDepthMaterial材质的克隆函数 61 | * @returns {THREE.MeshDepthMaterial} 62 | */ 63 | THREE.MeshDepthMaterial.prototype.clone = function () { 64 | 65 | var material = new THREE.MeshDepthMaterial(); 66 | 67 | THREE.Material.prototype.clone.call( this, material ); 68 | 69 | material.wireframe = this.wireframe; 70 | material.wireframeLinewidth = this.wireframeLinewidth; 71 | 72 | return material; 73 | 74 | }; 75 | -------------------------------------------------------------------------------- /materials/MeshFaceMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | /** 5 | * @classdesc mesh(网格)的网格复合材质 6 | * @desc 多材质,支持材质的列表
7 | * 离相机越近,材质越亮(白),离相机越远,材质越暗(黑) 8 | * @param {String} parameters 材质参数 9 | * @extends {THREE.Material} 10 | * @constructor 11 | */ 12 | THREE.MeshFaceMaterial = function ( materials ) { 13 | 14 | this.uuid = THREE.Math.generateUUID(); 15 | /** 16 | * @default 'MeshFaceMaterial' 17 | * @type {string} 18 | */ 19 | this.type = 'MeshFaceMaterial'; 20 | 21 | /** 22 | * @desc 材质列表 23 | */ 24 | this.materials = materials instanceof Array ? materials : []; 25 | 26 | }; 27 | 28 | THREE.MeshFaceMaterial.prototype = { 29 | 30 | constructor: THREE.MeshFaceMaterial, 31 | /** 32 | * @desc 材质列表转换JSON格式 33 | * @returns {*} 34 | */ 35 | toJSON: function () { 36 | 37 | var output = { 38 | metadata: { 39 | version: 4.2, 40 | type: 'material', 41 | generator: 'MaterialExporter' 42 | }, 43 | uuid: this.uuid, 44 | type: this.type, 45 | materials: [] 46 | }; 47 | 48 | for ( var i = 0, l = this.materials.length; i < l; i ++ ) { 49 | 50 | output.materials.push( this.materials[ i ].toJSON() ); 51 | 52 | } 53 | 54 | return output; 55 | 56 | }, 57 | /** 58 | * @desc MeshFaceMaterial材质的克隆函数 59 | * @returns {THREE.MeshFaceMaterial} 60 | */ 61 | clone: function () { 62 | 63 | var material = new THREE.MeshFaceMaterial(); 64 | 65 | for ( var i = 0; i < this.materials.length; i ++ ) { 66 | 67 | material.materials.push( this.materials[ i ].clone() ); 68 | 69 | } 70 | 71 | return material; 72 | 73 | } 74 | 75 | }; 76 | -------------------------------------------------------------------------------- /materials/MeshLambertMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | * 5 | * parameters = { 6 | * color: , 7 | * ambient: , 8 | * emissive: , 9 | * opacity: , 10 | * 11 | * map: new THREE.Texture( ), 12 | * 13 | * lightMap: new THREE.Texture( ), 14 | * 15 | * specularMap: new THREE.Texture( ), 16 | * 17 | * alphaMap: new THREE.Texture( ), 18 | * 19 | * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ), 20 | * combine: THREE.Multiply, 21 | * reflectivity: , 22 | * refractionRatio: , 23 | * 24 | * shading: THREE.SmoothShading, 25 | * blending: THREE.NormalBlending, 26 | * depthTest: , 27 | * depthWrite: , 28 | * 29 | * wireframe: , 30 | * wireframeLinewidth: , 31 | * 32 | * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, 33 | * 34 | * skinning: , 35 | * morphTargets: , 36 | * morphNormals: , 37 | * 38 | * fog: 39 | * } 40 | */ 41 | /** 42 | * @classdesc mesh(网格)的Lambert(兰伯特)材质 43 | * @desc 表面有光泽的材质类型,计算每个像素) 44 | * @param {String} parameters 材质参数 45 | * @extends {THREE.Material} 46 | * @constructor 47 | */ 48 | THREE.MeshLambertMaterial = function ( parameters ) { 49 | 50 | THREE.Material.call( this ); 51 | /** 52 | * @default 'MeshLambertMaterial' 53 | * @type {string} 54 | */ 55 | this.type = 'MeshLambertMaterial'; 56 | /** 57 | * @desc 材质颜色 58 | * @default 0xffffff 白色 59 | * @type {THREE.Color} 60 | */ 61 | this.color = new THREE.Color( 0xffffff ); // diffuse 62 | /** 63 | * @desc 环境色 64 | * @default 0xffffff 白色 65 | * @type {THREE.Color} 66 | */ 67 | this.ambient = new THREE.Color( 0xffffff ); 68 | /** 69 | * @desc 自发光(荧光)颜色 70 | * @default 0x000000 黑色 71 | * @type {THREE.Color} 72 | */ 73 | this.emissive = new THREE.Color( 0x000000 ); 74 | /** 75 | * @desc 是否遮罩 76 | * @default 77 | * @type {boolean} 78 | */ 79 | this.wrapAround = false; 80 | /** 81 | * @desc 遮罩颜色 82 | * @default ( 1, 1, 1 ) 83 | * @type {THREE.Vector3} 84 | */ 85 | this.wrapRGB = new THREE.Vector3( 1, 1, 1 ); 86 | /** 87 | * @desc 纹理贴图 88 | * @default 89 | * @type {THREE.Texture} 90 | */ 91 | this.map = null; 92 | /** 93 | * @desc 光照贴图 94 | * @default 95 | * @type {THREE.Texture} 96 | */ 97 | this.lightMap = null; 98 | /** 99 | * @desc 高光贴图 100 | * @default 101 | * @type {THREE.Texture} 102 | */ 103 | this.specularMap = null; 104 | /** 105 | * @desc 透明贴图 106 | * @default 107 | * @type {THREE.Texture} 108 | */ 109 | this.alphaMap = null; 110 | /** 111 | * @desc 环境贴图 112 | * @default 113 | * @type {THREE.Texture} 114 | */ 115 | this.envMap = null; 116 | /** 117 | * @desc 材质混合模式 118 | * @default THREE.MultiplyOperation 119 | * @type {number} 120 | */ 121 | this.combine = THREE.MultiplyOperation; 122 | /** 123 | * @desc 反射率 124 | * @default 125 | * @type {float} 126 | */ 127 | this.reflectivity = 1; 128 | /** 129 | * @desc 折射率 130 | * @default 131 | * @type {float} 132 | */ 133 | this.refractionRatio = 0.98; 134 | 135 | /** 136 | * @desc 雾效,默认开启 137 | * @default 138 | * @type {boolean} 139 | */ 140 | this.fog = true; 141 | /** 142 | * @desc 着色方式
143 | * THREE.SmoothShading平滑着色:用多种颜色进行绘制
144 | * 每个顶点都是单独进行处理的,各顶点和各图元之间采用均匀插值。 145 | * @default 146 | * @type {number} 147 | */ 148 | this.shading = THREE.SmoothShading; 149 | 150 | /** 151 | * @desc 是否以线框方式渲染几何体 152 | * @default 153 | * @type {boolean} 154 | */ 155 | this.wireframe = false; 156 | /** 157 | * @desc 线框宽度 158 | * @default 159 | * @type {float} 160 | */ 161 | this.wireframeLinewidth = 1; 162 | /** 163 | * @desc 线框端点类型,参照LineBasicMaterial的定义 164 | * @default 'round' 165 | * @type {string} 166 | */ 167 | this.wireframeLinecap = 'round'; 168 | /** 169 | * @desc 线框连接类型,参照LineBasicMaterial的定义 170 | * @default 'round' 171 | * @type {string} 172 | */ 173 | this.wireframeLinejoin = 'round'; 174 | 175 | /** 176 | * @desc 材质顶点颜色 177 | * @default THREE.NoColors 178 | * @type {number} 179 | */ 180 | this.vertexColors = THREE.NoColors; 181 | 182 | /** 183 | * @desc 材质是否使用蒙皮 184 | * @default 185 | * @type {boolean} 186 | */ 187 | this.skinning = false; 188 | /** 189 | * @desc 材质是否设定目标变形动画 190 | * @default 191 | * @type {boolean} 192 | */ 193 | this.morphTargets = false; 194 | /** 195 | * @desc 材质是否反转(变换)法线 196 | * @default 197 | * @type {boolean} 198 | */ 199 | this.morphNormals = false; 200 | 201 | this.setValues( parameters ); 202 | 203 | }; 204 | /** 205 | * @desc MeshLambertMaterial对象从THREE.Material的原型继承所有属性方法 206 | * @type {THREE.Material} 207 | */ 208 | THREE.MeshLambertMaterial.prototype = Object.create( THREE.Material.prototype ); 209 | /** 210 | * @desc MeshLambertMaterial材质的克隆函数 211 | * @returns {THREE.MeshLambertMaterial} 212 | */ 213 | THREE.MeshLambertMaterial.prototype.clone = function () { 214 | 215 | var material = new THREE.MeshLambertMaterial(); 216 | 217 | THREE.Material.prototype.clone.call( this, material ); 218 | 219 | material.color.copy( this.color ); 220 | material.ambient.copy( this.ambient ); 221 | material.emissive.copy( this.emissive ); 222 | 223 | material.wrapAround = this.wrapAround; 224 | material.wrapRGB.copy( this.wrapRGB ); 225 | 226 | material.map = this.map; 227 | 228 | material.lightMap = this.lightMap; 229 | 230 | material.specularMap = this.specularMap; 231 | 232 | material.alphaMap = this.alphaMap; 233 | 234 | material.envMap = this.envMap; 235 | material.combine = this.combine; 236 | material.reflectivity = this.reflectivity; 237 | material.refractionRatio = this.refractionRatio; 238 | 239 | material.fog = this.fog; 240 | 241 | material.shading = this.shading; 242 | 243 | material.wireframe = this.wireframe; 244 | material.wireframeLinewidth = this.wireframeLinewidth; 245 | material.wireframeLinecap = this.wireframeLinecap; 246 | material.wireframeLinejoin = this.wireframeLinejoin; 247 | 248 | material.vertexColors = this.vertexColors; 249 | 250 | material.skinning = this.skinning; 251 | material.morphTargets = this.morphTargets; 252 | material.morphNormals = this.morphNormals; 253 | 254 | return material; 255 | 256 | }; 257 | -------------------------------------------------------------------------------- /materials/MeshNormalMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * 4 | * parameters = { 5 | * opacity: , 6 | * 7 | * shading: THREE.FlatShading, 8 | * blending: THREE.NormalBlending, 9 | * depthTest: , 10 | * depthWrite: , 11 | * 12 | * wireframe: , 13 | * wireframeLinewidth: 14 | * } 15 | */ 16 | /** 17 | * @classdesc mesh(网格)的标准材质类型 18 | * @param {String} parameters 材质参数 19 | * @extends {THREE.Material} 20 | * @constructor 21 | */ 22 | THREE.MeshNormalMaterial = function ( parameters ) { 23 | 24 | THREE.Material.call( this, parameters ); 25 | /** 26 | * @default 'FlatShading' 27 | * @type {string} 28 | */ 29 | this.type = 'MeshNormalMaterial'; 30 | 31 | /** 32 | * @desc 着色方式
33 | * THREE.SmoothShading平滑着色:用多种颜色进行绘制
34 | * 每个顶点都是单独进行处理的,各顶点和各图元之间采用均匀插值。 35 | * @default 36 | * @type {number} 37 | */ 38 | this.shading = THREE.SmoothShading; 39 | 40 | /** 41 | * @desc 是否以线框方式渲染几何体 42 | * @default 43 | * @type {boolean} 44 | */ 45 | this.wireframe = false; 46 | /** 47 | * @desc 线框宽度 48 | * @default 49 | * @type {float} 50 | */ 51 | this.wireframeLinewidth = 1; 52 | 53 | /** 54 | * @desc 材质是否设定目标变形动画 55 | * @default 56 | * @type {boolean} 57 | */ 58 | this.morphTargets = false; 59 | 60 | this.setValues( parameters ); 61 | 62 | }; 63 | /** 64 | * @desc MeshNormalMaterial对象从THREE.Material的原型继承所有属性方法 65 | * @type {THREE.Material} 66 | */ 67 | THREE.MeshNormalMaterial.prototype = Object.create( THREE.Material.prototype ); 68 | /** 69 | * @desc MeshNormalMaterial材质的克隆函数 70 | * @returns {THREE.MeshNormalMaterial} 71 | */ 72 | THREE.MeshNormalMaterial.prototype.clone = function () { 73 | 74 | var material = new THREE.MeshNormalMaterial(); 75 | 76 | THREE.Material.prototype.clone.call( this, material ); 77 | 78 | material.shading = this.shading; 79 | 80 | material.wireframe = this.wireframe; 81 | material.wireframeLinewidth = this.wireframeLinewidth; 82 | 83 | return material; 84 | 85 | }; 86 | -------------------------------------------------------------------------------- /materials/MeshPhongMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | * 5 | * parameters = { 6 | * color: , 7 | * ambient: , 8 | * emissive: , 9 | * specular: , 10 | * shininess: , 11 | * opacity: , 12 | * 13 | * map: new THREE.Texture( ), 14 | * 15 | * lightMap: new THREE.Texture( ), 16 | * 17 | * bumpMap: new THREE.Texture( ), 18 | * bumpScale: , 19 | * 20 | * normalMap: new THREE.Texture( ), 21 | * normalScale: , 22 | * 23 | * specularMap: new THREE.Texture( ), 24 | * 25 | * alphaMap: new THREE.Texture( ), 26 | * 27 | * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ), 28 | * combine: THREE.Multiply, 29 | * reflectivity: , 30 | * refractionRatio: , 31 | * 32 | * shading: THREE.SmoothShading, 33 | * blending: THREE.NormalBlending, 34 | * depthTest: , 35 | * depthWrite: , 36 | * 37 | * wireframe: , 38 | * wireframeLinewidth: , 39 | * 40 | * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, 41 | * 42 | * skinning: , 43 | * morphTargets: , 44 | * morphNormals: , 45 | * 46 | * fog: 47 | * } 48 | */ 49 | /** 50 | * @classdesc 高光材质类型 51 | * @desc mesh(网格)的phong(冯氏)高光材质类型
52 | * 表面有光泽的材质类型,计算每个像素 53 | * @param {String} parameters 材质参数 54 | * @extends {THREE.Material} 55 | * @constructor 56 | */ 57 | THREE.MeshPhongMaterial = function ( parameters ) { 58 | 59 | THREE.Material.call( this ); 60 | /** 61 | * @default 'MeshPhongMaterial' 62 | * @type {string} 63 | */ 64 | this.type = 'MeshPhongMaterial'; 65 | 66 | /** 67 | * @desc 材质颜色 68 | * @default 0xffffff 白色 69 | * @type {THREE.Color} 70 | */ 71 | this.color = new THREE.Color( 0xffffff ); // diffuse 72 | /** 73 | * @desc 环境色 74 | * @default 0xffffff 白色 75 | * @type {THREE.Color} 76 | */ 77 | this.ambient = new THREE.Color( 0xffffff ); 78 | /** 79 | * @desc 自发光(荧光)颜色 80 | * @default 0x000000 黑色 81 | * @type {THREE.Color} 82 | */ 83 | this.emissive = new THREE.Color( 0x000000 ); 84 | /** 85 | * @desc 高光色
86 | * 默认初始化为0x111111,灰色, 材质发光区域的颜色,
87 | * 比如设置为漫射颜色,亮度加大,材质更像金属,
88 | * 设成灰色,使材质更像塑料.默认是灰色的. 89 | * @default 0x111111 灰色 90 | * @type {THREE.Color} 91 | */ 92 | this.specular = new THREE.Color( 0x111111 ); 93 | /** 94 | * @desc 高光的强度,数值越大,高光呈现出一个亮点. 95 | * @default 96 | * @type {number} 97 | */ 98 | this.shininess = 30; 99 | /** 100 | * @desc 是否是金属 101 | * @default 102 | * @type {boolean} 103 | */ 104 | this.metal = false; 105 | 106 | /** 107 | * @desc 是否遮罩 108 | * @default 109 | * @type {boolean} 110 | */ 111 | this.wrapAround = false; 112 | /** 113 | * @desc 遮罩颜色 114 | * @default ( 1, 1, 1 ) 115 | * @type {THREE.Vector3} 116 | */ 117 | this.wrapRGB = new THREE.Vector3( 1, 1, 1 ); 118 | 119 | /** 120 | * @desc 纹理贴图 121 | * @default 122 | * @type {THREE.Texture} 123 | */ 124 | this.map = null; 125 | /** 126 | * @desc 光照贴图 127 | * @default 128 | * @type {THREE.Texture} 129 | */ 130 | this.lightMap = null; 131 | 132 | //所谓纯色的凹凸贴图就是如同浮雕效果一样的图像。其颜色与线框色相同。 133 | // 如果按默认色的话则为黑(白)色(即:黑色屏幕时为白色,白色背景时为黑色。) 134 | // 如下面的浮雕效果,就是白色线框绘出的立方体而凹凸贴图的。 135 | /** 136 | * @desc 凹凸贴图 137 | * @default 138 | * @type {THREE.Texture} 139 | */ 140 | this.bumpMap = null; 141 | /** 142 | * @desc 凹凸贴图的纹理大小. 143 | * @default 144 | * @type {float} 145 | */ 146 | this.bumpScale = 1; 147 | // 法线贴图就是在原物体的凹凸表面的每个点上均作法线, 148 | // 通过RGB颜色通道来标记法线的方向, 149 | // 你可以把它理解成与原凹凸表面平行的另一个不同的表面, 150 | // 但实际上它又只是一个光滑的平面。 151 | // 对于视觉效果而言,它的效率比原有的凹凸表面更高, 152 | // 若在特定位置上应用光源, 153 | // 可以让细节程度较低的表面生成高细节程度的精确光照方向和反射效果。 154 | /** 155 | * @desc 法线贴图 156 | * @default 157 | * @type {THREE.Texture} 158 | */ 159 | this.normalMap = null; 160 | /** 161 | * @desc 法线缩放,指定一个数值,将法线贴图与网格大小进行匹配. 162 | * @default ( 1, 1 ) 163 | * @type {THREE.Vector2} 164 | */ 165 | this.normalScale = new THREE.Vector2( 1, 1 ); 166 | 167 | /** 168 | * @desc 高光贴图 169 | * @default 170 | * @type {THREE.Texture} 171 | */ 172 | this.specularMap = null; 173 | /** 174 | * @desc 透明贴图 175 | * @default 176 | * @type {THREE.Texture} 177 | */ 178 | this.alphaMap = null; 179 | /** 180 | * @desc 环境贴图 181 | * @default 182 | * @type {THREE.Texture} 183 | */ 184 | this.envMap = null; 185 | /** 186 | * @desc 材质混合模式 187 | * @default THREE.MultiplyOperation 188 | * @type {number} 189 | */ 190 | this.combine = THREE.MultiplyOperation; 191 | /** 192 | * @desc 反射率 193 | * @default 194 | * @type {float} 195 | */ 196 | this.reflectivity = 1; 197 | /** 198 | * @desc 折射率 199 | * @default 200 | * @type {float} 201 | */ 202 | this.refractionRatio = 0.98; 203 | 204 | /** 205 | * @desc 雾效,默认开启 206 | * @default 207 | * @type {boolean} 208 | */ 209 | this.fog = true; 210 | 211 | /** 212 | * @desc 着色方式
213 | * THREE.SmoothShading平滑着色:用多种颜色进行绘制
214 | * 每个顶点都是单独进行处理的,各顶点和各图元之间采用均匀插值。 215 | * @default 216 | * @type {number} 217 | */ 218 | this.shading = THREE.SmoothShading; 219 | 220 | /** 221 | * @desc 是否以线框方式渲染几何体 222 | * @default 223 | * @type {boolean} 224 | */ 225 | this.wireframe = false; 226 | /** 227 | * @desc 线框宽度 228 | * @default 229 | * @type {float} 230 | */ 231 | this.wireframeLinewidth = 1; 232 | /** 233 | * @desc 线框端点类型,参照LineBasicMaterial的定义 234 | * @default 'round' 235 | * @type {string} 236 | */ 237 | this.wireframeLinecap = 'round'; 238 | /** 239 | * @desc 线框连接类型,参照LineBasicMaterial的定义 240 | * @default 'round' 241 | * @type {string} 242 | */ 243 | this.wireframeLinejoin = 'round'; 244 | 245 | /** 246 | * @desc 材质顶点颜色 247 | * @default THREE.NoColors 248 | * @type {number} 249 | */ 250 | this.vertexColors = THREE.NoColors; 251 | 252 | /** 253 | * @desc 材质是否使用蒙皮 254 | * @default 255 | * @type {boolean} 256 | */ 257 | this.skinning = false; 258 | /** 259 | * @desc 材质是否设定目标变形动画 260 | * @default 261 | * @type {boolean} 262 | */ 263 | this.morphTargets = false; 264 | /** 265 | * @desc 材质是否反转(变换)法线 266 | * @default 267 | * @type {boolean} 268 | */ 269 | this.morphNormals = false; 270 | 271 | this.setValues( parameters ); 272 | 273 | }; 274 | /** 275 | * @desc MeshPhongMaterial对象从THREE.Material的原型继承所有属性方法 276 | * @type {THREE.Material} 277 | */ 278 | THREE.MeshPhongMaterial.prototype = Object.create( THREE.Material.prototype ); 279 | /** 280 | * @desc MeshPhongMaterial材质的克隆函数 281 | * @returns {THREE.MeshPhongMaterial} 282 | */ 283 | THREE.MeshPhongMaterial.prototype.clone = function () { 284 | 285 | var material = new THREE.MeshPhongMaterial(); 286 | 287 | THREE.Material.prototype.clone.call( this, material ); 288 | 289 | material.color.copy( this.color ); 290 | material.ambient.copy( this.ambient ); 291 | material.emissive.copy( this.emissive ); 292 | material.specular.copy( this.specular ); 293 | material.shininess = this.shininess; 294 | 295 | material.metal = this.metal; 296 | 297 | material.wrapAround = this.wrapAround; 298 | material.wrapRGB.copy( this.wrapRGB ); 299 | 300 | material.map = this.map; 301 | 302 | material.lightMap = this.lightMap; 303 | 304 | material.bumpMap = this.bumpMap; 305 | material.bumpScale = this.bumpScale; 306 | 307 | material.normalMap = this.normalMap; 308 | material.normalScale.copy( this.normalScale ); 309 | 310 | material.specularMap = this.specularMap; 311 | 312 | material.alphaMap = this.alphaMap; 313 | 314 | material.envMap = this.envMap; 315 | material.combine = this.combine; 316 | material.reflectivity = this.reflectivity; 317 | material.refractionRatio = this.refractionRatio; 318 | 319 | material.fog = this.fog; 320 | 321 | material.shading = this.shading; 322 | 323 | material.wireframe = this.wireframe; 324 | material.wireframeLinewidth = this.wireframeLinewidth; 325 | material.wireframeLinecap = this.wireframeLinecap; 326 | material.wireframeLinejoin = this.wireframeLinejoin; 327 | 328 | material.vertexColors = this.vertexColors; 329 | 330 | material.skinning = this.skinning; 331 | material.morphTargets = this.morphTargets; 332 | material.morphNormals = this.morphNormals; 333 | 334 | return material; 335 | 336 | }; 337 | -------------------------------------------------------------------------------- /materials/PointCloudMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | * 5 | * parameters = { 6 | * color: , 7 | * opacity: , 8 | * map: new THREE.Texture( ), 9 | * 10 | * size: , 11 | * 12 | * blending: THREE.NormalBlending, 13 | * depthTest: , 14 | * depthWrite: , 15 | * 16 | * vertexColors: , 17 | * 18 | * fog: 19 | * } 20 | */ 21 | /** 22 | * @classdesc 点云(粒子系统)材质基类 23 | * @param {String} parameters 材质参数 24 | * @extends {THREE.Material} 25 | * @constructor 26 | */ 27 | THREE.PointCloudMaterial = function ( parameters ) { 28 | 29 | THREE.Material.call( this ); 30 | /** 31 | * @default 'PointCloudMaterial' 32 | * @type {string} 33 | */ 34 | this.type = 'PointCloudMaterial'; 35 | /** 36 | * @desc 材质颜色 37 | * @default 0xffffff 白色 38 | * @type {THREE.Color} 39 | */ 40 | this.color = new THREE.Color( 0xffffff ); 41 | /** 42 | * @desc 纹理贴图 43 | * @default 44 | * @type {THREE.Texture} 45 | */ 46 | this.map = null; 47 | /** 48 | * @desc 点云点大小 49 | * @default 50 | * @type {number} 51 | */ 52 | this.size = 1; 53 | /** 54 | * @desc 粒子是否衰减 55 | * @default 56 | * @type {boolean} 57 | */ 58 | this.sizeAttenuation = true; 59 | /** 60 | * @desc 材质顶点颜色 61 | * @default THREE.NoColors 62 | * @type {number} 63 | */ 64 | this.vertexColors = THREE.NoColors; 65 | /** 66 | * @desc 雾效,默认开启 67 | * @default 68 | * @type {boolean} 69 | */ 70 | this.fog = true; 71 | 72 | this.setValues( parameters ); 73 | 74 | }; 75 | /** 76 | * @desc PointCloudMaterial对象从THREE.Material的原型继承所有属性方法 77 | * @type {THREE.Material} 78 | */ 79 | THREE.PointCloudMaterial.prototype = Object.create( THREE.Material.prototype ); 80 | /** 81 | * @desc PointCloudMaterial材质的克隆函数 82 | * @returns {THREE.PointCloudMaterial} 83 | */ 84 | THREE.PointCloudMaterial.prototype.clone = function () { 85 | 86 | var material = new THREE.PointCloudMaterial(); 87 | 88 | THREE.Material.prototype.clone.call( this, material ); 89 | 90 | material.color.copy( this.color ); 91 | 92 | material.map = this.map; 93 | 94 | material.size = this.size; 95 | material.sizeAttenuation = this.sizeAttenuation; 96 | 97 | material.vertexColors = this.vertexColors; 98 | 99 | material.fog = this.fog; 100 | 101 | return material; 102 | 103 | }; 104 | 105 | // backwards compatibility 106 | /** 107 | * @ignore 108 | */ 109 | THREE.ParticleBasicMaterial = function ( parameters ) { 110 | 111 | console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointCloudMaterial.' ); 112 | return new THREE.PointCloudMaterial( parameters ); 113 | 114 | }; 115 | /** 116 | * @ignore 117 | */ 118 | THREE.ParticleSystemMaterial = function ( parameters ) { 119 | 120 | console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointCloudMaterial.' ); 121 | return new THREE.PointCloudMaterial( parameters ); 122 | 123 | }; 124 | -------------------------------------------------------------------------------- /materials/RawShaderMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | /** 5 | * @classdesc 自定义着色器材质类型 6 | * @desc 自定义着色器材质类型让用户扩充材质类型,有了无限的可能
7 | * 这个类和ShaderMaterial工作方式一样
8 | * 除了自定义的uniforms和attribute属性不会自动追加到GLSL着色器代码中 9 | * 表面有光泽的材质类型,计算每个像素 10 | * @param {String} parameters 材质参数 11 | * @extends {THREE.ShaderMaterial} 12 | * @constructor 13 | */ 14 | THREE.RawShaderMaterial = function ( parameters ) { 15 | 16 | THREE.ShaderMaterial.call( this, parameters ); 17 | /** 18 | * @default 'RawShaderMaterial' 19 | * @type {string} 20 | */ 21 | this.type = 'RawShaderMaterial'; 22 | 23 | }; 24 | /** 25 | * @desc RawShaderMaterial对象从THREE.Material的原型继承所有属性方法 26 | * @type {THREE.ShaderMaterial} 27 | */ 28 | THREE.RawShaderMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype ); 29 | /** 30 | * @desc RawShaderMaterial材质的克隆函数 31 | * @returns {THREE.RawShaderMaterial} 32 | */ 33 | THREE.RawShaderMaterial.prototype.clone = function () { 34 | 35 | var material = new THREE.RawShaderMaterial(); 36 | 37 | THREE.ShaderMaterial.prototype.clone.call( this, material ); 38 | 39 | return material; 40 | 41 | }; 42 | -------------------------------------------------------------------------------- /materials/ShaderMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * parameters = { 5 | * defines: { "label" : "value" }, 6 | * uniforms: { "parameter1": { type: "f", value: 1.0 }, "parameter2": { type: "i" value2: 2 } }, 7 | * 8 | * fragmentShader: , 9 | * vertexShader: , 10 | * 11 | * shading: THREE.SmoothShading, 12 | * blending: THREE.NormalBlending, 13 | * depthTest: , 14 | * depthWrite: , 15 | * 16 | * wireframe: , 17 | * wireframeLinewidth: , 18 | * 19 | * lights: , 20 | * 21 | * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, 22 | * 23 | * skinning: , 24 | * morphTargets: , 25 | * morphNormals: , 26 | * 27 | * fog: 28 | * } 29 | */ 30 | /** 31 | * @classdesc 自定义着色器创建材质类型 32 | * @desc 这样的材质对象让用户扩充材质类型,有了无限的可能 33 | * @param {String} parameters 材质参数 34 | * @extends {THREE.Material} 35 | * @constructor 36 | */ 37 | THREE.ShaderMaterial = function ( parameters ) { 38 | 39 | THREE.Material.call( this ); 40 | /** 41 | * @default 'ShaderMaterial' 42 | * @type {string} 43 | */ 44 | this.type = 'ShaderMaterial'; 45 | /** 46 | * @desc 用户自定义defines变量 47 | * @default 48 | * @type {*} 49 | */ 50 | this.defines = {}; 51 | /** 52 | * @desc 用户自定义uniforms变量 53 | * @default 54 | * @type {*} 55 | */ 56 | this.uniforms = {}; 57 | /** 58 | * @desc 用户自定义attributes变量 59 | * @default 60 | * @type {*} 61 | */ 62 | this.attributes = null; 63 | /** 64 | * @desc 自定义顶点着色器 65 | * @type {string} 66 | */ 67 | this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}'; 68 | /** 69 | * @desc 自定义片段着色器 70 | * @type {string} 71 | */ 72 | this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}'; 73 | /** 74 | * @desc 着色方式
75 | * THREE.SmoothShading平滑着色:用多种颜色进行绘制
76 | * 每个顶点都是单独进行处理的,各顶点和各图元之间采用均匀插值。 77 | * @default 78 | * @type {number} 79 | */ 80 | this.shading = THREE.SmoothShading; 81 | /** 82 | * @desc 线的宽度 83 | * @default 84 | * @type {float} 85 | */ 86 | this.linewidth = 1; 87 | /** 88 | * @desc 是否以线框方式渲染几何体 89 | * @default 90 | * @type {boolean} 91 | */ 92 | this.wireframe = false; 93 | /** 94 | * @desc 线框宽度 95 | * @default 96 | * @type {float} 97 | */ 98 | this.wireframeLinewidth = 1; 99 | /** 100 | * @desc 雾效,默认关闭 101 | * @default 102 | * @type {boolean} 103 | */ 104 | this.fog = false; // set to use scene fog 105 | /** 106 | * @desc 是否使用场景内的灯光,默认关闭 107 | * @default 108 | * @type {boolean} 109 | */ 110 | this.lights = false; // set to use scene lights 111 | /** 112 | * @desc 材质顶点颜色 113 | * @default THREE.NoColors 114 | * @type {number} 115 | */ 116 | this.vertexColors = THREE.NoColors; // set to use "color" attribute stream 117 | /** 118 | * @desc 材质是否使用蒙皮 119 | * @default 120 | * @type {boolean} 121 | */ 122 | this.skinning = false; // set to use skinning attribute streams 123 | 124 | /** 125 | * @desc 材质是否设定目标变形动画 126 | * @default 127 | * @type {boolean} 128 | */ 129 | this.morphTargets = false; 130 | /** 131 | * @desc 材质是否反转(变换)法线 132 | * @default 133 | * @type {boolean} 134 | */ 135 | this.morphNormals = false; 136 | 137 | // When rendered geometry doesn't include these attributes but the material does, 138 | // use these default values in WebGL. This avoids errors when buffer data is missing. 139 | // 当渲染几何体不包含这些属性,但是材质中包含,在WEBGL中使用这些默认的值,可以避免缓存数据丢失发生错误. 140 | /** 141 | * @des 默认渲染属性 142 | * @type {*} 143 | */ 144 | this.defaultAttributeValues = { 145 | 'color': [ 1, 1, 1 ], 146 | 'uv': [ 0, 0 ], 147 | 'uv2': [ 0, 0 ] 148 | }; 149 | /** 150 | * @desc 用来接收索引为0的属性 151 | * @type {String} 152 | */ 153 | this.index0AttributeName = undefined; 154 | 155 | this.setValues( parameters ); 156 | 157 | }; 158 | /** 159 | * @desc ShaderMaterial对象从THREE.Material的原型继承所有属性方法 160 | * @type {THREE.Material} 161 | */ 162 | THREE.ShaderMaterial.prototype = Object.create( THREE.Material.prototype ); 163 | /** 164 | * @desc ShaderMaterial材质的克隆函数 165 | * @returns {THREE.ShaderMaterial} 166 | */ 167 | THREE.ShaderMaterial.prototype.clone = function () { 168 | 169 | var material = new THREE.ShaderMaterial(); 170 | 171 | THREE.Material.prototype.clone.call( this, material ); 172 | 173 | material.fragmentShader = this.fragmentShader; 174 | material.vertexShader = this.vertexShader; 175 | 176 | material.uniforms = THREE.UniformsUtils.clone( this.uniforms ); 177 | 178 | material.attributes = this.attributes; 179 | material.defines = this.defines; 180 | 181 | material.shading = this.shading; 182 | 183 | material.wireframe = this.wireframe; 184 | material.wireframeLinewidth = this.wireframeLinewidth; 185 | 186 | material.fog = this.fog; 187 | 188 | material.lights = this.lights; 189 | 190 | material.vertexColors = this.vertexColors; 191 | 192 | material.skinning = this.skinning; 193 | 194 | material.morphTargets = this.morphTargets; 195 | material.morphNormals = this.morphNormals; 196 | 197 | return material; 198 | 199 | }; 200 | -------------------------------------------------------------------------------- /materials/SpriteMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * parameters = { 5 | * color: , 6 | * opacity: , 7 | * map: new THREE.Texture( ), 8 | * 9 | * blending: THREE.NormalBlending, 10 | * depthTest: , 11 | * depthWrite: , 12 | * 13 | * uvOffset: new THREE.Vector2(), 14 | * uvScale: new THREE.Vector2(), 15 | * 16 | * fog: 17 | * } 18 | */ 19 | /** 20 | * @desc Sprite(点精灵)的材质 21 | * @param {String} parameters 材质参数 22 | * @extends {THREE.Material} 23 | * @constructor 24 | */ 25 | THREE.SpriteMaterial = function ( parameters ) { 26 | 27 | THREE.Material.call( this ); 28 | /** 29 | * @default 'SpriteMaterial' 30 | * @type {string} 31 | */ 32 | this.type = 'SpriteMaterial'; 33 | /** 34 | * @desc 材质颜色 35 | * @default 0xffffff 白色 36 | * @type {THREE.Color} 37 | */ 38 | this.color = new THREE.Color( 0xffffff ); 39 | /** 40 | * @desc 纹理贴图 41 | * @default 42 | * @type {THREE.Texture} 43 | */ 44 | this.map = null; 45 | /** 46 | * @desc 旋转角度,粒子系统的贴图的旋转角度 47 | * @type {float} 48 | */ 49 | this.rotation = 0; 50 | /** 51 | * @desc 雾效,默认关闭 52 | * @default 53 | * @type {boolean} 54 | */ 55 | this.fog = false; 56 | 57 | // set parameters 58 | 59 | this.setValues( parameters ); 60 | 61 | }; 62 | 63 | THREE.SpriteMaterial.prototype = Object.create( THREE.Material.prototype ); 64 | 65 | THREE.SpriteMaterial.prototype.clone = function () { 66 | 67 | var material = new THREE.SpriteMaterial(); 68 | 69 | THREE.Material.prototype.clone.call( this, material ); 70 | 71 | material.color.copy( this.color ); 72 | material.map = this.map; 73 | 74 | material.rotation = this.rotation; 75 | 76 | material.fog = this.fog; 77 | 78 | return material; 79 | 80 | }; 81 | -------------------------------------------------------------------------------- /math/Box2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author bhouston / http://exocortex.com 3 | */ 4 | /** 5 | * @classdesc 2维矩形类 6 | * @param {THREE.Vector2} min 未定义则为无穷大 7 | * @param {THREE.Vector2} max 未定义则为无穷小 8 | * @constructor 9 | */ 10 | THREE.Box2 = function ( min, max ) { 11 | /** 12 | * @desc 最小值 13 | * @default ( Infinity, Infinity ) 14 | * @type {THREE.Vector2} 15 | */ 16 | this.min = ( min !== undefined ) ? min : new THREE.Vector2( Infinity, Infinity ); 17 | /** 18 | * @desc 最大值 19 | * @default ( - Infinity, - Infinity ) 20 | * @type {THREE.Vector2} 21 | */ 22 | this.max = ( max !== undefined ) ? max : new THREE.Vector2( - Infinity, - Infinity ); 23 | 24 | }; 25 | 26 | THREE.Box2.prototype = { 27 | 28 | constructor: THREE.Box2, 29 | /** 30 | * @desc 设置2维矩形 31 | * @param {THREE.Vector2} min 32 | * @param {THREE.Vector2} max 33 | * @returns {THREE.Box2} 34 | */ 35 | set: function ( min, max ) { 36 | 37 | this.min.copy( min ); 38 | this.max.copy( max ); 39 | 40 | return this; 41 | 42 | }, 43 | /** 44 | * @desc 2维坐标数组的外包围盒 45 | * @param {THREE.Vector2[]}points 46 | * @returns {THREE.Box2} 47 | */ 48 | setFromPoints: function ( points ) { 49 | 50 | this.makeEmpty(); 51 | 52 | for ( var i = 0, il = points.length; i < il; i ++ ) { 53 | 54 | this.expandByPoint( points[ i ] ) 55 | 56 | } 57 | 58 | return this; 59 | 60 | }, 61 | /** 62 | * @function 63 | * @desc 由中心点和边长设置2维矩形 64 | * @param {THREE.Vector2} center 中心点 65 | * @param {float} size 边长 66 | * @returns {THREE.Box2} 67 | */ 68 | setFromCenterAndSize: function () { 69 | 70 | var v1 = new THREE.Vector2(); 71 | 72 | return function ( center, size ) { 73 | 74 | var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); 75 | this.min.copy( center ).sub( halfSize ); 76 | this.max.copy( center ).add( halfSize ); 77 | 78 | return this; 79 | 80 | }; 81 | 82 | }(), 83 | /** 84 | * @desc 拷贝2维矩形 85 | * @param {THREE.Box2} box 86 | * @returns {THREE.Box2} 87 | */ 88 | copy: function ( box ) { 89 | 90 | this.min.copy( box.min ); 91 | this.max.copy( box.max ); 92 | 93 | return this; 94 | 95 | }, 96 | /** 97 | * @desc 设置无效2维矩形 98 | * @returns {THREE.Box2} 99 | */ 100 | makeEmpty: function () { 101 | 102 | this.min.x = this.min.y = Infinity; 103 | this.max.x = this.max.y = - Infinity; 104 | 105 | return this; 106 | 107 | }, 108 | /** 109 | * @desc 是否是无效2维矩形 110 | * @returns {boolean} 111 | */ 112 | empty: function () { 113 | 114 | // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes 115 | 116 | return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ); 117 | 118 | }, 119 | /** 120 | * @desc 获得2维矩形中心点 121 | * @param {THREE.Vector2} optionalTarget 122 | * @returns {THREE.Vector2} 123 | */ 124 | center: function ( optionalTarget ) { 125 | 126 | var result = optionalTarget || new THREE.Vector2(); 127 | return result.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); 128 | 129 | }, 130 | /** 131 | * @desc 获得2维矩形边界尺寸向量 132 | * @param {THREE.Vector2} optionalTarget 133 | * @returns {THREE.Vector2} 134 | */ 135 | size: function ( optionalTarget ) { 136 | 137 | var result = optionalTarget || new THREE.Vector2(); 138 | return result.subVectors( this.max, this.min ); 139 | 140 | }, 141 | /** 142 | * @desc 通过vector2对象(point参数)扩展二维矩形边界的最小值,最大值 143 | * @param {THREE.Vector2} point 144 | * @returns {THREE.Box2} 145 | */ 146 | expandByPoint: function ( point ) { 147 | 148 | this.min.min( point ); 149 | this.max.max( point ); 150 | 151 | return this; 152 | }, 153 | /** 154 | * @desc 通过Vector2对象(vector参数)扩展二维矩形边界的最小值,最大值 155 | * @param {THREE.Vector2} vector 156 | * @returns {THREE.Box2} 157 | */ 158 | expandByVector: function ( vector ) { 159 | 160 | this.min.sub( vector ); 161 | this.max.add( vector ); 162 | 163 | return this; 164 | }, 165 | /** 166 | * @desc 通过scalar值(scalar参数)扩展二维矩形边界的最小值,最大值 167 | * @param {float} scalar 168 | * @returns {THREE.Box2} 169 | */ 170 | expandByScalar: function ( scalar ) { 171 | 172 | this.min.addScalar( - scalar ); 173 | this.max.addScalar( scalar ); 174 | 175 | return this; 176 | }, 177 | /** 178 | * @desc 判断点是否在2维矩形内 179 | * @param {THREE.Vector2} point 180 | * @returns {boolean} 181 | */ 182 | containsPoint: function ( point ) { 183 | 184 | if ( point.x < this.min.x || point.x > this.max.x || 185 | point.y < this.min.y || point.y > this.max.y ) { 186 | 187 | return false; 188 | 189 | } 190 | 191 | return true; 192 | 193 | }, 194 | /** 195 | * @desc 判断box是否在当前2维矩形内 196 | * @param {THREE.Box2} box 197 | * @returns {boolean} 198 | */ 199 | containsBox: function ( box ) { 200 | 201 | if ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) && 202 | ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) ) { 203 | 204 | return true; 205 | 206 | } 207 | 208 | return false; 209 | 210 | }, 211 | /** 212 | * @desc 获得参数point(一个Vector2的二维点坐标)在当前二维矩形边界的高宽比 213 | * @param {THREE.Vector2} point 214 | * @param {THREE.Vector2} optionalTarget 215 | * @returns {THREE.Vector2} 216 | */ 217 | getParameter: function ( point, optionalTarget ) { 218 | 219 | // This can potentially have a divide by zero if the box 220 | // has a size dimension of 0. 221 | 222 | var result = optionalTarget || new THREE.Vector2(); 223 | 224 | return result.set( 225 | ( point.x - this.min.x ) / ( this.max.x - this.min.x ), 226 | ( point.y - this.min.y ) / ( this.max.y - this.min.y ) 227 | ); 228 | 229 | }, 230 | /** 231 | * @desc 判断box是否和当前2维矩形相交 232 | * @param {THREE.Box2} box 233 | * @returns {boolean} 234 | */ 235 | isIntersectionBox: function ( box ) { 236 | 237 | // using 6 splitting planes to rule out intersections. 238 | 239 | if ( box.max.x < this.min.x || box.min.x > this.max.x || 240 | box.max.y < this.min.y || box.min.y > this.max.y ) { 241 | 242 | return false; 243 | 244 | } 245 | 246 | return true; 247 | 248 | }, 249 | /** 250 | * @desc 限制参数point在二维矩形边界内.如果point小于min,返回min,如果大于max返回max,否则返回point 251 | * @param {THREE.Vector2} point 252 | * @param {THREE.Vector2} optionalTarget 253 | * @returns {THREE.Vector2} 254 | */ 255 | clampPoint: function ( point, optionalTarget ) { 256 | 257 | var result = optionalTarget || new THREE.Vector2(); 258 | return result.copy( point ).clamp( this.min, this.max ); 259 | 260 | }, 261 | /** 262 | * @function 263 | * @desc 边界内一点到最小边界,最大边界的长度 264 | * @param {THREE.Vector2} point 265 | * @return {THREE.Vector2} 266 | */ 267 | distanceToPoint: function () { 268 | 269 | var v1 = new THREE.Vector2(); 270 | 271 | return function ( point ) { 272 | 273 | var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); 274 | return clampedPoint.sub( point ).length(); 275 | 276 | }; 277 | 278 | }(), 279 | 280 | /** 281 | * @desc 获取box和当前box的相交矩形 282 | * @param {THREE.Box2} box 283 | * @returns {THREE.Box2} 284 | */ 285 | intersect: function ( box ) { 286 | 287 | this.min.max( box.min ); 288 | this.max.min( box.max ); 289 | 290 | return this; 291 | 292 | }, 293 | 294 | /** 295 | * @desc 获取box和当前box的相并矩形 296 | * @param {THREE.Box2} box 297 | * @returns {THREE.Box2} 298 | */ 299 | union: function ( box ) { 300 | 301 | this.min.min( box.min ); 302 | this.max.max( box.max ); 303 | 304 | return this; 305 | 306 | }, 307 | /** 308 | * @desc 2维矩形的平移 309 | * @param {float} offset 310 | * @returns {THREE.Box2} 311 | */ 312 | translate: function ( offset ) { 313 | 314 | this.min.add( offset ); 315 | this.max.add( offset ); 316 | 317 | return this; 318 | 319 | }, 320 | 321 | /** 322 | * @desc 判断box和当前2维矩形是否相等 323 | * @param {THREE.Box2} box 324 | * @returns {boolean} 325 | */ 326 | equals: function ( box ) { 327 | 328 | return box.min.equals( this.min ) && box.max.equals( this.max ); 329 | 330 | }, 331 | /** 332 | * @desc 克隆当前2维矩形 333 | * @returns {THREE.Box2} 334 | */ 335 | clone: function () { 336 | 337 | return new THREE.Box2().copy( this ); 338 | 339 | } 340 | 341 | }; 342 | -------------------------------------------------------------------------------- /math/Frustum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | * @author bhouston / http://exocortex.com 5 | */ 6 | /** 7 | * @classdesc 平截头体对象 8 | * @param {THREE.Plane} p0 9 | * @param {THREE.Plane} p1 10 | * @param {THREE.Plane} p2 11 | * @param {THREE.Plane} p3 12 | * @param {THREE.Plane} p4 13 | * @param {THREE.Plane} p5 14 | * @constructor 15 | */ 16 | THREE.Frustum = function ( p0, p1, p2, p3, p4, p5 ) { 17 | 18 | this.planes = [ 19 | 20 | ( p0 !== undefined ) ? p0 : new THREE.Plane(), 21 | ( p1 !== undefined ) ? p1 : new THREE.Plane(), 22 | ( p2 !== undefined ) ? p2 : new THREE.Plane(), 23 | ( p3 !== undefined ) ? p3 : new THREE.Plane(), 24 | ( p4 !== undefined ) ? p4 : new THREE.Plane(), 25 | ( p5 !== undefined ) ? p5 : new THREE.Plane() 26 | 27 | ]; 28 | 29 | }; 30 | 31 | THREE.Frustum.prototype = { 32 | 33 | constructor: THREE.Frustum, 34 | /** 35 | * @desc 设置平截头体对象 36 | * @param {THREE.Plane} p0 37 | * @param {THREE.Plane} p1 38 | * @param {THREE.Plane} p2 39 | * @param {THREE.Plane} p3 40 | * @param {THREE.Plane} p4 41 | * @param {THREE.Plane} p5 42 | * @returns {THREE.Frustum} 43 | */ 44 | set: function ( p0, p1, p2, p3, p4, p5 ) { 45 | 46 | var planes = this.planes; 47 | 48 | planes[ 0 ].copy( p0 ); 49 | planes[ 1 ].copy( p1 ); 50 | planes[ 2 ].copy( p2 ); 51 | planes[ 3 ].copy( p3 ); 52 | planes[ 4 ].copy( p4 ); 53 | planes[ 5 ].copy( p5 ); 54 | 55 | return this; 56 | 57 | }, 58 | /** 59 | * @desc 拷贝平截头体对象 60 | * @param {THREE.Frustum} frustum 61 | * @returns {THREE.Frustum} 62 | */ 63 | copy: function ( frustum ) { 64 | 65 | var planes = this.planes; 66 | 67 | for ( var i = 0; i < 6; i ++ ) { 68 | 69 | planes[ i ].copy( frustum.planes[ i ] ); 70 | 71 | } 72 | 73 | return this; 74 | 75 | }, 76 | /** 77 | * @desc 通过对当前平截头体应用变换,返回新的平截头体 78 | * @param {THREE.Matrix4} m 79 | * @returns {THREE.Frustum} 80 | */ 81 | setFromMatrix: function ( m ) { 82 | 83 | var planes = this.planes; 84 | var me = m.elements; 85 | var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ]; 86 | var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ]; 87 | var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ]; 88 | var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ]; 89 | 90 | planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize(); 91 | planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize(); 92 | planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize(); 93 | planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize(); 94 | planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize(); 95 | planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize(); 96 | 97 | return this; 98 | 99 | }, 100 | /** 101 | * @function 102 | * @desc 当前平截头体是否与参数object对象相交 103 | * @param {THREE.Object3D} object 104 | * @return {boolean} 105 | */ 106 | intersectsObject: function () { 107 | 108 | var sphere = new THREE.Sphere(); 109 | 110 | return function ( object ) { 111 | 112 | var geometry = object.geometry; 113 | 114 | if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); 115 | 116 | sphere.copy( geometry.boundingSphere ); 117 | sphere.applyMatrix4( object.matrixWorld ); 118 | 119 | return this.intersectsSphere( sphere ); 120 | 121 | }; 122 | 123 | }(), 124 | /** 125 | * @desc 当前平截头体是否与参数sphere球体对象相交 126 | * @param {THREE.Sphere} sphere 127 | * @returns {boolean} 128 | */ 129 | intersectsSphere: function ( sphere ) { 130 | 131 | var planes = this.planes; 132 | var center = sphere.center; 133 | var negRadius = - sphere.radius; 134 | 135 | for ( var i = 0; i < 6; i ++ ) { 136 | 137 | var distance = planes[ i ].distanceToPoint( center ); 138 | 139 | if ( distance < negRadius ) { 140 | 141 | return false; 142 | 143 | } 144 | 145 | } 146 | 147 | return true; 148 | 149 | }, 150 | /** 151 | * 152 | * @function 153 | * @desc 当前平截头体是否与参数box立方体对象相交 154 | * @param {THREE.Box3} box 155 | * @returns {boolean} 156 | */ 157 | intersectsBox: function () { 158 | 159 | var p1 = new THREE.Vector3(), 160 | p2 = new THREE.Vector3(); 161 | 162 | return function ( box ) { 163 | 164 | var planes = this.planes; 165 | 166 | for ( var i = 0; i < 6 ; i ++ ) { 167 | 168 | var plane = planes[ i ]; 169 | 170 | p1.x = plane.normal.x > 0 ? box.min.x : box.max.x; 171 | p2.x = plane.normal.x > 0 ? box.max.x : box.min.x; 172 | p1.y = plane.normal.y > 0 ? box.min.y : box.max.y; 173 | p2.y = plane.normal.y > 0 ? box.max.y : box.min.y; 174 | p1.z = plane.normal.z > 0 ? box.min.z : box.max.z; 175 | p2.z = plane.normal.z > 0 ? box.max.z : box.min.z; 176 | 177 | var d1 = plane.distanceToPoint( p1 ); 178 | var d2 = plane.distanceToPoint( p2 ); 179 | 180 | // if both outside plane, no intersection 181 | 182 | if ( d1 < 0 && d2 < 0 ) { 183 | 184 | return false; 185 | 186 | } 187 | } 188 | 189 | return true; 190 | }; 191 | 192 | }(), 193 | 194 | /** 195 | * @desc 参数point(一个Vector3的三维点坐标)是否在当前平截头体内 196 | * @param {THREE.Vector3} point 197 | * @returns {boolean} 198 | */ 199 | containsPoint: function ( point ) { 200 | 201 | var planes = this.planes; 202 | 203 | for ( var i = 0; i < 6; i ++ ) { 204 | 205 | if ( planes[ i ].distanceToPoint( point ) < 0 ) { 206 | 207 | return false; 208 | 209 | } 210 | 211 | } 212 | 213 | return true; 214 | 215 | }, 216 | /** 217 | * @desc 克隆当前平截头体 218 | * @returns {THREE.Frustum} 219 | */ 220 | clone: function () { 221 | 222 | return new THREE.Frustum().copy( this ); 223 | 224 | } 225 | 226 | }; 227 | -------------------------------------------------------------------------------- /math/Line3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author bhouston / http://exocortex.com 3 | */ 4 | /** 5 | * @classdesc 3维线段 6 | * @param {THREE.Vector3} start 7 | * @param {THREE.Vector3} end 8 | * @class 9 | * @example var start = new Vector3(0,0,0),end = new Vector3(1,1,1); var line = new Line3(start,end); 10 | */ 11 | THREE.Line3 = function ( start, end ) { 12 | /** 13 | * @desc 线段起点 14 | * @type {THREE.Vector3} 15 | */ 16 | this.start = ( start !== undefined ) ? start : new THREE.Vector3(); 17 | /** 18 | * @desc 线段终点 19 | * @type {THREE.Vector3} 20 | */ 21 | this.end = ( end !== undefined ) ? end : new THREE.Vector3(); 22 | 23 | }; 24 | 25 | THREE.Line3.prototype = { 26 | 27 | constructor: THREE.Line3, 28 | 29 | /** 30 | * @desc 根据start,end坐标值设置3维线段 31 | * @param {THREE.Vector3} start 32 | * @param {THREE.Vector3} end 33 | * @returns {THREE.Line3} 34 | */ 35 | set: function ( start, end ) { 36 | 37 | this.start.copy( start ); 38 | this.end.copy( end ); 39 | 40 | return this; 41 | 42 | }, 43 | /** 44 | * @desc 拷贝3维线段 45 | * @param {THREE.Line3} line 46 | * @returns {THREE.Line3} 47 | */ 48 | copy: function ( line ) { 49 | 50 | this.start.copy( line.start ); 51 | this.end.copy( line.end ); 52 | 53 | return this; 54 | 55 | }, 56 | 57 | /** 58 | * @desc 返回3维线段中点 59 | * @param {THREE.Line3} optionalTarget 60 | * @returns {THREE.Vector3} 61 | */ 62 | center: function ( optionalTarget ) { 63 | 64 | var result = optionalTarget || new THREE.Vector3(); 65 | return result.addVectors( this.start, this.end ).multiplyScalar( 0.5 ); 66 | 67 | }, 68 | 69 | /** 70 | * @desc 获得线段的向量 71 | * @param {THREE.Line3} optionalTarget 72 | * @returns {THREE.Vector3} 73 | */ 74 | delta: function ( optionalTarget ) { 75 | 76 | var result = optionalTarget || new THREE.Vector3(); 77 | return result.subVectors( this.end, this.start ); 78 | 79 | }, 80 | /** 81 | * @desc 获得当前三维线段起始点到端点的点积 82 | * @returns {float} 83 | */ 84 | distanceSq: function () { 85 | 86 | return this.start.distanceToSquared( this.end ); 87 | 88 | }, 89 | /** 90 | * @desc 获得当前三维线段起始点到端点的距离 91 | * @returns {float} 92 | */ 93 | distance: function () { 94 | 95 | return this.start.distanceTo( this.end ); 96 | 97 | }, 98 | /** 99 | * @desc 当前三维线段方向的任意向量
100 | * @param {float} t [0,1] 当t=0,返回起点向量,当t=1返回结束点向量 101 | * @param {THREE.Vector3} optionalTarget 102 | * @returns {THREE.Vector3} 103 | */ 104 | at: function ( t, optionalTarget ) { 105 | 106 | var result = optionalTarget || new THREE.Vector3(); 107 | 108 | return this.delta( result ).multiplyScalar( t ).add( this.start ); 109 | 110 | }, 111 | /** 112 | * @function 113 | * @desc 返回一个基于点投影到线段上点的参数(就是参数point投影到线段的位置) 114 | * @param {THREE.Vector3} point 115 | * @param {boolean} clampToLine 为true,那么返回值将是0和1之间 116 | * @return {float} 117 | */ 118 | closestPointToPointParameter: function () { 119 | 120 | var startP = new THREE.Vector3(); 121 | var startEnd = new THREE.Vector3(); 122 | 123 | return function ( point, clampToLine ) { 124 | 125 | startP.subVectors( point, this.start ); 126 | startEnd.subVectors( this.end, this.start ); 127 | 128 | var startEnd2 = startEnd.dot( startEnd ); 129 | var startEnd_startP = startEnd.dot( startP ); 130 | 131 | var t = startEnd_startP / startEnd2; 132 | 133 | if ( clampToLine ) { 134 | 135 | t = THREE.Math.clamp( t, 0, 1 ); 136 | 137 | } 138 | 139 | return t; 140 | 141 | }; 142 | 143 | }(), 144 | 145 | /** 146 | * @desc 返回一个基于点投影到线段上的向量 147 | * @param {THREE.Vector3} point 148 | * @param {boolean} clampToLine 为true,那么返回的向量在线段起始点和结束点之间。 149 | * @param {THREE.Vector3} optionalTarget 150 | * @returns {*|THREE.Vector3} 151 | */ 152 | closestPointToPoint: function ( point, clampToLine, optionalTarget ) { 153 | 154 | var t = this.closestPointToPointParameter( point, clampToLine ); 155 | 156 | var result = optionalTarget || new THREE.Vector3(); 157 | 158 | return this.delta( result ).multiplyScalar( t ).add( this.start ); 159 | 160 | }, 161 | /** 162 | * @desc 线段的起始点,结束点应用矩阵变换.达到旋转,缩放,移动的目的 163 | * @param {THREE.Matrix3} matrix 164 | * @returns {THREE.Line3} 165 | */ 166 | applyMatrix4: function ( matrix ) { 167 | 168 | this.start.applyMatrix4( matrix ); 169 | this.end.applyMatrix4( matrix ); 170 | 171 | return this; 172 | 173 | }, 174 | /** 175 | * @desc 3维线段等号 176 | * @param {THREE.Line3} line 177 | * @returns {boolean} 178 | */ 179 | equals: function ( line ) { 180 | 181 | return line.start.equals( this.start ) && line.end.equals( this.end ); 182 | 183 | }, 184 | 185 | /** 186 | * @desc 克隆3维线段 187 | * @returns {THREE.Line3} 188 | */ 189 | clone: function () { 190 | 191 | return new THREE.Line3().copy( this ); 192 | 193 | } 194 | 195 | }; 196 | -------------------------------------------------------------------------------- /math/Math.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author mrdoob / http://mrdoob.com/ 4 | */ 5 | /** 6 | * @classdesc 数学类 7 | * @desc 数学相关函数 8 | * @class 9 | */ 10 | THREE.Math = { 11 | 12 | /** 13 | * @function 14 | * @desc 生成36位的UUID 15 | * @return {char[]} 16 | */ 17 | generateUUID: function () { 18 | 19 | // http://www.broofa.com/Tools/Math.uuid.htm 20 | 21 | var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' ); 22 | var uuid = new Array( 36 ); 23 | var rnd = 0, r; 24 | 25 | return function () { 26 | 27 | for ( var i = 0; i < 36; i ++ ) { 28 | 29 | if ( i == 8 || i == 13 || i == 18 || i == 23 ) { 30 | 31 | uuid[ i ] = '-'; 32 | 33 | } else if ( i == 14 ) { 34 | 35 | uuid[ i ] = '4'; 36 | 37 | } else { 38 | 39 | if ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0; 40 | r = rnd & 0xf; 41 | rnd = rnd >> 4; 42 | uuid[ i ] = chars[ ( i == 19 ) ? ( r & 0x3 ) | 0x8 : r ]; 43 | 44 | } 45 | } 46 | 47 | return uuid.join( '' ); 48 | 49 | }; 50 | 51 | }(), 52 | 53 | // Clamp value to range 54 | 55 | /** 56 | * @desc 限制x的值在a和b之间
57 | * 如果x小于a,返回a。 如果x大于b,返回b,否则返回x 58 | * @param {float} x 59 | * @param {float} a 60 | * @param {float} b 61 | * @returns {float} 62 | */ 63 | clamp: function ( x, a, b ) { 64 | 65 | return ( x < a ) ? a : ( ( x > b ) ? b : x ); 66 | 67 | }, 68 | 69 | // Clamp value to range 72 | * 如果x小于a,返回a。 否则返回x 73 | * @param {float} x 74 | * @param {float} a 75 | * @returns {float} 76 | */ 77 | clampBottom: function ( x, a ) { 78 | 79 | return x < a ? a : x; 80 | 81 | }, 82 | 83 | // Linear mapping from range to range 84 | /** 85 | * @desc 参数x在range到range的线性映射 86 | * @param {float} x 87 | * @param {float} a1 88 | * @param {float} a2 89 | * @param {float} b1 90 | * @param {float} b2 91 | * @returns {*} 92 | */ 93 | mapLinear: function ( x, a1, a2, b1, b2 ) { 94 | 95 | return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 ); 96 | 97 | }, 98 | 99 | // http://en.wikipedia.org/wiki/Smoothstep 100 | 101 | /** 102 | * @desc 最小和最大值之间的插值,并在限制处渐入渐出。三次平滑插值 103 | * @param {float} x 104 | * @param {float} min 105 | * @param {float} max 106 | * @returns {float} 107 | */ 108 | smoothstep: function ( x, min, max ) { 109 | 110 | if ( x <= min ) return 0; 111 | if ( x >= max ) return 1; 112 | 113 | x = ( x - min ) / ( max - min ); 114 | 115 | return x * x * ( 3 - 2 * x ); 116 | 117 | }, 118 | /** 119 | * @desc 在最小和最大值之间的插值,并在限制处渐入渐出。五次平滑插值 120 | * @param {float} x 121 | * @param {float} min 122 | * @param {float} max 123 | * @returns {float} 124 | */ 125 | smootherstep: function ( x, min, max ) { 126 | 127 | if ( x <= min ) return 0; 128 | if ( x >= max ) return 1; 129 | 130 | x = ( x - min ) / ( max - min ); 131 | 132 | return x * x * x * ( x * ( x * 6 - 15 ) + 10 ); 133 | 134 | }, 135 | 136 | // Random float from <0, 1> with 16 bits of randomness 137 | // (standard Math.random() creates repetitive patterns when applied over larger space) 138 | 139 | /** 140 | * @desc 生成0,到1的随机浮点数,有16位大小选择范围 141 | * @returns {float} 142 | */ 143 | random16: function () { 144 | 145 | return ( 65280 * Math.random() + 255 * Math.random() ) / 65535; 146 | 147 | }, 148 | 149 | // Random integer from interval 150 | /** 151 | * @desc 通过参数low,high定义的取值范围生成随机整数 152 | * @param {number} vfhgplow 153 | * @param {number} vfhgphigh 154 | * @returns {number} 155 | */ 156 | randInt: function ( low, high ) { 157 | 158 | return low + Math.floor( Math.random() * ( high - low + 1 ) ); 159 | 160 | }, 161 | 162 | // Random float from interval 163 | /** 164 | * @desc 通过参数low,high定义的取值范围生成随机浮点数 165 | * @param {float} vfhgplow 166 | * @param {float} vfhgphigh 167 | * @returns {float} 168 | */ 169 | randFloat: function ( low, high ) { 170 | 171 | return low + Math.random() * ( high - low ); 172 | 173 | }, 174 | 175 | // Random float from <-range/2, range/2> interval 176 | 177 | /** 178 | * @desc 生成[-range/2,range/2]区间随机浮点数 179 | * @param {float} range 180 | * @returns {float} 181 | */ 182 | randFloatSpread: function ( range ) { 183 | 184 | return range * ( 0.5 - Math.random() ); 185 | 186 | }, 187 | 188 | /** 189 | * @function 190 | * @desc 角度转换弧度 191 | * @param {float} degrees 192 | * @return {float} 193 | */ 194 | degToRad: function () { 195 | 196 | var degreeToRadiansFactor = Math.PI / 180; 197 | 198 | return function ( degrees ) { 199 | 200 | return degrees * degreeToRadiansFactor; 201 | 202 | }; 203 | 204 | }(), 205 | /** 206 | * @function 207 | * @desc 弧度转换角度 208 | * @param {float} radians 209 | * @return {float} 210 | */ 211 | radToDeg: function () { 212 | 213 | var radianToDegreesFactor = 180 / Math.PI; 214 | 215 | return function ( radians ) { 216 | 217 | return radians * radianToDegreesFactor; 218 | 219 | }; 220 | 221 | }(), 222 | 223 | /** 224 | * @desc 是否2的幂,如果该值是2的幂,返回true 225 | * @param {number} value 226 | * @returns {boolean} 227 | */ 228 | isPowerOfTwo: function ( value ) { 229 | 230 | return ( value & ( value - 1 ) ) === 0 && value !== 0; 231 | 232 | } 233 | 234 | }; 235 | -------------------------------------------------------------------------------- /math/Matrix3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author WestLangley / http://github.com/WestLangley 4 | * @author bhouston / http://exocortex.com 5 | */ 6 | 7 | /** 8 | * @classdesc 3×3矩阵 9 | * @desc 行优先存储
10 | * 0 1 2
11 | * 3 4 5
12 | * 7 7 8 13 | * @class 14 | */ 15 | THREE.Matrix3 = function () { 16 | 17 | /** 18 | * @desc 矩阵内数组 19 | * @type {Float32Array} 20 | */ 21 | this.elements = new Float32Array( [ 22 | 23 | 1, 0, 0, 24 | 0, 1, 0, 25 | 0, 0, 1 26 | 27 | ] ); 28 | 29 | if ( arguments.length > 0 ) { 30 | 31 | console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); 32 | 33 | } 34 | 35 | }; 36 | 37 | THREE.Matrix3.prototype = { 38 | 39 | constructor: THREE.Matrix3, 40 | 41 | /** 42 | * @desc 设置3×3矩阵 43 | * @param {float} n11 44 | * @param {float} n12 45 | * @param {float} n13 46 | * @param {float} n21 47 | * @param {float} n22 48 | * @param {float} n23 49 | * @param {float} n31 50 | * @param {float} n32 51 | * @param {float} n33 52 | * @returns {THREE.Matrix3} 53 | */ 54 | set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { 55 | 56 | var te = this.elements; 57 | 58 | te[ 0 ] = n11; te[ 3 ] = n12; te[ 6 ] = n13; 59 | te[ 1 ] = n21; te[ 4 ] = n22; te[ 7 ] = n23; 60 | te[ 2 ] = n31; te[ 5 ] = n32; te[ 8 ] = n33; 61 | 62 | return this; 63 | 64 | }, 65 | 66 | /** 67 | * @desc 设置3×3单位矩阵 68 | * @returns {THREE.Matrix3} 69 | */ 70 | identity: function () { 71 | 72 | this.set( 73 | 74 | 1, 0, 0, 75 | 0, 1, 0, 76 | 0, 0, 1 77 | 78 | ); 79 | 80 | return this; 81 | 82 | }, 83 | 84 | /** 85 | * @desc 拷贝3×3矩阵 86 | * @param {THREE.Matrix3} m 87 | * @returns {THREE.Matrix3} 88 | */ 89 | copy: function ( m ) { 90 | 91 | var me = m.elements; 92 | 93 | this.set( 94 | 95 | me[ 0 ], me[ 3 ], me[ 6 ], 96 | me[ 1 ], me[ 4 ], me[ 7 ], 97 | me[ 2 ], me[ 5 ], me[ 8 ] 98 | 99 | ); 100 | 101 | return this; 102 | 103 | }, 104 | 105 | /** 106 | * @desc 3×3矩阵和3维向量乘法 107 | * @deprecated 改为 THREE.Vector3.applyMatrix3( matrix ) 108 | * @param {THREE.Vector3} vector 109 | * @returns {THREE.Vector3} 110 | */ 111 | multiplyVector3: function ( vector ) { 112 | 113 | console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); 114 | return vector.applyMatrix3( this ); 115 | 116 | }, 117 | /** 118 | * @desc 3×3矩阵和数组乘法 119 | * @deprecated 改为 THREE.Matrix3.applyToVector3Array( array ) 120 | * @param {float[]} a 121 | * @returns {float[]} 122 | */ 123 | multiplyVector3Array: function ( a ) { 124 | 125 | console.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); 126 | return this.applyToVector3Array( a ); 127 | 128 | }, 129 | /** 130 | * @function 131 | * @desc 3×3矩阵和数组乘法
132 | * 等于数据的每3个元素和矩阵相乘,结果存回数组 133 | * @param {float[]} array 134 | * @param {number} offset 起始位置,忽略则为0 135 | * @param {float} length 需要计算的长度,忽略则为数组长度 136 | * @returns {float[]} 137 | */ 138 | applyToVector3Array: function () { 139 | 140 | var v1 = new THREE.Vector3(); 141 | 142 | return function ( array, offset, length ) { 143 | 144 | if ( offset === undefined ) offset = 0; 145 | if ( length === undefined ) length = array.length; 146 | 147 | for ( var i = 0, j = offset, il; i < length; i += 3, j += 3 ) { 148 | 149 | v1.x = array[ j ]; 150 | v1.y = array[ j + 1 ]; 151 | v1.z = array[ j + 2 ]; 152 | 153 | v1.applyMatrix3( this ); 154 | 155 | array[ j ] = v1.x; 156 | array[ j + 1 ] = v1.y; 157 | array[ j + 2 ] = v1.z; 158 | 159 | } 160 | 161 | return array; 162 | 163 | }; 164 | 165 | }(), 166 | 167 | /** 168 | * @desc 3×3矩阵和标量乘法 169 | * @param {float} s 170 | * @returns {THREE.Matrix3} 171 | */ 172 | multiplyScalar: function ( s ) { 173 | 174 | var te = this.elements; 175 | 176 | te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; 177 | te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; 178 | te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; 179 | 180 | return this; 181 | 182 | }, 183 | 184 | /** 185 | * @desc 计算3×3矩阵的行列式
186 | * 几何意义:以基向量为边的平行六面体的有符号体积(可能为负) 187 | * @returns {float} 188 | */ 189 | determinant: function () { 190 | 191 | var te = this.elements; 192 | 193 | var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], 194 | d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], 195 | g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; 196 | 197 | return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; 198 | 199 | }, 200 | 201 | /** 202 | * @desc 计算3×3的逆矩阵
203 | * M*M-1 = 1v
204 | * v*M = v1 v1*M-1 = 205 | * @param {THREE.Matrix3} matrix 206 | * @param {number} throwOnInvertible 异常标志 207 | * @returns {THREE.Matrix3} 208 | */ 209 | getInverse: function ( matrix, throwOnInvertible ) { 210 | 211 | // input: THREE.Matrix4 212 | // ( based on http://code.google.com/p/webgl-mjs/ ) 213 | 214 | var me = matrix.elements; 215 | var te = this.elements; 216 | 217 | te[ 0 ] = me[ 10 ] * me[ 5 ] - me[ 6 ] * me[ 9 ]; 218 | te[ 1 ] = - me[ 10 ] * me[ 1 ] + me[ 2 ] * me[ 9 ]; 219 | te[ 2 ] = me[ 6 ] * me[ 1 ] - me[ 2 ] * me[ 5 ]; 220 | te[ 3 ] = - me[ 10 ] * me[ 4 ] + me[ 6 ] * me[ 8 ]; 221 | te[ 4 ] = me[ 10 ] * me[ 0 ] - me[ 2 ] * me[ 8 ]; 222 | te[ 5 ] = - me[ 6 ] * me[ 0 ] + me[ 2 ] * me[ 4 ]; 223 | te[ 6 ] = me[ 9 ] * me[ 4 ] - me[ 5 ] * me[ 8 ]; 224 | te[ 7 ] = - me[ 9 ] * me[ 0 ] + me[ 1 ] * me[ 8 ]; 225 | te[ 8 ] = me[ 5 ] * me[ 0 ] - me[ 1 ] * me[ 4 ]; 226 | 227 | var det = me[ 0 ] * te[ 0 ] + me[ 1 ] * te[ 3 ] + me[ 2 ] * te[ 6 ]; 228 | 229 | // no inverse 230 | 231 | if ( det === 0 ) { 232 | 233 | var msg = "Matrix3.getInverse(): can't invert matrix, determinant is 0"; 234 | 235 | if ( throwOnInvertible || false ) { 236 | 237 | throw new Error( msg ); 238 | 239 | } else { 240 | 241 | console.warn( msg ); 242 | 243 | } 244 | 245 | this.identity(); 246 | 247 | return this; 248 | 249 | } 250 | 251 | this.multiplyScalar( 1.0 / det ); 252 | 253 | return this; 254 | 255 | }, 256 | 257 | /** 258 | * @desc 计算3×3矩阵的转置矩阵
259 | * 几何意义: 矩阵的行列互换 260 | * @returns {THREE.Matrix3} 261 | */ 262 | transpose: function () { 263 | 264 | var tmp, m = this.elements; 265 | 266 | tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; 267 | tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; 268 | tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; 269 | 270 | return this; 271 | 272 | }, 273 | 274 | /** 275 | * @desc 3×3矩阵到数组 276 | * @param {float[]} array 277 | * @param {number} offset 偏移量 278 | * @returns {float[]} 279 | */ 280 | flattenToArrayOffset: function ( array, offset ) { 281 | 282 | var te = this.elements; 283 | 284 | array[ offset ] = te[ 0 ]; 285 | array[ offset + 1 ] = te[ 1 ]; 286 | array[ offset + 2 ] = te[ 2 ]; 287 | 288 | array[ offset + 3 ] = te[ 3 ]; 289 | array[ offset + 4 ] = te[ 4 ]; 290 | array[ offset + 5 ] = te[ 5 ]; 291 | 292 | array[ offset + 6 ] = te[ 6 ]; 293 | array[ offset + 7 ] = te[ 7 ]; 294 | array[ offset + 8 ] = te[ 8 ]; 295 | 296 | return array; 297 | 298 | }, 299 | 300 | /** 301 | * @desc 获得正规矩阵
302 | * 几何意义: 伴随矩阵,4维矩阵左上角的3×3矩阵 303 | * @param {THREE.Matrix4} m 304 | * @returns {THREE.Matrix3} 305 | */ 306 | getNormalMatrix: function ( m ) { 307 | 308 | // input: THREE.Matrix4 309 | 310 | this.getInverse( m ).transpose(); 311 | 312 | return this; 313 | 314 | }, 315 | 316 | /** 317 | * @desc 转置矩阵到数组 318 | * @param r 319 | * @returns {THREE.Matrix3} 320 | */ 321 | transposeIntoArray: function ( r ) { 322 | 323 | var m = this.elements; 324 | 325 | r[ 0 ] = m[ 0 ]; 326 | r[ 1 ] = m[ 3 ]; 327 | r[ 2 ] = m[ 6 ]; 328 | r[ 3 ] = m[ 1 ]; 329 | r[ 4 ] = m[ 4 ]; 330 | r[ 5 ] = m[ 7 ]; 331 | r[ 6 ] = m[ 2 ]; 332 | r[ 7 ] = m[ 5 ]; 333 | r[ 8 ] = m[ 8 ]; 334 | 335 | return this; 336 | 337 | }, 338 | 339 | /** 340 | * @desc 数组到3×3矩阵 341 | * @param {float[]} array 342 | * @returns {THREE.Matrix3} 343 | */ 344 | fromArray: function ( array ) { 345 | 346 | this.elements.set( array ); 347 | 348 | return this; 349 | 350 | }, 351 | 352 | /** 353 | * @desc 3×3矩阵到数组 354 | * @returns {float[]} 355 | */ 356 | toArray: function () { 357 | 358 | var te = this.elements; 359 | 360 | return [ 361 | te[ 0 ], te[ 1 ], te[ 2 ], 362 | te[ 3 ], te[ 4 ], te[ 5 ], 363 | te[ 6 ], te[ 7 ], te[ 8 ] 364 | ]; 365 | 366 | }, 367 | 368 | /** 369 | * @desc 克隆3×3矩阵 370 | * @returns {THREE.Matrix3} 371 | */ 372 | clone: function () { 373 | 374 | return new THREE.Matrix3().fromArray( this.elements ); 375 | 376 | } 377 | 378 | }; 379 | -------------------------------------------------------------------------------- /math/Plane.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author bhouston / http://exocortex.com 3 | */ 4 | /** 5 | * @classdesc 平面类 6 | * @desc 法线向量为normal,从原点到平面的距离为constant的无限延展的2维平面对象 7 | * @param {THREE.Vector3} normal 法线向量 8 | * @param {number} constant 原点到平面的距离 9 | * @constructor 10 | */ 11 | THREE.Plane = function ( normal, constant ) { 12 | /** 13 | * @desc 平面法线 14 | * @default (1,0,0) 15 | * @type {THREE.Vector3} 16 | */ 17 | this.normal = ( normal !== undefined ) ? normal : new THREE.Vector3( 1, 0, 0 ); 18 | /** 19 | * @desc 原点到平面的距离 20 | * @default 0 21 | * @type {float} 22 | */ 23 | this.constant = ( constant !== undefined ) ? constant : 0; 24 | 25 | }; 26 | 27 | THREE.Plane.prototype = { 28 | 29 | constructor: THREE.Plane, 30 | /** 31 | * @desc 根据 normal 和 constant 设置平面 32 | * @param {THREE.Vector3} normal 法线向量 33 | * @param {float} constant 原点到平面的距离 34 | * @returns {THREE.Plane} 35 | */ 36 | set: function ( normal, constant ) { 37 | 38 | this.normal.copy( normal ); 39 | this.constant = constant; 40 | 41 | return this; 42 | 43 | }, 44 | /** 45 | * @desc 过x,y,z,w分量重新设置二维平面 46 | * @param {float} x 平面法线向量x坐标 47 | * @param {float} y 平面法线向量y坐标 48 | * @param {float} z 平面法线向量z坐标 49 | * @param {float} w 二维平面离原点的距离 50 | * @returns {THREE.Plane} 51 | */ 52 | setComponents: function ( x, y, z, w ) { 53 | 54 | this.normal.set( x, y, z ); 55 | this.constant = w; 56 | 57 | return this; 58 | 59 | }, 60 | /** 61 | * @desc 通过参数normal(平面法线向量)和参数point(共面的点)重新设置二维平面 62 | * @param {THREE.Vector3} normal 63 | * @param {THREE.Vector3} point 64 | * @returns {THREE.Plane} 65 | */ 66 | setFromNormalAndCoplanarPoint: function ( normal, point ) { 67 | 68 | this.normal.copy( normal ); 69 | this.constant = - point.dot( this.normal ); // must be this.normal, not normal, as this.normal is normalized 70 | 71 | return this; 72 | 73 | }, 74 | 75 | /** 76 | * @function 77 | * @desc 通过共面的点a,b,c重新设置二维平面 78 | * @param {THREE.Vector3} a 79 | * @param {THREE.Vector3} b 80 | * @param {THREE.Vector3} c 81 | * @returns {THREE.Plane} 82 | */ 83 | setFromCoplanarPoints: function () { 84 | 85 | var v1 = new THREE.Vector3(); 86 | var v2 = new THREE.Vector3(); 87 | 88 | return function ( a, b, c ) { 89 | 90 | var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize(); 91 | 92 | // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? 93 | 94 | this.setFromNormalAndCoplanarPoint( normal, a ); 95 | 96 | return this; 97 | 98 | }; 99 | 100 | }(), 101 | 102 | /** 103 | * @desc 二维平面的拷贝 104 | * @param {THREE.Plane} plane 105 | * @returns {THREE.Plane} 106 | */ 107 | copy: function ( plane ) { 108 | 109 | this.normal.copy( plane.normal ); 110 | this.constant = plane.constant; 111 | 112 | return this; 113 | 114 | }, 115 | /** 116 | * @desc 二维平面的单位化
117 | * 几何意义:单位化法线向量,并调整constant常量的值 118 | * @returns {THREE.Plane} 119 | */ 120 | normalize: function () { 121 | 122 | // Note: will lead to a divide by zero if the plane is invalid. 123 | 124 | var inverseNormalLength = 1.0 / this.normal.length(); 125 | this.normal.multiplyScalar( inverseNormalLength ); 126 | this.constant *= inverseNormalLength; 127 | 128 | return this; 129 | 130 | }, 131 | /** 132 | * @desc 获得二维平面的负平面
133 | * 几何意义:获得二维平面的背面 134 | * @returns {THREE.Plane} 135 | */ 136 | negate: function () { 137 | 138 | this.constant *= - 1; 139 | this.normal.negate(); 140 | 141 | return this; 142 | 143 | }, 144 | /** 145 | * @desc 三维空间内一点到Plane二维平面对象表面的最小长度.
146 | * 几何意义:点到面上的投影等于从参数point到平面上的垂距 147 | * @param {THREE.Vector3} point 148 | * @returns {float} 149 | */ 150 | distanceToPoint: function ( point ) { 151 | 152 | return this.normal.dot( point ) + this.constant; 153 | 154 | }, 155 | /** 156 | * @desc 三维空间内球体到Plane二维平面对象表面的最小长度
157 | * 几何意义:球体到面上的投影等于从球体表面到平面上的最小垂距 158 | * @param {THREE.Sphere} sphere 159 | * @returns {float} 160 | */ 161 | distanceToSphere: function ( sphere ) { 162 | 163 | return this.distanceToPoint( sphere.center ) - sphere.radius; 164 | 165 | }, 166 | /** 167 | * @desc 三维空间中一点到当前平面的投影
168 | * 几何意义:点到面上的投影等于从参数point到平面上的垂足 169 | * @param {THREE.Vector3} point 170 | * @param {THREE.Vector3} optionalTarget 171 | * @returns {THREE.Vector3} 172 | */ 173 | projectPoint: function ( point, optionalTarget ) { 174 | 175 | return this.orthoPoint( point, optionalTarget ).sub( point ).negate(); 176 | 177 | }, 178 | 179 | /** 180 | * @desc 当前二维平面对象法线向量方向相同,与参数point到平面距离相等大小的向量
181 | * 几何意义:点到面上的投影等于从参数point到平面上的垂足向量 182 | * @param {THREE.Vector3} point 183 | * @param {THREE.Vector3} optionalTarget 184 | * @returns {THREE.Vector3} 185 | */ 186 | orthoPoint: function ( point, optionalTarget ) { 187 | 188 | var perpendicularMagnitude = this.distanceToPoint( point ); 189 | 190 | var result = optionalTarget || new THREE.Vector3(); 191 | return result.copy( this.normal ).multiplyScalar( perpendicularMagnitude ); 192 | 193 | }, 194 | /** 195 | * @desc 当前二维平面是否与参数line相交 196 | * @param {THREE.Line3} line 197 | * @returns {boolean} 198 | */ 199 | isIntersectionLine: function ( line ) { 200 | 201 | // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. 202 | 203 | var startSign = this.distanceToPoint( line.start ); 204 | var endSign = this.distanceToPoint( line.end ); 205 | 206 | return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); 207 | 208 | }, 209 | /** 210 | * @function 211 | * @desc 当前二维平面与参数line相交的交点 212 | * @param {THREE.Line3} line 213 | * @param {THREE.Vector3} optionalTarget 214 | * @return {THREE.Vector3} 215 | */ 216 | intersectLine: function () { 217 | 218 | var v1 = new THREE.Vector3(); 219 | 220 | return function ( line, optionalTarget ) { 221 | 222 | var result = optionalTarget || new THREE.Vector3(); 223 | 224 | var direction = line.delta( v1 ); 225 | 226 | var denominator = this.normal.dot( direction ); 227 | 228 | if ( denominator == 0 ) { 229 | 230 | // line is coplanar, return origin 231 | if ( this.distanceToPoint( line.start ) == 0 ) { 232 | 233 | return result.copy( line.start ); 234 | 235 | } 236 | 237 | // Unsure if this is the correct method to handle this case. 238 | return undefined; 239 | 240 | } 241 | 242 | var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; 243 | 244 | if ( t < 0 || t > 1 ) { 245 | 246 | return undefined; 247 | 248 | } 249 | 250 | return result.copy( direction ).multiplyScalar( t ).add( line.start ); 251 | 252 | }; 253 | 254 | }(), 255 | 256 | /** 257 | * @desc 当前二维平面的法线向量到当前二维平面投影点 258 | * @param {THREE.Vector3} optionalTarget 259 | * @returns {THREE.Vector3} 260 | */ 261 | coplanarPoint: function ( optionalTarget ) { 262 | 263 | var result = optionalTarget || new THREE.Vector3(); 264 | return result.copy( this.normal ).multiplyScalar( - this.constant ); 265 | 266 | }, 267 | /** 268 | * @function 269 | * @desc 通过传递matrix(旋转,缩放,移动等变换矩阵)对当前Plane二维平面对象的法线向量normal和,应用变换. 270 | * @param {THREE.Matrix4} matrix 271 | * @param {THREE.Matrix4} optionalNormalMatrix 若设置了,可以对法线变换 272 | * @return {THREE.Plane} 273 | */ 274 | applyMatrix4: function () { 275 | 276 | var v1 = new THREE.Vector3(); 277 | var v2 = new THREE.Vector3(); 278 | var m1 = new THREE.Matrix3(); 279 | 280 | return function ( matrix, optionalNormalMatrix ) { 281 | 282 | // compute new normal based on theory here: 283 | // http://www.songho.ca/opengl/gl_normaltransform.html 284 | var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix ); 285 | var newNormal = v1.copy( this.normal ).applyMatrix3( normalMatrix ); 286 | 287 | var newCoplanarPoint = this.coplanarPoint( v2 ); 288 | newCoplanarPoint.applyMatrix4( matrix ); 289 | 290 | this.setFromNormalAndCoplanarPoint( newNormal, newCoplanarPoint ); 291 | 292 | return this; 293 | 294 | }; 295 | 296 | }(), 297 | 298 | /** 299 | * @desc 移动当前二维平面的位置 300 | * @param {THREE.Vector3} offset 301 | * @returns {THREE.Plane} 302 | */ 303 | translate: function ( offset ) { 304 | 305 | this.constant = this.constant - offset.dot( this.normal ); 306 | 307 | return this; 308 | 309 | }, 310 | /** 311 | * @desc 判断二维平面是否相等 312 | * @param plane 313 | * @returns {boolean} 314 | */ 315 | equals: function ( plane ) { 316 | 317 | return plane.normal.equals( this.normal ) && ( plane.constant == this.constant ); 318 | 319 | }, 320 | /** 321 | * @desc 克隆二维平面 322 | * @returns {THREE.Plane} 323 | */ 324 | clone: function () { 325 | 326 | return new THREE.Plane().copy( this ); 327 | 328 | } 329 | 330 | }; 331 | -------------------------------------------------------------------------------- /math/Sphere.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author bhouston / http://exocortex.com 3 | * @author mrdoob / http://mrdoob.com/ 4 | */ 5 | /** 6 | * @classdesc 球体类 7 | * @desc center,半径为radius的球体 8 | * @param {THREE.Vector3} center 中心点坐标 9 | * @param {float} radius 半径 10 | * @constructor 11 | */ 12 | THREE.Sphere = function ( center, radius ) { 13 | /** 14 | * @desc 球体中心点 15 | * @type {THREE.Vector3} 16 | */ 17 | this.center = ( center !== undefined ) ? center : new THREE.Vector3(); 18 | /** 19 | * @desc 球体半径 20 | * @default 0 21 | * @type {float} 22 | */ 23 | this.radius = ( radius !== undefined ) ? radius : 0; 24 | 25 | }; 26 | 27 | THREE.Sphere.prototype = { 28 | 29 | constructor: THREE.Sphere, 30 | /** 31 | * @desc 根据圆心和半径设置球体 32 | * @param center 33 | * @param radius 34 | * @returns {THREE.Sphere} 35 | */ 36 | set: function ( center, radius ) { 37 | 38 | this.center.copy( center ); 39 | this.radius = radius; 40 | 41 | return this; 42 | }, 43 | /** 44 | * @function 45 | * @desc Vector3对象组成的points数组中的到圆心距离最大的值重新设置球体的半径 46 | * @param {THREE.Vector3[]} points 47 | * @param {THREE.Vector3} optionalCenter 球体中心 48 | * @returns {THREE.Sphere} 49 | */ 50 | setFromPoints: function () { 51 | 52 | var box = new THREE.Box3(); 53 | 54 | return function ( points, optionalCenter ) { 55 | 56 | var center = this.center; 57 | 58 | if ( optionalCenter !== undefined ) { 59 | 60 | center.copy( optionalCenter ); 61 | 62 | } else { 63 | 64 | box.setFromPoints( points ).center( center ); 65 | 66 | } 67 | 68 | var maxRadiusSq = 0; 69 | 70 | for ( var i = 0, il = points.length; i < il; i ++ ) { 71 | 72 | maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); 73 | 74 | } 75 | 76 | this.radius = Math.sqrt( maxRadiusSq ); 77 | 78 | return this; 79 | 80 | }; 81 | 82 | }(), 83 | 84 | /** 85 | * @desc 拷贝球体 86 | * @param {THREE.Sphere} sphere 87 | * @returns {THREE.Sphere} 88 | */ 89 | copy: function ( sphere ) { 90 | 91 | this.center.copy( sphere.center ); 92 | this.radius = sphere.radius; 93 | 94 | return this; 95 | 96 | }, 97 | /** 98 | * @desc 判断球体是否合法 99 | * @returns {boolean} 100 | */ 101 | empty: function () { 102 | 103 | return ( this.radius <= 0 ); 104 | 105 | }, 106 | 107 | /** 108 | * @desc 判断点是否在球体内 109 | * @param {THREE.Vector3} point 110 | * @returns {boolean} 111 | */ 112 | containsPoint: function ( point ) { 113 | 114 | return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); 115 | 116 | }, 117 | 118 | /** 119 | * @desc 点到球心的距离 120 | * @param {THREE.Vector3} point 121 | * @returns {float} 122 | */ 123 | distanceToPoint: function ( point ) { 124 | 125 | return ( point.distanceTo( this.center ) - this.radius ); 126 | 127 | }, 128 | /** 129 | * @desc 两个球体是否相交 130 | * @param {THREE.Sphere} sphere 131 | * @returns {boolean} 132 | */ 133 | intersectsSphere: function ( sphere ) { 134 | 135 | var radiusSum = this.radius + sphere.radius; 136 | 137 | return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); 138 | 139 | }, 140 | /** 141 | * @desc 根据点来重新定义球体半径
142 | * 如果point在球体外,强制将point设置到球体表面,如果point在球体内,重新设置球体半径为point到当前球体半径的距离 143 | * @param {THREE.Vector3} point 144 | * @param {THREE.Vector3} optionalTarget 145 | * @returns {THREE.Vector3} 146 | */ 147 | clampPoint: function ( point, optionalTarget ) { 148 | 149 | var deltaLengthSq = this.center.distanceToSquared( point ); 150 | 151 | var result = optionalTarget || new THREE.Vector3(); 152 | result.copy( point ); 153 | 154 | if ( deltaLengthSq > ( this.radius * this.radius ) ) { 155 | 156 | result.sub( this.center ).normalize(); 157 | result.multiplyScalar( this.radius ).add( this.center ); 158 | 159 | } 160 | 161 | return result; 162 | 163 | }, 164 | 165 | /** 166 | * @desc 计算球体的外包围盒 167 | * @param {THREE.Box3} optionalTarget 168 | * @returns {THREE.Box3} 169 | */ 170 | getBoundingBox: function ( optionalTarget ) { 171 | 172 | var box = optionalTarget || new THREE.Box3(); 173 | 174 | box.set( this.center, this.center ); 175 | box.expandByScalar( this.radius ); 176 | 177 | return box; 178 | 179 | }, 180 | /** 181 | * @desc 球体的投影变换
182 | * 平移相对于球心,缩放相对于半径 183 | * @param {THREE.Matrix4} matrix 184 | * @returns {THREE.Sphere} 185 | */ 186 | applyMatrix4: function ( matrix ) { 187 | 188 | this.center.applyMatrix4( matrix ); 189 | this.radius = this.radius * matrix.getMaxScaleOnAxis(); 190 | 191 | return this; 192 | 193 | }, 194 | /** 195 | * @desc 球体平移 196 | * @param {THREE.Vector3} offset 197 | * @returns {THREE.Sphere} 198 | */ 199 | translate: function ( offset ) { 200 | 201 | this.center.add( offset ); 202 | 203 | return this; 204 | 205 | }, 206 | /** 207 | * @desc 球体是否相等 208 | * @param {THREE.Sphere} sphere 209 | * @returns {boolean} 210 | */ 211 | equals: function ( sphere ) { 212 | 213 | return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); 214 | 215 | }, 216 | 217 | /** 218 | * @desc 球体克隆 219 | * @returns {THREE.Sphere} 220 | */ 221 | clone: function () { 222 | 223 | return new THREE.Sphere().copy( this ); 224 | 225 | } 226 | 227 | }; 228 | -------------------------------------------------------------------------------- /math/Spline.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Spline from Tween.js, slightly optimized (and trashed) 3 | * http://sole.github.com/tween.js/examples/05_spline.html 4 | * 5 | * @author mrdoob / http://mrdoob.com/ 6 | * @author alteredq / http://alteredqualia.com/ 7 | */ 8 | /** 9 | * @classdesc 曲线对象类 10 | * @desc 由Vector3数组(points)组成的曲线 11 | * @param {THREE.Vector3[]} points 12 | * @constructor 13 | */ 14 | THREE.Spline = function ( points ) { 15 | /** 16 | * @desc 曲线控制点 17 | * @type {THREE.Vector3[]} 18 | */ 19 | this.points = points; 20 | 21 | var c = [], v3 = { x: 0, y: 0, z: 0 }, 22 | point, intPoint, weight, w2, w3, 23 | pa, pb, pc, pd; 24 | 25 | /** 26 | * @desc 从数组初始化曲线 27 | * @param {THREE.Vector3} a 28 | */ 29 | this.initFromArray = function ( a ) { 30 | 31 | this.points = []; 32 | 33 | for ( var i = 0; i < a.length; i ++ ) { 34 | 35 | this.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] }; 36 | 37 | } 38 | 39 | }; 40 | /** 41 | * @desc 当前样条曲线作为一个整体,返回位于当前样条曲线k位置上的点坐标. 42 | * @param {float} k 43 | * @returns {{x: float, y: float, z: float}} 44 | */ 45 | this.getPoint = function ( k ) { 46 | 47 | point = ( this.points.length - 1 ) * k; 48 | intPoint = Math.floor( point ); 49 | weight = point - intPoint; 50 | 51 | c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1; 52 | c[ 1 ] = intPoint; 53 | c[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1; 54 | c[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2; 55 | 56 | pa = this.points[ c[ 0 ] ]; 57 | pb = this.points[ c[ 1 ] ]; 58 | pc = this.points[ c[ 2 ] ]; 59 | pd = this.points[ c[ 3 ] ]; 60 | 61 | w2 = weight * weight; 62 | w3 = weight * w2; 63 | 64 | v3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 ); 65 | v3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 ); 66 | v3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 ); 67 | 68 | return v3; 69 | 70 | }; 71 | 72 | /** 73 | * @desc 返回当前样条曲线节点坐标构成的数组 74 | * @returns {THREE.Vector3[]} 75 | */ 76 | this.getControlPointsArray = function () { 77 | 78 | var i, p, l = this.points.length, 79 | coords = []; 80 | 81 | for ( i = 0; i < l; i ++ ) { 82 | 83 | p = this.points[ i ]; 84 | coords[ i ] = [ p.x, p.y, p.z ]; 85 | 86 | } 87 | 88 | return coords; 89 | 90 | }; 91 | 92 | // approximate length by summing linear segments 93 | /** 94 | * @desc 被参数nSubDivisions(将当前样条曲线等分成多少段)等分当前样条曲线的长度数组和总长度组成的对象. 95 | * @param {number} nSubDivisions 96 | * @returns {{chunks: Array, total: number}} 97 | */ 98 | this.getLength = function ( nSubDivisions ) { 99 | 100 | var i, index, nSamples, position, 101 | point = 0, intPoint = 0, oldIntPoint = 0, 102 | oldPosition = new THREE.Vector3(), 103 | tmpVec = new THREE.Vector3(), 104 | chunkLengths = [], 105 | totalLength = 0; 106 | 107 | // first point has 0 length 108 | 109 | chunkLengths[ 0 ] = 0; 110 | 111 | if ( ! nSubDivisions ) nSubDivisions = 100; 112 | 113 | nSamples = this.points.length * nSubDivisions; 114 | 115 | oldPosition.copy( this.points[ 0 ] ); 116 | 117 | for ( i = 1; i < nSamples; i ++ ) { 118 | 119 | index = i / nSamples; 120 | 121 | position = this.getPoint( index ); 122 | tmpVec.copy( position ); 123 | 124 | totalLength += tmpVec.distanceTo( oldPosition ); 125 | 126 | oldPosition.copy( position ); 127 | 128 | point = ( this.points.length - 1 ) * index; 129 | intPoint = Math.floor( point ); 130 | 131 | if ( intPoint != oldIntPoint ) { 132 | 133 | chunkLengths[ intPoint ] = totalLength; 134 | oldIntPoint = intPoint; 135 | 136 | } 137 | 138 | } 139 | 140 | // last point ends with total length 141 | 142 | chunkLengths[ chunkLengths.length ] = totalLength; 143 | 144 | return { chunks: chunkLengths, total: totalLength }; 145 | 146 | }; 147 | 148 | this.reparametrizeByArcLength = function ( samplingCoef ) { 149 | 150 | var i, j, 151 | index, indexCurrent, indexNext, 152 | linearDistance, realDistance, 153 | sampling, position, 154 | newpoints = [], 155 | tmpVec = new THREE.Vector3(), 156 | sl = this.getLength(); 157 | 158 | newpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() ); 159 | 160 | for ( i = 1; i < this.points.length; i ++ ) { 161 | 162 | //tmpVec.copy( this.points[ i - 1 ] ); 163 | //linearDistance = tmpVec.distanceTo( this.points[ i ] ); 164 | 165 | realDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ]; 166 | 167 | sampling = Math.ceil( samplingCoef * realDistance / sl.total ); 168 | 169 | indexCurrent = ( i - 1 ) / ( this.points.length - 1 ); 170 | indexNext = i / ( this.points.length - 1 ); 171 | 172 | for ( j = 1; j < sampling - 1; j ++ ) { 173 | 174 | index = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent ); 175 | 176 | position = this.getPoint( index ); 177 | newpoints.push( tmpVec.copy( position ).clone() ); 178 | 179 | } 180 | 181 | newpoints.push( tmpVec.copy( this.points[ i ] ).clone() ); 182 | 183 | } 184 | 185 | this.points = newpoints; 186 | 187 | }; 188 | 189 | // Catmull-Rom 190 | 191 | /** 192 | * @desc 三次样条插值算法,返回计算位于参数值t的曲线点 193 | * @param {float} p0 样条曲线起始点p0 194 | * @param {float} p1 样条曲线起始点p1 195 | * @param {float} p2 样条曲线起始点p2 196 | * @param {float} p3 样条曲线起始点p3 197 | * @param {float} t 参数值 (0,1) 198 | * @param {float} t2 参数值t的平方 199 | * @param {float} t3 参数值t的立方 200 | * @returns {float} 计算位于参数值t的曲线点 201 | */ 202 | function interpolate( p0, p1, p2, p3, t, t2, t3 ) { 203 | 204 | var v0 = ( p2 - p0 ) * 0.5, 205 | v1 = ( p3 - p1 ) * 0.5; 206 | 207 | return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1; 208 | 209 | }; 210 | 211 | }; 212 | -------------------------------------------------------------------------------- /math/Triangle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author bhouston / http://exocortex.com 3 | * @author mrdoob / http://mrdoob.com/ 4 | */ 5 | /** 6 | * @classdesc 三角形类 7 | * @desc 由a,b,c三个向量组成的三角形 8 | * @param {THREE.Vector3} a 9 | * @param {THREE.Vector3} b 10 | * @param {THREE.Vector3} c 11 | * @constructor 12 | */ 13 | THREE.Triangle = function ( a, b, c ) { 14 | /** 15 | * 16 | * @type {THREE.Vector3} 17 | */ 18 | this.a = ( a !== undefined ) ? a : new THREE.Vector3(); 19 | /** 20 | * 21 | * @type {THREE.Vector3} 22 | */ 23 | this.b = ( b !== undefined ) ? b : new THREE.Vector3(); 24 | /** 25 | * 26 | * @type {THREE.Vector3} 27 | */ 28 | this.c = ( c !== undefined ) ? c : new THREE.Vector3(); 29 | 30 | }; 31 | /** 32 | * @function 33 | * @desc 计算三角形的法线向量 34 | * @param {THREE.Vector3} a 35 | * @param {THREE.Vector3} b 36 | * @param {THREE.Vector3} c 37 | * @param {THREE.Vector3} optionalTarget 38 | * @return {THREE.Vector3} 39 | */ 40 | THREE.Triangle.normal = function () { 41 | 42 | var v0 = new THREE.Vector3(); 43 | 44 | return function ( a, b, c, optionalTarget ) { 45 | 46 | var result = optionalTarget || new THREE.Vector3(); 47 | 48 | result.subVectors( c, b ); 49 | v0.subVectors( a, b ); 50 | result.cross( v0 ); 51 | 52 | var resultLengthSq = result.lengthSq(); 53 | if ( resultLengthSq > 0 ) { 54 | 55 | return result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) ); 56 | 57 | } 58 | 59 | return result.set( 0, 0, 0 ); 60 | 61 | }; 62 | 63 | }(); 64 | 65 | // static/instance method to calculate barycoordinates 66 | // based on: http://www.blackpawn.com/texts/pointinpoly/default.html 67 | /** 68 | * @function 69 | * @desc 算返回参数a,b,c所组成的三角形所在的平面上任意点(参数point)所表示三角形顶点的加权平均值
70 | * 这个权值就是重心坐标 71 | * @param {THREE.Vector3} point 三角平面上任意点 72 | * @param {THREE.Vector3} a 73 | * @param {THREE.Vector3} b 74 | * @param {THREE.Vector3} c 75 | * @param {THREE.Vector3} optionalTarget 76 | */ 77 | THREE.Triangle.barycoordFromPoint = function () { 78 | 79 | var v0 = new THREE.Vector3(); 80 | var v1 = new THREE.Vector3(); 81 | var v2 = new THREE.Vector3(); 82 | 83 | return function ( point, a, b, c, optionalTarget ) { 84 | 85 | v0.subVectors( c, a ); 86 | v1.subVectors( b, a ); 87 | v2.subVectors( point, a ); 88 | 89 | var dot00 = v0.dot( v0 ); 90 | var dot01 = v0.dot( v1 ); 91 | var dot02 = v0.dot( v2 ); 92 | var dot11 = v1.dot( v1 ); 93 | var dot12 = v1.dot( v2 ); 94 | 95 | var denom = ( dot00 * dot11 - dot01 * dot01 ); 96 | 97 | var result = optionalTarget || new THREE.Vector3(); 98 | 99 | // colinear or singular triangle 100 | if ( denom == 0 ) { 101 | // arbitrary location outside of triangle? 102 | // not sure if this is the best idea, maybe should be returning undefined 103 | return result.set( - 2, - 1, - 1 ); 104 | } 105 | 106 | var invDenom = 1 / denom; 107 | var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; 108 | var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; 109 | 110 | // barycoordinates must always sum to 1 111 | return result.set( 1 - u - v, v, u ); 112 | 113 | }; 114 | 115 | }(); 116 | 117 | /** 118 | * @function 119 | * @desc 判断任意点(参数point)是否在a,b,c所组成的三角形内 120 | * @param {THREE.Vector3} point 三角平面上任意点 121 | * @param {THREE.Vector3} a 122 | * @param {THREE.Vector3} b 123 | * @param {THREE.Vector3} c 124 | * @return {boolean} 125 | */ 126 | THREE.Triangle.containsPoint = function () { 127 | 128 | var v1 = new THREE.Vector3(); 129 | 130 | return function ( point, a, b, c ) { 131 | 132 | var result = THREE.Triangle.barycoordFromPoint( point, a, b, c, v1 ); 133 | 134 | return ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 ); 135 | 136 | }; 137 | 138 | }(); 139 | 140 | THREE.Triangle.prototype = { 141 | 142 | constructor: THREE.Triangle, 143 | /** 144 | * @desc 设置三角平面 145 | * @param {THREE.Vector3} a 146 | * @param {THREE.Vector3} b 147 | * @param {THREE.Vector3} c 148 | * @returns {THREE.Triangle} 149 | */ 150 | set: function ( a, b, c ) { 151 | 152 | this.a.copy( a ); 153 | this.b.copy( b ); 154 | this.c.copy( c ); 155 | 156 | return this; 157 | 158 | }, 159 | 160 | /** 161 | * @desc 通过数组和索引设置三角平面 162 | * @param {THREE.Vector3[]} points 163 | * @param {float} i0 164 | * @param {float} i1 165 | * @param {float} i2 166 | * @returns {THREE.Triangle} 167 | */ 168 | setFromPointsAndIndices: function ( points, i0, i1, i2 ) { 169 | 170 | this.a.copy( points[ i0 ] ); 171 | this.b.copy( points[ i1 ] ); 172 | this.c.copy( points[ i2 ] ); 173 | 174 | return this; 175 | 176 | }, 177 | 178 | /** 179 | * @desc 拷贝三角平面 180 | * @param {THREE.Triangle} triangle 181 | * @returns {THREE.Triangle} 182 | */ 183 | copy: function ( triangle ) { 184 | 185 | this.a.copy( triangle.a ); 186 | this.b.copy( triangle.b ); 187 | this.c.copy( triangle.c ); 188 | 189 | return this; 190 | 191 | }, 192 | 193 | /** 194 | * @function 195 | * @desc 计算三角形面他积 196 | * @return {float} 197 | */ 198 | area: function () { 199 | 200 | var v0 = new THREE.Vector3(); 201 | var v1 = new THREE.Vector3(); 202 | 203 | return function () { 204 | 205 | v0.subVectors( this.c, this.b ); 206 | v1.subVectors( this.a, this.b ); 207 | 208 | return v0.cross( v1 ).length() * 0.5; 209 | 210 | }; 211 | 212 | }(), 213 | 214 | /** 215 | * @desc 计算三角形中心 216 | * @param {THREE.Vector3} optionalTarget 217 | * @returns {THREE.Vector3} 218 | */ 219 | midpoint: function ( optionalTarget ) { 220 | 221 | var result = optionalTarget || new THREE.Vector3(); 222 | return result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); 223 | 224 | }, 225 | 226 | /** 227 | * @desc 计算三角形的法向量 228 | * @param {THREE.Vector3} optionalTarget 229 | * @returns {THREE.Vector3} 230 | */ 231 | normal: function ( optionalTarget ) { 232 | 233 | return THREE.Triangle.normal( this.a, this.b, this.c, optionalTarget ); 234 | 235 | }, 236 | /** 237 | * @desc 创建三角形共面的平面Plane对象 238 | * @param {THREE.Plane} optionalTarget 239 | * @returns {THREE.Plane} 240 | */ 241 | plane: function ( optionalTarget ) { 242 | 243 | var result = optionalTarget || new THREE.Plane(); 244 | 245 | return result.setFromCoplanarPoints( this.a, this.b, this.c ); 246 | 247 | }, 248 | 249 | /** 250 | * @desc 计算返回当前三角形所在的平面上任意点(参数point)所表示当前三角形顶点的加权平均值
251 | * 这个权值就是重心坐标 252 | * @param {THREE.Vector3} point 253 | * @param {THREE.Vector3} optionalTarget 254 | * @returns {THREE.Vector3} 255 | */ 256 | barycoordFromPoint: function ( point, optionalTarget ) { 257 | 258 | return THREE.Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget ); 259 | 260 | }, 261 | 262 | /** 263 | * @desc 计算点是否在三角形内 264 | * @param {THREE.Vector3} point 265 | * @returns {boolean} 266 | */ 267 | containsPoint: function ( point ) { 268 | 269 | return THREE.Triangle.containsPoint( point, this.a, this.b, this.c ); 270 | 271 | }, 272 | 273 | /** 274 | * @desc 计算三角形是否相等 275 | * @param {THREE.Triangle} triangle 276 | * @returns {boolean} 277 | */ 278 | equals: function ( triangle ) { 279 | 280 | return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); 281 | 282 | }, 283 | 284 | /** 285 | * @desc 克隆三角形 286 | * @returns {THREE.Triangle} 287 | */ 288 | clone: function () { 289 | 290 | return new THREE.Triangle().copy( this ); 291 | 292 | } 293 | 294 | }; 295 | -------------------------------------------------------------------------------- /objects/Line.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | /** 5 | * @classdesc 线对象 6 | * @desc WebGL中好像线不能设置宽度 7 | * @param {THREE.Geometry} geometry 几何信息 8 | * @param {THREE.Material} material 材质信息 9 | * @param {number} mode 线型 10 | * @extends {THREE.Object3D} 11 | * @constructor 12 | */ 13 | THREE.Line = function ( geometry, material, mode ) { 14 | 15 | THREE.Object3D.call( this ); 16 | /** 17 | * @default 'Line' 18 | * @type {string} 19 | */ 20 | this.type = 'Line'; 21 | 22 | /** 23 | * @desc 几何信息 24 | * @default THREE.Geometry() 25 | * @type {THREE.Geometry} 26 | */ 27 | this.geometry = geometry !== undefined ? geometry : new THREE.Geometry(); 28 | /** 29 | * @desc 材质信息 30 | * @default THREE.LineBasicMaterial() 随机颜色的线 31 | * @type {THREE.Geometry} 32 | */ 33 | this.material = material !== undefined ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } ); 34 | /** 35 | * @desc 线的绘制方式 36 | * @default THREE.LineStrip 37 | * @type {number} 38 | */ 39 | this.mode = ( mode !== undefined ) ? mode : THREE.LineStrip; 40 | 41 | }; 42 | /** 43 | * @memberof THREE 44 | * @desc 线型定义 45 | * @default 46 | * @type {number} 47 | */ 48 | THREE.LineStrip = 0; 49 | /** 50 | * @memberof THREE 51 | * @desc 线型定义 52 | * @default 53 | * @type {number} 54 | */ 55 | THREE.LinePieces = 1; 56 | /** 57 | * @desc Line对象从THREE.Objec3D的原型继承所有属性方法 58 | * @type {THREE.Object3D} 59 | */ 60 | THREE.Line.prototype = Object.create( THREE.Object3D.prototype ); 61 | /** 62 | * @function 63 | * @desc 线的拾取判断函数 64 | * @param {THREE.Raycaster} raycaster 拾取射线对象 65 | * @param {*} intersects 拾取结果对象数组 66 | */ 67 | THREE.Line.prototype.raycast = ( function () { 68 | 69 | var inverseMatrix = new THREE.Matrix4(); 70 | var ray = new THREE.Ray(); 71 | var sphere = new THREE.Sphere(); 72 | 73 | return function ( raycaster, intersects ) { 74 | 75 | var precision = raycaster.linePrecision; 76 | var precisionSq = precision * precision; 77 | 78 | var geometry = this.geometry; 79 | 80 | if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); 81 | 82 | // Checking boundingSphere distance to ray 83 | // 先进行外包围球体判断 84 | sphere.copy( geometry.boundingSphere ); 85 | sphere.applyMatrix4( this.matrixWorld ); 86 | 87 | if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) { 88 | 89 | return; 90 | 91 | } 92 | 93 | inverseMatrix.getInverse( this.matrixWorld ); 94 | ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); 95 | 96 | /* if ( geometry instanceof THREE.BufferGeometry ) { 97 | 98 | } else */ if ( geometry instanceof THREE.Geometry ) { 99 | 100 | var vertices = geometry.vertices; 101 | var nbVertices = vertices.length; 102 | var interSegment = new THREE.Vector3(); 103 | var interRay = new THREE.Vector3(); 104 | var step = this.mode === THREE.LineStrip ? 1 : 2; 105 | 106 | // 三角面判断 107 | for ( var i = 0; i < nbVertices - 1; i = i + step ) { 108 | 109 | var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); 110 | 111 | if ( distSq > precisionSq ) continue; 112 | 113 | var distance = ray.origin.distanceTo( interRay ); 114 | 115 | if ( distance < raycaster.near || distance > raycaster.far ) continue; 116 | 117 | // 加入结果数组内 118 | intersects.push( { 119 | 120 | distance: distance, 121 | // What do we want? intersection point on the ray or on the segment?? 122 | // point: raycaster.ray.at( distance ), 123 | point: interSegment.clone().applyMatrix4( this.matrixWorld ), 124 | face: null, 125 | faceIndex: null, 126 | object: this 127 | 128 | } ); 129 | 130 | } 131 | 132 | } 133 | 134 | }; 135 | 136 | }() ); 137 | /** 138 | * @desc Three.Line 拷贝函数 139 | * @param {THREE.Line} object 140 | * @returns {THREE.Line} 141 | */ 142 | THREE.Line.prototype.clone = function ( object ) { 143 | 144 | if ( object === undefined ) object = new THREE.Line( this.geometry, this.material, this.mode ); 145 | 146 | THREE.Object3D.prototype.clone.call( this, object ); 147 | 148 | return object; 149 | 150 | }; 151 | -------------------------------------------------------------------------------- /objects/Mesh.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | * @author mikael emtinger / http://gomo.se/ 5 | * @author jonobr1 / http://jonobr1.com/ 6 | */ 7 | /** 8 | * @classdesc Mesh对象 9 | * @param {THREE.Geometry} geometry 几何信息 10 | * @param {THREE.Material} material 材质信息 11 | * @extends {THREE.Object3D} 12 | * @constructor 13 | */ 14 | THREE.Mesh = function ( geometry, material ) { 15 | 16 | THREE.Object3D.call( this ); 17 | /** 18 | * @default 'Mesh' 19 | * @type {string} 20 | */ 21 | this.type = 'Mesh'; 22 | /** 23 | * @desc 几何信息 24 | * @type {THREE.Geometry} 25 | */ 26 | this.geometry = geometry !== undefined ? geometry : new THREE.Geometry(); 27 | /** 28 | * @desc 材质信息 29 | * @type {THREE.Geometry} 30 | */ 31 | this.material = material !== undefined ? material : new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } ); 32 | 33 | this.updateMorphTargets(); 34 | 35 | }; 36 | /** 37 | * @desc Mesh对象从THREE.Objec3D的原型继承所有属性方法 38 | * @type {THREE.Object3D} 39 | */ 40 | THREE.Mesh.prototype = Object.create( THREE.Object3D.prototype ); 41 | /** 42 | * @desc 更新变形顶点数组 43 | */ 44 | THREE.Mesh.prototype.updateMorphTargets = function () { 45 | 46 | if ( this.geometry.morphTargets !== undefined && this.geometry.morphTargets.length > 0 ) { 47 | 48 | this.morphTargetBase = - 1; 49 | this.morphTargetForcedOrder = []; 50 | this.morphTargetInfluences = []; 51 | this.morphTargetDictionary = {}; 52 | 53 | for ( var m = 0, ml = this.geometry.morphTargets.length; m < ml; m ++ ) { 54 | 55 | this.morphTargetInfluences.push( 0 ); 56 | this.morphTargetDictionary[ this.geometry.morphTargets[ m ].name ] = m; 57 | 58 | } 59 | 60 | } 61 | 62 | }; 63 | /** 64 | * @desc 根据名称获得变形顶点索引 65 | * @param {String} name 名称 66 | * @returns {*} 67 | */ 68 | THREE.Mesh.prototype.getMorphTargetIndexByName = function ( name ) { 69 | 70 | if ( this.morphTargetDictionary[ name ] !== undefined ) { 71 | 72 | return this.morphTargetDictionary[ name ]; 73 | 74 | } 75 | 76 | console.log( 'THREE.Mesh.getMorphTargetIndexByName: morph target ' + name + ' does not exist. Returning 0.' ); 77 | 78 | return 0; 79 | 80 | }; 81 | 82 | /** 83 | * @function 84 | * @desc 线的拾取判断函数 85 | * @param {THREE.Raycaster} raycaster 拾取射线对象 86 | * @param {*} intersects 拾取结果对象数组 87 | */ 88 | THREE.Mesh.prototype.raycast = ( function () { 89 | 90 | var inverseMatrix = new THREE.Matrix4(); 91 | var ray = new THREE.Ray(); 92 | var sphere = new THREE.Sphere(); 93 | 94 | var vA = new THREE.Vector3(); 95 | var vB = new THREE.Vector3(); 96 | var vC = new THREE.Vector3(); 97 | 98 | return function ( raycaster, intersects ) { 99 | 100 | var geometry = this.geometry; 101 | 102 | // Checking boundingSphere distance to ray 103 | // 先进行外包围球体判断 104 | if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); 105 | 106 | sphere.copy( geometry.boundingSphere ); 107 | sphere.applyMatrix4( this.matrixWorld ); 108 | 109 | if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) { 110 | 111 | return; 112 | 113 | } 114 | 115 | // Check boundingBox before continuing 116 | // 再进行外包围盒判断 117 | inverseMatrix.getInverse( this.matrixWorld ); 118 | ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); 119 | 120 | if ( geometry.boundingBox !== null ) { 121 | 122 | if ( ray.isIntersectionBox( geometry.boundingBox ) === false ) { 123 | 124 | return; 125 | 126 | } 127 | 128 | } 129 | 130 | // 每个三角面依次判断 131 | if ( geometry instanceof THREE.BufferGeometry ) { 132 | 133 | var material = this.material; 134 | 135 | if ( material === undefined ) return; 136 | 137 | var attributes = geometry.attributes; 138 | 139 | var a, b, c; 140 | var precision = raycaster.precision; 141 | 142 | if ( attributes.index !== undefined ) { 143 | 144 | var indices = attributes.index.array; 145 | var positions = attributes.position.array; 146 | var offsets = geometry.offsets; 147 | 148 | if ( offsets.length === 0 ) { 149 | 150 | offsets = [ { start: 0, count: indices.length, index: 0 } ]; 151 | 152 | } 153 | 154 | for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) { 155 | 156 | var start = offsets[ oi ].start; 157 | var count = offsets[ oi ].count; 158 | var index = offsets[ oi ].index; 159 | 160 | for ( var i = start, il = start + count; i < il; i += 3 ) { 161 | 162 | a = index + indices[ i ]; 163 | b = index + indices[ i + 1 ]; 164 | c = index + indices[ i + 2 ]; 165 | 166 | vA.fromArray( positions, a * 3 ); 167 | vB.fromArray( positions, b * 3 ); 168 | vC.fromArray( positions, c * 3 ); 169 | 170 | if ( material.side === THREE.BackSide ) { 171 | 172 | var intersectionPoint = ray.intersectTriangle( vC, vB, vA, true ); 173 | 174 | } else { 175 | 176 | var intersectionPoint = ray.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide ); 177 | 178 | } 179 | 180 | if ( intersectionPoint === null ) continue; 181 | 182 | intersectionPoint.applyMatrix4( this.matrixWorld ); 183 | 184 | var distance = raycaster.ray.origin.distanceTo( intersectionPoint ); 185 | 186 | if ( distance < precision || distance < raycaster.near || distance > raycaster.far ) continue; 187 | 188 | intersects.push( { 189 | 190 | distance: distance, 191 | point: intersectionPoint, 192 | face: new THREE.Face3( a, b, c, THREE.Triangle.normal( vA, vB, vC ) ), 193 | faceIndex: null, 194 | object: this 195 | 196 | } ); 197 | 198 | } 199 | 200 | } 201 | 202 | } else { 203 | 204 | var positions = attributes.position.array; 205 | 206 | for ( var i = 0, j = 0, il = positions.length; i < il; i += 3, j += 9 ) { 207 | 208 | a = i; 209 | b = i + 1; 210 | c = i + 2; 211 | 212 | vA.fromArray( positions, j ); 213 | vB.fromArray( positions, j + 3 ); 214 | vC.fromArray( positions, j + 6 ); 215 | 216 | if ( material.side === THREE.BackSide ) { 217 | 218 | var intersectionPoint = ray.intersectTriangle( vC, vB, vA, true ); 219 | 220 | } else { 221 | 222 | var intersectionPoint = ray.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide ); 223 | 224 | } 225 | 226 | if ( intersectionPoint === null ) continue; 227 | 228 | intersectionPoint.applyMatrix4( this.matrixWorld ); 229 | 230 | var distance = raycaster.ray.origin.distanceTo( intersectionPoint ); 231 | 232 | if ( distance < precision || distance < raycaster.near || distance > raycaster.far ) continue; 233 | 234 | intersects.push( { 235 | 236 | distance: distance, 237 | point: intersectionPoint, 238 | face: new THREE.Face3( a, b, c, THREE.Triangle.normal( vA, vB, vC ) ), 239 | faceIndex: null, 240 | object: this 241 | 242 | } ); 243 | 244 | } 245 | 246 | } 247 | 248 | } else if ( geometry instanceof THREE.Geometry ) { 249 | 250 | var isFaceMaterial = this.material instanceof THREE.MeshFaceMaterial; 251 | var objectMaterials = isFaceMaterial === true ? this.material.materials : null; 252 | 253 | var a, b, c, d; 254 | var precision = raycaster.precision; 255 | 256 | var vertices = geometry.vertices; 257 | 258 | for ( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) { 259 | 260 | var face = geometry.faces[ f ]; 261 | 262 | var material = isFaceMaterial === true ? objectMaterials[ face.materialIndex ] : this.material; 263 | 264 | if ( material === undefined ) continue; 265 | 266 | a = vertices[ face.a ]; 267 | b = vertices[ face.b ]; 268 | c = vertices[ face.c ]; 269 | 270 | if ( material.morphTargets === true ) { 271 | 272 | var morphTargets = geometry.morphTargets; 273 | var morphInfluences = this.morphTargetInfluences; 274 | 275 | vA.set( 0, 0, 0 ); 276 | vB.set( 0, 0, 0 ); 277 | vC.set( 0, 0, 0 ); 278 | 279 | for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) { 280 | 281 | var influence = morphInfluences[ t ]; 282 | 283 | if ( influence === 0 ) continue; 284 | 285 | var targets = morphTargets[ t ].vertices; 286 | 287 | vA.x += ( targets[ face.a ].x - a.x ) * influence; 288 | vA.y += ( targets[ face.a ].y - a.y ) * influence; 289 | vA.z += ( targets[ face.a ].z - a.z ) * influence; 290 | 291 | vB.x += ( targets[ face.b ].x - b.x ) * influence; 292 | vB.y += ( targets[ face.b ].y - b.y ) * influence; 293 | vB.z += ( targets[ face.b ].z - b.z ) * influence; 294 | 295 | vC.x += ( targets[ face.c ].x - c.x ) * influence; 296 | vC.y += ( targets[ face.c ].y - c.y ) * influence; 297 | vC.z += ( targets[ face.c ].z - c.z ) * influence; 298 | 299 | } 300 | 301 | vA.add( a ); 302 | vB.add( b ); 303 | vC.add( c ); 304 | 305 | a = vA; 306 | b = vB; 307 | c = vC; 308 | 309 | } 310 | 311 | if ( material.side === THREE.BackSide ) { 312 | 313 | var intersectionPoint = ray.intersectTriangle( c, b, a, true ); 314 | 315 | } else { 316 | 317 | var intersectionPoint = ray.intersectTriangle( a, b, c, material.side !== THREE.DoubleSide ); 318 | 319 | } 320 | 321 | if ( intersectionPoint === null ) continue; 322 | 323 | intersectionPoint.applyMatrix4( this.matrixWorld ); 324 | 325 | var distance = raycaster.ray.origin.distanceTo( intersectionPoint ); 326 | 327 | if ( distance < precision || distance < raycaster.near || distance > raycaster.far ) continue; 328 | 329 | intersects.push( { 330 | 331 | distance: distance, 332 | point: intersectionPoint, 333 | face: face, 334 | faceIndex: f, 335 | object: this 336 | 337 | } ); 338 | 339 | } 340 | 341 | } 342 | 343 | }; 344 | 345 | }() ); 346 | /** 347 | * @desc Three.Mesh 拷贝函数 348 | * @param {THREE.Mesh} object 349 | * @param {boolean} recursive 是否递归拷贝 350 | * @returns {THREE.Mesh} 351 | */ 352 | THREE.Mesh.prototype.clone = function ( object, recursive ) { 353 | 354 | if ( object === undefined ) object = new THREE.Mesh( this.geometry, this.material ); 355 | 356 | THREE.Object3D.prototype.clone.call( this, object, recursive ); 357 | 358 | return object; 359 | 360 | }; 361 | -------------------------------------------------------------------------------- /objects/PointCloud.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | /** 5 | * @classdesc 点云对象 6 | * @param {THREE.Geometry} geometry 点云对象的几何对象 7 | * @param {THREE.Material} material 点云对象的材质对象 8 | * @constructor 9 | */ 10 | THREE.PointCloud = function ( geometry, material ) { 11 | 12 | THREE.Object3D.call( this ); 13 | 14 | this.type = 'PointCloud'; 15 | 16 | this.geometry = geometry !== undefined ? geometry : new THREE.Geometry(); 17 | this.material = material !== undefined ? material : new THREE.PointCloudMaterial( { color: Math.random() * 0xffffff } ); 18 | 19 | this.sortParticles = false; 20 | 21 | }; 22 | /** 23 | * @desc PointCloud.Objec3D的原型继承所有属性方法 24 | * @type {THREE.Object3D} 25 | */ 26 | THREE.PointCloud.prototype = Object.create( THREE.Object3D.prototype ); 27 | 28 | /** 29 | * @function 30 | * @desc 点云的拾取判断函数 31 | * @param {THREE.Raycaster} raycaster 拾取射线对象 32 | * @param {*} intersects 拾取结果对象数组 33 | */ 34 | THREE.PointCloud.prototype.raycast = ( function () { 35 | 36 | var inverseMatrix = new THREE.Matrix4(); 37 | var ray = new THREE.Ray(); 38 | 39 | return function ( raycaster, intersects ) { 40 | 41 | var object = this; 42 | var geometry = object.geometry; 43 | var threshold = raycaster.params.PointCloud.threshold; 44 | 45 | inverseMatrix.getInverse( this.matrixWorld ); 46 | ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); 47 | 48 | if ( geometry.boundingBox !== null ) { 49 | 50 | if ( ray.isIntersectionBox( geometry.boundingBox ) === false ) { 51 | 52 | return; 53 | 54 | } 55 | 56 | } 57 | 58 | var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); 59 | var position = new THREE.Vector3(); 60 | 61 | var testPoint = function ( point, index ) { 62 | 63 | var rayPointDistance = ray.distanceToPoint( point ); 64 | 65 | if ( rayPointDistance < localThreshold ) { 66 | 67 | var intersectPoint = ray.closestPointToPoint( point ); 68 | intersectPoint.applyMatrix4( object.matrixWorld ); 69 | 70 | var distance = raycaster.ray.origin.distanceTo( intersectPoint ); 71 | 72 | intersects.push( { 73 | 74 | distance: distance, 75 | distanceToRay: rayPointDistance, 76 | point: intersectPoint.clone(), 77 | index: index, 78 | face: null, 79 | object: object 80 | 81 | } ); 82 | 83 | } 84 | 85 | }; 86 | 87 | if ( geometry instanceof THREE.BufferGeometry ) { 88 | 89 | var attributes = geometry.attributes; 90 | var positions = attributes.position.array; 91 | 92 | if ( attributes.index !== undefined ) { 93 | 94 | var indices = attributes.index.array; 95 | var offsets = geometry.offsets; 96 | 97 | if ( offsets.length === 0 ) { 98 | 99 | var offset = { 100 | start: 0, 101 | count: indices.length, 102 | index: 0 103 | }; 104 | 105 | offsets = [ offset ]; 106 | 107 | } 108 | 109 | for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) { 110 | 111 | var start = offsets[ oi ].start; 112 | var count = offsets[ oi ].count; 113 | var index = offsets[ oi ].index; 114 | 115 | for ( var i = start, il = start + count; i < il; i ++ ) { 116 | 117 | var a = index + indices[ i ]; 118 | 119 | position.fromArray( positions, a * 3 ); 120 | 121 | testPoint( position, a ); 122 | 123 | } 124 | 125 | } 126 | 127 | } else { 128 | 129 | var pointCount = positions.length / 3; 130 | 131 | for ( var i = 0; i < pointCount; i ++ ) { 132 | 133 | position.set( 134 | positions[ 3 * i ], 135 | positions[ 3 * i + 1 ], 136 | positions[ 3 * i + 2 ] 137 | ); 138 | 139 | testPoint( position, i ); 140 | 141 | } 142 | 143 | } 144 | 145 | } else { 146 | 147 | var vertices = this.geometry.vertices; 148 | 149 | for ( var i = 0; i < vertices.length; i ++ ) { 150 | 151 | testPoint( vertices[ i ], i ); 152 | 153 | } 154 | 155 | } 156 | 157 | }; 158 | 159 | }() ); 160 | /** 161 | * @desc Three.PointCloud 拷贝函数 162 | * @param {THREE.PointCloud} object 163 | * @returns {THREE.PointCloud} 164 | */ 165 | THREE.PointCloud.prototype.clone = function ( object ) { 166 | 167 | if ( object === undefined ) object = new THREE.PointCloud( this.geometry, this.material ); 168 | 169 | object.sortParticles = this.sortParticles; 170 | 171 | THREE.Object3D.prototype.clone.call( this, object ); 172 | 173 | return object; 174 | 175 | }; 176 | 177 | // Backwards compatibility 178 | /** 179 | * @ignore 180 | * @param geometry 181 | * @param material 182 | * @returns {THREE.PointCloud} 183 | * @constructor 184 | */ 185 | THREE.ParticleSystem = function ( geometry, material ) { 186 | 187 | console.warn( 'THREE.ParticleSystem has been renamed to THREE.PointCloud.' ); 188 | return new THREE.PointCloud( geometry, material ); 189 | 190 | }; 191 | -------------------------------------------------------------------------------- /renderers/WebGLRenderTarget.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author szimek / https://github.com/szimek/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | */ 5 | /** 6 | * @classdesc 渲染目标对象 7 | * @desc 通过options设置渲染目标对象,参数见对象的成员变量 8 | * @param {number} width 宽度 9 | * @param {number} height 高度 10 | * @param {*} options 参数列表 11 | * @constructor 12 | */ 13 | THREE.WebGLRenderTarget = function ( width, height, options ) { 14 | /** 15 | * @desc 宽度 16 | * @type {number} 17 | */ 18 | this.width = width; 19 | /** 20 | * @desc 高度 21 | * @type {number} 22 | */ 23 | this.height = height; 24 | 25 | options = options || {}; 26 | /** 27 | * @desc 纹理横轴覆盖模式 28 | * @type {number} 29 | */ 30 | this.wrapS = options.wrapS !== undefined ? options.wrapS : THREE.ClampToEdgeWrapping; 31 | /** 32 | * @desc 纹理纵轴覆盖模式 33 | * @type {number} 34 | */ 35 | this.wrapT = options.wrapT !== undefined ? options.wrapT : THREE.ClampToEdgeWrapping; 36 | /** 37 | * @desc 纹理扩大插值模式 38 | * @type {number} 39 | */ 40 | this.magFilter = options.magFilter !== undefined ? options.magFilter : THREE.LinearFilter; 41 | /** 42 | * @desc 纹理缩小插值模式 43 | * @type {number} 44 | */ 45 | this.minFilter = options.minFilter !== undefined ? options.minFilter : THREE.LinearMipMapLinearFilter; 46 | /** 47 | * @desc 各向异性参数 48 | * @type {number} 49 | */ 50 | this.anisotropy = options.anisotropy !== undefined ? options.anisotropy : 1; 51 | /** 52 | * @desc 纹理起始偏移 53 | * @type {number} 54 | */ 55 | this.offset = new THREE.Vector2( 0, 0 ); 56 | /** 57 | * @desc 纹理重复参数 58 | * @type {number} 59 | */ 60 | this.repeat = new THREE.Vector2( 1, 1 ); 61 | /** 62 | * @desc 纹理颜色格式 63 | * @type {number} 64 | */ 65 | this.format = options.format !== undefined ? options.format : THREE.RGBAFormat; 66 | /** 67 | * @desc 纹理数据字节大小 68 | * @type {number} 69 | */ 70 | this.type = options.type !== undefined ? options.type : THREE.UnsignedByteType; 71 | /** 72 | * @desc 是否是深度缓冲 73 | * @type {boolean} 74 | */ 75 | this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; 76 | /** 77 | * @desc 是否是模板缓冲 78 | * @type {number} 79 | */ 80 | this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; 81 | /** 82 | * @desc 是否生成Mipmap 83 | * @type {boolean} 84 | */ 85 | this.generateMipmaps = true; 86 | /** 87 | * @desc 共享深度连接 88 | * @type {*} 89 | */ 90 | this.shareDepthFrom = null; 91 | 92 | }; 93 | 94 | THREE.WebGLRenderTarget.prototype = { 95 | 96 | constructor: THREE.WebGLRenderTarget, 97 | /** 98 | * @desc 设置渲染目标的尺寸 99 | * @param {number} width 宽度 100 | * @param {number} height 高度 101 | */ 102 | setSize: function ( width, height ) { 103 | 104 | this.width = width; 105 | this.height = height; 106 | 107 | }, 108 | /** 109 | * @desc 渲染目标的克隆 110 | * @returns {THREE.WebGLRenderTarget} 111 | */ 112 | clone: function () { 113 | 114 | var tmp = new THREE.WebGLRenderTarget( this.width, this.height ); 115 | 116 | tmp.wrapS = this.wrapS; 117 | tmp.wrapT = this.wrapT; 118 | 119 | tmp.magFilter = this.magFilter; 120 | tmp.minFilter = this.minFilter; 121 | 122 | tmp.anisotropy = this.anisotropy; 123 | 124 | tmp.offset.copy( this.offset ); 125 | tmp.repeat.copy( this.repeat ); 126 | 127 | tmp.format = this.format; 128 | tmp.type = this.type; 129 | 130 | tmp.depthBuffer = this.depthBuffer; 131 | tmp.stencilBuffer = this.stencilBuffer; 132 | 133 | tmp.generateMipmaps = this.generateMipmaps; 134 | 135 | tmp.shareDepthFrom = this.shareDepthFrom; 136 | 137 | return tmp; 138 | 139 | }, 140 | /** 141 | * @desc WebGLRenderTarget的销毁事件 142 | */ 143 | dispose: function () { 144 | 145 | this.dispatchEvent( { type: 'dispose' } ); 146 | 147 | } 148 | 149 | }; 150 | 151 | THREE.EventDispatcher.prototype.apply( THREE.WebGLRenderTarget.prototype ); 152 | -------------------------------------------------------------------------------- /renderers/WebGLRenderTargetCube.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com 3 | */ 4 | /** 5 | * @classdesc 立方体渲染目标对象 6 | * @param {number} width 宽度 7 | * @param {number} height 高度 8 | * @param {*} options 参数列表 9 | * @constructor 10 | */ 11 | THREE.WebGLRenderTargetCube = function ( width, height, options ) { 12 | 13 | THREE.WebGLRenderTarget.call( this, width, height, options ); 14 | 15 | this.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5 16 | 17 | }; 18 | /** 19 | * @desc WebGLRenderTargetCube对象从WebGLRenderTarget的原型继承所有属性方法 20 | * @type {THREE.WebGLRenderTarget} 21 | */ 22 | THREE.WebGLRenderTargetCube.prototype = Object.create( THREE.WebGLRenderTarget.prototype ); 23 | -------------------------------------------------------------------------------- /renderers/shaders/ShaderChunk.js: -------------------------------------------------------------------------------- 1 | THREE.ShaderChunk = {}; 2 | -------------------------------------------------------------------------------- /renderers/shaders/UniformsLib.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Uniforms library for shared webgl shaders 3 | */ 4 | /** 5 | * @desc Uniforms库,包含各种定义的shader的uniform组成 6 | * @memberof THREE 7 | * @type {*} 8 | */ 9 | THREE.UniformsLib = { 10 | 11 | // 普通 12 | common: { 13 | 14 | "diffuse" : { type: "c", value: new THREE.Color( 0xeeeeee ) }, 15 | "opacity" : { type: "f", value: 1.0 }, 16 | 17 | "map" : { type: "t", value: null }, 18 | "offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, 19 | 20 | "lightMap" : { type: "t", value: null }, 21 | "specularMap" : { type: "t", value: null }, 22 | "alphaMap" : { type: "t", value: null }, 23 | 24 | "envMap" : { type: "t", value: null }, 25 | "flipEnvMap" : { type: "f", value: - 1 }, 26 | "useRefract" : { type: "i", value: 0 }, 27 | "reflectivity" : { type: "f", value: 1.0 }, 28 | "refractionRatio" : { type: "f", value: 0.98 }, 29 | "combine" : { type: "i", value: 0 }, 30 | 31 | "morphTargetInfluences" : { type: "f", value: 0 } 32 | 33 | }, 34 | 35 | // 碰撞 36 | bump: { 37 | 38 | "bumpMap" : { type: "t", value: null }, 39 | "bumpScale" : { type: "f", value: 1 } 40 | 41 | }, 42 | // 法线贴图 43 | normalmap: { 44 | 45 | "normalMap" : { type: "t", value: null }, 46 | "normalScale" : { type: "v2", value: new THREE.Vector2( 1, 1 ) } 47 | }, 48 | // 雾 49 | fog : { 50 | 51 | "fogDensity" : { type: "f", value: 0.00025 }, 52 | "fogNear" : { type: "f", value: 1 }, 53 | "fogFar" : { type: "f", value: 2000 }, 54 | "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) } 55 | 56 | }, 57 | // 光照 58 | lights: { 59 | 60 | "ambientLightColor" : { type: "fv", value: [] }, 61 | 62 | "directionalLightDirection" : { type: "fv", value: [] }, 63 | "directionalLightColor" : { type: "fv", value: [] }, 64 | 65 | "hemisphereLightDirection" : { type: "fv", value: [] }, 66 | "hemisphereLightSkyColor" : { type: "fv", value: [] }, 67 | "hemisphereLightGroundColor" : { type: "fv", value: [] }, 68 | 69 | "pointLightColor" : { type: "fv", value: [] }, 70 | "pointLightPosition" : { type: "fv", value: [] }, 71 | "pointLightDistance" : { type: "fv1", value: [] }, 72 | 73 | "spotLightColor" : { type: "fv", value: [] }, 74 | "spotLightPosition" : { type: "fv", value: [] }, 75 | "spotLightDirection" : { type: "fv", value: [] }, 76 | "spotLightDistance" : { type: "fv1", value: [] }, 77 | "spotLightAngleCos" : { type: "fv1", value: [] }, 78 | "spotLightExponent" : { type: "fv1", value: [] } 79 | 80 | }, 81 | // 粒子 82 | particle: { 83 | 84 | "psColor" : { type: "c", value: new THREE.Color( 0xeeeeee ) }, 85 | "opacity" : { type: "f", value: 1.0 }, 86 | "size" : { type: "f", value: 1.0 }, 87 | "scale" : { type: "f", value: 1.0 }, 88 | "map" : { type: "t", value: null }, 89 | 90 | "fogDensity" : { type: "f", value: 0.00025 }, 91 | "fogNear" : { type: "f", value: 1 }, 92 | "fogFar" : { type: "f", value: 2000 }, 93 | "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) } 94 | 95 | }, 96 | // 阴影贴图 97 | shadowmap: { 98 | 99 | "shadowMap": { type: "tv", value: [] }, 100 | "shadowMapSize": { type: "v2v", value: [] }, 101 | 102 | "shadowBias" : { type: "fv1", value: [] }, 103 | "shadowDarkness": { type: "fv1", value: [] }, 104 | 105 | "shadowMatrix" : { type: "m4v", value: [] } 106 | 107 | } 108 | 109 | }; 110 | -------------------------------------------------------------------------------- /renderers/shaders/UniformsUtils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Uniform Utilities 3 | */ 4 | /** 5 | * @desc Uniforms操作 6 | * @memberof THREE 7 | * @type {*} 8 | */ 9 | THREE.UniformsUtils = { 10 | // 合并 11 | merge: function ( uniforms ) { 12 | 13 | var merged = {}; 14 | 15 | for ( var u = 0; u < uniforms.length; u ++ ) { 16 | 17 | var tmp = this.clone( uniforms[ u ] ); 18 | 19 | for ( var p in tmp ) { 20 | 21 | merged[ p ] = tmp[ p ]; 22 | 23 | } 24 | 25 | } 26 | 27 | return merged; 28 | 29 | }, 30 | // 克隆 31 | clone: function ( uniforms_src ) { 32 | 33 | var uniforms_dst = {}; 34 | 35 | for ( var u in uniforms_src ) { 36 | 37 | uniforms_dst[ u ] = {}; 38 | 39 | for ( var p in uniforms_src[ u ] ) { 40 | 41 | var parameter_src = uniforms_src[ u ][ p ]; 42 | 43 | if ( parameter_src instanceof THREE.Color || 44 | parameter_src instanceof THREE.Vector2 || 45 | parameter_src instanceof THREE.Vector3 || 46 | parameter_src instanceof THREE.Vector4 || 47 | parameter_src instanceof THREE.Matrix4 || 48 | parameter_src instanceof THREE.Texture ) { 49 | 50 | uniforms_dst[ u ][ p ] = parameter_src.clone(); 51 | 52 | } else if ( parameter_src instanceof Array ) { 53 | 54 | uniforms_dst[ u ][ p ] = parameter_src.slice(); 55 | 56 | } else { 57 | 58 | uniforms_dst[ u ][ p ] = parameter_src; 59 | 60 | } 61 | 62 | } 63 | 64 | } 65 | 66 | return uniforms_dst; 67 | 68 | } 69 | 70 | }; 71 | -------------------------------------------------------------------------------- /renderers/webgl/WebGLExtensions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @classdesc webgl扩展标记 3 | * @param {*} gl webgl上下文对象 4 | * @constructor 5 | */ 6 | THREE.WebGLExtensions = function ( gl ) { 7 | 8 | var extensions = {}; 9 | /** 10 | * @desc 通过名称获得gl的对象值 11 | * @param {string} name 对象名称 12 | * @returns {*} 13 | */ 14 | this.get = function ( name ) { 15 | 16 | if ( extensions[ name ] !== undefined ) { 17 | 18 | return extensions[ name ]; 19 | 20 | } 21 | 22 | var extension; 23 | 24 | switch ( name ) { 25 | 26 | case 'OES_texture_float': 27 | extension = gl.getExtension( 'OES_texture_float' ); 28 | break; 29 | 30 | case 'OES_texture_float_linear': 31 | extension = gl.getExtension( 'OES_texture_float_linear' ); 32 | break; 33 | 34 | case 'OES_standard_derivatives': 35 | extension = gl.getExtension( 'OES_standard_derivatives' ); 36 | break; 37 | 38 | case 'EXT_texture_filter_anisotropic': 39 | extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' ); 40 | break; 41 | 42 | case 'WEBGL_compressed_texture_s3tc': 43 | extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' ); 44 | break; 45 | 46 | case 'WEBGL_compressed_texture_pvrtc': 47 | extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' ); 48 | break; 49 | 50 | case 'OES_element_index_uint': 51 | extension = gl.getExtension( 'OES_element_index_uint' ); 52 | break; 53 | 54 | case 'EXT_blend_minmax': 55 | extension = gl.getExtension( 'EXT_blend_minmax' ); 56 | break; 57 | 58 | case 'EXT_frag_depth': 59 | extension = gl.getExtension( 'EXT_frag_depth' ); 60 | break; 61 | 62 | } 63 | 64 | if ( extension === null ) { 65 | 66 | console.log( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); 67 | 68 | } 69 | 70 | extensions[ name ] = extension; 71 | 72 | return extension; 73 | 74 | }; 75 | 76 | }; 77 | -------------------------------------------------------------------------------- /renderers/webgl/WebGLShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @classdesc webglshader 对象 3 | * @param {*} gl gl上下文对象 4 | * @param {number} type 类型 5 | * @param {string} string shader字符串 6 | * @constructor 7 | */ 8 | THREE.WebGLShader = ( function () { 9 | /** 10 | * @desc 格式化行对象 11 | * @param {string} string shader指令 12 | * @returns {string} 13 | */ 14 | var addLineNumbers = function ( string ) { 15 | 16 | var lines = string.split( '\n' ); 17 | 18 | for ( var i = 0; i < lines.length; i ++ ) { 19 | 20 | lines[ i ] = ( i + 1 ) + ': ' + lines[ i ]; 21 | 22 | } 23 | 24 | return lines.join( '\n' ); 25 | 26 | }; 27 | 28 | return function ( gl, type, string ) { 29 | 30 | var shader = gl.createShader( type ); 31 | 32 | gl.shaderSource( shader, string ); 33 | gl.compileShader( shader ); 34 | 35 | if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) { 36 | 37 | console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' ); 38 | 39 | } 40 | 41 | if ( gl.getShaderInfoLog( shader ) !== '' ) { 42 | 43 | console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', gl.getShaderInfoLog( shader ) ); 44 | console.warn( addLineNumbers( string ) ); 45 | 46 | } 47 | 48 | // --enable-privileged-webgl-extension 49 | // console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); 50 | 51 | return shader; 52 | 53 | }; 54 | 55 | } )(); 56 | -------------------------------------------------------------------------------- /renderers/webgl/plugins/SpritePlugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mikael emtinger / http://gomo.se/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | */ 5 | /** 6 | * @classdesc 闪光效果插件 7 | * @param {THREE.WebGLRenderer} renderer 渲染器 8 | * @param {THREE.Sprite[]} sprites 闪光对象列表 9 | * @constructor 10 | */ 11 | THREE.SpritePlugin = function ( renderer, sprites ) { 12 | 13 | var gl = renderer.context; 14 | 15 | var vertexBuffer, elementBuffer; 16 | var program, attributes, uniforms; 17 | 18 | var texture; 19 | // 初始化闪光插件 20 | var init = function () { 21 | 22 | var vertices = new Float32Array( [ 23 | - 0.5, - 0.5, 0, 0, 24 | 0.5, - 0.5, 1, 0, 25 | 0.5, 0.5, 1, 1, 26 | - 0.5, 0.5, 0, 1 27 | ] ); 28 | 29 | var faces = new Uint16Array( [ 30 | 0, 1, 2, 31 | 0, 2, 3 32 | ] ); 33 | 34 | vertexBuffer = gl.createBuffer(); 35 | elementBuffer = gl.createBuffer(); 36 | 37 | gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer ); 38 | gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW ); 39 | 40 | gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer ); 41 | gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW ); 42 | 43 | program = createProgram(); 44 | 45 | attributes = { 46 | position: gl.getAttribLocation ( program, 'position' ), 47 | uv: gl.getAttribLocation ( program, 'uv' ) 48 | }; 49 | 50 | uniforms = { 51 | uvOffset: gl.getUniformLocation( program, 'uvOffset' ), 52 | uvScale: gl.getUniformLocation( program, 'uvScale' ), 53 | 54 | rotation: gl.getUniformLocation( program, 'rotation' ), 55 | scale: gl.getUniformLocation( program, 'scale' ), 56 | 57 | color: gl.getUniformLocation( program, 'color' ), 58 | map: gl.getUniformLocation( program, 'map' ), 59 | opacity: gl.getUniformLocation( program, 'opacity' ), 60 | 61 | modelViewMatrix: gl.getUniformLocation( program, 'modelViewMatrix' ), 62 | projectionMatrix: gl.getUniformLocation( program, 'projectionMatrix' ), 63 | 64 | fogType: gl.getUniformLocation( program, 'fogType' ), 65 | fogDensity: gl.getUniformLocation( program, 'fogDensity' ), 66 | fogNear: gl.getUniformLocation( program, 'fogNear' ), 67 | fogFar: gl.getUniformLocation( program, 'fogFar' ), 68 | fogColor: gl.getUniformLocation( program, 'fogColor' ), 69 | 70 | alphaTest: gl.getUniformLocation( program, 'alphaTest' ) 71 | }; 72 | 73 | var canvas = document.createElement( 'canvas' ); 74 | canvas.width = 8; 75 | canvas.height = 8; 76 | 77 | var context = canvas.getContext( '2d' ); 78 | context.fillStyle = 'white'; 79 | context.fillRect( 0, 0, 8, 8 ); 80 | 81 | texture = new THREE.Texture( canvas ); 82 | texture.needsUpdate = true; 83 | 84 | }; 85 | /** 86 | * @desc 闪光对象渲染 87 | * @param {THREE.Scene} scene 场景 88 | * @param {THREE.Camera} camera 相机 89 | */ 90 | this.render = function ( scene, camera ) { 91 | 92 | if ( sprites.length === 0 ) return; 93 | 94 | // setup gl 95 | 96 | if ( program === undefined ) { 97 | 98 | init(); 99 | 100 | } 101 | 102 | gl.useProgram( program ); 103 | 104 | gl.enableVertexAttribArray( attributes.position ); 105 | gl.enableVertexAttribArray( attributes.uv ); 106 | 107 | gl.disable( gl.CULL_FACE ); 108 | gl.enable( gl.BLEND ); 109 | 110 | gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer ); 111 | gl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 ); 112 | gl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 ); 113 | 114 | gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer ); 115 | 116 | gl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements ); 117 | 118 | gl.activeTexture( gl.TEXTURE0 ); 119 | gl.uniform1i( uniforms.map, 0 ); 120 | 121 | var oldFogType = 0; 122 | var sceneFogType = 0; 123 | var fog = scene.fog; 124 | 125 | if ( fog ) { 126 | 127 | gl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b ); 128 | 129 | if ( fog instanceof THREE.Fog ) { 130 | 131 | gl.uniform1f( uniforms.fogNear, fog.near ); 132 | gl.uniform1f( uniforms.fogFar, fog.far ); 133 | 134 | gl.uniform1i( uniforms.fogType, 1 ); 135 | oldFogType = 1; 136 | sceneFogType = 1; 137 | 138 | } else if ( fog instanceof THREE.FogExp2 ) { 139 | 140 | gl.uniform1f( uniforms.fogDensity, fog.density ); 141 | 142 | gl.uniform1i( uniforms.fogType, 2 ); 143 | oldFogType = 2; 144 | sceneFogType = 2; 145 | 146 | } 147 | 148 | } else { 149 | 150 | gl.uniform1i( uniforms.fogType, 0 ); 151 | oldFogType = 0; 152 | sceneFogType = 0; 153 | 154 | } 155 | 156 | 157 | // update positions and sort 158 | 159 | for ( var i = 0, l = sprites.length; i < l; i ++ ) { 160 | 161 | var sprite = sprites[ i ]; 162 | 163 | sprite._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld ); 164 | 165 | if ( sprite.renderDepth === null ) { 166 | 167 | sprite.z = - sprite._modelViewMatrix.elements[ 14 ]; 168 | 169 | } else { 170 | 171 | sprite.z = sprite.renderDepth; 172 | 173 | } 174 | 175 | } 176 | 177 | sprites.sort( painterSortStable ); 178 | 179 | // render all sprites 180 | 181 | var scale = []; 182 | 183 | for ( var i = 0, l = sprites.length; i < l; i ++ ) { 184 | 185 | var sprite = sprites[ i ]; 186 | var material = sprite.material; 187 | 188 | gl.uniform1f( uniforms.alphaTest, material.alphaTest ); 189 | gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite._modelViewMatrix.elements ); 190 | 191 | scale[ 0 ] = sprite.scale.x; 192 | scale[ 1 ] = sprite.scale.y; 193 | 194 | var fogType = 0; 195 | 196 | if ( scene.fog && material.fog ) { 197 | 198 | fogType = sceneFogType; 199 | 200 | } 201 | 202 | if ( oldFogType !== fogType ) { 203 | 204 | gl.uniform1i( uniforms.fogType, fogType ); 205 | oldFogType = fogType; 206 | 207 | } 208 | 209 | if ( material.map !== null ) { 210 | 211 | gl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y ); 212 | gl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y ); 213 | 214 | } else { 215 | 216 | gl.uniform2f( uniforms.uvOffset, 0, 0 ); 217 | gl.uniform2f( uniforms.uvScale, 1, 1 ); 218 | 219 | } 220 | 221 | gl.uniform1f( uniforms.opacity, material.opacity ); 222 | gl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b ); 223 | 224 | gl.uniform1f( uniforms.rotation, material.rotation ); 225 | gl.uniform2fv( uniforms.scale, scale ); 226 | 227 | renderer.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst ); 228 | renderer.setDepthTest( material.depthTest ); 229 | renderer.setDepthWrite( material.depthWrite ); 230 | 231 | if ( material.map && material.map.image && material.map.image.width ) { 232 | 233 | renderer.setTexture( material.map, 0 ); 234 | 235 | } else { 236 | 237 | renderer.setTexture( texture, 0 ); 238 | 239 | } 240 | 241 | gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); 242 | 243 | } 244 | 245 | // restore gl 246 | 247 | gl.enable( gl.CULL_FACE ); 248 | 249 | renderer.resetGLState(); 250 | 251 | }; 252 | 253 | // 创建program 254 | function createProgram () { 255 | 256 | var program = gl.createProgram(); 257 | 258 | var vertexShader = gl.createShader( gl.VERTEX_SHADER ); 259 | var fragmentShader = gl.createShader( gl.FRAGMENT_SHADER ); 260 | 261 | gl.shaderSource( vertexShader, [ 262 | 263 | 'precision ' + renderer.getPrecision() + ' float;', 264 | 265 | 'uniform mat4 modelViewMatrix;', 266 | 'uniform mat4 projectionMatrix;', 267 | 'uniform float rotation;', 268 | 'uniform vec2 scale;', 269 | 'uniform vec2 uvOffset;', 270 | 'uniform vec2 uvScale;', 271 | 272 | 'attribute vec2 position;', 273 | 'attribute vec2 uv;', 274 | 275 | 'varying vec2 vUV;', 276 | 277 | 'void main() {', 278 | 279 | 'vUV = uvOffset + uv * uvScale;', 280 | 281 | 'vec2 alignedPosition = position * scale;', 282 | 283 | 'vec2 rotatedPosition;', 284 | 'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;', 285 | 'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;', 286 | 287 | 'vec4 finalPosition;', 288 | 289 | 'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );', 290 | 'finalPosition.xy += rotatedPosition;', 291 | 'finalPosition = projectionMatrix * finalPosition;', 292 | 293 | 'gl_Position = finalPosition;', 294 | 295 | '}' 296 | 297 | ].join( '\n' ) ); 298 | 299 | gl.shaderSource( fragmentShader, [ 300 | 301 | 'precision ' + renderer.getPrecision() + ' float;', 302 | 303 | 'uniform vec3 color;', 304 | 'uniform sampler2D map;', 305 | 'uniform float opacity;', 306 | 307 | 'uniform int fogType;', 308 | 'uniform vec3 fogColor;', 309 | 'uniform float fogDensity;', 310 | 'uniform float fogNear;', 311 | 'uniform float fogFar;', 312 | 'uniform float alphaTest;', 313 | 314 | 'varying vec2 vUV;', 315 | 316 | 'void main() {', 317 | 318 | 'vec4 texture = texture2D( map, vUV );', 319 | 320 | 'if ( texture.a < alphaTest ) discard;', 321 | 322 | 'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );', 323 | 324 | 'if ( fogType > 0 ) {', 325 | 326 | 'float depth = gl_FragCoord.z / gl_FragCoord.w;', 327 | 'float fogFactor = 0.0;', 328 | 329 | 'if ( fogType == 1 ) {', 330 | 331 | 'fogFactor = smoothstep( fogNear, fogFar, depth );', 332 | 333 | '} else {', 334 | 335 | 'const float LOG2 = 1.442695;', 336 | 'float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );', 337 | 'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );', 338 | 339 | '}', 340 | 341 | 'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );', 342 | 343 | '}', 344 | 345 | '}' 346 | 347 | ].join( '\n' ) ); 348 | 349 | gl.compileShader( vertexShader ); 350 | gl.compileShader( fragmentShader ); 351 | 352 | gl.attachShader( program, vertexShader ); 353 | gl.attachShader( program, fragmentShader ); 354 | 355 | gl.linkProgram( program ); 356 | 357 | return program; 358 | 359 | }; 360 | // 根据远近排序 361 | function painterSortStable ( a, b ) { 362 | 363 | if ( a.z !== b.z ) { 364 | 365 | return b.z - a.z; 366 | 367 | } else { 368 | 369 | return b.id - a.id; 370 | 371 | } 372 | 373 | }; 374 | 375 | }; 376 | -------------------------------------------------------------------------------- /scenes/Fog.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | */ 5 | /** 6 | * @classdesc 线性雾效对象
7 | * Fog对象的构造函数.用来在场景内创建线性雾效,线性雾效就是从雾效的起始点参数near,到结束点参数far,雾效强度线性递增 8 | * @param {THREE.Color} color 雾的颜色 9 | * @param {float} near 雾效的起始点,雾效的near属性大于当前相机的near属性,当前相机才不会受相机影响,可选参数,默认是1 10 | * @param {float} far 雾效的结束点,雾效的far属性小于当前相机的far属性,当前相机才不会受相机影响,可选参数,默认是1000 11 | * @constructor 12 | */ 13 | THREE.Fog = function ( color, near, far ) { 14 | /** 15 | * @desc 雾的名字 16 | * @default '' 17 | * @type {string} 18 | */ 19 | this.name = ''; 20 | /** 21 | * @desc 雾效颜色 22 | * @type {THREE.Color} 23 | */ 24 | this.color = new THREE.Color( color ); 25 | /** 26 | * @desc 雾的最近距离 27 | * @default 1 28 | * @type {float} 29 | */ 30 | this.near = ( near !== undefined ) ? near : 1; 31 | /** 32 | * @desc 雾的最远距离 33 | * @default 1000 34 | * @type {float} 35 | */ 36 | this.far = ( far !== undefined ) ? far : 1000; 37 | 38 | }; 39 | /** 40 | * @desc 雾对象的克隆 41 | * @returns {THREE.Fog} 42 | */ 43 | THREE.Fog.prototype.clone = function () { 44 | 45 | return new THREE.Fog( this.color.getHex(), this.near, this.far ); 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /scenes/FogExp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | */ 5 | /** 6 | * @classdesc 指数雾效对象
7 | * FogExp2.用来在场景内创建指数雾效,指数雾效是雾效浓度递增根据指数(参数density)设定,Fog对象的功能函数采用 8 | * @param {THREE.Color} color 雾效的颜色属性,如果雾效颜色设置成黑色,远处的对象将被渲染成黑色 9 | * @param {float} density 雾效强度递增指数属性,可选参数,默认是0.00025 10 | * @constructor 11 | */ 12 | THREE.FogExp2 = function ( color, density ) { 13 | /** 14 | * @desc 雾的名字 15 | * @default '' 16 | * @type {string} 17 | */ 18 | this.name = ''; 19 | /** 20 | * @desc 雾效颜色 21 | * @type {THREE.Color} 22 | */ 23 | this.color = new THREE.Color( color ); 24 | /** 25 | * @desc 雾效强度递增指数 26 | * @default 0.00025 27 | * @type {float} 28 | */ 29 | this.density = ( density !== undefined ) ? density : 0.00025; 30 | 31 | }; 32 | 33 | /** 34 | * @desc 指数雾的克隆 35 | * @returns {THREE.FogExp2} 36 | */ 37 | THREE.FogExp2.prototype.clone = function () { 38 | 39 | return new THREE.FogExp2( this.color.getHex(), this.density ); 40 | 41 | }; 42 | -------------------------------------------------------------------------------- /scenes/Scene.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | 5 | /** 6 | * @classdesc Scene是场景对象,所有的对象,灯光,动画,骨骼等都需要放置在场景内.Scene对象的功能函数采用定义构造的函数原型对象来实现. 7 | * @desc 场景对象构造函数 8 | * @class 9 | * @extends {THREE.Object3D} 10 | */ 11 | THREE.Scene = function () { 12 | 13 | // 调用Object3D对象的call方法,将原本属于Object3D的方法交给当前对象Scene来使用. 14 | THREE.Object3D.call( this ); 15 | 16 | /** 17 | * @desc 场景的类型定义 18 | * @default 19 | * @type {string} 20 | */ 21 | this.type = 'Scene'; 22 | /** 23 | * @desc 场景的雾效属性 24 | * @default 25 | * @type {THREE.fog} 26 | */ 27 | this.fog = null; 28 | /** 29 | * @desc 场景的材质属性,默认为null,如果设置了这个属性,场景中的所有对象渲染成这个材质. 30 | * @default 31 | * @type {THREE.Material} 32 | */ 33 | this.overrideMaterial = null; 34 | 35 | /** 36 | * @desc 默认为true,表示渲染器每一帧都会检查场景和场景中的对象的矩阵的是否更新,如果为false,场景中的对象将不会被自动更新 37 | * @default 38 | * @type {boolean} 39 | */ 40 | this.autoUpdate = true; // checked by the renderer 41 | 42 | }; 43 | 44 | /** 45 | * @desc Scene对象从THREE.Objec3D的原型继承所有属性方法 46 | * @type {THREE.Object3D} 47 | */ 48 | THREE.Scene.prototype = Object.create( THREE.Object3D.prototype ); 49 | 50 | /** 51 | * @desc Three.Scene 拷贝函数,将属性数组分别复制 52 | * @param {THREE.Scene} object - 源Scene 53 | * @returns {THREE.Scene} 54 | */ 55 | THREE.Scene.prototype.clone = function ( object ) { 56 | 57 | if ( object === undefined ) object = new THREE.Scene(); 58 | 59 | THREE.Object3D.prototype.clone.call( this, object ); 60 | 61 | if ( this.fog !== null ) object.fog = this.fog.clone(); 62 | if ( this.overrideMaterial !== null ) object.overrideMaterial = this.overrideMaterial.clone(); 63 | 64 | object.autoUpdate = this.autoUpdate; 65 | object.matrixAutoUpdate = this.matrixAutoUpdate; 66 | 67 | return object; 68 | 69 | }; 70 | -------------------------------------------------------------------------------- /textures/Texture.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | * @author szimek / https://github.com/szimek/ 5 | */ 6 | 7 | /** 8 | * @classdesc 纹理对象基类 9 | * @desc 用来创建一个反射折射或者纹理贴图对象 10 | * @param {Image} image 图片等Image类型对象 11 | * @param {number} mapping 映射模式 12 | * @param {number} wrapS S方向覆盖模式 13 | * @param {number} wrapT T方向覆盖模式 14 | * @param {number} magFilter 纹理在放大时的过滤方式 15 | * @param {number} minFilter 纹理在缩小时的过滤方式 16 | * @param {number} format 像素数据的颜色格式 17 | * @param {number} type 数据类型,默认为不带符号8位整形值 18 | * @param {float} anisotropy 各向异性,取值范围0.0-1.0 ,,经常用来通过这个值,产生不同的表面效果,木材和金属都发光,但是发光的特点是有区别的. 19 | * @constructor 20 | */ 21 | THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { 22 | 23 | Object.defineProperty( this, 'id', { value: THREE.TextureIdCount ++ } ); 24 | /** 25 | * @desc 纹理的唯一ID 26 | */ 27 | this.uuid = THREE.Math.generateUUID(); 28 | /** 29 | * @default 30 | * @type {string} 31 | */ 32 | this.name = ''; 33 | /** 34 | * @default THREE.Texture.DEFAULT_IMAGE 35 | * @type {Image} 36 | */ 37 | this.image = image !== undefined ? image : THREE.Texture.DEFAULT_IMAGE; 38 | 39 | /** 40 | * @desc 存放mipmaps的数组
41 | * Mipmap在三维世界中,显示一张图的大小与摄象机的位置有关,近的地方,图片实际象素就大一些,远的地方图片实际象
42 | * 素就会小一些,就要进行一些压缩,例如一张64*64的图,在近处,显示出来可能是50*50,在远处可能显示出来是20*20.
43 | * 如果只限于简单的支掉某些像素,将会使缩小后的图片损失很多细节,图片变得很粗糙,因此,图形学有很多复杂的方
44 | * 法来处理缩小图片的问题,使得缩小后的图片依然清晰,然而,这些计算都会耗费一定的时间.
45 | *
46 | * Mipmap纹理技术是目前解决纹理分辨率与视点距离关系的最有效途径,它会先将图片压缩成很多逐渐缩小的图片,
47 | * 例如一张64*64的图片,会产生64*64,32*32,16*16,8*8,4*4,2*2,1*1的7张图片,当屏幕上需要绘制像素点为20*20 时,
48 | * 程序只是利用 32*32 和 16*16 这两张图片来计算出即将显示为 20*20 大小的一个图片,这比单独利用 32*32 的
49 | * 那张原始片计算出来的图片效果要好得多,速度也更快.
50 | *
51 | * 参考:http://zh.wikipedia.org/wiki/Mipmap
52 | * 参考:http://staff.cs.psu.ac.th/iew/cs344-481/p1-williams.pdf
53 | * 参考:http://blog.csdn.net/linber214/article/details/3342051
54 | * @default 55 | * @type {Array} 56 | */ 57 | this.mipmaps = []; 58 | /** 59 | * @desc 映射模式,有
60 | * THREE.UVMapping平展映射
61 | * THREE.CubeReflectionMapping 立方体反射映射
62 | * THREE.CubeRefractionMapping立方体折射映射
63 | * THREE.SphericalReflectionMapping球面反射映射
64 | * THREE.SphericalRefractionMapping球面折射映射. 65 | * @default THREE.Texture.DEFAULT_MAPPING 66 | * @type {number} 67 | */ 68 | this.mapping = mapping !== undefined ? mapping : THREE.Texture.DEFAULT_MAPPING; 69 | /** 70 | * @desc S方向纹理覆盖方式,有
71 | * THREE.RepeatWrapping = 1000; //平铺
72 | * THREE.ClampToEdgeWrapping = 1001; //夹取
73 | * THREE.MirroredRepeatWrapping = 1002; //镜像
74 | * 纹理映射范围 (0.0 , 1.0) 75 | * @default THREE.ClampToEdgeWrapping 76 | * @type {number} 77 | */ 78 | this.wrapS = wrapS !== undefined ? wrapS : THREE.ClampToEdgeWrapping; 79 | /** 80 | * @desc T方向纹理覆盖方式,有
81 | * THREE.RepeatWrapping = 1000; //平铺
82 | * THREE.ClampToEdgeWrapping = 1001; //夹取
83 | * THREE.MirroredRepeatWrapping = 1002; //镜像
84 | * 纹理映射范围 (0.0 , 1.0) 85 | * @default THREE.ClampToEdgeWrapping 86 | * @type {number} 87 | */ 88 | this.wrapT = wrapT !== undefined ? wrapT : THREE.ClampToEdgeWrapping; 89 | /** 90 | * @desc 纹理放大采样方式,有
91 | * THREE.NearestFilter = 1003; //在纹理基层上执行最邻近过滤,
92 | * THREE.NearestMipMapNearestFilter = 1004; //在mip层之间执行线性插补,并执行最临近的过滤,
93 | * THREE.NearestMipMapLinearFilter = 1005; //选择最临近的mip层,并执行最临近的过滤,
94 | * THREE.LinearFilter = 1006; //在纹理基层上执行线性过滤
95 | * THREE.LinearMipMapNearestFilter = 1007; //选择最临近的mip层,并执行线性过滤,
96 | * THREE.LinearMipMapLinearFilter = 1008; //在mip层之间执行线性插补,并执行线性过滤
97 | * @default THREE.LinearFilter 98 | * @type {number} 99 | */ 100 | this.magFilter = magFilter !== undefined ? magFilter : THREE.LinearFilter; 101 | /** 102 | * @desc 纹理缩小采样方式,只有缩小能用Mipmap ,有
103 | * THREE.NearestFilter = 1003; //在纹理基层上执行最邻近过滤,
104 | * THREE.NearestMipMapNearestFilter = 1004; //在mip层之间执行线性插补,并执行最临近的过滤,
105 | * THREE.NearestMipMapLinearFilter = 1005; //选择最临近的mip层,并执行最临近的过滤,
106 | * THREE.LinearFilter = 1006; //在纹理基层上执行线性过滤
107 | * THREE.LinearMipMapNearestFilter = 1007; //选择最临近的mip层,并执行线性过滤,
108 | * THREE.LinearMipMapLinearFilter = 1008; //在mip层之间执行线性插补,并执行线性过滤
109 | * @default THREE.LinearMipMapLinearFilter 110 | * @type {number} 111 | */ 112 | this.minFilter = minFilter !== undefined ? minFilter : THREE.LinearMipMapLinearFilter; 113 | /** 114 | * @desc 各向异性,取值范围0.0-1.0,经常用来通过这个值,产生不同的表面效果,木材和金属都发光,但是发光的特点是有区别的. 115 | * @default 1 116 | * @type {float} 117 | */ 118 | this.anisotropy = anisotropy !== undefined ? anisotropy : 1; 119 | /** 120 | * @desc 像素颜色格式,有
121 | * THREE.AlphaFormat = 1019; //GL_ALPHA Alpha 值
122 | * THREE.RGBFormat = 1020; //Red, Green, Blue 三原色值
123 | * THREE.RGBAFormat = 1021; //Red, Green, Blue 和 Alpha 值
124 | * THREE.LuminanceFormat = 1022; //灰度值
125 | * THREE.LuminanceAlphaFormat = 1023; //灰度值和 Alpha 值
126 | * @default THREE.RGBAFormat 127 | * @type {number} 128 | */ 129 | this.format = format !== undefined ? format : THREE.RGBAFormat; 130 | /** 131 | * @desc 定义纹理像素的数据类型,有
132 | * THREE.UnsignedByteType = 1009; //不带符号8位整形值(一个字节)
133 | * THREE.ByteType = 1010; //带符号8位整形值(一个字节)
134 | * THREE.ShortType = 1011; //带符号16位整形值(2个字节)
135 | * THREE.UnsignedShortType = 1012; //不带符号16未整形值(2个字节)
136 | * THREE.IntType = 1013; //带符号32位整形值(4个字节)
137 | * THREE.UnsignedIntType = 1014; //不带符号32位整形值(4个字节)
138 | * THREE.FloatType = 1015; //单精度浮点型(4个字节) 139 | * @default THREE.UnsignedByteType 140 | * @type {number} 141 | */ 142 | this.type = type !== undefined ? type : THREE.UnsignedByteType; 143 | /** 144 | * @desc 纹理偏移值 145 | * @default ( 0 , 0) 146 | * @type {THREE.Vector2} 147 | */ 148 | this.offset = new THREE.Vector2( 0, 0 ); 149 | /** 150 | * @desc 纹理重复值 151 | * @default ( 1 , 1) 152 | * @type {THREE.Vector2} 153 | */ 154 | this.repeat = new THREE.Vector2( 1, 1 ); 155 | /** 156 | * @desc 是否生成Mipmap 157 | * @default 158 | * @type {boolean} 159 | */ 160 | this.generateMipmaps = true; 161 | /** 162 | * @desc 预乘Alpha值,如果设置为true,纹素的rgb值会先乘以alpha值,然后在存储 163 | * @default 164 | * @type {boolean} 165 | */ 166 | this.premultiplyAlpha = false; 167 | /** 168 | * @desc 纹理是否需要垂直翻转 169 | * @default 170 | * @type {boolean} 171 | */ 172 | this.flipY = true; 173 | /** 174 | * @desc 字节对齐 175 | * @default 176 | * @type {number} 177 | */ 178 | this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) 179 | /** 180 | * @desc 当设为true,则纹理已更新 181 | * @default 182 | * @pravite 183 | * @type {number} 184 | */ 185 | this._needsUpdate = false; 186 | /** 187 | * @dsc 更新回调函数 188 | * @type {null} 189 | */ 190 | this.onUpdate = null; 191 | 192 | }; 193 | /** 194 | * @memberof THREE.Texture 195 | * @desc 默认纹理 196 | * @type {number} 197 | */ 198 | THREE.Texture.DEFAULT_IMAGE = undefined; 199 | /** 200 | * @memberof THREE.Texture 201 | * @desc 默认UVMapping方式 202 | * @type {number} 203 | */ 204 | THREE.Texture.DEFAULT_MAPPING = new THREE.UVMapping(); 205 | 206 | THREE.Texture.prototype = { 207 | 208 | constructor: THREE.Texture, 209 | /** 210 | * @desc 获得是否更新 211 | * @returns {number} 212 | */ 213 | get needsUpdate () { 214 | 215 | return this._needsUpdate; 216 | 217 | }, 218 | 219 | /** 220 | * @desc 设置是否更新,若为true则执行更新函数 221 | * @param value 222 | */ 223 | set needsUpdate ( value ) { 224 | 225 | if ( value === true ) this.update(); 226 | 227 | this._needsUpdate = value; 228 | 229 | }, 230 | /** 231 | * @desc 纹理克隆 232 | * @param {THREE.Texture} texture 233 | * @returns {THREE.Texture} 234 | */ 235 | clone: function ( texture ) { 236 | 237 | if ( texture === undefined ) texture = new THREE.Texture(); 238 | 239 | texture.image = this.image; 240 | texture.mipmaps = this.mipmaps.slice( 0 ); 241 | 242 | texture.mapping = this.mapping; 243 | 244 | texture.wrapS = this.wrapS; 245 | texture.wrapT = this.wrapT; 246 | 247 | texture.magFilter = this.magFilter; 248 | texture.minFilter = this.minFilter; 249 | 250 | texture.anisotropy = this.anisotropy; 251 | 252 | texture.format = this.format; 253 | texture.type = this.type; 254 | 255 | texture.offset.copy( this.offset ); 256 | texture.repeat.copy( this.repeat ); 257 | 258 | texture.generateMipmaps = this.generateMipmaps; 259 | texture.premultiplyAlpha = this.premultiplyAlpha; 260 | texture.flipY = this.flipY; 261 | texture.unpackAlignment = this.unpackAlignment; 262 | 263 | return texture; 264 | 265 | }, 266 | /** 267 | * @desc 纹理更新事件 268 | */ 269 | update: function () { 270 | 271 | this.dispatchEvent( { type: 'update' } ); 272 | 273 | }, 274 | /** 275 | * @desc 纹理销毁事件 276 | */ 277 | dispose: function () { 278 | 279 | this.dispatchEvent( { type: 'dispose' } ); 280 | 281 | } 282 | 283 | }; 284 | 285 | THREE.EventDispatcher.prototype.apply( THREE.Texture.prototype ); 286 | /** 287 | * @memberof THREE 288 | * @desc 全局纹理数目 289 | * @type {number} 290 | */ 291 | THREE.TextureIdCount = 0; 292 | --------------------------------------------------------------------------------