├── .idea
└── .name
├── renderers
├── shaders
│ ├── ShaderChunk.js
│ ├── UniformsUtils.js
│ └── UniformsLib.js
├── WebGLRenderTargetCube.js
├── webgl
│ ├── WebGLShader.js
│ └── WebGLExtensions.js
└── WebGLRenderTarget.js
├── README.md
├── core
├── Face4.js
├── Projector.js
├── Clock.js
├── Face3.js
├── EventDispatcher.js
├── Raycaster.js
└── BufferAttribute.js
├── objects
├── Group.js
├── Bone.js
├── Sprite.js
├── LensFlare.js
├── LOD.js
├── Line.js
├── PointCloud.js
├── SkinnedMesh.js
├── Skeleton.js
└── MorphAnimMesh.js
├── extras
├── objects
│ └── ImmediateRenderObject.js
├── GeometryUtils.js
├── SceneUtils.js
└── ImageUtils.js
├── lights
├── AmbientLight.js
├── Light.js
├── PointLight.js
├── HemisphereLight.js
├── AreaLight.js
├── SpotLight.js
└── DirectionalLight.js
├── scenes
├── FogExp2.js
├── Fog.js
└── Scene.js
├── materials
├── RawShaderMaterial.js
├── MeshFaceMaterial.js
├── SpriteMaterial.js
├── MeshDepthMaterial.js
├── MeshNormalMaterial.js
├── LineBasicMaterial.js
├── LineDashedMaterial.js
├── PointCloudMaterial.js
├── ShaderMaterial.js
├── MeshBasicMaterial.js
├── MeshLambertMaterial.js
└── MeshPhongMaterial.js
├── textures
├── VideoTexture.js
├── CubeTexture.js
├── DataTexture.js
└── CompressedTexture.js
├── cameras
├── Camera.js
├── OrthographicCamera.js
├── CubeCamera.js
└── PerspectiveCamera.js
└── math
├── Line3.js
├── Sphere.js
├── Math.js
├── Spline.js
├── Frustum.js
├── Triangle.js
├── Box2.js
└── Plane.js
/.idea/.name:
--------------------------------------------------------------------------------
1 | ThreeJS-Notes
--------------------------------------------------------------------------------
/renderers/shaders/ShaderChunk.js:
--------------------------------------------------------------------------------
1 | THREE.ShaderChunk = {};
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ThreeJS-Notes
2 | 对ThreeJS的中文注释,可以使用JSDOC可以自动生成说明文档
3 | 部分内容参照omni360同学已经写过的注释,https://github.com/omni360/three.js.sourcecode
4 |
5 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/objects/Group.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 | /**
5 | * @classdesc 对象组
6 | * @constructor
7 | */
8 | THREE.Group = function () {
9 |
10 | THREE.Object3D.call( this );
11 |
12 | this.type = 'Group';
13 |
14 | };
15 | /**
16 | * @desc Group从Object3D的原型继承所有属性方法
17 | * @type {THREE.Object3D}
18 | */
19 | THREE.Group.prototype = Object.create( THREE.Object3D.prototype );
20 |
--------------------------------------------------------------------------------
/extras/objects/ImmediateRenderObject.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 | /**
5 | * @classdesc 即时渲染对象
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @constructor
8 | */
9 | THREE.ImmediateRenderObject = function () {
10 |
11 | THREE.Object3D.call( this );
12 |
13 | this.render = function ( renderCallback ) {};
14 |
15 | };
16 | /**
17 | * @desc ImmediateRenderObject从Object3D的原型继承所有属性方法
18 | * @type {THREE.Object3D}
19 | */
20 | THREE.ImmediateRenderObject.prototype = Object.create( THREE.Object3D.prototype );
21 |
--------------------------------------------------------------------------------
/objects/Bone.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mikael emtinger / http://gomo.se/
3 | * @author alteredq / http://alteredqualia.com/
4 | * @author ikerr / http://verold.com
5 | */
6 | /**
7 | * @classdesc 骨骼对象
8 | * 注释内容部分参照 http://blog.csdn.net/omni360
9 | * @param {THREE.SkinnedMesh} belongsToSkin 蒙皮对象
10 | * @constructor
11 | */
12 | THREE.Bone = function ( belongsToSkin ) {
13 |
14 | THREE.Object3D.call( this );
15 | /**
16 | * @desc 骨骼对象的皮肤
17 | * @type {THREE.SkinnedMesh}
18 | */
19 | this.skin = belongsToSkin;
20 |
21 | };
22 | /**
23 | * @desc Bone从Object3D的原型继承所有属性方法
24 | * @type {THREE.Object3D}
25 | */
26 | THREE.Bone.prototype = Object.create( THREE.Object3D.prototype );
27 |
28 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lights/AmbientLight.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 | /**
5 | * @classdesc 环境光对象
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @param {THREE.Color} color 环境光的颜色
8 | * @extends {THREE.Light}
9 | * @constructor
10 | */
11 | THREE.AmbientLight = function ( color ) {
12 |
13 | THREE.Light.call( this, color );
14 | /**
15 | * @default
16 | * @type {string}
17 | */
18 | this.type = 'AmbientLight';
19 |
20 | };
21 | /**
22 | * @desc AmbientLight对象从THREE.Light的原型继承所有属性方法
23 | * @type {THREE.Light}
24 | */
25 | THREE.AmbientLight.prototype = Object.create( THREE.Light.prototype );
26 | /**
27 | * @desc AmbientLight克隆函数
28 | * @returns {THREE.AmbientLight}
29 | */
30 | THREE.AmbientLight.prototype.clone = function () {
31 |
32 | var light = new THREE.AmbientLight();
33 |
34 | THREE.Light.prototype.clone.call( this, light );
35 |
36 | return light;
37 |
38 | };
39 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
9 | * @param {THREE.Color} color 雾效的颜色属性,如果雾效颜色设置成黑色,远处的对象将被渲染成黑色
10 | * @param {float} density 雾效强度递增指数属性,可选参数,默认是0.00025
11 | * @constructor
12 | */
13 | THREE.FogExp2 = function ( color, density ) {
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 0.00025
28 | * @type {float}
29 | */
30 | this.density = ( density !== undefined ) ? density : 0.00025;
31 |
32 | };
33 |
34 | /**
35 | * @desc 指数雾的克隆
36 | * @returns {THREE.FogExp2}
37 | */
38 | THREE.FogExp2.prototype.clone = function () {
39 |
40 | return new THREE.FogExp2( this.color.getHex(), this.density );
41 |
42 | };
43 |
--------------------------------------------------------------------------------
/materials/RawShaderMaterial.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 | /**
5 | * @classdesc 自定义着色器材质类型
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @desc 自定义着色器材质类型让用户扩充材质类型,有了无限的可能
8 | * 这个类和ShaderMaterial工作方式一样
9 | * 除了自定义的uniforms和attribute属性不会自动追加到GLSL着色器代码中
10 | * 表面有光泽的材质类型,计算每个像素
11 | * @param {String} parameters 材质参数
12 | * @extends {THREE.ShaderMaterial}
13 | * @constructor
14 | */
15 | THREE.RawShaderMaterial = function ( parameters ) {
16 |
17 | THREE.ShaderMaterial.call( this, parameters );
18 | /**
19 | * @default 'RawShaderMaterial'
20 | * @type {string}
21 | */
22 | this.type = 'RawShaderMaterial';
23 |
24 | };
25 | /**
26 | * @desc RawShaderMaterial对象从THREE.Material的原型继承所有属性方法
27 | * @type {THREE.ShaderMaterial}
28 | */
29 | THREE.RawShaderMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype );
30 | /**
31 | * @desc RawShaderMaterial材质的克隆函数
32 | * @returns {THREE.RawShaderMaterial}
33 | */
34 | THREE.RawShaderMaterial.prototype.clone = function () {
35 |
36 | var material = new THREE.RawShaderMaterial();
37 |
38 | THREE.ShaderMaterial.prototype.clone.call( this, material );
39 |
40 | return material;
41 |
42 | };
43 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
9 | * @param {THREE.Color} color 雾的颜色
10 | * @param {float} near 雾效的起始点,雾效的near属性大于当前相机的near属性,当前相机才不会受相机影响,可选参数,默认是1
11 | * @param {float} far 雾效的结束点,雾效的far属性小于当前相机的far属性,当前相机才不会受相机影响,可选参数,默认是1000
12 | * @constructor
13 | */
14 | THREE.Fog = function ( color, near, far ) {
15 | /**
16 | * @desc 雾的名字
17 | * @default ''
18 | * @type {string}
19 | */
20 | this.name = '';
21 | /**
22 | * @desc 雾效颜色
23 | * @type {THREE.Color}
24 | */
25 | this.color = new THREE.Color( color );
26 | /**
27 | * @desc 雾的最近距离
28 | * @default 1
29 | * @type {float}
30 | */
31 | this.near = ( near !== undefined ) ? near : 1;
32 | /**
33 | * @desc 雾的最远距离
34 | * @default 1000
35 | * @type {float}
36 | */
37 | this.far = ( far !== undefined ) ? far : 1000;
38 |
39 | };
40 | /**
41 | * @desc 雾对象的克隆
42 | * @returns {THREE.Fog}
43 | */
44 | THREE.Fog.prototype.clone = function () {
45 |
46 | return new THREE.Fog( this.color.getHex(), this.near, this.far );
47 |
48 | };
49 |
--------------------------------------------------------------------------------
/extras/GeometryUtils.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 | /**
5 | * @classdesc 几何对象工具集
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @ignore
8 | * @constructor
9 | */
10 | THREE.GeometryUtils = {
11 | /**
12 | * @desc 合并几何对象
13 | * @param {THREE.Geometry} geometry1 几何对象1
14 | * @param {THREE.Geometry} geometry2 几何对象2
15 | * @param {float} materialIndexOffset 材质索引偏移量
16 | */
17 | merge: function ( geometry1, geometry2, materialIndexOffset ) {
18 |
19 | console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );
20 |
21 | var matrix;
22 |
23 | if ( geometry2 instanceof THREE.Mesh ) {
24 |
25 | geometry2.matrixAutoUpdate && geometry2.updateMatrix();
26 |
27 | matrix = geometry2.matrix;
28 | geometry2 = geometry2.geometry;
29 |
30 | }
31 |
32 | geometry1.merge( geometry2, matrix, materialIndexOffset );
33 |
34 | },
35 | /**
36 | * @desc 计算几何对象的中心
37 | * @param {THREE.Geometry} geometry
38 | * @returns {*}
39 | */
40 | center: function ( geometry ) {
41 |
42 | console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );
43 | return geometry.center();
44 |
45 | }
46 |
47 | };
48 |
--------------------------------------------------------------------------------
/lights/Light.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | * @author alteredq / http://alteredqualia.com/
4 | */
5 | /**
6 | * @classdesc 灯光对象的抽象基类
7 | * 注释内容部分参照 http://blog.csdn.net/omni360
8 | * @desc 在WebGL的三维空间中,存在点光源PointLight和聚光灯SpotLight两种类型,还有作为点光源的一种特例
9 | * 平行光DirectionLight,和环境光AmbientLight.在3D场景中,基本上是这几种光源的组合,创建各种各样的效果
10 | * @param {THREE.Color} color 灯光颜色值
11 | * @extends {THREE.Object3D}
12 | * @constructor
13 | */
14 | THREE.Light = function ( color ) {
15 |
16 | THREE.Object3D.call( this );
17 | /**
18 | * @default
19 | * @type {string}
20 | */
21 | this.type = 'Light';
22 |
23 | /**
24 | * @desc //设置灯光的颜色属性
25 | * @type {THREE.Color}
26 | */
27 | this.color = new THREE.Color( color );
28 |
29 | };
30 | /**
31 | * @desc Light对象从THREE.Objec3D的原型继承所有属性方法
32 | * @type {THREE.Object3D}
33 | */
34 | THREE.Light.prototype = Object.create( THREE.Object3D.prototype );
35 | /**
36 | * @desc Light克隆函数
37 | * @param {THREE.Light} light
38 | * @returns {THREE.Light}
39 | */
40 | THREE.Light.prototype.clone = function ( light ) {
41 |
42 | if ( light === undefined ) light = new THREE.Light();
43 |
44 | THREE.Object3D.prototype.clone.call( this, light );
45 |
46 | light.color.copy( this.color );
47 |
48 | return light;
49 |
50 | };
51 |
--------------------------------------------------------------------------------
/textures/VideoTexture.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 | /**
5 | * @classdesc 视频纹理对象
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @extends {THREE.Texture}
8 | * @param {*} video 视频对象
9 | * @param {number} mapping 映射模式
10 | * @param {number} wrapS S方向覆盖模式
11 | * @param {number} wrapT T方向覆盖模式
12 | * @param {number} magFilter 纹理在放大时的过滤方式
13 | * @param {number} minFilter 纹理在缩小时的过滤方式
14 | * @param {number} format 像素数据的颜色格式
15 | * @param {number} type 数据类型
16 | * @param {number} anisotropy 各向异性
17 | * @constructor
18 | */
19 | THREE.VideoTexture = function ( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
20 |
21 | THREE.Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
22 | /**
23 | * @default
24 | * @type {boolean}
25 | */
26 | this.generateMipmaps = false;
27 |
28 | // 视频运行
29 | var scope = this;
30 |
31 | var update = function () {
32 |
33 | requestAnimationFrame( update );
34 |
35 | if ( video.readyState === video.HAVE_ENOUGH_DATA ) {
36 |
37 | scope.needsUpdate = true;
38 |
39 | }
40 |
41 | };
42 |
43 | update();
44 |
45 | };
46 | /**
47 | * @desc 数据纹理从THREE.Texture的原型继承所有属性方法
48 | * @type {THREE.Object3D}
49 | */
50 | THREE.VideoTexture.prototype = Object.create( THREE.Texture.prototype );
51 |
--------------------------------------------------------------------------------
/textures/CubeTexture.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 | /**
5 | * @classdesc 立方体纹理对象
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @extends {THREE.Texture}
8 | * @param {Image} images 图像对象
9 | * @param {number} mapping 映射模式
10 | * @param {number} wrapS S方向覆盖模式
11 | * @param {number} wrapT T方向覆盖模式
12 | * @param {number} magFilter 纹理在放大时的过滤方式
13 | * @param {number} minFilter 纹理在缩小时的过滤方式
14 | * @param {number} format 像素数据的颜色格式
15 | * @param {number} type 数据类型
16 | * @param {number} anisotropy 各向异性
17 | * @constructor
18 | */
19 | THREE.CubeTexture = function ( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
20 |
21 | THREE.Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
22 |
23 | this.images = images;
24 |
25 | };
26 | /**
27 | * @desc 数据纹理从THREE.Texture的原型继承所有属性方法
28 | * @type {THREE.Object3D}
29 | */
30 | THREE.CubeTexture.prototype = Object.create( THREE.Texture.prototype );
31 | /**
32 | * @desc 克隆函数
33 | * @returns {THREE.DataTexture}
34 | */
35 | THREE.CubeTexture.clone = function ( texture ) {
36 |
37 | if ( texture === undefined ) texture = new THREE.CubeTexture();
38 |
39 | THREE.Texture.prototype.clone.call( this, texture );
40 |
41 | texture.images = this.images;
42 |
43 | return texture;
44 |
45 | };
46 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/textures/DataTexture.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 | /**
5 | * @classdesc 由二进制数据生成的纹理对象
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @extends {THREE.Texture}
8 | * @param {*} data 图像数据
9 | * @param {number} width 图像宽度
10 | * @param {number} height 图像高度
11 | * @param {number} format 像素数据的颜色格式
12 | * @param {number} type 数据类型
13 | * @param {number} mapping 映射模式
14 | * @param {number} wrapS S方向覆盖模式
15 | * @param {number} wrapT T方向覆盖模式
16 | * @param {number} magFilter 纹理在放大时的过滤方式
17 | * @param {number} minFilter 纹理在缩小时的过滤方式
18 | * @param {number} anisotropy 各向异性
19 | * @constructor
20 | */
21 | THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy ) {
22 |
23 | THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
24 |
25 | this.image = { data: data, width: width, height: height };
26 |
27 | };
28 | /**
29 | * @desc 数据纹理从THREE.Texture的原型继承所有属性方法
30 | * @type {THREE.Object3D}
31 | */
32 | THREE.DataTexture.prototype = Object.create( THREE.Texture.prototype );
33 |
34 | /**
35 | * @desc 克隆函数
36 | * @returns {THREE.DataTexture}
37 | */
38 | THREE.DataTexture.prototype.clone = function () {
39 |
40 | var texture = new THREE.DataTexture();
41 |
42 | THREE.Texture.prototype.clone.call( this, texture );
43 |
44 | return texture;
45 |
46 | };
47 |
--------------------------------------------------------------------------------
/extras/SceneUtils.js:
--------------------------------------------------------------------------------
1 | /**
* @author alteredq / http://alteredqualia.com/
*/
/**
* @classdesc 场景对象工具集
* 注释内容部分参照 http://blog.csdn.net/omni360
* @constructor
*/
THREE.SceneUtils = {
/**
* @desc 创建一种新的Objec3D对象,每个网格对象对应一种材质
* 这里和一个网格的每个面使用Meshfacematerial 材质不同.这种方式适用于网格对象在线框和着色几种材质之间变换频繁
* @param {THREE.Geometry} geometry 几何对象
* @param {THREE.Material} materials 材质对象
* @returns {THREE.Object3D}
*/
createMultiMaterialObject: function ( geometry, materials ) {
var group = new THREE.Object3D();
for ( var i = 0, l = materials.length; i < l; i ++ ) {
group.add( new THREE.Mesh( geometry, materials[ i ] ) );
}
return group;
},
/**
* @desc 将子对象(参数child)从父对象中删除(参数parent),并重新将子对象添加到场景中.
* @param {THREE.Object3D} child 子对象
* @param {THREE.Object3D} parent 父对象
* @param {THREE.Scene} scene 场景对象
*/
detach: function ( child, parent, scene ) {
child.applyMatrix( parent.matrixWorld );
parent.remove( child );
scene.add( child );
},
/**
* @desc 将子对象冲场景中移除,加入父对象中
* @param {THREE.Object3D} child 子对象
* @param {THREE.Scene} scene 场景对象
* @param {THREE.Object3D} parent 父对象
*/
attach: function ( child, scene, parent ) {
var matrixWorldInverse = new THREE.Matrix4();
matrixWorldInverse.getInverse( parent.matrixWorld );
child.applyMatrix( matrixWorldInverse );
scene.remove( child );
parent.add( child );
}
};
--------------------------------------------------------------------------------
/lights/PointLight.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 | /**
5 | * @classdesc 点光源对象
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @desc 点光源目前不支持阴影
8 | * @param {THREE.Color} color 点光源颜色
9 | * @param {float} intensity 光的强度,默认是1
10 | * @param {float} distance 光的长度,从光的position位置,开始衰减,衰减到distance的长度,默认是0
11 | * @extends {THREE.Light}
12 | * @example var light = new THREE.PointLight(0xff0000,1,100);
13 | * light.position.set(50,50,30); //设置位置
14 | * scene.add(lignt); //加入场景
15 | * @constructor
16 | */
17 | THREE.PointLight = function ( color, intensity, distance ) {
18 |
19 | THREE.Light.call( this, color );
20 | /**
21 | * @default
22 | * @type {string}
23 | */
24 | this.type = 'PointLight';
25 | /**
26 | * @desc 光的强度
27 | * @default 1
28 | * @type {float}
29 | */
30 | this.intensity = ( intensity !== undefined ) ? intensity : 1;
31 | /**
32 | * @desc 光的长度
33 | * @default 0
34 | * @type {float}
35 | */
36 | this.distance = ( distance !== undefined ) ? distance : 0;
37 |
38 | };
39 | /**
40 | * @desc PointLight对象从THREE.Light的原型继承所有属性方法
41 | * @type {THREE.Light}
42 | */
43 | THREE.PointLight.prototype = Object.create( THREE.Light.prototype );
44 | /**
45 | * @desc PointLight克隆函数
46 | * @returns {THREE.PointLight}
47 | */
48 | THREE.PointLight.prototype.clone = function () {
49 |
50 | var light = new THREE.PointLight();
51 |
52 | THREE.Light.prototype.clone.call( this, light );
53 |
54 | light.intensity = this.intensity;
55 | light.distance = this.distance;
56 |
57 | return light;
58 |
59 | };
60 |
--------------------------------------------------------------------------------
/lights/HemisphereLight.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 | /**
5 | * @classdesc 半球光对象
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @desc HemisphereLight类是在场景中创建半球光,就是天光效果
8 | * 经常用在室外,将各个位置的物体都照亮,室内的光线大多是方向性的
9 | * 半球光不支持阴影
10 | * @param {THREE.Color} skyColor 半球光的颜色(天光的颜色)
11 | * @param {THREE.Color} groundColor 半球光的地面颜色
12 | * @param {float} intensity 灯光的强度,默认是1
13 | * @extends {THREE.Light}
14 | * @constructor
15 | */
16 | THREE.HemisphereLight = function ( skyColor, groundColor, intensity ) {
17 |
18 | THREE.Light.call( this, skyColor );
19 | /**
20 | * @default
21 | * @type {string}
22 | */
23 | this.type = 'HemisphereLight';
24 |
25 | /**
26 | * @desc 灯光初始化位置为(0,100,0)
27 | */
28 | this.position.set( 0, 100, 0 );
29 |
30 | /**
31 | * @desc 半球光的地面颜色
32 | * @type {THREE.Color}
33 | */
34 | this.groundColor = new THREE.Color( groundColor );
35 | /**
36 | * @desc 灯光的强度
37 | * @default 1
38 | * @type {number}
39 | */
40 | this.intensity = ( intensity !== undefined ) ? intensity : 1;
41 |
42 | };
43 | /**
44 | * @desc HemisphereLight对象从THREE.Light的原型继承所有属性方法
45 | * @type {THREE.Light}
46 | */
47 | THREE.HemisphereLight.prototype = Object.create( THREE.Light.prototype );
48 | /**
49 | * @desc HemisphereLight克隆函数
50 | * @returns {THREE.HemisphereLight}
51 | */
52 | THREE.HemisphereLight.prototype.clone = function () {
53 |
54 | var light = new THREE.HemisphereLight();
55 |
56 | THREE.Light.prototype.clone.call( this, light );
57 |
58 | light.groundColor.copy( this.groundColor );
59 | light.intensity = this.intensity;
60 |
61 | return light;
62 |
63 | };
64 |
--------------------------------------------------------------------------------
/materials/MeshFaceMaterial.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 | /**
5 | * @classdesc mesh(网格)的网格复合材质
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @desc 多材质,支持材质的列表
8 | * 离相机越近,材质越亮(白),离相机越远,材质越暗(黑)
9 | * @param {String} parameters 材质参数
10 | * @extends {THREE.Material}
11 | * @constructor
12 | */
13 | THREE.MeshFaceMaterial = function ( materials ) {
14 |
15 | this.uuid = THREE.Math.generateUUID();
16 | /**
17 | * @default 'MeshFaceMaterial'
18 | * @type {string}
19 | */
20 | this.type = 'MeshFaceMaterial';
21 |
22 | /**
23 | * @desc 材质列表
24 | */
25 | this.materials = materials instanceof Array ? materials : [];
26 |
27 | };
28 |
29 | THREE.MeshFaceMaterial.prototype = {
30 |
31 | constructor: THREE.MeshFaceMaterial,
32 | /**
33 | * @desc 材质列表转换JSON格式
34 | * @returns {*}
35 | */
36 | toJSON: function () {
37 |
38 | var output = {
39 | metadata: {
40 | version: 4.2,
41 | type: 'material',
42 | generator: 'MaterialExporter'
43 | },
44 | uuid: this.uuid,
45 | type: this.type,
46 | materials: []
47 | };
48 |
49 | for ( var i = 0, l = this.materials.length; i < l; i ++ ) {
50 |
51 | output.materials.push( this.materials[ i ].toJSON() );
52 |
53 | }
54 |
55 | return output;
56 |
57 | },
58 | /**
59 | * @desc MeshFaceMaterial材质的克隆函数
60 | * @returns {THREE.MeshFaceMaterial}
61 | */
62 | clone: function () {
63 |
64 | var material = new THREE.MeshFaceMaterial();
65 |
66 | for ( var i = 0; i < this.materials.length; i ++ ) {
67 |
68 | material.materials.push( this.materials[ i ].clone() );
69 |
70 | }
71 |
72 | return material;
73 |
74 | }
75 |
76 | };
77 |
--------------------------------------------------------------------------------
/renderers/shaders/UniformsUtils.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Uniform Utilities
3 | */
4 | /**
5 | * @classdesc Uniforms操作
6 | * @memberof THREE
7 | * @constructor
8 | */
9 | THREE.UniformsUtils = {
10 | /**
11 | * @desc 合并uniform参数
12 | * @param {array} uniforms
13 | * @returns {array}
14 | */
15 | merge: function ( uniforms ) {
16 |
17 | var merged = {};
18 |
19 | for ( var u = 0; u < uniforms.length; u ++ ) {
20 |
21 | var tmp = this.clone( uniforms[ u ] );
22 |
23 | for ( var p in tmp ) {
24 |
25 | merged[ p ] = tmp[ p ];
26 |
27 | }
28 |
29 | }
30 |
31 | return merged;
32 |
33 | },
34 | /**
35 | * @desc THREE.UniformsUtils 克隆函数
36 | * @param {THREE.UniformsUtils} uniforms_src
37 | * @returns {THREE.UniformsUtils}
38 | */
39 | clone: function ( uniforms_src ) {
40 |
41 | var uniforms_dst = {};
42 |
43 | for ( var u in uniforms_src ) {
44 |
45 | uniforms_dst[ u ] = {};
46 |
47 | for ( var p in uniforms_src[ u ] ) {
48 |
49 | var parameter_src = uniforms_src[ u ][ p ];
50 |
51 | if ( parameter_src instanceof THREE.Color ||
52 | parameter_src instanceof THREE.Vector2 ||
53 | parameter_src instanceof THREE.Vector3 ||
54 | parameter_src instanceof THREE.Vector4 ||
55 | parameter_src instanceof THREE.Matrix4 ||
56 | parameter_src instanceof THREE.Texture ) {
57 |
58 | uniforms_dst[ u ][ p ] = parameter_src.clone();
59 |
60 | } else if ( parameter_src instanceof Array ) {
61 |
62 | uniforms_dst[ u ][ p ] = parameter_src.slice();
63 |
64 | } else {
65 |
66 | uniforms_dst[ u ][ p ] = parameter_src;
67 |
68 | }
69 |
70 | }
71 |
72 | }
73 |
74 | return uniforms_dst;
75 |
76 | }
77 |
78 | };
79 |
--------------------------------------------------------------------------------
/scenes/Scene.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 |
5 | /**
6 | * @classdesc Scene是场景对象,所有的对象,灯光,动画,骨骼等都需要放置在场景内.Scene对象的功能函数采用定义构造的函数原型对象来实现.
7 | * 注释内容部分参照 http://blog.csdn.net/omni360
8 | * @desc 场景对象构造函数
9 | * @class
10 | * @extends {THREE.Object3D}
11 | */
12 | THREE.Scene = function () {
13 |
14 | // 调用Object3D对象的call方法,将原本属于Object3D的方法交给当前对象Scene来使用.
15 | THREE.Object3D.call( this );
16 |
17 | /**
18 | * @desc 场景的类型定义
19 | * @default
20 | * @type {string}
21 | */
22 | this.type = 'Scene';
23 | /**
24 | * @desc 场景的雾效属性
25 | * @default
26 | * @type {THREE.fog}
27 | */
28 | this.fog = null;
29 | /**
30 | * @desc 场景的材质属性,默认为null,如果设置了这个属性,场景中的所有对象渲染成这个材质.
31 | * @default
32 | * @type {THREE.Material}
33 | */
34 | this.overrideMaterial = null;
35 |
36 | /**
37 | * @desc 默认为true,表示渲染器每一帧都会检查场景和场景中的对象的矩阵的是否更新,如果为false,场景中的对象将不会被自动更新
38 | * @default
39 | * @type {boolean}
40 | */
41 | this.autoUpdate = true; // checked by the renderer
42 |
43 | };
44 |
45 | /**
46 | * @desc Scene对象从THREE.Objec3D的原型继承所有属性方法
47 | * @type {THREE.Object3D}
48 | */
49 | THREE.Scene.prototype = Object.create( THREE.Object3D.prototype );
50 |
51 | /**
52 | * @desc Three.Scene 拷贝函数,将属性数组分别复制
53 | * @param {THREE.Scene} object - 源Scene
54 | * @returns {THREE.Scene}
55 | */
56 | THREE.Scene.prototype.clone = function ( object ) {
57 |
58 | if ( object === undefined ) object = new THREE.Scene();
59 |
60 | THREE.Object3D.prototype.clone.call( this, object );
61 |
62 | if ( this.fog !== null ) object.fog = this.fog.clone();
63 | if ( this.overrideMaterial !== null ) object.overrideMaterial = this.overrideMaterial.clone();
64 |
65 | object.autoUpdate = this.autoUpdate;
66 | object.matrixAutoUpdate = this.matrixAutoUpdate;
67 |
68 | return object;
69 |
70 | };
71 |
--------------------------------------------------------------------------------
/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 | * @classdesc Sprite(点精灵)的材质
21 | * 注释内容部分参照 http://blog.csdn.net/omni360
22 | * @param {String} parameters 材质参数
23 | * @extends {THREE.Material}
24 | * @constructor
25 | */
26 | THREE.SpriteMaterial = function ( parameters ) {
27 |
28 | THREE.Material.call( this );
29 | /**
30 | * @default 'SpriteMaterial'
31 | * @type {string}
32 | */
33 | this.type = 'SpriteMaterial';
34 | /**
35 | * @desc 材质颜色
36 | * @default 0xffffff 白色
37 | * @type {THREE.Color}
38 | */
39 | this.color = new THREE.Color( 0xffffff );
40 | /**
41 | * @desc 纹理贴图
42 | * @default
43 | * @type {THREE.Texture}
44 | */
45 | this.map = null;
46 | /**
47 | * @desc 旋转角度,粒子系统的贴图的旋转角度
48 | * @type {float}
49 | */
50 | this.rotation = 0;
51 | /**
52 | * @desc 雾效,默认关闭
53 | * @default
54 | * @type {boolean}
55 | */
56 | this.fog = false;
57 |
58 | // set parameters
59 |
60 | this.setValues( parameters );
61 |
62 | };
63 |
64 | THREE.SpriteMaterial.prototype = Object.create( THREE.Material.prototype );
65 |
66 | THREE.SpriteMaterial.prototype.clone = function () {
67 |
68 | var material = new THREE.SpriteMaterial();
69 |
70 | THREE.Material.prototype.clone.call( this, material );
71 |
72 | material.color.copy( this.color );
73 | material.map = this.map;
74 |
75 | material.rotation = this.rotation;
76 |
77 | material.fog = this.fog;
78 |
79 | return material;
80 |
81 | };
82 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
19 | * @desc 基于相机远近裁切面自动变换亮度(明暗度)的mesh(网格)的材质
20 | * 离相机越近,材质越亮(白),离相机越远,材质越暗(黑)
21 | * @param {String} parameters 材质参数
22 | * @extends {THREE.Material}
23 | * @constructor
24 | */
25 | THREE.MeshDepthMaterial = function ( parameters ) {
26 |
27 | THREE.Material.call( this );
28 | /**
29 | * @default 'MeshDepthMaterial'
30 | * @type {string}
31 | */
32 | this.type = 'MeshDepthMaterial';
33 | /**
34 | * @desc 定义材质是否设定目标变形动画
35 | * @default
36 | * @type {boolean}
37 | */
38 | this.morphTargets = false;
39 | /**
40 | * @desc 是否使用线框模式
41 | * @default
42 | * @type {boolean}
43 | */
44 | this.wireframe = false;
45 | /**
46 | * @default 线框宽度
47 | * @default
48 | * @type {number}
49 | */
50 | this.wireframeLinewidth = 1;
51 |
52 | this.setValues( parameters );
53 |
54 | };
55 | /**
56 | * @desc MeshDepthMaterial对象从THREE.Material的原型继承所有属性方法
57 | * @type {THREE.Material}
58 | */
59 | THREE.MeshDepthMaterial.prototype = Object.create( THREE.Material.prototype );
60 | /**
61 | * @desc MeshDepthMaterial材质的克隆函数
62 | * @returns {THREE.MeshDepthMaterial}
63 | */
64 | THREE.MeshDepthMaterial.prototype.clone = function () {
65 |
66 | var material = new THREE.MeshDepthMaterial();
67 |
68 | THREE.Material.prototype.clone.call( this, material );
69 |
70 | material.wireframe = this.wireframe;
71 | material.wireframeLinewidth = this.wireframeLinewidth;
72 |
73 | return material;
74 |
75 | };
76 |
--------------------------------------------------------------------------------
/textures/CompressedTexture.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 | /**
5 | * @classdesc 由Mipmaps生成的纹理对象
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @extends {THREE.Texture}
8 | * @param {number} mipmaps mipmaps对象,,WebGL不能生成mipmaps,mipmaps只能嵌入到DDS文件
9 | * @param {number} width 图像宽度
10 | * @param {number} height 图像高度
11 | * @param {number} format 像素数据的颜色格式
12 | * @param {number} type 数据类型
13 | * @param {number} mapping 映射模式
14 | * @param {number} wrapS S方向覆盖模式
15 | * @param {number} wrapT T方向覆盖模式
16 | * @param {number} magFilter 纹理在放大时的过滤方式
17 | * @param {number} minFilter 纹理在缩小时的过滤方式
18 | * @param {number} anisotropy 各向异性
19 | * @constructor
20 | */
21 | THREE.CompressedTexture = function ( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy ) {
22 |
23 | THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
24 |
25 | this.image = { width: width, height: height };
26 | this.mipmaps = mipmaps;
27 |
28 | // no flipping for cube textures
29 | // (also flipping doesn't work for compressed textures )
30 | // flipping 不能在压缩纹理中生效
31 | /**
32 | * @default
33 | * @type {boolean}
34 | */
35 | this.flipY = false;
36 |
37 | // can't generate mipmaps for compressed textures
38 | // mips must be embedded in DDS files
39 | // //WebGL不能生成mipmaps,mipmaps只能嵌入到DDS文件
40 | /**
41 | * @default
42 | * @type {boolean}
43 | */
44 | this.generateMipmaps = false;
45 |
46 | };
47 | /**
48 | * @desc 数据纹理从THREE.Texture的原型继承所有属性方法
49 | * @type {THREE.Object3D}
50 | */
51 | THREE.CompressedTexture.prototype = Object.create( THREE.Texture.prototype );
52 | /**
53 | * @desc 克隆函数
54 | * @returns {THREE.DataTexture}
55 | */
56 | THREE.CompressedTexture.prototype.clone = function () {
57 |
58 | var texture = new THREE.CompressedTexture();
59 |
60 | THREE.Texture.prototype.clone.call( this, texture );
61 |
62 | return texture;
63 |
64 | };
65 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
19 | * @param {String} parameters 材质参数
20 | * @extends {THREE.Material}
21 | * @constructor
22 | */
23 | THREE.MeshNormalMaterial = function ( parameters ) {
24 |
25 | THREE.Material.call( this, parameters );
26 | /**
27 | * @default 'FlatShading'
28 | * @type {string}
29 | */
30 | this.type = 'MeshNormalMaterial';
31 |
32 | /**
33 | * @desc 着色方式
34 | * THREE.SmoothShading平滑着色:用多种颜色进行绘制
35 | * 每个顶点都是单独进行处理的,各顶点和各图元之间采用均匀插值。
36 | * @default
37 | * @type {number}
38 | */
39 | this.shading = THREE.SmoothShading;
40 |
41 | /**
42 | * @desc 是否以线框方式渲染几何体
43 | * @default
44 | * @type {boolean}
45 | */
46 | this.wireframe = false;
47 | /**
48 | * @desc 线框宽度
49 | * @default
50 | * @type {float}
51 | */
52 | this.wireframeLinewidth = 1;
53 |
54 | /**
55 | * @desc 材质是否设定目标变形动画
56 | * @default
57 | * @type {boolean}
58 | */
59 | this.morphTargets = false;
60 |
61 | this.setValues( parameters );
62 |
63 | };
64 | /**
65 | * @desc MeshNormalMaterial对象从THREE.Material的原型继承所有属性方法
66 | * @type {THREE.Material}
67 | */
68 | THREE.MeshNormalMaterial.prototype = Object.create( THREE.Material.prototype );
69 | /**
70 | * @desc MeshNormalMaterial材质的克隆函数
71 | * @returns {THREE.MeshNormalMaterial}
72 | */
73 | THREE.MeshNormalMaterial.prototype.clone = function () {
74 |
75 | var material = new THREE.MeshNormalMaterial();
76 |
77 | THREE.Material.prototype.clone.call( this, material );
78 |
79 | material.shading = this.shading;
80 |
81 | material.wireframe = this.wireframe;
82 | material.wireframeLinewidth = this.wireframeLinewidth;
83 |
84 | return material;
85 |
86 | };
87 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/core/Clock.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | /**
6 | * @classdesc 时钟类
7 | * 注释内容部分参照 http://blog.csdn.net/omni360
8 | * @desc 用来记录时间等功能
9 | * @param {boolean} autoStart 是否自动启动,默认为启动
10 | * @constructor
11 | */
12 | THREE.Clock = function ( autoStart ) {
13 |
14 | /**
15 | * @desc 是否自动启动
16 | * @default true
17 | * @type {boolean}
18 | */
19 | this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
20 | /**
21 | * @desc 启动时间
22 | * @default 0
23 | * @type {number}
24 | */
25 | this.startTime = 0;
26 | /**
27 | * @desc 上一次时间
28 | * @default 0
29 | * @type {number}
30 | */
31 | this.oldTime = 0;
32 | /**
33 | * @desc 运行时间
34 | * @default 0
35 | * @type {number}
36 | */
37 | this.elapsedTime = 0;
38 | /**
39 | * @desc 是否正在运行
40 | * @default false
41 | * @type {boolean}
42 | */
43 | this.running = false;
44 |
45 | };
46 |
47 | THREE.Clock.prototype = {
48 |
49 | constructor: THREE.Clock,
50 | /**
51 | * @desc 开始记录时间,获得开始的时间截
52 | */
53 | start: function () {
54 |
55 | this.startTime = self.performance !== undefined && self.performance.now !== undefined
56 | ? self.performance.now()
57 | : Date.now();
58 |
59 | this.oldTime = this.startTime;
60 | this.running = true;
61 | },
62 | /**
63 | * @desc 停止记录时间,获得结束的时间截
64 | */
65 | stop: function () {
66 |
67 | this.getElapsedTime();
68 | this.running = false;
69 |
70 | },
71 | /**
72 | * @desc 返回从oldTimed到stop之间的时间长度,以秒为单位
73 | * @returns {number} 秒为单位
74 | */
75 | getElapsedTime: function () {
76 |
77 | this.getDelta();
78 | return this.elapsedTime;
79 |
80 | },
81 | /**
82 | * @desc 获oldTimed到现在的时间差值,以秒为单位
83 | * @returns {number} 秒为单位
84 | */
85 | getDelta: function () {
86 |
87 | var diff = 0;
88 |
89 | if ( this.autoStart && ! this.running ) {
90 |
91 | this.start();
92 |
93 | }
94 |
95 | if ( this.running ) {
96 |
97 | var newTime = self.performance !== undefined && self.performance.now !== undefined
98 | ? self.performance.now()
99 | : Date.now();
100 |
101 | diff = 0.001 * ( newTime - this.oldTime );
102 | this.oldTime = newTime;
103 |
104 | this.elapsedTime += diff;
105 |
106 | }
107 |
108 | return diff;
109 |
110 | }
111 |
112 | };
113 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
9 | * @constructor
10 | * @extends {THREE.Object3D}
11 | */
12 | THREE.Camera = function () {
13 |
14 | THREE.Object3D.call( this );
15 | /**
16 | * @default
17 | * @type {string}
18 | */
19 | this.type = 'Camera';
20 | /**
21 | * @desc 这是matrixWorld的逆矩阵,matrixWorld包含相机在世界坐标系的变换矩阵
22 | * @type {THREE.Matrix4}
23 | */
24 | this.matrixWorldInverse = new THREE.Matrix4();
25 | /**
26 | * @desc 相机设置属性projectionMatrix,包含相机的投影矩阵
27 | * @type {THREE.Matrix4}
28 | */
29 | this.projectionMatrix = new THREE.Matrix4();
30 |
31 | };
32 | /**
33 | * @desc 相机对象从THREE.Objec3D的原型继承所有属性方法
34 | * @type {THREE.Object3D}
35 | */
36 | THREE.Camera.prototype = Object.create( THREE.Object3D.prototype );
37 | /**
38 | * @function
39 | * @desc 获取世界坐标系内的四元数参数
40 | * @param {THREE.Quaternion} optionalTarget
41 | * @return {THREE.Quaternion}
42 | */
43 | THREE.Camera.prototype.getWorldDirection = function () {
44 |
45 | var quaternion = new THREE.Quaternion();
46 |
47 | return function ( optionalTarget ) {
48 |
49 | var result = optionalTarget || new THREE.Vector3();
50 |
51 | this.getWorldQuaternion( quaternion );
52 |
53 | return result.set( 0, 0, - 1 ).applyQuaternion( quaternion );
54 |
55 | }
56 |
57 | }();
58 | /**
59 | * @function
60 | * @desc 用来旋转相机对象,并将对象面对空间中的点(参数vector)
61 | * @param {THREE.Vector3} vector
62 | */
63 | THREE.Camera.prototype.lookAt = function () {
64 |
65 | // This routine does not support cameras with rotated and/or translated parent(s)
66 |
67 | var m1 = new THREE.Matrix4();
68 |
69 | return function ( vector ) {
70 |
71 | m1.lookAt( this.position, vector, this.up );
72 |
73 | this.quaternion.setFromRotationMatrix( m1 );
74 |
75 | };
76 |
77 | }();
78 | /**
79 | * @desc 克隆相机
80 | * @param {THREE.Camera} camera
81 | * @returns {THREE.Camera}
82 | */
83 | THREE.Camera.prototype.clone = function ( camera ) {
84 |
85 | if ( camera === undefined ) camera = new THREE.Camera();
86 |
87 | THREE.Object3D.prototype.clone.call( this, camera );
88 |
89 | camera.matrixWorldInverse.copy( this.matrixWorldInverse );
90 | camera.projectionMatrix.copy( this.projectionMatrix );
91 |
92 | return camera;
93 | };
94 |
--------------------------------------------------------------------------------
/lights/AreaLight.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author MPanknin / http://www.redplant.de/
3 | * @author alteredq / http://alteredqualia.com/
4 | */
5 | /**
6 | * @classdesc 面光,区域光对象
7 | * 注释内容部分参照 http://blog.csdn.net/omni360
8 | * @desc 区域光和其他光源不同,是一种二维面积光源,他的亮度不仅和强度有关,而且还和他的面积大小有关.
9 | * 通过变换灯光的width,height,normal属性,区域光可以模拟窗户射入光线
10 | * @param {THREE.Color} color 环境光的颜色
11 | * @param {float} intensity 灯光的强度,默认是1
12 | * @extends {THREE.Light}
13 | * @example var light = new THREE.AreaLight(0xff0000,1); //创建平面灯光对象
14 | * light.position.set(50,50,30); //设置位置
15 | * light.rotation.set(-0.3,0.3,0.002); //设置角度
16 | * light.width = 10; //设置宽度
17 | * light.height = 1; //设置高度
18 | * scene.add(lignt); //加入场景
19 | * @constructor
20 | */
21 | THREE.AreaLight = function ( color, intensity ) {
22 |
23 | THREE.Light.call( this, color );
24 | /**
25 | * @default
26 | * @type {string}
27 | */
28 | this.type = 'AreaLight';
29 |
30 | /**
31 | * @desc 面法线
32 | * 可以设置或者获得面光的单位向量,确认灯光照射面正确.这是在局部空间计算.
33 | * @default ( 0, - 1, 0 )
34 | * @type {THREE.Vector3}
35 | */
36 | this.normal = new THREE.Vector3( 0, - 1, 0 );
37 | /**
38 | * @desc 灯光的方向
39 | * @default ( 1, 0, 0 )
40 | * @type {THREE.Vector3}
41 | */
42 | this.right = new THREE.Vector3( 1, 0, 0 );
43 | /**
44 | * @desc 灯光的强度
45 | * @default ( 1, 0, 0 )
46 | * @type {THREE.Vector3}
47 | */
48 | this.intensity = ( intensity !== undefined ) ? intensity : 1;
49 | /**
50 | * @desc 区域光的宽度,初始化为1.0
51 | * @default
52 | * @type {float}
53 | */
54 | this.width = 1.0;
55 | /**
56 | * @desc 区域光的宽度,初始化为1.0
57 | * @default
58 | * @type {float}
59 | */
60 | this.height = 1.0;
61 | //WebGL是通过光强乘以衰减系数来计算衰减光照的,
62 | //attenuation (衰减系数) = 1`/ (this.constantAttenuation + this.distance * this.linearAttenuation + this.quadraticAttenuation * this.distance * this.distance )
63 | /**
64 | * @desc 常量衰减系数,系数值越大,衰变越快
65 | * @default
66 | * @type {float}
67 | */
68 | this.constantAttenuation = 1.5;
69 | /**
70 | * @desc 线性衰减系数,系数值越大,衰变越快
71 | * @default
72 | * @type {float}
73 | */
74 | this.linearAttenuation = 0.5;
75 | /**
76 | * @desc 衰减平方系数,系数值越大,衰变越快
77 | * @default
78 | * @type {float}
79 | */
80 | this.quadraticAttenuation = 0.1;
81 |
82 | };
83 | /**
84 | * @desc AreaLight对象从THREE.Light的原型继承所有属性方法
85 | * @type {THREE.Light}
86 | */
87 | THREE.AreaLight.prototype = Object.create( THREE.Light.prototype );
88 |
89 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
25 | * @desc 据参数parameters创建线段的线线型材质,参数为JSON格式的属性参数
26 | * @param {String} parameters 材质参数
27 | * @extends {THREE.Material}
28 | * @constructor
29 | */
30 | THREE.LineBasicMaterial = function ( parameters ) {
31 |
32 | THREE.Material.call( this );
33 | /**
34 | * @default 'LineBasicMaterial'
35 | * @type {string}
36 | */
37 | this.type = 'LineBasicMaterial';
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 线头类型 "round" 圆角 "butt" 平角 "square" 方角
52 | * @default "round" 圆角
53 | * @type {string}
54 | */
55 | this.linecap = 'round';
56 | /**
57 | * @desc 线连接类型 "bevel" 斜角 "round" 圆角 "miter" 尖角
58 | * @default "round" 圆角
59 | * @type {string}
60 | */
61 | this.linejoin = 'round';
62 | /**
63 | * @desc 线顶点颜色
64 | * @default THREE.NoColors
65 | * @type {number}
66 | */
67 | this.vertexColors = THREE.NoColors;
68 | /**
69 | * @desc 雾效
70 | * @default
71 | * @type {boolean}
72 | */
73 | this.fog = true;
74 |
75 | this.setValues( parameters );
76 |
77 | };
78 | /**
79 | * @desc LineBasicMaterial对象从THREE.Material的原型继承所有属性方法
80 | * @type {THREE.Material}
81 | */
82 | THREE.LineBasicMaterial.prototype = Object.create( THREE.Material.prototype );
83 |
84 | /**
85 | * @desc 线材质的克隆函数
86 | * @returns {THREE.LineBasicMaterial}
87 | */
88 | THREE.LineBasicMaterial.prototype.clone = function () {
89 |
90 | var material = new THREE.LineBasicMaterial();
91 |
92 | THREE.Material.prototype.clone.call( this, material );
93 |
94 | material.color.copy( this.color );
95 |
96 | material.linewidth = this.linewidth;
97 | material.linecap = this.linecap;
98 | material.linejoin = this.linejoin;
99 |
100 | material.vertexColors = this.vertexColors;
101 |
102 | material.fog = this.fog;
103 |
104 | return material;
105 |
106 | };
107 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
26 | * @desc 据参数parameters创建线段的线线型材质,参数为JSON格式的属性参数
27 | * @param {String} parameters 材质参数
28 | * @extends {THREE.Material}
29 | * @constructor
30 | */
31 | THREE.LineDashedMaterial = function ( parameters ) {
32 |
33 | THREE.Material.call( this );
34 | /**
35 | * @default 'LineDashedMaterial'
36 | * @type {string}
37 | */
38 | this.type = 'LineDashedMaterial';
39 | /**
40 | * @desc 线材质颜色
41 | * @default 0xffffff 白色
42 | * @type {THREE.Color}
43 | */
44 | this.color = new THREE.Color( 0xffffff );
45 | /**
46 | * @desc 线的宽度
47 | * @default
48 | * @type {float}
49 | */
50 | this.linewidth = 1;
51 | /**
52 | * @desc 虚线的线型比例属性
53 | * @default
54 | * @type {float}
55 | */
56 | this.scale = 1;
57 | /**
58 | * @desc 虚线(点化线),线段的长度
59 | * @default
60 | * @type {float}
61 | */
62 | this.dashSize = 3;
63 | /**
64 | * @desc 虚线(点化线)的线段间距长度
65 | * @default
66 | * @type {float}
67 | */
68 | this.gapSize = 1;
69 | /**
70 | * @desc 线顶点颜色
71 | * @default THREE.NoColors
72 | * @type {number}
73 | */
74 | this.vertexColors = false;
75 | /**
76 | * @desc 雾效
77 | * @default
78 | * @type {boolean}
79 | */
80 | this.fog = true;
81 |
82 | this.setValues( parameters );
83 |
84 | };
85 | /**
86 | * @desc LineDashedMaterial对象从THREE.Material的原型继承所有属性方法
87 | * @type {THREE.Material}
88 | */
89 | THREE.LineDashedMaterial.prototype = Object.create( THREE.Material.prototype );
90 | /**
91 | * @desc 虚线材质的克隆函数
92 | * @returns {THREE.LineDashedMaterial}
93 | */
94 | THREE.LineDashedMaterial.prototype.clone = function () {
95 |
96 | var material = new THREE.LineDashedMaterial();
97 |
98 | THREE.Material.prototype.clone.call( this, material );
99 |
100 | material.color.copy( this.color );
101 |
102 | material.linewidth = this.linewidth;
103 |
104 | material.scale = this.scale;
105 | material.dashSize = this.dashSize;
106 | material.gapSize = this.gapSize;
107 |
108 | material.vertexColors = this.vertexColors;
109 |
110 | material.fog = this.fog;
111 |
112 | return material;
113 |
114 | };
115 |
--------------------------------------------------------------------------------
/objects/Sprite.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mikael emtinger / http://gomo.se/
3 | * @author alteredq / http://alteredqualia.com/
4 | */
5 | /**
6 | * @classdesc 点对象,也就是粒子对象
7 | * 注释内容部分参照 http://blog.csdn.net/omni360
8 | * @desc 通过BufferGeometry创建一个正对相机的类似buildborad的粒子点
9 | * @param {THREE.Material} material 材质
10 | * @constructor
11 | */
12 | THREE.Sprite = ( function () {
13 |
14 | var indices = new Uint16Array( [ 0, 1, 2, 0, 2, 3 ] );
15 | var vertices = new Float32Array( [ - 0.5, - 0.5, 0, 0.5, - 0.5, 0, 0.5, 0.5, 0, - 0.5, 0.5, 0 ] );
16 | var uvs = new Float32Array( [ 0, 0, 1, 0, 1, 1, 0, 1 ] );
17 |
18 | // 使用buffergeometry对象
19 | var geometry = new THREE.BufferGeometry();
20 | // 索引,顶点,UV
21 | geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
22 | geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
23 | geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
24 |
25 | return function ( material ) {
26 |
27 | THREE.Object3D.call( this );
28 |
29 | this.type = 'Sprite';
30 | /**
31 | * @memberof THREE.Sprite
32 | * @desc 粒子对象的几何对象
33 | * @type {THREE.BufferGeometry}
34 | */
35 | this.geometry = geometry;
36 | /**
37 | *
38 | * @memberof THREE.Sprite
39 | * @desc 粒子对象的材质对象
40 | * @type {THREE.Material}
41 | */
42 | this.material = ( material !== undefined ) ? material : new THREE.SpriteMaterial();
43 |
44 | };
45 |
46 | } )();
47 | /**
48 | * @desc Sprite从Objec3D的原型继承所有属性方法
49 | * @type {THREE.Object3D}
50 | */
51 | THREE.Sprite.prototype = Object.create( THREE.Object3D.prototype );
52 | /**
53 | * @function
54 | * @desc 粒子对象的拾取判断函数
55 | * @param {THREE.Raycaster} raycaster 拾取射线对象
56 | * @param {*} intersects 拾取结果对象数组
57 | */
58 | THREE.Sprite.prototype.raycast = ( function () {
59 |
60 | var matrixPosition = new THREE.Vector3();
61 |
62 | return function ( raycaster, intersects ) {
63 |
64 | matrixPosition.setFromMatrixPosition( this.matrixWorld );
65 | // 点距离判断
66 | var distance = raycaster.ray.distanceToPoint( matrixPosition );
67 |
68 | if ( distance > this.scale.x ) {
69 |
70 | return;
71 |
72 | }
73 |
74 | intersects.push( {
75 |
76 | distance: distance,
77 | point: this.position,
78 | face: null,
79 | object: this
80 |
81 | } );
82 |
83 | };
84 |
85 | }() );
86 | /**
87 | * @desc Three.Sprite 克隆函数
88 | * @param {THREE.Sprite} object
89 | * @returns {THREE.Sprite}
90 | */
91 | THREE.Sprite.prototype.clone = function ( object ) {
92 |
93 | if ( object === undefined ) object = new THREE.Sprite( this.material );
94 |
95 | THREE.Object3D.prototype.clone.call( this, object );
96 |
97 | return object;
98 |
99 | };
100 |
101 | // Backwards compatibility
102 | /**
103 | * @classdesc 粒子对象,其实就是Sprite对象
104 | * @constructor
105 | */
106 | THREE.Particle = THREE.Sprite;
107 |
--------------------------------------------------------------------------------
/cameras/OrthographicCamera.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 | /**
5 | * @classdesc 正交投影相机
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @desc 根据 left, right, top, bottom, near, far 生成正交投影相
8 | * @constructor
9 | * @param {float} left 垂直平面的左侧坐标位置
10 | * @param {float} right 垂直平面的右侧坐标位置
11 | * @param {float} top 垂直平面的顶部坐标位置
12 | * @param {float} bottom 垂直平面的底部坐标位置
13 | * @param {float} near 相对于深度剪切面的近的距离,必须为正数,可选参数,如果未指定,初始化为0.1
14 | * @param {float} far 相对于深度剪切面的远的距离,必须为正数,可选参数,如果未指定,初始化为2000
15 | * @extends {THREE.Camera}
16 | */
17 | THREE.OrthographicCamera = function ( left, right, top, bottom, near, far ) {
18 |
19 | THREE.Camera.call( this );
20 | /**
21 | * @default
22 | * @type {string}
23 | */
24 | this.type = 'OrthographicCamera';
25 | /**
26 | * @desc 缩放级别
27 | * @default
28 | * @type {float}
29 | */
30 | this.zoom = 1;
31 | /**
32 | * @desc 垂直平面的左侧坐标位置
33 | * @type {float}
34 | */
35 | this.left = left;
36 | /**
37 | * @desc 垂直平面的右侧坐标位置
38 | * @type {float}
39 | */
40 | this.right = right;
41 | /**
42 | * @desc 垂直平面的顶部坐标位置
43 | * @type {float}
44 | */
45 | this.top = top;
46 | /**
47 | * @desc 垂直平面的底部坐标位置
48 | * @type {float}
49 | */
50 | this.bottom = bottom;
51 | /**
52 | * @desc 指明相对于深度剪切面的近的距离,必须为正数,可选参数,如果未指定,初始化为0.1
53 | * @default 0.1
54 | * @type {float}
55 | */
56 | this.near = ( near !== undefined ) ? near : 0.1;
57 | /**
58 | * @desc 指明相对于深度剪切面的近的距离,必须为正数,可选参数,如果未指定,初始化为0.1
59 | * @default 2000
60 | * @type {float}
61 | */
62 | this.far = ( far !== undefined ) ? far : 2000;
63 |
64 | this.updateProjectionMatrix();
65 |
66 | };
67 | /**
68 | * @desc 正交相机对象从THREE.Camera的原型继承所有属性方法
69 | * @type {THREE.Camera}
70 | */
71 | THREE.OrthographicCamera.prototype = Object.create( THREE.Camera.prototype );
72 |
73 | /**
74 | * @desc 返回正交投影相机的可视边界的矩阵
75 | */
76 | THREE.OrthographicCamera.prototype.updateProjectionMatrix = function () {
77 |
78 | var dx = ( this.right - this.left ) / ( 2 * this.zoom );
79 | var dy = ( this.top - this.bottom ) / ( 2 * this.zoom );
80 | var cx = ( this.right + this.left ) / 2;
81 | var cy = ( this.top + this.bottom ) / 2;
82 |
83 | this.projectionMatrix.makeOrthographic( cx - dx, cx + dx, cy + dy, cy - dy, this.near, this.far );
84 |
85 | };
86 |
87 | /**
88 | * @desc 克隆正交相机对象
89 | * @returns {THREE.OrthographicCamera}
90 | */
91 | THREE.OrthographicCamera.prototype.clone = function () {
92 |
93 | var camera = new THREE.OrthographicCamera();
94 |
95 | THREE.Camera.prototype.clone.call( this, camera );
96 |
97 | camera.zoom = this.zoom;
98 |
99 | camera.left = this.left;
100 | camera.right = this.right;
101 | camera.top = this.top;
102 | camera.bottom = this.bottom;
103 |
104 | camera.near = this.near;
105 | camera.far = this.far;
106 |
107 | camera.projectionMatrix.copy( this.projectionMatrix );
108 |
109 | return camera;
110 | };
111 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
10 | * @desc 根据 near, far, cubeResolution 生成立方体投影相机
11 | * @constructor
12 | * @param {float} near 相对于深度剪切面的近的距离,必须为正数,可选参数,如果未指定,初始化为0.1
13 | * @param {float} far 相对于深度剪切面的远的距离,必须为正数,可选参数,如果未指定,初始化为2000
14 | * @param {float} cubeResolution
15 | * @extends {THREE.Camera}
16 | */
17 | THREE.CubeCamera = function ( near, far, cubeResolution ) { //garreet
18 |
19 | THREE.Object3D.call( this );
20 |
21 | this.type = 'CubeCamera';
22 |
23 | var fov = 90, aspect = 1;
24 |
25 | var cameraPX = new THREE.PerspectiveCamera( fov, aspect, near, far );
26 | cameraPX.up.set( 0, - 1, 0 );
27 | cameraPX.lookAt( new THREE.Vector3( 1, 0, 0 ) );
28 | this.add( cameraPX );
29 |
30 | var cameraNX = new THREE.PerspectiveCamera( fov, aspect, near, far );
31 | cameraNX.up.set( 0, - 1, 0 );
32 | cameraNX.lookAt( new THREE.Vector3( - 1, 0, 0 ) );
33 | this.add( cameraNX );
34 |
35 | var cameraPY = new THREE.PerspectiveCamera( fov, aspect, near, far );
36 | cameraPY.up.set( 0, 0, 1 );
37 | cameraPY.lookAt( new THREE.Vector3( 0, 1, 0 ) );
38 | this.add( cameraPY );
39 |
40 | var cameraNY = new THREE.PerspectiveCamera( fov, aspect, near, far );
41 | cameraNY.up.set( 0, 0, - 1 );
42 | cameraNY.lookAt( new THREE.Vector3( 0, - 1, 0 ) );
43 | this.add( cameraNY );
44 |
45 | var cameraPZ = new THREE.PerspectiveCamera( fov, aspect, near, far );
46 | cameraPZ.up.set( 0, - 1, 0 );
47 | cameraPZ.lookAt( new THREE.Vector3( 0, 0, 1 ) );
48 | this.add( cameraPZ );
49 |
50 | var cameraNZ = new THREE.PerspectiveCamera( fov, aspect, near, far );
51 | cameraNZ.up.set( 0, - 1, 0 );
52 | cameraNZ.lookAt( new THREE.Vector3( 0, 0, - 1 ) );
53 | this.add( cameraNZ );
54 |
55 | this.renderTarget = new THREE.WebGLRenderTargetCube( cubeResolution, cubeResolution, { format: THREE.RGBFormat, magFilter: THREE.LinearFilter, minFilter: THREE.LinearFilter } );
56 |
57 | this.updateCubeMap = function ( renderer, scene ) {
58 |
59 | var renderTarget = this.renderTarget;
60 | var generateMipmaps = renderTarget.generateMipmaps;
61 |
62 | renderTarget.generateMipmaps = false;
63 |
64 | renderTarget.activeCubeFace = 0;
65 | renderer.render( scene, cameraPX, renderTarget );
66 |
67 | renderTarget.activeCubeFace = 1;
68 | renderer.render( scene, cameraNX, renderTarget );
69 |
70 | renderTarget.activeCubeFace = 2;
71 | renderer.render( scene, cameraPY, renderTarget );
72 |
73 | renderTarget.activeCubeFace = 3;
74 | renderer.render( scene, cameraNY, renderTarget );
75 |
76 | renderTarget.activeCubeFace = 4;
77 | renderer.render( scene, cameraPZ, renderTarget );
78 |
79 | renderTarget.generateMipmaps = generateMipmaps;
80 |
81 | renderTarget.activeCubeFace = 5;
82 | renderer.render( scene, cameraNZ, renderTarget );
83 |
84 | };
85 |
86 | };
87 |
88 | THREE.CubeCamera.prototype = Object.create( THREE.Object3D.prototype );
89 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
24 | * @param {String} parameters 材质参数
25 | * @extends {THREE.Material}
26 | * @constructor
27 | */
28 | THREE.PointCloudMaterial = function ( parameters ) {
29 |
30 | THREE.Material.call( this );
31 | /**
32 | * @default 'PointCloudMaterial'
33 | * @type {string}
34 | */
35 | this.type = 'PointCloudMaterial';
36 | /**
37 | * @desc 材质颜色
38 | * @default 0xffffff 白色
39 | * @type {THREE.Color}
40 | */
41 | this.color = new THREE.Color( 0xffffff );
42 | /**
43 | * @desc 纹理贴图
44 | * @default
45 | * @type {THREE.Texture}
46 | */
47 | this.map = null;
48 | /**
49 | * @desc 点云点大小
50 | * @default
51 | * @type {number}
52 | */
53 | this.size = 1;
54 | /**
55 | * @desc 粒子是否衰减
56 | * @default
57 | * @type {boolean}
58 | */
59 | this.sizeAttenuation = true;
60 | /**
61 | * @desc 材质顶点颜色
62 | * @default THREE.NoColors
63 | * @type {number}
64 | */
65 | this.vertexColors = THREE.NoColors;
66 | /**
67 | * @desc 雾效,默认开启
68 | * @default
69 | * @type {boolean}
70 | */
71 | this.fog = true;
72 |
73 | this.setValues( parameters );
74 |
75 | };
76 | /**
77 | * @desc PointCloudMaterial对象从THREE.Material的原型继承所有属性方法
78 | * @type {THREE.Material}
79 | */
80 | THREE.PointCloudMaterial.prototype = Object.create( THREE.Material.prototype );
81 | /**
82 | * @desc PointCloudMaterial材质的克隆函数
83 | * @returns {THREE.PointCloudMaterial}
84 | */
85 | THREE.PointCloudMaterial.prototype.clone = function () {
86 |
87 | var material = new THREE.PointCloudMaterial();
88 |
89 | THREE.Material.prototype.clone.call( this, material );
90 |
91 | material.color.copy( this.color );
92 |
93 | material.map = this.map;
94 |
95 | material.size = this.size;
96 | material.sizeAttenuation = this.sizeAttenuation;
97 |
98 | material.vertexColors = this.vertexColors;
99 |
100 | material.fog = this.fog;
101 |
102 | return material;
103 |
104 | };
105 |
106 | // backwards compatibility
107 | /**
108 | * @ignore
109 | */
110 | THREE.ParticleBasicMaterial = function ( parameters ) {
111 |
112 | console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointCloudMaterial.' );
113 | return new THREE.PointCloudMaterial( parameters );
114 |
115 | };
116 | /**
117 | * @ignore
118 | */
119 | THREE.ParticleSystemMaterial = function ( parameters ) {
120 |
121 | console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointCloudMaterial.' );
122 | return new THREE.PointCloudMaterial( parameters );
123 |
124 | };
125 |
--------------------------------------------------------------------------------
/objects/LensFlare.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mikael emtinger / http://gomo.se/
3 | * @author alteredq / http://alteredqualia.com/
4 | */
5 | /**
6 | * @classdesc 透镜对象
7 | * @param {THREE.Texture} texture 纹理
8 | * @param {number} size 尺寸
9 | * @param {float} distance 距离
10 | * @param {number} blending blend方式
11 | * @param {THREE.Color} color 颜色
12 | * @constructor
13 | */
14 | THREE.LensFlare = function ( texture, size, distance, blending, color ) {
15 |
16 | THREE.Object3D.call( this );
17 | /**
18 | * @desc 透镜对象数组
19 | * @type {Array}
20 | */
21 | this.lensFlares = [];
22 | /**
23 | * @desc 屏幕位置
24 | * @type {THREE.Vector3}
25 | */
26 | this.positionScreen = new THREE.Vector3();
27 | /**
28 | * @desc 更新回调函数
29 | * @type {*}
30 | */
31 | this.customUpdateCallback = undefined;
32 |
33 | if( texture !== undefined ) {
34 | // 初始化
35 | this.add( texture, size, distance, blending, color );
36 |
37 | }
38 |
39 | };
40 | /**
41 | * @desc LensFlare从Objec3D的原型继承所有属性方法
42 | * @type {THREE.Object3D}
43 | */
44 | THREE.LensFlare.prototype = Object.create( THREE.Object3D.prototype );
45 |
46 |
47 | /*
48 | * Add: adds another flare
49 | */
50 | /**
51 | * @desc 添加透镜
52 | * @param {THREE.Texture} texture 纹理
53 | * @param {number} size 尺寸
54 | * @param {float} distance 距离
55 | * @param {number} blending blend方式
56 | * @param {THREE.Color} color 颜色
57 | * @param {float} opacity 透明值
58 | */
59 | THREE.LensFlare.prototype.add = function ( texture, size, distance, blending, color, opacity ) {
60 |
61 | if ( size === undefined ) size = - 1;
62 | if ( distance === undefined ) distance = 0;
63 | if ( opacity === undefined ) opacity = 1;
64 | if ( color === undefined ) color = new THREE.Color( 0xffffff );
65 | if ( blending === undefined ) blending = THREE.NormalBlending;
66 |
67 | distance = Math.min( distance, Math.max( 0, distance ) );
68 |
69 | this.lensFlares.push( {
70 | texture: texture, // THREE.Texture
71 | size: size, // size in pixels (-1 = use texture.width)
72 | distance: distance, // distance (0-1) from light source (0=at light source)
73 | x: 0, y: 0, z: 0, // screen position (-1 => 1) z = 0 is ontop z = 1 is back
74 | scale: 1, // scale
75 | rotation: 1, // rotation
76 | opacity: opacity, // opacity
77 | color: color, // color
78 | blending: blending // blending
79 | } );
80 |
81 | };
82 |
83 | /*
84 | * Update lens flares update positions on all flares based on the screen position
85 | * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.
86 | */
87 | /**
88 | * @desc 更新透镜对象的位置,旋转等参数
89 | */
90 | THREE.LensFlare.prototype.updateLensFlares = function () {
91 |
92 | var f, fl = this.lensFlares.length;
93 | var flare;
94 | var vecX = - this.positionScreen.x * 2;
95 | var vecY = - this.positionScreen.y * 2;
96 |
97 | for( f = 0; f < fl; f ++ ) {
98 |
99 | flare = this.lensFlares[ f ];
100 |
101 | flare.x = this.positionScreen.x + vecX * flare.distance;
102 | flare.y = this.positionScreen.y + vecY * flare.distance;
103 |
104 | flare.wantedRotation = flare.x * Math.PI * 0.25;
105 | flare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;
106 |
107 | }
108 |
109 | };
110 |
111 |
--------------------------------------------------------------------------------
/core/Face3.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | * @author alteredq / http://alteredqualia.com/
4 | */
5 | /**
6 | * @classdesc 三角面对象类(三维空间内)
7 | * 注释内容部分参照 http://blog.csdn.net/omni360
8 | * @param {THREE.Vector3} a 三角面角点a的索引
9 | * @param {THREE.Vector3} b 三角面角点b的索引
10 | * @param {THREE.Vector3} c 三角面角点c的索引
11 | * @param {THREE.Vector3[]} normal 三角面法线向量,或顶点法线向量数组
12 | * @param {THREE.Color[]} color 三角面颜色值,或顶点颜色值数组
13 | * @param {number[]} materialIndex 材质索引数组
14 | * @example 用法: 创建一个颜色为0xffaa00,0x00aaff,0x00ffaa的a,b,c三点组成的,法线指向normal,材质索引为0的三角面对象
15 | * var a=0,b=1,c=2;
16 | * var normal1 = new THREE.Vector3( 0, 1, 0 ), normal2 = new THREE.Vector3( 0, 1, 0 ), normal3 = new THREE.Vector3( 0, 1, 0 );
17 | * normal = new Array(normal1,normal2,normal3);
18 | * var color1 = new THREE.Color( 0xffaa00 ), color2 = new THREE.Color( 0x00aaff ), color3 = new THREE.Color( 0x00ffaa );
19 | * var color = new Array(color1,color2,color3);
20 | * var face = new THREE.Face3( a, b, c, normal, color, 0 );
21 | * 创建一个颜色为0xffaa00,0x00aaff,0x00ffaa的a,b,c三点组成的,法线指向normal,材质索引为0的三角面对象
22 | * @constructor
23 | */
24 | THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) {
25 |
26 | /**
27 | * @desc 顶点a
28 | * @type {THREE.Vector3}
29 | */
30 | this.a = a;
31 | /**
32 | * @desc 顶点b
33 | * @type {THREE.Vector3}
34 | */
35 | this.b = b;
36 | /**
37 | * @desc 顶点c
38 | * @type {THREE.Vector3}
39 | */
40 | this.c = c;
41 |
42 | /**
43 | * @desc 面法线
44 | * @type {THREE.Vector3}
45 | */
46 | this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
47 | /**
48 | * @desc 顶点法线
49 | * @type {THREE.Vector3[]}
50 | */
51 | this.vertexNormals = normal instanceof Array ? normal : [];
52 |
53 | /**
54 | * @desc 面颜色
55 | * @type {THREE.Color}
56 | */
57 | this.color = color instanceof THREE.Color ? color : new THREE.Color();
58 | /**
59 | * @desc 顶点颜色
60 | * @type {THREE.Color[]}
61 | */
62 | this.vertexColors = color instanceof Array ? color : [];
63 |
64 | /**
65 | * @desc 顶点正切数组
66 | * @type {Array}
67 | */
68 | this.vertexTangents = [];
69 |
70 | /**
71 | * @desc 三角面的材质索引
72 | * @type {number}
73 | */
74 | this.materialIndex = materialIndex !== undefined ? materialIndex : 0;
75 |
76 | };
77 |
78 | THREE.Face3.prototype = {
79 |
80 | constructor: THREE.Face3,
81 | /**
82 | * @desc 克隆三角面对象
83 | * @returns {THREE.Face3}
84 | */
85 | clone: function () {
86 |
87 | var face = new THREE.Face3( this.a, this.b, this.c );
88 |
89 | face.normal.copy( this.normal );
90 | face.color.copy( this.color );
91 |
92 | face.materialIndex = this.materialIndex;
93 |
94 | for ( var i = 0, il = this.vertexNormals.length; i < il; i ++ ) {
95 |
96 | face.vertexNormals[ i ] = this.vertexNormals[ i ].clone();
97 |
98 | }
99 |
100 | for ( var i = 0, il = this.vertexColors.length; i < il; i ++ ) {
101 |
102 | face.vertexColors[ i ] = this.vertexColors[ i ].clone();
103 |
104 | }
105 |
106 | for ( var i = 0, il = this.vertexTangents.length; i < il; i ++ ) {
107 |
108 | face.vertexTangents[ i ] = this.vertexTangents[ i ].clone();
109 |
110 | }
111 |
112 | return face;
113 |
114 | }
115 |
116 | };
117 |
--------------------------------------------------------------------------------
/core/EventDispatcher.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://github.com/mrdoob/eventdispatcher.js/
3 | */
4 | /**
5 | * @classdesc 事件调度类
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @desc 用来管理侦听函数,被嵌入Object3D对象之上.当Object3D发生事件时,这个方法就会自动被触发.
8 | * 可以通过调用调度该事件的对象的 addEventListener() 方法来注册函数以处理运行时事件
9 | * @constructor
10 | */
11 | THREE.EventDispatcher = function () {}
12 |
13 | THREE.EventDispatcher.prototype = {
14 |
15 | constructor: THREE.EventDispatcher,
16 | /**
17 | * @desc 将当前基类绑定到参数Object对象之上,将基类的方法添加到object对象内
18 | * @param {THREE.Object3D} object
19 | */
20 | apply: function ( object ) {
21 |
22 | object.addEventListener = THREE.EventDispatcher.prototype.addEventListener;
23 | object.hasEventListener = THREE.EventDispatcher.prototype.hasEventListener;
24 | object.removeEventListener = THREE.EventDispatcher.prototype.removeEventListener;
25 | object.dispatchEvent = THREE.EventDispatcher.prototype.dispatchEvent;
26 |
27 | },
28 | /**
29 | * @desc 使用 EventDispatcher 对象注册事件侦听器对象,以使侦听器能够接收事件通知
30 | * @param {String} type 事件类型
31 | * @param {requestCallback} listener 监听回调函数
32 | */
33 | addEventListener: function ( type, listener ) {
34 |
35 | if ( this._listeners === undefined ) this._listeners = {};
36 |
37 | var listeners = this._listeners;
38 |
39 | if ( listeners[ type ] === undefined ) {
40 |
41 | listeners[ type ] = [];
42 |
43 | }
44 |
45 | if ( listeners[ type ].indexOf( listener ) === - 1 ) {
46 |
47 | listeners[ type ].push( listener );
48 |
49 | }
50 |
51 | },
52 | /**
53 | * @desc 检查 EventDispatcher 对象是否为特定事件类型注册了任何侦听器
54 | * @param {String} type 事件类型
55 | * @param {requestCallback} listener
56 | * @returns {boolean} 监听回调函数
57 | */
58 | hasEventListener: function ( type, listener ) {
59 |
60 | if ( this._listeners === undefined ) return false;
61 |
62 | var listeners = this._listeners;
63 |
64 | if ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) {
65 |
66 | return true;
67 |
68 | }
69 |
70 | return false;
71 |
72 | },
73 |
74 | /**
75 | * @desc 从 EventDispatcher 对象中删除为特定事件类型注册了任何侦听器
76 | * @param {String} type 事件类型
77 | * @param {requestCallback} listener
78 | */
79 | removeEventListener: function ( type, listener ) {
80 |
81 | if ( this._listeners === undefined ) return;
82 |
83 | var listeners = this._listeners;
84 | var listenerArray = listeners[ type ];
85 |
86 | if ( listenerArray !== undefined ) {
87 |
88 | var index = listenerArray.indexOf( listener );
89 |
90 | if ( index !== - 1 ) {
91 |
92 | listenerArray.splice( index, 1 );
93 |
94 | }
95 |
96 | }
97 |
98 | },
99 | /**
100 | * @desc 将事件调度到事件流中
101 | * 事件目标是对其调用 dispatchEvent() 方法的 EventDispatcher 对象
102 | * 如果正在重新调度事件,则会自动创建此事件的一个克隆
103 | * 在调度了事件后,其 target 属性将无法更改,因此您必须创建此事件的一个新副本以能够重新调度
104 | * @param event 事件
105 | */
106 | dispatchEvent: function ( event ) {
107 |
108 | if ( this._listeners === undefined ) return;
109 |
110 | var listeners = this._listeners;
111 | var listenerArray = listeners[ event.type ];
112 |
113 | if ( listenerArray !== undefined ) {
114 |
115 | event.target = this;
116 |
117 | var array = [];
118 | var length = listenerArray.length;
119 |
120 | for ( var i = 0; i < length; i ++ ) {
121 |
122 | array[ i ] = listenerArray[ i ];
123 |
124 | }
125 |
126 | for ( var i = 0; i < length; i ++ ) {
127 |
128 | array[ i ].call( this, event );
129 |
130 | }
131 |
132 | }
133 |
134 | }
135 |
136 | };
137 |
--------------------------------------------------------------------------------
/renderers/shaders/UniformsLib.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Uniforms library for shared webgl shaders
3 | */
4 | /**
5 | * @classdesc Uniforms库,包含各种定义的shader的uniform组成
6 | * @memberof THREE
7 | * @constructor
8 | */
9 | THREE.UniformsLib = {
10 |
11 | /**
12 | * @desc 普通渲染参数
13 | */
14 | common: {
15 |
16 | "diffuse" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
17 | "opacity" : { type: "f", value: 1.0 },
18 |
19 | "map" : { type: "t", value: null },
20 | "offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
21 |
22 | "lightMap" : { type: "t", value: null },
23 | "specularMap" : { type: "t", value: null },
24 | "alphaMap" : { type: "t", value: null },
25 |
26 | "envMap" : { type: "t", value: null },
27 | "flipEnvMap" : { type: "f", value: - 1 },
28 | "useRefract" : { type: "i", value: 0 },
29 | "reflectivity" : { type: "f", value: 1.0 },
30 | "refractionRatio" : { type: "f", value: 0.98 },
31 | "combine" : { type: "i", value: 0 },
32 |
33 | "morphTargetInfluences" : { type: "f", value: 0 }
34 |
35 | },
36 |
37 | /**
38 | * @desc 碰撞参数
39 | */
40 | bump: {
41 |
42 | "bumpMap" : { type: "t", value: null },
43 | "bumpScale" : { type: "f", value: 1 }
44 |
45 | },
46 | /**
47 | * @desc 法线贴图参数
48 | */
49 | normalmap: {
50 |
51 | "normalMap" : { type: "t", value: null },
52 | "normalScale" : { type: "v2", value: new THREE.Vector2( 1, 1 ) }
53 | },
54 | /**
55 | * @desc 雾效果参数
56 | */
57 | fog : {
58 |
59 | "fogDensity" : { type: "f", value: 0.00025 },
60 | "fogNear" : { type: "f", value: 1 },
61 | "fogFar" : { type: "f", value: 2000 },
62 | "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
63 |
64 | },
65 | /**
66 | * @desc 光照效果参数
67 | */
68 | lights: {
69 |
70 | "ambientLightColor" : { type: "fv", value: [] },
71 |
72 | "directionalLightDirection" : { type: "fv", value: [] },
73 | "directionalLightColor" : { type: "fv", value: [] },
74 |
75 | "hemisphereLightDirection" : { type: "fv", value: [] },
76 | "hemisphereLightSkyColor" : { type: "fv", value: [] },
77 | "hemisphereLightGroundColor" : { type: "fv", value: [] },
78 |
79 | "pointLightColor" : { type: "fv", value: [] },
80 | "pointLightPosition" : { type: "fv", value: [] },
81 | "pointLightDistance" : { type: "fv1", value: [] },
82 |
83 | "spotLightColor" : { type: "fv", value: [] },
84 | "spotLightPosition" : { type: "fv", value: [] },
85 | "spotLightDirection" : { type: "fv", value: [] },
86 | "spotLightDistance" : { type: "fv1", value: [] },
87 | "spotLightAngleCos" : { type: "fv1", value: [] },
88 | "spotLightExponent" : { type: "fv1", value: [] }
89 |
90 | },
91 | /**
92 | * @desc 粒子效果参数
93 | */
94 | particle: {
95 |
96 | "psColor" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
97 | "opacity" : { type: "f", value: 1.0 },
98 | "size" : { type: "f", value: 1.0 },
99 | "scale" : { type: "f", value: 1.0 },
100 | "map" : { type: "t", value: null },
101 |
102 | "fogDensity" : { type: "f", value: 0.00025 },
103 | "fogNear" : { type: "f", value: 1 },
104 | "fogFar" : { type: "f", value: 2000 },
105 | "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
106 |
107 | },
108 | /**
109 | * @desc 阴影贴图效果参数
110 | */
111 | shadowmap: {
112 |
113 | "shadowMap": { type: "tv", value: [] },
114 | "shadowMapSize": { type: "v2v", value: [] },
115 |
116 | "shadowBias" : { type: "fv1", value: [] },
117 | "shadowDarkness": { type: "fv1", value: [] },
118 |
119 | "shadowMatrix" : { type: "m4v", value: [] }
120 |
121 | }
122 |
123 | };
124 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
11 | * @param {THREE.Vector3} origin 射线起点
12 | * @param {THREE.Vector3} direction 射线方向
13 | * @param {float} near 最近距离
14 | * @param {float} far 最远距离
15 | * @constructor
16 | */
17 | THREE.Raycaster = function ( origin, direction, near, far ) {
18 | /**
19 | * @desc 射线
20 | * @type {THREE.Ray}
21 | */
22 | this.ray = new THREE.Ray( origin, direction );
23 | // direction is assumed to be normalized (for accurate distance calculations)
24 | /**
25 | * @desc 最近距离
26 | * @default 0
27 | * @type {float}
28 | */
29 | this.near = near || 0;
30 | /**
31 | * @desc 最远距离
32 | * @default Infinity
33 | * @type {float}
34 | */
35 | this.far = far || Infinity;
36 | /**
37 | * @desc 拾取结果
38 | * @type {*}
39 | */
40 | this.params = {
41 | Sprite: {},
42 | Mesh: {},
43 | PointCloud: { threshold: 1 },
44 | LOD: {},
45 | Line: {}
46 | };
47 |
48 | };
49 | /**
50 | * @desc 距离降序排序方法
51 | * @param {THREE.Object3D} a
52 | * @param {THREE.Object3D} b
53 | * @returns {float}
54 | */
55 | var descSort = function ( a, b ) {
56 |
57 | return a.distance - b.distance;
58 |
59 | };
60 | /**
61 | * @desc 插入对象
62 | * @param {THREE.Object3D} object
63 | * @param {THREE.Raycaster} raycaster
64 | * @param {*} intersects 拾取结果对象数组,结果添加至数组
65 | * @param {boolean} recursive 是否递归判断子对象
66 | */
67 | var intersectObject = function ( object, raycaster, intersects, recursive ) {
68 |
69 | object.raycast( raycaster, intersects );
70 |
71 | if ( recursive === true ) {
72 |
73 | var children = object.children;
74 |
75 | for ( var i = 0, l = children.length; i < l; i ++ ) {
76 |
77 | intersectObject( children[ i ], raycaster, intersects, true );
78 |
79 | }
80 |
81 | }
82 |
83 | };
84 |
85 | //
86 |
87 | THREE.Raycaster.prototype = {
88 |
89 | constructor: THREE.Raycaster,
90 | /**
91 | * @desc 拾取精度
92 | * @default
93 | * @type {float}
94 | */
95 | precision: 0.0001,
96 | /**
97 | * @desc 线的精度
98 | * @default
99 | * @type {float}
100 | */
101 | linePrecision: 1,
102 | /**
103 | * @desc 设置拾取对象
104 | * @param {THREE.Ray} origin 射线起点
105 | * @param {THREE.Vector3} direction 射线方向
106 | */
107 | set: function ( origin, direction ) {
108 |
109 | this.ray.set( origin, direction );
110 | // direction is assumed to be normalized (for accurate distance calculations)
111 |
112 | },
113 | /**
114 | * @desc 拾取相交判断
115 | * @param {THREE.Object3D} object 需要判断对象
116 | * @param {boolean} recursive 是否递归
117 | * @returns {*} 被拾取对象数组
118 | */
119 | intersectObject: function ( object, recursive ) {
120 |
121 | var intersects = [];
122 |
123 | intersectObject( object, this, intersects, recursive );
124 |
125 | intersects.sort( descSort );
126 |
127 | return intersects;
128 |
129 | },
130 | /**
131 | * @desc 拾取相交判断
132 | * @param {THREE.Object3D} objects 需要判断对象数组
133 | * @param {boolean} recursive 是否递归
134 | * @returns {*} 被拾取对象数组
135 | */
136 | intersectObjects: function ( objects, recursive ) {
137 |
138 | var intersects = [];
139 |
140 | if ( objects instanceof Array === false ) {
141 |
142 | console.log( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );
143 | return intersects;
144 |
145 | }
146 |
147 | for ( var i = 0, l = objects.length; i < l; i ++ ) {
148 |
149 | intersectObject( objects[ i ], this, intersects, recursive );
150 |
151 | }
152 |
153 | intersects.sort( descSort );
154 |
155 | return intersects;
156 |
157 | }
158 |
159 | };
160 |
161 | }( THREE ) );
162 |
--------------------------------------------------------------------------------
/objects/LOD.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mikael emtinger / http://gomo.se/
3 | * @author alteredq / http://alteredqualia.com/
4 | * @author mrdoob / http://mrdoob.com/
5 | */
6 | /**
7 | * @classdesc LOD对象
8 | * 注释内容部分参照 http://blog.csdn.net/omni360
9 | * @desc LOD技术即Levels of Detail的简称,意为多细节层次。
10 | * LOD技术指根据物体模型的节点在显示环境中所处的位置和重要度
11 | * 决定物体渲染的资源分配,降低非重要物体的面数和细节度,从而获得高效率的渲染运算。
12 | * @constructor
13 | */
14 | THREE.LOD = function () {
15 |
16 | THREE.Object3D.call( this );
17 | /**
18 | * @desc 对象数组
19 | * @type {Array}
20 | */
21 | this.objects = [];
22 |
23 | };
24 |
25 | /**
26 | * @desc LOD.Objec3D的原型继承所有属性方法
27 | * @type {THREE.Object3D}
28 | */
29 | THREE.LOD.prototype = Object.create( THREE.Object3D.prototype );
30 | /**
31 | * @desc 将对象(参数object)根据参数distance插入到存放层次细节展示的对象集合中(LOD.Objects)
32 | * @param {THREE.Object3D} object 3D对象
33 | * @param {float} distance 层次距离
34 | */
35 | THREE.LOD.prototype.addLevel = function ( object, distance ) {
36 |
37 | if ( distance === undefined ) distance = 0;
38 |
39 | distance = Math.abs( distance );
40 |
41 | for ( var l = 0; l < this.objects.length; l ++ ) {
42 |
43 | if ( distance < this.objects[ l ].distance ) {
44 |
45 | break;
46 |
47 | }
48 |
49 | }
50 |
51 | this.objects.splice( l, 0, { distance: distance, object: object } );
52 | this.add( object );
53 |
54 | };
55 | /**
56 | * @desc 根据距离返回对应层次的对象
57 | * @param {float} distance 层次距离
58 | * @returns {THREE.Object3D}
59 | */
60 | THREE.LOD.prototype.getObjectForDistance = function ( distance ) {
61 | //排序由小到大遍历
62 | for ( var i = 1, l = this.objects.length; i < l; i ++ ) {
63 |
64 | if ( distance < this.objects[ i ].distance ) {
65 |
66 | break;
67 |
68 | }
69 |
70 | }
71 |
72 | return this.objects[ i - 1 ].object;
73 |
74 | };
75 | /**
76 | * @function
77 | * @desc LOD的拾取判断函数
78 | * @param {THREE.Raycaster} raycaster 拾取射线对象
79 | * @param {*} intersects 拾取结果对象数组
80 | */
81 | THREE.LOD.prototype.raycast = ( function () {
82 |
83 | var matrixPosition = new THREE.Vector3();
84 |
85 | return function ( raycaster, intersects ) {
86 |
87 | matrixPosition.setFromMatrixPosition( this.matrixWorld );
88 |
89 | var distance = raycaster.ray.origin.distanceTo( matrixPosition );
90 |
91 | //将当前层次的对象,进行光线跟踪计算.
92 | this.getObjectForDistance( distance ).raycast( raycaster, intersects );
93 |
94 | };
95 |
96 | }() );
97 | /**
98 | * @function
99 | * @desc 根据相机的位置更新显示的层次
100 | * @param {THREE.Camera} camera 相机
101 | * @return {THREE.Lod} 新的LOD对象
102 | */
103 | THREE.LOD.prototype.update = function () {
104 |
105 | var v1 = new THREE.Vector3();
106 | var v2 = new THREE.Vector3();
107 |
108 | return function ( camera ) {
109 |
110 | if ( this.objects.length > 1 ) {
111 |
112 | v1.setFromMatrixPosition( camera.matrixWorld );
113 | v2.setFromMatrixPosition( this.matrixWorld );
114 |
115 | // 重新计算相机的位置到当前层次的距离
116 | var distance = v1.distanceTo( v2 );
117 |
118 | this.objects[ 0 ].object.visible = true;
119 |
120 | for ( var i = 1, l = this.objects.length; i < l; i ++ ) {
121 | // 如果计算相机的位置到当前层次的距离大于当前对象的距离
122 | if ( distance >= this.objects[ i ].distance ) {
123 | // 计算相机的位置到当前层次的距离之前的对象不显示
124 | this.objects[ i - 1 ].object.visible = false;
125 | // 计算相机的位置到当前层次的距离之后的对象显示.
126 | this.objects[ i ].object.visible = true;
127 |
128 | } else {
129 |
130 | break;
131 |
132 | }
133 |
134 | }
135 |
136 | for ( ; i < l; i ++ ) {
137 |
138 | this.objects[ i ].object.visible = false;
139 |
140 | }
141 |
142 | }
143 |
144 | };
145 |
146 | }();
147 | /**
148 | * @desc Three.LOD 拷贝函数
149 | * @param {THREE.LOD} object
150 | * @returns {THREE.LOD}
151 | */
152 | THREE.LOD.prototype.clone = function ( object ) {
153 |
154 | if ( object === undefined ) object = new THREE.LOD();
155 |
156 | THREE.Object3D.prototype.clone.call( this, object );
157 |
158 | for ( var i = 0, l = this.objects.length; i < l; i ++ ) {
159 | var x = this.objects[ i ].object.clone();
160 | x.visible = i === 0;
161 | object.addLevel( x, this.objects[ i ].distance );
162 | }
163 |
164 | return object;
165 |
166 | };
167 |
--------------------------------------------------------------------------------
/objects/Line.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 | /**
5 | * @classdesc 线对象
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @desc WebGL中好像线不能设置宽度
8 | * @param {THREE.Geometry} geometry 几何信息
9 | * @param {THREE.Material} material 材质信息
10 | * @param {number} mode 线型
11 | * @extends {THREE.Object3D}
12 | * @constructor
13 | */
14 | THREE.Line = function ( geometry, material, mode ) {
15 |
16 | THREE.Object3D.call( this );
17 | /**
18 | * @default 'Line'
19 | * @type {string}
20 | */
21 | this.type = 'Line';
22 |
23 | /**
24 | * @desc 几何信息
25 | * @default THREE.Geometry()
26 | * @type {THREE.Geometry}
27 | */
28 | this.geometry = geometry !== undefined ? geometry : new THREE.Geometry();
29 | /**
30 | * @desc 材质信息
31 | * @default THREE.LineBasicMaterial() 随机颜色的线
32 | * @type {THREE.Geometry}
33 | */
34 | this.material = material !== undefined ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } );
35 | /**
36 | * @desc 线的绘制方式
37 | * @default THREE.LineStrip
38 | * @type {number}
39 | */
40 | this.mode = ( mode !== undefined ) ? mode : THREE.LineStrip;
41 |
42 | };
43 | /**
44 | * @memberof THREE
45 | * @desc 线型定义
46 | * @default
47 | * @type {number}
48 | */
49 | THREE.LineStrip = 0;
50 | /**
51 | * @memberof THREE
52 | * @desc 线型定义
53 | * @default
54 | * @type {number}
55 | */
56 | THREE.LinePieces = 1;
57 | /**
58 | * @desc Line对象从THREE.Objec3D的原型继承所有属性方法
59 | * @type {THREE.Object3D}
60 | */
61 | THREE.Line.prototype = Object.create( THREE.Object3D.prototype );
62 | /**
63 | * @function
64 | * @desc 线的拾取判断函数
65 | * @param {THREE.Raycaster} raycaster 拾取射线对象
66 | * @param {*} intersects 拾取结果对象数组
67 | */
68 | THREE.Line.prototype.raycast = ( function () {
69 |
70 | var inverseMatrix = new THREE.Matrix4();
71 | var ray = new THREE.Ray();
72 | var sphere = new THREE.Sphere();
73 |
74 | return function ( raycaster, intersects ) {
75 |
76 | var precision = raycaster.linePrecision;
77 | var precisionSq = precision * precision;
78 |
79 | var geometry = this.geometry;
80 |
81 | if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
82 |
83 | // Checking boundingSphere distance to ray
84 | // 先进行外包围球体判断
85 | sphere.copy( geometry.boundingSphere );
86 | sphere.applyMatrix4( this.matrixWorld );
87 |
88 | if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) {
89 |
90 | return;
91 |
92 | }
93 |
94 | inverseMatrix.getInverse( this.matrixWorld );
95 | ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
96 |
97 | /* if ( geometry instanceof THREE.BufferGeometry ) {
98 |
99 | } else */ if ( geometry instanceof THREE.Geometry ) {
100 |
101 | var vertices = geometry.vertices;
102 | var nbVertices = vertices.length;
103 | var interSegment = new THREE.Vector3();
104 | var interRay = new THREE.Vector3();
105 | var step = this.mode === THREE.LineStrip ? 1 : 2;
106 |
107 | // 三角面判断
108 | for ( var i = 0; i < nbVertices - 1; i = i + step ) {
109 |
110 | var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
111 |
112 | if ( distSq > precisionSq ) continue;
113 |
114 | var distance = ray.origin.distanceTo( interRay );
115 |
116 | if ( distance < raycaster.near || distance > raycaster.far ) continue;
117 |
118 | // 加入结果数组内
119 | intersects.push( {
120 |
121 | distance: distance,
122 | // What do we want? intersection point on the ray or on the segment??
123 | // point: raycaster.ray.at( distance ),
124 | point: interSegment.clone().applyMatrix4( this.matrixWorld ),
125 | face: null,
126 | faceIndex: null,
127 | object: this
128 |
129 | } );
130 |
131 | }
132 |
133 | }
134 |
135 | };
136 |
137 | }() );
138 | /**
139 | * @desc Three.Line 克隆函数
140 | * @param {THREE.Line} object
141 | * @returns {THREE.Line}
142 | */
143 | THREE.Line.prototype.clone = function ( object ) {
144 |
145 | if ( object === undefined ) object = new THREE.Line( this.geometry, this.material, this.mode );
146 |
147 | THREE.Object3D.prototype.clone.call( this, object );
148 |
149 | return object;
150 |
151 | };
152 |
--------------------------------------------------------------------------------
/math/Line3.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author bhouston / http://exocortex.com
3 | */
4 | /**
5 | * @classdesc 3维线段
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @param {THREE.Vector3} start
8 | * @param {THREE.Vector3} end
9 | * @class
10 | * @example var start = new Vector3(0,0,0),end = new Vector3(1,1,1); var line = new Line3(start,end);
11 | */
12 | THREE.Line3 = function ( start, end ) {
13 | /**
14 | * @desc 线段起点
15 | * @type {THREE.Vector3}
16 | */
17 | this.start = ( start !== undefined ) ? start : new THREE.Vector3();
18 | /**
19 | * @desc 线段终点
20 | * @type {THREE.Vector3}
21 | */
22 | this.end = ( end !== undefined ) ? end : new THREE.Vector3();
23 |
24 | };
25 |
26 | THREE.Line3.prototype = {
27 |
28 | constructor: THREE.Line3,
29 |
30 | /**
31 | * @desc 根据start,end坐标值设置3维线段
32 | * @param {THREE.Vector3} start
33 | * @param {THREE.Vector3} end
34 | * @returns {THREE.Line3}
35 | */
36 | set: function ( start, end ) {
37 |
38 | this.start.copy( start );
39 | this.end.copy( end );
40 |
41 | return this;
42 |
43 | },
44 | /**
45 | * @desc 拷贝3维线段
46 | * @param {THREE.Line3} line
47 | * @returns {THREE.Line3}
48 | */
49 | copy: function ( line ) {
50 |
51 | this.start.copy( line.start );
52 | this.end.copy( line.end );
53 |
54 | return this;
55 |
56 | },
57 |
58 | /**
59 | * @desc 返回3维线段中点
60 | * @param {THREE.Line3} optionalTarget
61 | * @returns {THREE.Vector3}
62 | */
63 | center: function ( optionalTarget ) {
64 |
65 | var result = optionalTarget || new THREE.Vector3();
66 | return result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );
67 |
68 | },
69 |
70 | /**
71 | * @desc 获得线段的向量
72 | * @param {THREE.Line3} optionalTarget
73 | * @returns {THREE.Vector3}
74 | */
75 | delta: function ( optionalTarget ) {
76 |
77 | var result = optionalTarget || new THREE.Vector3();
78 | return result.subVectors( this.end, this.start );
79 |
80 | },
81 | /**
82 | * @desc 获得当前三维线段起始点到端点的点积
83 | * @returns {float}
84 | */
85 | distanceSq: function () {
86 |
87 | return this.start.distanceToSquared( this.end );
88 |
89 | },
90 | /**
91 | * @desc 获得当前三维线段起始点到端点的距离
92 | * @returns {float}
93 | */
94 | distance: function () {
95 |
96 | return this.start.distanceTo( this.end );
97 |
98 | },
99 | /**
100 | * @desc 当前三维线段方向的任意向量
101 | * @param {float} t [0,1] 当t=0,返回起点向量,当t=1返回结束点向量
102 | * @param {THREE.Vector3} optionalTarget
103 | * @returns {THREE.Vector3}
104 | */
105 | at: function ( t, optionalTarget ) {
106 |
107 | var result = optionalTarget || new THREE.Vector3();
108 |
109 | return this.delta( result ).multiplyScalar( t ).add( this.start );
110 |
111 | },
112 | /**
113 | * @function
114 | * @desc 返回一个基于点投影到线段上点的参数(就是参数point投影到线段的位置)
115 | * @param {THREE.Vector3} point
116 | * @param {boolean} clampToLine 为true,那么返回值将是0和1之间
117 | * @return {float}
118 | */
119 | closestPointToPointParameter: function () {
120 |
121 | var startP = new THREE.Vector3();
122 | var startEnd = new THREE.Vector3();
123 |
124 | return function ( point, clampToLine ) {
125 |
126 | startP.subVectors( point, this.start );
127 | startEnd.subVectors( this.end, this.start );
128 |
129 | var startEnd2 = startEnd.dot( startEnd );
130 | var startEnd_startP = startEnd.dot( startP );
131 |
132 | var t = startEnd_startP / startEnd2;
133 |
134 | if ( clampToLine ) {
135 |
136 | t = THREE.Math.clamp( t, 0, 1 );
137 |
138 | }
139 |
140 | return t;
141 |
142 | };
143 |
144 | }(),
145 |
146 | /**
147 | * @desc 返回一个基于点投影到线段上的向量
148 | * @param {THREE.Vector3} point
149 | * @param {boolean} clampToLine 为true,那么返回的向量在线段起始点和结束点之间。
150 | * @param {THREE.Vector3} optionalTarget
151 | * @returns {*|THREE.Vector3}
152 | */
153 | closestPointToPoint: function ( point, clampToLine, optionalTarget ) {
154 |
155 | var t = this.closestPointToPointParameter( point, clampToLine );
156 |
157 | var result = optionalTarget || new THREE.Vector3();
158 |
159 | return this.delta( result ).multiplyScalar( t ).add( this.start );
160 |
161 | },
162 | /**
163 | * @desc 线段的起始点,结束点应用矩阵变换.达到旋转,缩放,移动的目的
164 | * @param {THREE.Matrix3} matrix
165 | * @returns {THREE.Line3}
166 | */
167 | applyMatrix4: function ( matrix ) {
168 |
169 | this.start.applyMatrix4( matrix );
170 | this.end.applyMatrix4( matrix );
171 |
172 | return this;
173 |
174 | },
175 | /**
176 | * @desc 3维线段等号
177 | * @param {THREE.Line3} line
178 | * @returns {boolean}
179 | */
180 | equals: function ( line ) {
181 |
182 | return line.start.equals( this.start ) && line.end.equals( this.end );
183 |
184 | },
185 |
186 | /**
187 | * @desc 克隆3维线段
188 | * @returns {THREE.Line3}
189 | */
190 | clone: function () {
191 |
192 | return new THREE.Line3().copy( this );
193 |
194 | }
195 |
196 | };
197 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
33 | * @desc 这样的材质对象让用户扩充材质类型,有了无限的可能
34 | * @param {String} parameters 材质参数
35 | * @extends {THREE.Material}
36 | * @constructor
37 | */
38 | THREE.ShaderMaterial = function ( parameters ) {
39 |
40 | THREE.Material.call( this );
41 | /**
42 | * @default 'ShaderMaterial'
43 | * @type {string}
44 | */
45 | this.type = 'ShaderMaterial';
46 | /**
47 | * @desc 用户自定义defines变量
48 | * @default
49 | * @type {*}
50 | */
51 | this.defines = {};
52 | /**
53 | * @desc 用户自定义uniforms变量
54 | * @default
55 | * @type {*}
56 | */
57 | this.uniforms = {};
58 | /**
59 | * @desc 用户自定义attributes变量
60 | * @default
61 | * @type {*}
62 | */
63 | this.attributes = null;
64 | /**
65 | * @desc 自定义顶点着色器
66 | * @type {string}
67 | */
68 | this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}';
69 | /**
70 | * @desc 自定义片段着色器
71 | * @type {string}
72 | */
73 | this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}';
74 | /**
75 | * @desc 着色方式
76 | * THREE.SmoothShading平滑着色:用多种颜色进行绘制
77 | * 每个顶点都是单独进行处理的,各顶点和各图元之间采用均匀插值。
78 | * @default
79 | * @type {number}
80 | */
81 | this.shading = THREE.SmoothShading;
82 | /**
83 | * @desc 线的宽度
84 | * @default
85 | * @type {float}
86 | */
87 | this.linewidth = 1;
88 | /**
89 | * @desc 是否以线框方式渲染几何体
90 | * @default
91 | * @type {boolean}
92 | */
93 | this.wireframe = false;
94 | /**
95 | * @desc 线框宽度
96 | * @default
97 | * @type {float}
98 | */
99 | this.wireframeLinewidth = 1;
100 | /**
101 | * @desc 雾效,默认关闭
102 | * @default
103 | * @type {boolean}
104 | */
105 | this.fog = false; // set to use scene fog
106 | /**
107 | * @desc 是否使用场景内的灯光,默认关闭
108 | * @default
109 | * @type {boolean}
110 | */
111 | this.lights = false; // set to use scene lights
112 | /**
113 | * @desc 材质顶点颜色
114 | * @default THREE.NoColors
115 | * @type {number}
116 | */
117 | this.vertexColors = THREE.NoColors; // set to use "color" attribute stream
118 | /**
119 | * @desc 材质是否使用蒙皮
120 | * @default
121 | * @type {boolean}
122 | */
123 | this.skinning = false; // set to use skinning attribute streams
124 |
125 | /**
126 | * @desc 材质是否设定目标变形动画
127 | * @default
128 | * @type {boolean}
129 | */
130 | this.morphTargets = false;
131 | /**
132 | * @desc 材质是否反转(变换)法线
133 | * @default
134 | * @type {boolean}
135 | */
136 | this.morphNormals = false;
137 |
138 | // When rendered geometry doesn't include these attributes but the material does,
139 | // use these default values in WebGL. This avoids errors when buffer data is missing.
140 | // 当渲染几何体不包含这些属性,但是材质中包含,在WEBGL中使用这些默认的值,可以避免缓存数据丢失发生错误.
141 | /**
142 | * @des 默认渲染属性
143 | * @type {*}
144 | */
145 | this.defaultAttributeValues = {
146 | 'color': [ 1, 1, 1 ],
147 | 'uv': [ 0, 0 ],
148 | 'uv2': [ 0, 0 ]
149 | };
150 | /**
151 | * @desc 用来接收索引为0的属性
152 | * @type {String}
153 | */
154 | this.index0AttributeName = undefined;
155 |
156 | this.setValues( parameters );
157 |
158 | };
159 | /**
160 | * @desc ShaderMaterial对象从THREE.Material的原型继承所有属性方法
161 | * @type {THREE.Material}
162 | */
163 | THREE.ShaderMaterial.prototype = Object.create( THREE.Material.prototype );
164 | /**
165 | * @desc ShaderMaterial材质的克隆函数
166 | * @returns {THREE.ShaderMaterial}
167 | */
168 | THREE.ShaderMaterial.prototype.clone = function () {
169 |
170 | var material = new THREE.ShaderMaterial();
171 |
172 | THREE.Material.prototype.clone.call( this, material );
173 |
174 | material.fragmentShader = this.fragmentShader;
175 | material.vertexShader = this.vertexShader;
176 |
177 | material.uniforms = THREE.UniformsUtils.clone( this.uniforms );
178 |
179 | material.attributes = this.attributes;
180 | material.defines = this.defines;
181 |
182 | material.shading = this.shading;
183 |
184 | material.wireframe = this.wireframe;
185 | material.wireframeLinewidth = this.wireframeLinewidth;
186 |
187 | material.fog = this.fog;
188 |
189 | material.lights = this.lights;
190 |
191 | material.vertexColors = this.vertexColors;
192 |
193 | material.skinning = this.skinning;
194 |
195 | material.morphTargets = this.morphTargets;
196 | material.morphNormals = this.morphNormals;
197 |
198 | return material;
199 |
200 | };
201 |
--------------------------------------------------------------------------------
/objects/PointCloud.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 | /**
5 | * @classdesc 点云对象
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @param {THREE.Geometry} geometry 点云对象的几何对象
8 | * @param {THREE.Material} material 点云对象的材质对象
9 | * @constructor
10 | */
11 | THREE.PointCloud = function ( geometry, material ) {
12 |
13 | THREE.Object3D.call( this );
14 |
15 | this.type = 'PointCloud';
16 | /**
17 | * @desc 点云对象的几何对象
18 | * @type {THREE.Geometry}
19 | */
20 | this.geometry = geometry !== undefined ? geometry : new THREE.Geometry();
21 | /**
22 | * @desc 点云对象的材质对象
23 | * @type {THREE.Material}
24 | */
25 | this.material = material !== undefined ? material : new THREE.PointCloudMaterial( { color: Math.random() * 0xffffff } );
26 | /**
27 | * @desc 是否对点云排序
28 | * @type {boolean}
29 | */
30 | this.sortParticles = false;
31 |
32 | };
33 | /**
34 | * @desc PointCloud从Objec3D的原型继承所有属性方法
35 | * @type {THREE.Object3D}
36 | */
37 | THREE.PointCloud.prototype = Object.create( THREE.Object3D.prototype );
38 |
39 | /**
40 | * @function
41 | * @desc 点云的拾取判断函数
42 | * @param {THREE.Raycaster} raycaster 拾取射线对象
43 | * @param {*} intersects 拾取结果对象数组
44 | */
45 | THREE.PointCloud.prototype.raycast = ( function () {
46 |
47 | var inverseMatrix = new THREE.Matrix4();
48 | var ray = new THREE.Ray();
49 |
50 | return function ( raycaster, intersects ) {
51 |
52 | var object = this;
53 | var geometry = object.geometry;
54 | var threshold = raycaster.params.PointCloud.threshold;
55 |
56 | inverseMatrix.getInverse( this.matrixWorld );
57 | ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
58 | // 外包围盒碰撞判断
59 | if ( geometry.boundingBox !== null ) {
60 |
61 | if ( ray.isIntersectionBox( geometry.boundingBox ) === false ) {
62 |
63 | return;
64 |
65 | }
66 |
67 | }
68 |
69 | var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
70 | var position = new THREE.Vector3();
71 | //检查射线与点云元素是否碰撞的具体实现.
72 | var testPoint = function ( point, index ) {
73 |
74 | var rayPointDistance = ray.distanceToPoint( point );
75 |
76 | if ( rayPointDistance < localThreshold ) {
77 |
78 | var intersectPoint = ray.closestPointToPoint( point );
79 | intersectPoint.applyMatrix4( object.matrixWorld );
80 |
81 | var distance = raycaster.ray.origin.distanceTo( intersectPoint );
82 |
83 | intersects.push( {
84 |
85 | distance: distance,
86 | distanceToRay: rayPointDistance,
87 | point: intersectPoint.clone(),
88 | index: index,
89 | face: null,
90 | object: object
91 |
92 | } );
93 |
94 | }
95 |
96 | };
97 | // 如果geometry对象是BufferGeometry对象
98 | if ( geometry instanceof THREE.BufferGeometry ) {
99 |
100 | var attributes = geometry.attributes;
101 | var positions = attributes.position.array;
102 | // 下面对三种数据格式的pointCloud对象的元素进行检测.
103 | if ( attributes.index !== undefined ) {
104 |
105 | var indices = attributes.index.array;
106 | var offsets = geometry.offsets;
107 |
108 | if ( offsets.length === 0 ) {
109 |
110 | var offset = {
111 | start: 0,
112 | count: indices.length,
113 | index: 0
114 | };
115 |
116 | offsets = [ offset ];
117 |
118 | }
119 |
120 | for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) {
121 |
122 | var start = offsets[ oi ].start;
123 | var count = offsets[ oi ].count;
124 | var index = offsets[ oi ].index;
125 |
126 | for ( var i = start, il = start + count; i < il; i ++ ) {
127 |
128 | var a = index + indices[ i ];
129 |
130 | position.fromArray( positions, a * 3 );
131 |
132 | testPoint( position, a );
133 |
134 | }
135 |
136 | }
137 |
138 | } else {
139 |
140 | var pointCount = positions.length / 3;
141 |
142 | for ( var i = 0; i < pointCount; i ++ ) {
143 |
144 | position.set(
145 | positions[ 3 * i ],
146 | positions[ 3 * i + 1 ],
147 | positions[ 3 * i + 2 ]
148 | );
149 |
150 | testPoint( position, i );
151 |
152 | }
153 |
154 | }
155 |
156 | } else {
157 |
158 | var vertices = this.geometry.vertices;
159 |
160 | for ( var i = 0; i < vertices.length; i ++ ) {
161 |
162 | testPoint( vertices[ i ], i );
163 |
164 | }
165 |
166 | }
167 |
168 | };
169 |
170 | }() );
171 | /**
172 | * @desc Three.PointCloud 克隆函数
173 | * @param {THREE.PointCloud} object
174 | * @returns {THREE.PointCloud}
175 | */
176 | THREE.PointCloud.prototype.clone = function ( object ) {
177 |
178 | if ( object === undefined ) object = new THREE.PointCloud( this.geometry, this.material );
179 |
180 | object.sortParticles = this.sortParticles;
181 |
182 | THREE.Object3D.prototype.clone.call( this, object );
183 |
184 | return object;
185 |
186 | };
187 |
188 | // Backwards compatibility
189 | /**
190 | * @ignore
191 | * @param geometry
192 | * @param material
193 | * @returns {THREE.PointCloud}
194 | * @constructor
195 | */
196 | THREE.ParticleSystem = function ( geometry, material ) {
197 |
198 | console.warn( 'THREE.ParticleSystem has been renamed to THREE.PointCloud.' );
199 | return new THREE.PointCloud( geometry, material );
200 |
201 | };
202 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
40 | * @desc 据参数parameters创建线段的线线型材质,参数为JSON格式的属性参数
41 | * @param {String} parameters 材质参数
42 | * @extends {THREE.Material}
43 | * @constructor
44 | */
45 | THREE.MeshBasicMaterial = function ( parameters ) {
46 |
47 | THREE.Material.call( this );
48 | /**
49 | * @default 'MeshBasicMaterial'
50 | * @type {string}
51 | */
52 | this.type = 'MeshBasicMaterial';
53 | /**
54 | * @desc 材质颜色
55 | * @default 0xffffff 白色
56 | * @type {THREE.Color}
57 | */
58 | this.color = new THREE.Color( 0xffffff ); // emissive
59 | /**
60 | * @desc 纹理贴图
61 | * @default
62 | * @type {THREE.Texture}
63 | */
64 | this.map = null;
65 | /**
66 | * @desc 光照贴图
67 | * @default
68 | * @type {THREE.Texture}
69 | */
70 | this.lightMap = null;
71 | /**
72 | * @desc 高光贴图
73 | * @default
74 | * @type {THREE.Texture}
75 | */
76 | this.specularMap = null;
77 | /**
78 | * @desc 透明贴图
79 | * @default
80 | * @type {THREE.Texture}
81 | */
82 | this.alphaMap = null;
83 | /**
84 | * @desc 环境贴图
85 | * @default
86 | * @type {THREE.Texture}
87 | */
88 | this.envMap = null;
89 | /**
90 | * @desc 材质混合模式
91 | * @default THREE.MultiplyOperation
92 | * @type {number}
93 | */
94 | this.combine = THREE.MultiplyOperation;
95 | /**
96 | * @desc 反射率
97 | * @default
98 | * @type {float}
99 | */
100 | this.reflectivity = 1;
101 | /**
102 | * @desc 折射率
103 | * @default
104 | * @type {float}
105 | */
106 | this.refractionRatio = 0.98;
107 | /**
108 | * @desc 雾效,默认开启
109 | * @default
110 | * @type {boolean}
111 | */
112 | this.fog = true;
113 | /**
114 | * @desc 着色方式
115 | * THREE.SmoothShading平滑着色:用多种颜色进行绘制
116 | * 每个顶点都是单独进行处理的,各顶点和各图元之间采用均匀插值。
117 | * @default
118 | * @type {number}
119 | */
120 | this.shading = THREE.SmoothShading;
121 | /**
122 | * @desc 是否以线框方式渲染几何体
123 | * @default
124 | * @type {boolean}
125 | */
126 | this.wireframe = false;
127 | /**
128 | * @desc 线框宽度
129 | * @default
130 | * @type {float}
131 | */
132 | this.wireframeLinewidth = 1;
133 | /**
134 | * @desc 线框端点类型,参照LineBasicMaterial的定义
135 | * @default 'round'
136 | * @type {string}
137 | */
138 | this.wireframeLinecap = 'round';
139 | /**
140 | * @desc 线框连接类型,参照LineBasicMaterial的定义
141 | * @default 'round'
142 | * @type {string}
143 | */
144 | this.wireframeLinejoin = 'round';
145 | /**
146 | * @desc 材质顶点颜色
147 | * @default THREE.NoColors
148 | * @type {number}
149 | */
150 | this.vertexColors = THREE.NoColors;
151 | /**
152 | * @desc 材质是否使用蒙皮
153 | * @default
154 | * @type {boolean}
155 | */
156 | this.skinning = false;
157 | /**
158 | * @desc 材质是否设定目标变形动画
159 | * @default
160 | * @type {boolean}
161 | */
162 | this.morphTargets = false;
163 |
164 | this.setValues( parameters );
165 |
166 | };
167 | /**
168 | * @desc MeshBasicMaterial对象从THREE.Material的原型继承所有属性方法
169 | * @type {THREE.Material}
170 | */
171 | THREE.MeshBasicMaterial.prototype = Object.create( THREE.Material.prototype );
172 | /**
173 | * @desc 面材质的克隆函数
174 | * @returns {THREE.MeshBasicMaterial}
175 | */
176 | THREE.MeshBasicMaterial.prototype.clone = function () {
177 |
178 | var material = new THREE.MeshBasicMaterial();
179 |
180 | THREE.Material.prototype.clone.call( this, material );
181 |
182 | material.color.copy( this.color );
183 |
184 | material.map = this.map;
185 |
186 | material.lightMap = this.lightMap;
187 |
188 | material.specularMap = this.specularMap;
189 |
190 | material.alphaMap = this.alphaMap;
191 |
192 | material.envMap = this.envMap;
193 | material.combine = this.combine;
194 | material.reflectivity = this.reflectivity;
195 | material.refractionRatio = this.refractionRatio;
196 |
197 | material.fog = this.fog;
198 |
199 | material.shading = this.shading;
200 |
201 | material.wireframe = this.wireframe;
202 | material.wireframeLinewidth = this.wireframeLinewidth;
203 | material.wireframeLinecap = this.wireframeLinecap;
204 | material.wireframeLinejoin = this.wireframeLinejoin;
205 |
206 | material.vertexColors = this.vertexColors;
207 |
208 | material.skinning = this.skinning;
209 | material.morphTargets = this.morphTargets;
210 |
211 | return material;
212 |
213 | };
214 |
--------------------------------------------------------------------------------
/math/Sphere.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author bhouston / http://exocortex.com
3 | * @author mrdoob / http://mrdoob.com/
4 | */
5 | /**
6 | * @classdesc 球体类
7 | * 注释内容部分参照 http://blog.csdn.net/omni360
8 | * @desc center,半径为radius的球体
9 | * @param {THREE.Vector3} center 中心点坐标
10 | * @param {float} radius 半径
11 | * @constructor
12 | */
13 | THREE.Sphere = function ( center, radius ) {
14 | /**
15 | * @desc 球体中心点
16 | * @type {THREE.Vector3}
17 | */
18 | this.center = ( center !== undefined ) ? center : new THREE.Vector3();
19 | /**
20 | * @desc 球体半径
21 | * @default 0
22 | * @type {float}
23 | */
24 | this.radius = ( radius !== undefined ) ? radius : 0;
25 |
26 | };
27 |
28 | THREE.Sphere.prototype = {
29 |
30 | constructor: THREE.Sphere,
31 | /**
32 | * @desc 根据圆心和半径设置球体
33 | * @param center
34 | * @param radius
35 | * @returns {THREE.Sphere}
36 | */
37 | set: function ( center, radius ) {
38 |
39 | this.center.copy( center );
40 | this.radius = radius;
41 |
42 | return this;
43 | },
44 | /**
45 | * @function
46 | * @desc Vector3对象组成的points数组中的到圆心距离最大的值重新设置球体的半径
47 | * @param {THREE.Vector3[]} points
48 | * @param {THREE.Vector3} optionalCenter 球体中心
49 | * @returns {THREE.Sphere}
50 | */
51 | setFromPoints: function () {
52 |
53 | var box = new THREE.Box3();
54 |
55 | return function ( points, optionalCenter ) {
56 |
57 | var center = this.center;
58 |
59 | if ( optionalCenter !== undefined ) {
60 |
61 | center.copy( optionalCenter );
62 |
63 | } else {
64 |
65 | box.setFromPoints( points ).center( center );
66 |
67 | }
68 |
69 | var maxRadiusSq = 0;
70 |
71 | for ( var i = 0, il = points.length; i < il; i ++ ) {
72 |
73 | maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
74 |
75 | }
76 |
77 | this.radius = Math.sqrt( maxRadiusSq );
78 |
79 | return this;
80 |
81 | };
82 |
83 | }(),
84 |
85 | /**
86 | * @desc 拷贝球体
87 | * @param {THREE.Sphere} sphere
88 | * @returns {THREE.Sphere}
89 | */
90 | copy: function ( sphere ) {
91 |
92 | this.center.copy( sphere.center );
93 | this.radius = sphere.radius;
94 |
95 | return this;
96 |
97 | },
98 | /**
99 | * @desc 判断球体是否合法
100 | * @returns {boolean}
101 | */
102 | empty: function () {
103 |
104 | return ( this.radius <= 0 );
105 |
106 | },
107 |
108 | /**
109 | * @desc 判断点是否在球体内
110 | * @param {THREE.Vector3} point
111 | * @returns {boolean}
112 | */
113 | containsPoint: function ( point ) {
114 |
115 | return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );
116 |
117 | },
118 |
119 | /**
120 | * @desc 点到球心的距离
121 | * @param {THREE.Vector3} point
122 | * @returns {float}
123 | */
124 | distanceToPoint: function ( point ) {
125 |
126 | return ( point.distanceTo( this.center ) - this.radius );
127 |
128 | },
129 | /**
130 | * @desc 两个球体是否相交
131 | * @param {THREE.Sphere} sphere
132 | * @returns {boolean}
133 | */
134 | intersectsSphere: function ( sphere ) {
135 |
136 | var radiusSum = this.radius + sphere.radius;
137 |
138 | return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );
139 |
140 | },
141 | /**
142 | * @desc 根据点来重新定义球体半径
143 | * 如果point在球体外,强制将point设置到球体表面,如果point在球体内,重新设置球体半径为point到当前球体半径的距离
144 | * @param {THREE.Vector3} point
145 | * @param {THREE.Vector3} optionalTarget
146 | * @returns {THREE.Vector3}
147 | */
148 | clampPoint: function ( point, optionalTarget ) {
149 |
150 | var deltaLengthSq = this.center.distanceToSquared( point );
151 |
152 | var result = optionalTarget || new THREE.Vector3();
153 | result.copy( point );
154 |
155 | if ( deltaLengthSq > ( this.radius * this.radius ) ) {
156 |
157 | result.sub( this.center ).normalize();
158 | result.multiplyScalar( this.radius ).add( this.center );
159 |
160 | }
161 |
162 | return result;
163 |
164 | },
165 |
166 | /**
167 | * @desc 计算球体的外包围盒
168 | * @param {THREE.Box3} optionalTarget
169 | * @returns {THREE.Box3}
170 | */
171 | getBoundingBox: function ( optionalTarget ) {
172 |
173 | var box = optionalTarget || new THREE.Box3();
174 |
175 | box.set( this.center, this.center );
176 | box.expandByScalar( this.radius );
177 |
178 | return box;
179 |
180 | },
181 | /**
182 | * @desc 球体的投影变换
183 | * 平移相对于球心,缩放相对于半径
184 | * @param {THREE.Matrix4} matrix
185 | * @returns {THREE.Sphere}
186 | */
187 | applyMatrix4: function ( matrix ) {
188 |
189 | this.center.applyMatrix4( matrix );
190 | this.radius = this.radius * matrix.getMaxScaleOnAxis();
191 |
192 | return this;
193 |
194 | },
195 | /**
196 | * @desc 球体平移
197 | * @param {THREE.Vector3} offset
198 | * @returns {THREE.Sphere}
199 | */
200 | translate: function ( offset ) {
201 |
202 | this.center.add( offset );
203 |
204 | return this;
205 |
206 | },
207 | /**
208 | * @desc 球体是否相等
209 | * @param {THREE.Sphere} sphere
210 | * @returns {boolean}
211 | */
212 | equals: function ( sphere ) {
213 |
214 | return sphere.center.equals( this.center ) && ( sphere.radius === this.radius );
215 |
216 | },
217 |
218 | /**
219 | * @desc 球体克隆
220 | * @returns {THREE.Sphere}
221 | */
222 | clone: function () {
223 |
224 | return new THREE.Sphere().copy( this );
225 |
226 | }
227 |
228 | };
229 |
--------------------------------------------------------------------------------
/math/Math.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | * @author mrdoob / http://mrdoob.com/
4 | */
5 | /**
6 | * @classdesc 数学类
7 | * 注释内容部分参照 http://blog.csdn.net/omni360
8 | * @desc 数学相关函数
9 | * @class
10 | */
11 | THREE.Math = {
12 |
13 | /**
14 | * @function
15 | * @desc 生成36位的UUID
16 | * @return {char[]}
17 | */
18 | generateUUID: function () {
19 |
20 | // http://www.broofa.com/Tools/Math.uuid.htm
21 |
22 | var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );
23 | var uuid = new Array( 36 );
24 | var rnd = 0, r;
25 |
26 | return function () {
27 |
28 | for ( var i = 0; i < 36; i ++ ) {
29 |
30 | if ( i == 8 || i == 13 || i == 18 || i == 23 ) {
31 |
32 | uuid[ i ] = '-';
33 |
34 | } else if ( i == 14 ) {
35 |
36 | uuid[ i ] = '4';
37 |
38 | } else {
39 |
40 | if ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;
41 | r = rnd & 0xf;
42 | rnd = rnd >> 4;
43 | uuid[ i ] = chars[ ( i == 19 ) ? ( r & 0x3 ) | 0x8 : r ];
44 |
45 | }
46 | }
47 |
48 | return uuid.join( '' );
49 |
50 | };
51 |
52 | }(),
53 |
54 | // Clamp value to range
55 |
56 | /**
57 | * @desc 限制x的值在a和b之间
58 | * 如果x小于a,返回a。 如果x大于b,返回b,否则返回x
59 | * @param {float} x
60 | * @param {float} a
61 | * @param {float} b
62 | * @returns {float}
63 | */
64 | clamp: function ( x, a, b ) {
65 |
66 | return ( x < a ) ? a : ( ( x > b ) ? b : x );
67 |
68 | },
69 |
70 | // Clamp value to range
73 | * 如果x小于a,返回a。 否则返回x
74 | * @param {float} x
75 | * @param {float} a
76 | * @returns {float}
77 | */
78 | clampBottom: function ( x, a ) {
79 |
80 | return x < a ? a : x;
81 |
82 | },
83 |
84 | // Linear mapping from range to range
85 | /**
86 | * @desc 参数x在range到range的线性映射
87 | * @param {float} x
88 | * @param {float} a1
89 | * @param {float} a2
90 | * @param {float} b1
91 | * @param {float} b2
92 | * @returns {*}
93 | */
94 | mapLinear: function ( x, a1, a2, b1, b2 ) {
95 |
96 | return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
97 |
98 | },
99 |
100 | // http://en.wikipedia.org/wiki/Smoothstep
101 |
102 | /**
103 | * @desc 最小和最大值之间的插值,并在限制处渐入渐出。三次平滑插值
104 | * @param {float} x
105 | * @param {float} min
106 | * @param {float} max
107 | * @returns {float}
108 | */
109 | smoothstep: function ( x, min, max ) {
110 |
111 | if ( x <= min ) return 0;
112 | if ( x >= max ) return 1;
113 |
114 | x = ( x - min ) / ( max - min );
115 |
116 | return x * x * ( 3 - 2 * x );
117 |
118 | },
119 | /**
120 | * @desc 在最小和最大值之间的插值,并在限制处渐入渐出。五次平滑插值
121 | * @param {float} x
122 | * @param {float} min
123 | * @param {float} max
124 | * @returns {float}
125 | */
126 | smootherstep: function ( x, min, max ) {
127 |
128 | if ( x <= min ) return 0;
129 | if ( x >= max ) return 1;
130 |
131 | x = ( x - min ) / ( max - min );
132 |
133 | return x * x * x * ( x * ( x * 6 - 15 ) + 10 );
134 |
135 | },
136 |
137 | // Random float from <0, 1> with 16 bits of randomness
138 | // (standard Math.random() creates repetitive patterns when applied over larger space)
139 |
140 | /**
141 | * @desc 生成0,到1的随机浮点数,有16位大小选择范围
142 | * @returns {float}
143 | */
144 | random16: function () {
145 |
146 | return ( 65280 * Math.random() + 255 * Math.random() ) / 65535;
147 |
148 | },
149 |
150 | // Random integer from interval
151 | /**
152 | * @desc 通过参数low,high定义的取值范围生成随机整数
153 | * @param {number} vfhgplow
154 | * @param {number} vfhgphigh
155 | * @returns {number}
156 | */
157 | randInt: function ( low, high ) {
158 |
159 | return low + Math.floor( Math.random() * ( high - low + 1 ) );
160 |
161 | },
162 |
163 | // Random float from interval
164 | /**
165 | * @desc 通过参数low,high定义的取值范围生成随机浮点数
166 | * @param {float} vfhgplow
167 | * @param {float} vfhgphigh
168 | * @returns {float}
169 | */
170 | randFloat: function ( low, high ) {
171 |
172 | return low + Math.random() * ( high - low );
173 |
174 | },
175 |
176 | // Random float from <-range/2, range/2> interval
177 |
178 | /**
179 | * @desc 生成[-range/2,range/2]区间随机浮点数
180 | * @param {float} range
181 | * @returns {float}
182 | */
183 | randFloatSpread: function ( range ) {
184 |
185 | return range * ( 0.5 - Math.random() );
186 |
187 | },
188 |
189 | /**
190 | * @function
191 | * @desc 角度转换弧度
192 | * @param {float} degrees
193 | * @return {float}
194 | */
195 | degToRad: function () {
196 |
197 | var degreeToRadiansFactor = Math.PI / 180;
198 |
199 | return function ( degrees ) {
200 |
201 | return degrees * degreeToRadiansFactor;
202 |
203 | };
204 |
205 | }(),
206 | /**
207 | * @function
208 | * @desc 弧度转换角度
209 | * @param {float} radians
210 | * @return {float}
211 | */
212 | radToDeg: function () {
213 |
214 | var radianToDegreesFactor = 180 / Math.PI;
215 |
216 | return function ( radians ) {
217 |
218 | return radians * radianToDegreesFactor;
219 |
220 | };
221 |
222 | }(),
223 |
224 | /**
225 | * @desc 是否2的幂,如果该值是2的幂,返回true
226 | * @param {number} value
227 | * @returns {boolean}
228 | */
229 | isPowerOfTwo: function ( value ) {
230 |
231 | return ( value & ( value - 1 ) ) === 0 && value !== 0;
232 |
233 | }
234 |
235 | };
236 |
--------------------------------------------------------------------------------
/objects/SkinnedMesh.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mikael emtinger / http://gomo.se/
3 | * @author alteredq / http://alteredqualia.com/
4 | * @author ikerr / http://verold.com
5 | */
6 | /**
7 | * @classdesc 蒙皮网格对象
8 | * 注释内容部分参照 http://blog.csdn.net/omni360
9 | * @desc 蒙皮网格用于渲染人物。人物动画使用的骨骼,而且每个骨骼影响网格的一部分.
10 | * @param {THREE.Geometry} geometry 几何对象
11 | * @param {THREE.Material} material 材质对象
12 | * @param {boolean} useVertexTexture 是否使用顶点纹理,对象构建后不能修改
13 | * @constructor
14 | */
15 | THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) {
16 |
17 | THREE.Mesh.call( this, geometry, material );
18 |
19 | this.type = 'SkinnedMesh';
20 | /**
21 | * @desc 绑定模式
22 | * @default "attached"
23 | * @type {string}
24 | */
25 | this.bindMode = "attached";
26 | /**
27 | * @desc 绑定矩阵
28 | * @type {THREE.Matrix4}
29 | */
30 | this.bindMatrix = new THREE.Matrix4();
31 | /**
32 | * @desc 绑定矩阵的逆矩阵
33 | * @type {THREE.Matrix4}
34 | */
35 | this.bindMatrixInverse = new THREE.Matrix4();
36 |
37 | // init bones
38 | // 初始化骨骼
39 | // TODO: remove bone creation as there is no reason (other than
40 | // convenience) for THREE.SkinnedMesh to do this.
41 | // 存储骨骼的数组,这个属性在构造函数中设置.
42 | var bones = [];
43 |
44 | if ( this.geometry && this.geometry.bones !== undefined ) {
45 |
46 | var bone, gbone, p, q, s;
47 |
48 | for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++b ) {
49 |
50 | gbone = this.geometry.bones[ b ];
51 |
52 | p = gbone.pos;
53 | q = gbone.rotq;
54 | s = gbone.scl;
55 |
56 | bone = new THREE.Bone( this );
57 | bones.push( bone );
58 |
59 | bone.name = gbone.name;
60 | // 位置属性
61 | bone.position.set( p[ 0 ], p[ 1 ], p[ 2 ] );
62 | // 四元数旋转属性
63 | bone.quaternion.set( q[ 0 ], q[ 1 ], q[ 2 ], q[ 3 ] );
64 | // 缩放属性
65 | if ( s !== undefined ) {
66 |
67 | bone.scale.set( s[ 0 ], s[ 1 ], s[ 2 ] );
68 |
69 | } else {
70 |
71 | bone.scale.set( 1, 1, 1 );
72 |
73 | }
74 |
75 | }
76 |
77 | for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++b ) {
78 |
79 | gbone = this.geometry.bones[ b ];
80 |
81 | if ( gbone.parent !== - 1 ) {
82 |
83 | bones[ gbone.parent ].add( bones[ b ] );
84 |
85 | } else {
86 |
87 | this.add( bones[ b ] );
88 |
89 | }
90 |
91 | }
92 |
93 | }
94 | // 构造SkinnedMesh对象时调用normalizeSkinWeights方法
95 | // 确保skinWeights的各元素是归一化的.
96 | this.normalizeSkinWeights();
97 | // 对当前对象及其子对象的matrix属性应用全局位移,旋转,缩放变换
98 | this.updateMatrixWorld( true );
99 | // 调用bind方法,绑定骨骼对象.
100 | this.bind( new THREE.Skeleton( bones, undefined, useVertexTexture ) );
101 |
102 | };
103 |
104 | /**
105 | * @desc SkinnedMesh从Mesh的原型继承所有属性方法
106 | * @type {THREE.Mesh}
107 | */
108 | THREE.SkinnedMesh.prototype = Object.create( THREE.Mesh.prototype );
109 | /**
110 | * @desc 将蒙皮网格对象根据绑定矩阵绑定骨架
111 | * @param {THREE.Skeleton[]} skeleton
112 | * @param {THREE.Matrix4} bindMatrix
113 | */
114 | THREE.SkinnedMesh.prototype.bind = function( skeleton, bindMatrix ) {
115 |
116 | this.skeleton = skeleton;
117 |
118 | // 如果没有指定绑定矩阵
119 | if ( bindMatrix === undefined ) {
120 |
121 | this.updateMatrixWorld( true );
122 | // 使用蒙皮网格对象的世界坐标矩阵
123 | bindMatrix = this.matrixWorld;
124 |
125 | }
126 |
127 | this.bindMatrix.copy( bindMatrix );
128 | this.bindMatrixInverse.getInverse( bindMatrix );
129 |
130 | };
131 | /**
132 | * @desc 重新计算蒙皮网格对象的骨架的计算本地矩阵,位置,旋转缩放属性
133 | */
134 | THREE.SkinnedMesh.prototype.pose = function () {
135 | // 调用骨架对象的pose方法
136 | this.skeleton.pose();
137 |
138 | };
139 | /**
140 | * @desc 归一化蒙皮网格对象的蒙皮权重
141 | */
142 | THREE.SkinnedMesh.prototype.normalizeSkinWeights = function () {
143 |
144 | if ( this.geometry instanceof THREE.Geometry ) {
145 | // 遍历蒙皮指数数组.
146 | for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) {
147 | // 蒙皮权重数组
148 | var sw = this.geometry.skinWeights[ i ];
149 | // 求和sw的x,y,z分量
150 | var scale = 1.0 / sw.lengthManhattan();
151 | // scale不等于正无穷大
152 | if ( scale !== Infinity ) {
153 | // sw的每个分量乘以scale
154 | sw.multiplyScalar( scale );
155 |
156 | } else {
157 | // sw将被着色器归一化
158 | sw.set( 1 ); // this will be normalized by the shader anyway
159 |
160 | }
161 |
162 | }
163 |
164 | } else {
165 |
166 | // skinning weights assumed to be normalized for THREE.BufferGeometry
167 | // 蒙皮权重确保是归一化的 ,供THREE.BufferGeometry使用
168 | }
169 |
170 | };
171 | /**
172 | * @desc 方法对当前对象及其子对象的matrix属性应用全局位移,旋转,缩放变换
173 | * @param {boolean} force 是否强制将子对象做同样的全局变换
174 | */
175 | THREE.SkinnedMesh.prototype.updateMatrixWorld = function( force ) {
176 |
177 | THREE.Mesh.prototype.updateMatrixWorld.call( this, true );
178 |
179 | if ( this.bindMode === "attached" ) {
180 |
181 | this.bindMatrixInverse.getInverse( this.matrixWorld );
182 |
183 | } else if ( this.bindMode === "detached" ) {
184 |
185 | this.bindMatrixInverse.getInverse( this.bindMatrix );
186 |
187 | } else {
188 |
189 | console.warn( 'THREE.SkinnedMesh unreckognized bindMode: ' + this.bindMode );
190 |
191 | }
192 |
193 | };
194 | /**
195 | * @desc Three.SkinnedMesh 克隆函数
196 | * @param {THREE.SkinnedMesh} object
197 | * @returns {THREE.SkinnedMesh}
198 | */
199 | THREE.SkinnedMesh.prototype.clone = function( object ) {
200 |
201 | if ( object === undefined ) {
202 |
203 | object = new THREE.SkinnedMesh( this.geometry, this.material, this.useVertexTexture );
204 |
205 | }
206 |
207 | THREE.Mesh.prototype.clone.call( this, object );
208 |
209 | return object;
210 |
211 | };
212 |
213 |
--------------------------------------------------------------------------------
/lights/SpotLight.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 | /**
5 | * @classdesc 聚光灯光源对象
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @desc 根据设置灯光的颜属性color, 强度属性intensity,距离属性 distance,灯光的照射角度 angle,衰减速度 exponent 创建聚光灯光源(射灯)
8 | * SpotLight类型灯光实现了阴影,但是需要在场景中使用MeshLambertMaterial或者MeshPhongMaterial
9 | * @param {THREE.Color} color 灯光的颜色属性
10 | * @param {float} intensity 灯光的强度,默认是1
11 | * @param {float} distance 灯光的长度属性,从灯光的position位置,开始衰减,衰减到distance的长度,默认是0
12 | * @param {float} angle 聚光灯的灯光照射角度属性,单位是弧度,默认是60度角的弧度
13 | * @param {float} exponent 聚光灯的从照射点的衰减速度属性,默认是10
14 | * @extends {THREE.Light}
15 | * @example var light = new THREE.SpotLight(0xff0000,1,100,Math.PI /2,5); //创建灯光对象
16 | * light.position.set(50,50,30); //设置位置
17 | * light.castShadow = true; //开启阴影
18 | * light.shadowMapWidth = 1024; //阴影贴图宽度设置为1024像素
19 | * light.shadowMapHeight = 1024; //阴影贴图高度设置为1024像素
20 | * light.shadowCameraNear = 500; //阴影的平截头体区域near属性
21 | * light.shadowCameraFar = 4000; //阴影的平截头体区域far属性
22 | * light.shadowCameraFov = 30; //阴影的平截头体区域fov属性
23 | * scene.add(lignt); //加入场景
24 | * @constructor
25 | */
26 | THREE.SpotLight = function ( color, intensity, distance, angle, exponent ) {
27 |
28 | THREE.Light.call( this, color );
29 | /**
30 | * @default
31 | * @type {string}
32 | */
33 | this.type = 'SpotLight';
34 | /**
35 | * @desc 灯光的位置属性初始化为,0,1,0
36 | */
37 | this.position.set( 0, 1, 0 );
38 | /**
39 | * @desc 创建一个目标点对象,目标点对象是一个Object3D对象
40 | * @type {THREE.Object3D}
41 | */
42 | this.target = new THREE.Object3D();
43 | /**
44 | * desc 灯光的强度
45 | * (光线的密度,默认为1。因为RGB的三个值均在0~255之间,
46 | * 不能反映出光照的强度变化,光照越强,物体表面就更明亮。)
47 | * @default 1
48 | * @type {float}
49 | */
50 | this.intensity = ( intensity !== undefined ) ? intensity : 1;
51 | /**
52 | * desc 灯光的长度度
53 | * 如果不指定,初始化为1.
54 | * (衰减距离,默认值为0,光照无衰减;如果是非0值,光照会从position位置
55 | * (实际上是position所处的那个平面)开始衰减,衰减到distance距离之后,光照强度intensity为0)
56 | * @default 0
57 | * @type {float}
58 | */
59 | this.distance = ( distance !== undefined ) ? distance : 0;
60 | /**
61 | * desc 聚光灯的灯光照射角度属性
62 | * 单位是弧度,默认是60度角的弧度
63 | * @default Math.PI / 3
64 | * @type {float}
65 | */
66 | this.angle = ( angle !== undefined ) ? angle : Math.PI / 3;
67 | /**
68 | * desc 光灯的从照射点的衰减速度指数
69 | * @default 10
70 | * @type {float}
71 | */
72 | this.exponent = ( exponent !== undefined ) ? exponent : 10;
73 | /**
74 | * @desc 是否对于所有表面都会逐像元地计算其在光照方向上是否被遮挡,这会消耗大量的计算
75 | * @default
76 | * @type {boolean}
77 | */
78 | this.castShadow = false;
79 | /**
80 | * @desc 控制是否只产生阴影而不“照亮”物体
81 | * @default
82 | * @type {boolean}
83 | */
84 | this.onlyShadow = false;
85 |
86 | //
87 | /**
88 | * @desc 平截头体近端,定义一个范围(平截头体),不计算在范围之外的物体的阴影
89 | * @default
90 | * @type {float}
91 | */
92 | this.shadowCameraNear = 50;
93 | /**
94 | * @desc 平截头体远端,定义一个范围(平截头体),不计算在范围之外的物体的阴影
95 | * @default
96 | * @type {float}
97 | */
98 | this.shadowCameraFar = 5000;
99 | /**
100 | * @desc 平截头体视野,定义一个范围(平截头体),不计算在范围之外的物体的阴影
101 | * @default
102 | * @type {float}
103 | */
104 | this.shadowCameraFov = 50;
105 | /**
106 | * @desc 会在场景中显示灯光的框架,方便调试
107 | * @default
108 | * @type {boolean}
109 | */
110 | this.shadowCameraVisible = false;
111 | /**
112 | * @desc 阴影贴图的偏移
113 | * @default
114 | * @type {float}
115 | */
116 | this.shadowBias = 0;
117 | /**
118 | * @desc 阴影对物体亮度的影响
119 | * @default
120 | * @type {float}
121 | */
122 | this.shadowDarkness = 0.5;
123 | /**
124 | * @desc 阴影贴图宽度
125 | * @default
126 | * @type {float}
127 | */
128 | this.shadowMapWidth = 512;
129 | /**
130 | * @desc 阴影贴图高度
131 | * @default
132 | * @type {float}
133 | */
134 | this.shadowMapHeight = 512;
135 |
136 | //
137 | /**
138 | * @desc 指定阴影贴图
139 | * @default
140 | * @type {null}
141 | */
142 | this.shadowMap = null;
143 | /**
144 | * @desc 指定阴影贴图大小
145 | * @default
146 | * @type {number}
147 | */
148 | this.shadowMapSize = null;
149 | /**
150 | * @desc 指定阴影相机
151 | * @default
152 | * @type {THREE.Camera}
153 | */
154 | this.shadowCamera = null;
155 | /**
156 | * @desc 指定阴影矩阵
157 | * @default
158 | * @type {THREE.Matrix4}
159 | */
160 | this.shadowMatrix = null;
161 |
162 | };
163 | /**
164 | * @desc SpotLight对象从THREE.Light的原型继承所有属性方法
165 | * @type {THREE.Light}
166 | */
167 | THREE.SpotLight.prototype = Object.create( THREE.Light.prototype );
168 | /**
169 | * @desc SpotLight克隆函数
170 | * @returns {THREE.SpotLight}
171 | */
172 | THREE.SpotLight.prototype.clone = function () {
173 |
174 | var light = new THREE.SpotLight();
175 |
176 | THREE.Light.prototype.clone.call( this, light );
177 |
178 | light.target = this.target.clone();
179 |
180 | light.intensity = this.intensity;
181 | light.distance = this.distance;
182 | light.angle = this.angle;
183 | light.exponent = this.exponent;
184 |
185 | light.castShadow = this.castShadow;
186 | light.onlyShadow = this.onlyShadow;
187 |
188 | //
189 |
190 | light.shadowCameraNear = this.shadowCameraNear;
191 | light.shadowCameraFar = this.shadowCameraFar;
192 | light.shadowCameraFov = this.shadowCameraFov;
193 |
194 | light.shadowCameraVisible = this.shadowCameraVisible;
195 |
196 | light.shadowBias = this.shadowBias;
197 | light.shadowDarkness = this.shadowDarkness;
198 |
199 | light.shadowMapWidth = this.shadowMapWidth;
200 | light.shadowMapHeight = this.shadowMapHeight;
201 |
202 | return light;
203 |
204 | };
205 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
11 | * @desc 由Vector3数组(points)组成的曲线
12 | * @param {THREE.Vector3[]} points
13 | * @constructor
14 | */
15 | THREE.Spline = function ( points ) {
16 | /**
17 | * @desc 曲线控制点
18 | * @type {THREE.Vector3[]}
19 | */
20 | this.points = points;
21 |
22 | var c = [], v3 = { x: 0, y: 0, z: 0 },
23 | point, intPoint, weight, w2, w3,
24 | pa, pb, pc, pd;
25 |
26 | /**
27 | * @desc 从数组初始化曲线
28 | * @param {THREE.Vector3} a
29 | */
30 | this.initFromArray = function ( a ) {
31 |
32 | this.points = [];
33 |
34 | for ( var i = 0; i < a.length; i ++ ) {
35 |
36 | this.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };
37 |
38 | }
39 |
40 | };
41 | /**
42 | * @desc 当前样条曲线作为一个整体,返回位于当前样条曲线k位置上的点坐标.
43 | * @param {float} k
44 | * @returns {{x: float, y: float, z: float}}
45 | */
46 | this.getPoint = function ( k ) {
47 |
48 | point = ( this.points.length - 1 ) * k;
49 | intPoint = Math.floor( point );
50 | weight = point - intPoint;
51 |
52 | c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
53 | c[ 1 ] = intPoint;
54 | c[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;
55 | c[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;
56 |
57 | pa = this.points[ c[ 0 ] ];
58 | pb = this.points[ c[ 1 ] ];
59 | pc = this.points[ c[ 2 ] ];
60 | pd = this.points[ c[ 3 ] ];
61 |
62 | w2 = weight * weight;
63 | w3 = weight * w2;
64 |
65 | v3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );
66 | v3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );
67 | v3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );
68 |
69 | return v3;
70 |
71 | };
72 |
73 | /**
74 | * @desc 返回当前样条曲线节点坐标构成的数组
75 | * @returns {THREE.Vector3[]}
76 | */
77 | this.getControlPointsArray = function () {
78 |
79 | var i, p, l = this.points.length,
80 | coords = [];
81 |
82 | for ( i = 0; i < l; i ++ ) {
83 |
84 | p = this.points[ i ];
85 | coords[ i ] = [ p.x, p.y, p.z ];
86 |
87 | }
88 |
89 | return coords;
90 |
91 | };
92 |
93 | // approximate length by summing linear segments
94 | /**
95 | * @desc 被参数nSubDivisions(将当前样条曲线等分成多少段)等分当前样条曲线的长度数组和总长度组成的对象.
96 | * @param {number} nSubDivisions
97 | * @returns {{chunks: Array, total: number}}
98 | */
99 | this.getLength = function ( nSubDivisions ) {
100 |
101 | var i, index, nSamples, position,
102 | point = 0, intPoint = 0, oldIntPoint = 0,
103 | oldPosition = new THREE.Vector3(),
104 | tmpVec = new THREE.Vector3(),
105 | chunkLengths = [],
106 | totalLength = 0;
107 |
108 | // first point has 0 length
109 |
110 | chunkLengths[ 0 ] = 0;
111 |
112 | if ( ! nSubDivisions ) nSubDivisions = 100;
113 |
114 | nSamples = this.points.length * nSubDivisions;
115 |
116 | oldPosition.copy( this.points[ 0 ] );
117 |
118 | for ( i = 1; i < nSamples; i ++ ) {
119 |
120 | index = i / nSamples;
121 |
122 | position = this.getPoint( index );
123 | tmpVec.copy( position );
124 |
125 | totalLength += tmpVec.distanceTo( oldPosition );
126 |
127 | oldPosition.copy( position );
128 |
129 | point = ( this.points.length - 1 ) * index;
130 | intPoint = Math.floor( point );
131 |
132 | if ( intPoint != oldIntPoint ) {
133 |
134 | chunkLengths[ intPoint ] = totalLength;
135 | oldIntPoint = intPoint;
136 |
137 | }
138 |
139 | }
140 |
141 | // last point ends with total length
142 |
143 | chunkLengths[ chunkLengths.length ] = totalLength;
144 |
145 | return { chunks: chunkLengths, total: totalLength };
146 |
147 | };
148 |
149 | this.reparametrizeByArcLength = function ( samplingCoef ) {
150 |
151 | var i, j,
152 | index, indexCurrent, indexNext,
153 | linearDistance, realDistance,
154 | sampling, position,
155 | newpoints = [],
156 | tmpVec = new THREE.Vector3(),
157 | sl = this.getLength();
158 |
159 | newpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );
160 |
161 | for ( i = 1; i < this.points.length; i ++ ) {
162 |
163 | //tmpVec.copy( this.points[ i - 1 ] );
164 | //linearDistance = tmpVec.distanceTo( this.points[ i ] );
165 |
166 | realDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];
167 |
168 | sampling = Math.ceil( samplingCoef * realDistance / sl.total );
169 |
170 | indexCurrent = ( i - 1 ) / ( this.points.length - 1 );
171 | indexNext = i / ( this.points.length - 1 );
172 |
173 | for ( j = 1; j < sampling - 1; j ++ ) {
174 |
175 | index = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );
176 |
177 | position = this.getPoint( index );
178 | newpoints.push( tmpVec.copy( position ).clone() );
179 |
180 | }
181 |
182 | newpoints.push( tmpVec.copy( this.points[ i ] ).clone() );
183 |
184 | }
185 |
186 | this.points = newpoints;
187 |
188 | };
189 |
190 | // Catmull-Rom
191 |
192 | /**
193 | * @desc 三次样条插值算法,返回计算位于参数值t的曲线点
194 | * @param {float} p0 样条曲线起始点p0
195 | * @param {float} p1 样条曲线起始点p1
196 | * @param {float} p2 样条曲线起始点p2
197 | * @param {float} p3 样条曲线起始点p3
198 | * @param {float} t 参数值 (0,1)
199 | * @param {float} t2 参数值t的平方
200 | * @param {float} t3 参数值t的立方
201 | * @returns {float} 计算位于参数值t的曲线点
202 | */
203 | function interpolate( p0, p1, p2, p3, t, t2, t3 ) {
204 |
205 | var v0 = ( p2 - p0 ) * 0.5,
206 | v1 = ( p3 - p1 ) * 0.5;
207 |
208 | return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;
209 |
210 | };
211 |
212 | };
213 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
9 | * @param {THREE.Plane} p0
10 | * @param {THREE.Plane} p1
11 | * @param {THREE.Plane} p2
12 | * @param {THREE.Plane} p3
13 | * @param {THREE.Plane} p4
14 | * @param {THREE.Plane} p5
15 | * @constructor
16 | */
17 | THREE.Frustum = function ( p0, p1, p2, p3, p4, p5 ) {
18 |
19 | this.planes = [
20 |
21 | ( p0 !== undefined ) ? p0 : new THREE.Plane(),
22 | ( p1 !== undefined ) ? p1 : new THREE.Plane(),
23 | ( p2 !== undefined ) ? p2 : new THREE.Plane(),
24 | ( p3 !== undefined ) ? p3 : new THREE.Plane(),
25 | ( p4 !== undefined ) ? p4 : new THREE.Plane(),
26 | ( p5 !== undefined ) ? p5 : new THREE.Plane()
27 |
28 | ];
29 |
30 | };
31 |
32 | THREE.Frustum.prototype = {
33 |
34 | constructor: THREE.Frustum,
35 | /**
36 | * @desc 设置平截头体对象
37 | * @param {THREE.Plane} p0
38 | * @param {THREE.Plane} p1
39 | * @param {THREE.Plane} p2
40 | * @param {THREE.Plane} p3
41 | * @param {THREE.Plane} p4
42 | * @param {THREE.Plane} p5
43 | * @returns {THREE.Frustum}
44 | */
45 | set: function ( p0, p1, p2, p3, p4, p5 ) {
46 |
47 | var planes = this.planes;
48 |
49 | planes[ 0 ].copy( p0 );
50 | planes[ 1 ].copy( p1 );
51 | planes[ 2 ].copy( p2 );
52 | planes[ 3 ].copy( p3 );
53 | planes[ 4 ].copy( p4 );
54 | planes[ 5 ].copy( p5 );
55 |
56 | return this;
57 |
58 | },
59 | /**
60 | * @desc 拷贝平截头体对象
61 | * @param {THREE.Frustum} frustum
62 | * @returns {THREE.Frustum}
63 | */
64 | copy: function ( frustum ) {
65 |
66 | var planes = this.planes;
67 |
68 | for ( var i = 0; i < 6; i ++ ) {
69 |
70 | planes[ i ].copy( frustum.planes[ i ] );
71 |
72 | }
73 |
74 | return this;
75 |
76 | },
77 | /**
78 | * @desc 通过对当前平截头体应用变换,返回新的平截头体
79 | * @param {THREE.Matrix4} m
80 | * @returns {THREE.Frustum}
81 | */
82 | setFromMatrix: function ( m ) {
83 |
84 | var planes = this.planes;
85 | var me = m.elements;
86 | var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];
87 | var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];
88 | var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];
89 | var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];
90 |
91 | planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();
92 | planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();
93 | planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();
94 | planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();
95 | planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();
96 | planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();
97 |
98 | return this;
99 |
100 | },
101 | /**
102 | * @function
103 | * @desc 当前平截头体是否与参数object对象相交
104 | * @param {THREE.Object3D} object
105 | * @return {boolean}
106 | */
107 | intersectsObject: function () {
108 |
109 | var sphere = new THREE.Sphere();
110 |
111 | return function ( object ) {
112 |
113 | var geometry = object.geometry;
114 |
115 | if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
116 |
117 | sphere.copy( geometry.boundingSphere );
118 | sphere.applyMatrix4( object.matrixWorld );
119 |
120 | return this.intersectsSphere( sphere );
121 |
122 | };
123 |
124 | }(),
125 | /**
126 | * @desc 当前平截头体是否与参数sphere球体对象相交
127 | * @param {THREE.Sphere} sphere
128 | * @returns {boolean}
129 | */
130 | intersectsSphere: function ( sphere ) {
131 |
132 | var planes = this.planes;
133 | var center = sphere.center;
134 | var negRadius = - sphere.radius;
135 |
136 | for ( var i = 0; i < 6; i ++ ) {
137 |
138 | var distance = planes[ i ].distanceToPoint( center );
139 |
140 | if ( distance < negRadius ) {
141 |
142 | return false;
143 |
144 | }
145 |
146 | }
147 |
148 | return true;
149 |
150 | },
151 | /**
152 | *
153 | * @function
154 | * @desc 当前平截头体是否与参数box立方体对象相交
155 | * @param {THREE.Box3} box
156 | * @returns {boolean}
157 | */
158 | intersectsBox: function () {
159 |
160 | var p1 = new THREE.Vector3(),
161 | p2 = new THREE.Vector3();
162 |
163 | return function ( box ) {
164 |
165 | var planes = this.planes;
166 |
167 | for ( var i = 0; i < 6 ; i ++ ) {
168 |
169 | var plane = planes[ i ];
170 |
171 | p1.x = plane.normal.x > 0 ? box.min.x : box.max.x;
172 | p2.x = plane.normal.x > 0 ? box.max.x : box.min.x;
173 | p1.y = plane.normal.y > 0 ? box.min.y : box.max.y;
174 | p2.y = plane.normal.y > 0 ? box.max.y : box.min.y;
175 | p1.z = plane.normal.z > 0 ? box.min.z : box.max.z;
176 | p2.z = plane.normal.z > 0 ? box.max.z : box.min.z;
177 |
178 | var d1 = plane.distanceToPoint( p1 );
179 | var d2 = plane.distanceToPoint( p2 );
180 |
181 | // if both outside plane, no intersection
182 |
183 | if ( d1 < 0 && d2 < 0 ) {
184 |
185 | return false;
186 |
187 | }
188 | }
189 |
190 | return true;
191 | };
192 |
193 | }(),
194 |
195 | /**
196 | * @desc 参数point(一个Vector3的三维点坐标)是否在当前平截头体内
197 | * @param {THREE.Vector3} point
198 | * @returns {boolean}
199 | */
200 | containsPoint: function ( point ) {
201 |
202 | var planes = this.planes;
203 |
204 | for ( var i = 0; i < 6; i ++ ) {
205 |
206 | if ( planes[ i ].distanceToPoint( point ) < 0 ) {
207 |
208 | return false;
209 |
210 | }
211 |
212 | }
213 |
214 | return true;
215 |
216 | },
217 | /**
218 | * @desc 克隆当前平截头体
219 | * @returns {THREE.Frustum}
220 | */
221 | clone: function () {
222 |
223 | return new THREE.Frustum().copy( this );
224 |
225 | }
226 |
227 | };
228 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
44 | * @desc 表面有光泽的材质类型,计算每个像素)
45 | * @param {String} parameters 材质参数
46 | * @extends {THREE.Material}
47 | * @constructor
48 | */
49 | THREE.MeshLambertMaterial = function ( parameters ) {
50 |
51 | THREE.Material.call( this );
52 | /**
53 | * @default 'MeshLambertMaterial'
54 | * @type {string}
55 | */
56 | this.type = 'MeshLambertMaterial';
57 | /**
58 | * @desc 材质颜色
59 | * @default 0xffffff 白色
60 | * @type {THREE.Color}
61 | */
62 | this.color = new THREE.Color( 0xffffff ); // diffuse
63 | /**
64 | * @desc 环境色
65 | * @default 0xffffff 白色
66 | * @type {THREE.Color}
67 | */
68 | this.ambient = new THREE.Color( 0xffffff );
69 | /**
70 | * @desc 自发光(荧光)颜色
71 | * @default 0x000000 黑色
72 | * @type {THREE.Color}
73 | */
74 | this.emissive = new THREE.Color( 0x000000 );
75 | /**
76 | * @desc 是否遮罩
77 | * @default
78 | * @type {boolean}
79 | */
80 | this.wrapAround = false;
81 | /**
82 | * @desc 遮罩颜色
83 | * @default ( 1, 1, 1 )
84 | * @type {THREE.Vector3}
85 | */
86 | this.wrapRGB = new THREE.Vector3( 1, 1, 1 );
87 | /**
88 | * @desc 纹理贴图
89 | * @default
90 | * @type {THREE.Texture}
91 | */
92 | this.map = null;
93 | /**
94 | * @desc 光照贴图
95 | * @default
96 | * @type {THREE.Texture}
97 | */
98 | this.lightMap = null;
99 | /**
100 | * @desc 高光贴图
101 | * @default
102 | * @type {THREE.Texture}
103 | */
104 | this.specularMap = null;
105 | /**
106 | * @desc 透明贴图
107 | * @default
108 | * @type {THREE.Texture}
109 | */
110 | this.alphaMap = null;
111 | /**
112 | * @desc 环境贴图
113 | * @default
114 | * @type {THREE.Texture}
115 | */
116 | this.envMap = null;
117 | /**
118 | * @desc 材质混合模式
119 | * @default THREE.MultiplyOperation
120 | * @type {number}
121 | */
122 | this.combine = THREE.MultiplyOperation;
123 | /**
124 | * @desc 反射率
125 | * @default
126 | * @type {float}
127 | */
128 | this.reflectivity = 1;
129 | /**
130 | * @desc 折射率
131 | * @default
132 | * @type {float}
133 | */
134 | this.refractionRatio = 0.98;
135 |
136 | /**
137 | * @desc 雾效,默认开启
138 | * @default
139 | * @type {boolean}
140 | */
141 | this.fog = true;
142 | /**
143 | * @desc 着色方式
144 | * THREE.SmoothShading平滑着色:用多种颜色进行绘制
145 | * 每个顶点都是单独进行处理的,各顶点和各图元之间采用均匀插值。
146 | * @default
147 | * @type {number}
148 | */
149 | this.shading = THREE.SmoothShading;
150 |
151 | /**
152 | * @desc 是否以线框方式渲染几何体
153 | * @default
154 | * @type {boolean}
155 | */
156 | this.wireframe = false;
157 | /**
158 | * @desc 线框宽度
159 | * @default
160 | * @type {float}
161 | */
162 | this.wireframeLinewidth = 1;
163 | /**
164 | * @desc 线框端点类型,参照LineBasicMaterial的定义
165 | * @default 'round'
166 | * @type {string}
167 | */
168 | this.wireframeLinecap = 'round';
169 | /**
170 | * @desc 线框连接类型,参照LineBasicMaterial的定义
171 | * @default 'round'
172 | * @type {string}
173 | */
174 | this.wireframeLinejoin = 'round';
175 |
176 | /**
177 | * @desc 材质顶点颜色
178 | * @default THREE.NoColors
179 | * @type {number}
180 | */
181 | this.vertexColors = THREE.NoColors;
182 |
183 | /**
184 | * @desc 材质是否使用蒙皮
185 | * @default
186 | * @type {boolean}
187 | */
188 | this.skinning = false;
189 | /**
190 | * @desc 材质是否设定目标变形动画
191 | * @default
192 | * @type {boolean}
193 | */
194 | this.morphTargets = false;
195 | /**
196 | * @desc 材质是否反转(变换)法线
197 | * @default
198 | * @type {boolean}
199 | */
200 | this.morphNormals = false;
201 |
202 | this.setValues( parameters );
203 |
204 | };
205 | /**
206 | * @desc MeshLambertMaterial对象从THREE.Material的原型继承所有属性方法
207 | * @type {THREE.Material}
208 | */
209 | THREE.MeshLambertMaterial.prototype = Object.create( THREE.Material.prototype );
210 | /**
211 | * @desc MeshLambertMaterial材质的克隆函数
212 | * @returns {THREE.MeshLambertMaterial}
213 | */
214 | THREE.MeshLambertMaterial.prototype.clone = function () {
215 |
216 | var material = new THREE.MeshLambertMaterial();
217 |
218 | THREE.Material.prototype.clone.call( this, material );
219 |
220 | material.color.copy( this.color );
221 | material.ambient.copy( this.ambient );
222 | material.emissive.copy( this.emissive );
223 |
224 | material.wrapAround = this.wrapAround;
225 | material.wrapRGB.copy( this.wrapRGB );
226 |
227 | material.map = this.map;
228 |
229 | material.lightMap = this.lightMap;
230 |
231 | material.specularMap = this.specularMap;
232 |
233 | material.alphaMap = this.alphaMap;
234 |
235 | material.envMap = this.envMap;
236 | material.combine = this.combine;
237 | material.reflectivity = this.reflectivity;
238 | material.refractionRatio = this.refractionRatio;
239 |
240 | material.fog = this.fog;
241 |
242 | material.shading = this.shading;
243 |
244 | material.wireframe = this.wireframe;
245 | material.wireframeLinewidth = this.wireframeLinewidth;
246 | material.wireframeLinecap = this.wireframeLinecap;
247 | material.wireframeLinejoin = this.wireframeLinejoin;
248 |
249 | material.vertexColors = this.vertexColors;
250 |
251 | material.skinning = this.skinning;
252 | material.morphTargets = this.morphTargets;
253 | material.morphNormals = this.morphNormals;
254 |
255 | return material;
256 |
257 | };
258 |
--------------------------------------------------------------------------------
/lights/DirectionalLight.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | * @author alteredq / http://alteredqualia.com/
4 | */
5 | /**
6 | * @classdesc 平行光源对象
7 | * 注释内容部分参照 http://blog.csdn.net/omni360
8 | * @desc 平行光支持阴影
9 | * @param {THREE.Color} color 平行光的颜色属性
10 | * @param {float} intensity 平行光的强度,默认是1
11 | * @extends {THREE.Light}
12 | * @constructor
13 | */
14 | THREE.DirectionalLight = function ( color, intensity ) {
15 |
16 | THREE.Light.call( this, color );
17 | /**
18 | * @default
19 | * @type {string}
20 | */
21 | this.type = 'DirectionalLight';
22 | /**
23 | * @desc 灯光的位置属性初始化为,0,1,0
24 | */
25 | this.position.set( 0, 1, 0 );
26 | /**
27 | * @desc 创建一个目标点对象,目标点对象是一个Object3D对象
28 | * @type {THREE.Object3D}
29 | */
30 | this.target = new THREE.Object3D();
31 | /**
32 | * desc 灯光的强度
33 | * (光线的密度,默认为1。因为RGB的三个值均在0~255之间,
34 | * 不能反映出光照的强度变化,光照越强,物体表面就更明亮。)
35 | * @default 1
36 | * @type {float}
37 | */
38 | this.intensity = ( intensity !== undefined ) ? intensity : 1;
39 | /**
40 | * @desc 是否对于所有表面都会逐像元地计算其在光照方向上是否被遮挡,这会消耗大量的计算
41 | * @default
42 | * @type {boolean}
43 | */
44 | this.castShadow = false;
45 | /**
46 | * @desc 控制是否只产生阴影而不“照亮”物体
47 | * @default
48 | * @type {boolean}
49 | */
50 | this.onlyShadow = false;
51 |
52 | //
53 | /**
54 | * @desc 平截头体近端,定义一个范围(平截头体),不计算在范围之外的物体的阴影
55 | * @default
56 | * @type {float}
57 | */
58 | this.shadowCameraNear = 50;
59 | /**
60 | * @desc 平截头体远端,定义一个范围(平截头体),不计算在范围之外的物体的阴影
61 | * @default
62 | * @type {float}
63 | */
64 | this.shadowCameraFar = 5000;
65 | /**
66 | * @desc 相机左侧距离,不计算在范围之外的物体的阴影
67 | * @default
68 | * @type {float}
69 | */
70 | this.shadowCameraLeft = - 500;
71 | /**
72 | * @desc 相机右侧距离,不计算在范围之外的物体的阴影
73 | * @default
74 | * @type {float}
75 | */
76 | this.shadowCameraRight = 500;
77 | /**
78 | * @desc 相机上侧距离,不计算在范围之外的物体的阴影
79 | * @default
80 | * @type {float}
81 | */
82 | this.shadowCameraTop = 500;
83 | /**
84 | * @desc 相机下侧距离,不计算在范围之外的物体的阴影
85 | * @default
86 | * @type {float}
87 | */
88 | this.shadowCameraBottom = - 500;
89 | /**
90 | * @desc 会在场景中显示灯光的框架,方便调试
91 | * @default
92 | * @type {boolean}
93 | */
94 | this.shadowCameraVisible = false;
95 | /**
96 | * @desc 阴影贴图的偏移
97 | * @default
98 | * @type {float}
99 | */
100 | this.shadowBias = 0;
101 | /**
102 | * @desc 阴影对物体亮度的影响
103 | * @default
104 | * @type {float}
105 | */
106 | this.shadowDarkness = 0.5;
107 | /**
108 | * @desc 阴影贴图宽度
109 | * @default
110 | * @type {float}
111 | */
112 | this.shadowMapWidth = 512;
113 | /**
114 | * @desc 阴影贴图高度
115 | * @default
116 | * @type {float}
117 | */
118 | this.shadowMapHeight = 512;
119 |
120 | //
121 | /**
122 | * @desc 是否支持阴影级联
123 | * @default
124 | * @type {boolean}
125 | */
126 | this.shadowCascade = false;
127 | /**
128 | * @desc 阴影级联偏移距离
129 | * @default ( 0, 0, - 1000 )
130 | * @type {THREE.Vector3}
131 | */
132 | this.shadowCascadeOffset = new THREE.Vector3( 0, 0, - 1000 );
133 | /**
134 | * @desc 当使用2个阴影级联时,整个阴影距离内,默认被分为两块,靠近观察者较小的块和远处较大的块
135 | * @default
136 | * @type {number}
137 | */
138 | this.shadowCascadeCount = 2;
139 | /**
140 | * @desc 阴影级联偏移数组
141 | * @default
142 | * @type {number[]}
143 | */
144 | this.shadowCascadeBias = [ 0, 0, 0 ];
145 | /**
146 | * @desc 阴影级联宽度数组
147 | * @default
148 | * @type {number[]}
149 | */
150 | this.shadowCascadeWidth = [ 512, 512, 512 ];
151 | /**
152 | * @desc 阴影级联高度数组
153 | * @default
154 | * @type {number[]}
155 | */
156 | this.shadowCascadeHeight = [ 512, 512, 512 ];
157 | /**
158 | * @desc 阴影级联近处
159 | * @default
160 | * @type {number[]}
161 | */
162 | this.shadowCascadeNearZ = [ - 1.000, 0.990, 0.998 ];
163 | /**
164 | * @desc 阴影级联远处
165 | * @default
166 | * @type {number[]}
167 | */
168 | this.shadowCascadeFarZ = [ 0.990, 0.998, 1.000 ];
169 | /**
170 | * @desc 阴影级联数组
171 | * @type {Array}
172 | */
173 | this.shadowCascadeArray = [];
174 |
175 | //
176 |
177 | /**
178 | * @desc 指定阴影贴图
179 | * @default
180 | * @type {null}
181 | */
182 | this.shadowMap = null;
183 | /**
184 | * @desc 指定阴影贴图大小
185 | * @default
186 | * @type {number}
187 | */
188 | this.shadowMapSize = null;
189 | /**
190 | * @desc 指定阴影相机
191 | * @default
192 | * @type {THREE.Camera}
193 | */
194 | this.shadowCamera = null;
195 | /**
196 | * @desc 指定阴影矩阵
197 | * @default
198 | * @type {THREE.Matrix4}
199 | */
200 | this.shadowMatrix = null;
201 |
202 | };
203 | /**
204 | * @desc DirectionalLight对象从THREE.Light的原型继承所有属性方法
205 | * @type {THREE.Light}
206 | */
207 | THREE.DirectionalLight.prototype = Object.create( THREE.Light.prototype );
208 | /**
209 | * @desc DirectionalLight克隆函数
210 | * @returns {THREE.DirectionalLight}
211 | */
212 | THREE.DirectionalLight.prototype.clone = function () {
213 |
214 | var light = new THREE.DirectionalLight();
215 |
216 | THREE.Light.prototype.clone.call( this, light );
217 |
218 | light.target = this.target.clone();
219 |
220 | light.intensity = this.intensity;
221 |
222 | light.castShadow = this.castShadow;
223 | light.onlyShadow = this.onlyShadow;
224 |
225 | //
226 |
227 | light.shadowCameraNear = this.shadowCameraNear;
228 | light.shadowCameraFar = this.shadowCameraFar;
229 |
230 | light.shadowCameraLeft = this.shadowCameraLeft;
231 | light.shadowCameraRight = this.shadowCameraRight;
232 | light.shadowCameraTop = this.shadowCameraTop;
233 | light.shadowCameraBottom = this.shadowCameraBottom;
234 |
235 | light.shadowCameraVisible = this.shadowCameraVisible;
236 |
237 | light.shadowBias = this.shadowBias;
238 | light.shadowDarkness = this.shadowDarkness;
239 |
240 | light.shadowMapWidth = this.shadowMapWidth;
241 | light.shadowMapHeight = this.shadowMapHeight;
242 |
243 | //
244 |
245 | light.shadowCascade = this.shadowCascade;
246 |
247 | light.shadowCascadeOffset.copy( this.shadowCascadeOffset );
248 | light.shadowCascadeCount = this.shadowCascadeCount;
249 |
250 | light.shadowCascadeBias = this.shadowCascadeBias.slice( 0 );
251 | light.shadowCascadeWidth = this.shadowCascadeWidth.slice( 0 );
252 | light.shadowCascadeHeight = this.shadowCascadeHeight.slice( 0 );
253 |
254 | light.shadowCascadeNearZ = this.shadowCascadeNearZ.slice( 0 );
255 | light.shadowCascadeFarZ = this.shadowCascadeFarZ.slice( 0 );
256 |
257 | return light;
258 |
259 | };
260 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
9 | * @desc 根据 fov, aspect, near, far 生成透视投影相机
10 | * @constructor
11 | * @param {float} fov 相机的可视角度,可选参数,如果未指定,初始化为50
12 | * @param {float} aspect 相机可视范围的长宽比,可选参数,如果未指定,初始化为1
13 | * @param {float} near 相对于深度剪切面的近的距离,必须为正数,可选参数,如果未指定,初始化为0.1
14 | * @param {float} far 相对于深度剪切面的远的距离,必须为正数,可选参数,如果未指定,初始化为2000
15 | * @extends {THREE.Camera}
16 | */
17 | THREE.PerspectiveCamera = function ( fov, aspect, near, far ) {
18 |
19 | THREE.Camera.call( this );
20 | /**
21 | * @default
22 | * @type {string}
23 | */
24 | this.type = 'PerspectiveCamera';
25 |
26 | /**
27 | * @desc 缩放比例
28 | * @default
29 | * @type {float}
30 | */
31 | this.zoom = 1;
32 | /**
33 | * @desc 相机的可视角度,可选参数
34 | * @default 50
35 | * @type {float}
36 | */
37 | this.fov = fov !== undefined ? fov : 50;
38 | /**
39 | * @desc 相机可视范围的长宽比
40 | * @default 1
41 | * @type {float}
42 | */
43 | this.aspect = aspect !== undefined ? aspect : 1;
44 | /**
45 | * @desc 相对于深度剪切面的近的距离
46 | * @default 0.1
47 | * @type {float}
48 | */
49 | this.near = near !== undefined ? near : 0.1;
50 | /**
51 | * @desc 相对于深度剪切面的远的距离
52 | * @default 2000
53 | * @type {float}
54 | */
55 | this.far = far !== undefined ? far : 2000;
56 |
57 | this.updateProjectionMatrix();
58 |
59 | };
60 | /**
61 | * @desc 透视相机对象从THREE.Camera的原型继承所有属性方法
62 | * @type {THREE.Camera}
63 | */
64 | THREE.PerspectiveCamera.prototype = Object.create( THREE.Camera.prototype );
65 |
66 |
67 | /**
68 | * Uses Focal Length (in mm) to estimate and set FOV
69 | * 35mm (fullframe) camera is used if frame size is not specified;
70 | * Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
71 | * 使用焦距(单位毫米)设置相机时,如果画幅大小没有指定,默认使用FOV(视野)35mm(全画幅)相机
72 | */
73 | /**
74 | * @desc 焦距 focalLength, 画幅大小 frameHeight 更新透视投影相机的视野
75 | * @param {float} focalLength 焦距
76 | * @param {float} frameHeight 画幅大小
77 | */
78 | THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, frameHeight ) {
79 |
80 | if ( frameHeight === undefined ) frameHeight = 24;
81 |
82 | this.fov = 2 * THREE.Math.radToDeg( Math.atan( frameHeight / ( focalLength * 2 ) ) );
83 | this.updateProjectionMatrix();
84 |
85 | };
86 |
87 |
88 | /**
89 | * Sets an offset in a larger frustum. This is useful for multi-window or
90 | * multi-monitor/multi-machine setups.
91 | * 为一个大的平截头体设置视口偏移,这个方法在多显示器,多台机器,显示器矩阵上应用非常有效
92 | * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
93 | * the monitors are in grid like this
94 | * 比如,你有3x2 个显示器,每个显示器的分辨率是1920x1080,组成的显示器矩阵向下面的网格
95 | * +---+---+---+
96 | * | A | B | C |
97 | * +---+---+---+
98 | * | D | E | F |
99 | * +---+---+---+
100 | *
101 | * then for each monitor you would call it like this
102 | * 然后,你可以向下面这样为每台显示器调用setOffset()方法,让每个显示器显示画布的一部分
103 | * var w = 1920;
104 | * var h = 1080;
105 | * var fullWidth = w * 3;
106 | * var fullHeight = h * 2;
107 | *
108 | * --A--
109 | * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
110 | * --B--
111 | * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
112 | * --C--
113 | * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
114 | * --D--
115 | * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
116 | * --E--
117 | * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
118 | * --F--
119 | * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
120 | *
121 | * Note there is no reason monitors have to be the same size or in a grid.
122 | * 注意,有可能,这些显示器不是同样的尺寸.所以你可以根据需要设置你想要的各种方式
123 | */
124 | /**
125 | * 一个大的平截头体设置视口偏移,这个方法在多显示器,多台机器,显示器矩阵上应用非常有效
126 | * @param {number} fullWidth 一个超大的摄像机场景的总宽度
127 | * @param {number} fullHeight 一个超大的摄像机场景的总高度
128 | * @param {number} x 当前摄像机左上角点的x坐标在网格内的起始点
129 | * @param {number} y 当前摄像机左上角点的y坐标在网格内的起始点
130 | * @param {number} width 当前摄像机的宽度
131 | * @param {number} height 当前摄像机的高度
132 | */
133 | THREE.PerspectiveCamera.prototype.setViewOffset = function ( fullWidth, fullHeight, x, y, width, height ) {
134 | /**
135 | * @memberof THREE.PerspectiveCamera
136 | * @type {number}
137 | */
138 | this.fullWidth = fullWidth;
139 | /**
140 | * @memberof THREE.PerspectiveCamera
141 | * @type {number}
142 | */
143 | this.fullHeight = fullHeight;
144 | /**
145 | * @memberof THREE.PerspectiveCamera
146 | * @type {number}
147 | */
148 | this.x = x;
149 | /**
150 | * @memberof THREE.PerspectiveCamera
151 | * @type {number}
152 | */
153 | this.y = y;
154 | /**
155 | * @memberof THREE.PerspectiveCamera
156 | * @type {number}
157 | */
158 | this.width = width;
159 | /**
160 | * @memberof THREE.PerspectiveCamera
161 | * @type {number}
162 | */
163 | this.height = height;
164 |
165 | this.updateProjectionMatrix();
166 |
167 | };
168 |
169 | /**
170 | * @desc 返回透视投影相机的可视边界的矩阵.当相机的参数被更改后,必须调用此参数
171 | */
172 | THREE.PerspectiveCamera.prototype.updateProjectionMatrix = function () {
173 |
174 | var fov = THREE.Math.radToDeg( 2 * Math.atan( Math.tan( THREE.Math.degToRad( this.fov ) * 0.5 ) / this.zoom ) );
175 |
176 | if ( this.fullWidth ) {
177 |
178 | var aspect = this.fullWidth / this.fullHeight;
179 | var top = Math.tan( THREE.Math.degToRad( fov * 0.5 ) ) * this.near;
180 | var bottom = - top;
181 | var left = aspect * bottom;
182 | var right = aspect * top;
183 | var width = Math.abs( right - left );
184 | var height = Math.abs( top - bottom );
185 |
186 | this.projectionMatrix.makeFrustum(
187 | left + this.x * width / this.fullWidth,
188 | left + ( this.x + this.width ) * width / this.fullWidth,
189 | top - ( this.y + this.height ) * height / this.fullHeight,
190 | top - this.y * height / this.fullHeight,
191 | this.near,
192 | this.far
193 | );
194 |
195 | } else {
196 |
197 | this.projectionMatrix.makePerspective( fov, this.aspect, this.near, this.far );
198 |
199 | }
200 |
201 | };
202 | /**
203 | * @desc 克隆透视投影矩阵
204 | * @returns {THREE.PerspectiveCamera}
205 | */
206 | THREE.PerspectiveCamera.prototype.clone = function () {
207 |
208 | var camera = new THREE.PerspectiveCamera();
209 |
210 | THREE.Camera.prototype.clone.call( this, camera );
211 |
212 | camera.zoom = this.zoom;
213 |
214 | camera.fov = this.fov;
215 | camera.aspect = this.aspect;
216 | camera.near = this.near;
217 | camera.far = this.far;
218 |
219 | camera.projectionMatrix.copy( this.projectionMatrix );
220 |
221 | return camera;
222 |
223 | };
224 |
--------------------------------------------------------------------------------
/objects/Skeleton.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mikael emtinger / http://gomo.se/
3 | * @author alteredq / http://alteredqualia.com/
4 | * @author michael guerrero / http://realitymeltdown.com
5 | * @author ikerr / http://verold.com
6 | */
7 | /**
8 | * @classdesc 骨架对象
9 | * 注释内容部分参照 http://blog.csdn.net/omni360
10 | * @desc 是骨骼对象的几何,是蒙皮对象的一部分
11 | * 用来制作支持骨骼动画,当前有两种模型动画的方式:
12 | * 顶点动画和骨骼动画。顶点动画中,每帧动画其实就是模型特定姿态的一个“快照”。
13 | * 通过在帧之间插值的方法,
14 | * @param {THREE.Bone[]} bones 骨骼对象数组
15 | * @param {THREE.Matrix4[]} boneInverses 骨骼对象逆矩阵
16 | * @param {boolean} useVertexTexture 是否适应顶点纹理,该属性之后不可以设置
17 | * @constructor
18 | */
19 | THREE.Skeleton = function ( bones, boneInverses, useVertexTexture ) {
20 | /**
21 | * @desc 是否使用顶点纹理
22 | * @default true
23 | * @type {boolean}
24 | */
25 | this.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;
26 | /**
27 | * @desc 单位矩阵
28 | * @type {THREE.Matrix4}
29 | */
30 | this.identityMatrix = new THREE.Matrix4();
31 |
32 | // copy the bone array
33 | // 拷贝骨骼数组
34 | bones = bones || [];
35 | /**
36 | * @desc 骨骼数组
37 | * @type {Array.}
38 | */
39 | this.bones = bones.slice( 0 );
40 |
41 | // create a bone texture or an array of floats
42 | // 创建骨架纹理或者骨架纹理数组
43 | if ( this.useVertexTexture ) {
44 |
45 | // layout (1 matrix = 4 pixels)
46 | // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
47 | // with 8x8 pixel texture max 16 bones (8 * 8 / 4)
48 | // 16x16 pixel texture max 64 bones (16 * 16 / 4)
49 | // 32x32 pixel texture max 256 bones (32 * 32 / 4)
50 | // 64x64 pixel texture max 1024 bones (64 * 64 / 4)
51 |
52 | var size;
53 |
54 | if ( this.bones.length > 256 )
55 | size = 64;
56 | else if ( this.bones.length > 64 )
57 | size = 32;
58 | else if ( this.bones.length > 16 )
59 | size = 16;
60 | else
61 | size = 8;
62 | /**
63 | * @desc 骨骼纹理宽度
64 | * @memberof THREE.Skeleton
65 | */
66 | this.boneTextureWidth = size;
67 | /**
68 | * @desc 骨骼纹理高度
69 | * @memberof THREE.Skeleton
70 | */
71 | this.boneTextureHeight = size;
72 | /**
73 | * @desc 骨骼矩阵
74 | * @memberof THREE.Skeleton
75 | * @type {Float32Array}
76 | */
77 | this.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel
78 | /**
79 | * @desc 骨骼纹理
80 | * @memberof THREE.Skeleton
81 | * @type {THREE.DataTexture}
82 | */
83 | this.boneTexture = new THREE.DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, THREE.RGBAFormat, THREE.FloatType );
84 | /**
85 | * @desc 骨骼纹理缩小插值方式
86 | * @memberof THREE.Skeleton
87 | * @type {number}
88 | */
89 | this.boneTexture.minFilter = THREE.NearestFilter;
90 | /**
91 | * @desc 骨骼纹理放大插值方式
92 | * @memberof THREE.Skeleton
93 | * @type {number}
94 | */
95 | this.boneTexture.magFilter = THREE.NearestFilter;
96 | /**
97 | * @desc 骨骼纹理是否生成Mipmap
98 | * @memberof THREE.Skeleton
99 | * @type {boolean}
100 | */
101 | this.boneTexture.generateMipmaps = false;
102 | /**
103 | * @desc 骨骼纹理是否Y反转
104 | * @memberof THREE.Skeleton
105 | * @type {boolean}
106 | */
107 | this.boneTexture.flipY = false;
108 |
109 | } else {
110 | // 不使用顶点纹理
111 | this.boneMatrices = new Float32Array( 16 * this.bones.length );
112 |
113 | }
114 |
115 | // use the supplied bone inverses or calculate the inverses
116 | // 使用提供的骨架位置逆矩阵或计算骨架位置逆矩阵
117 | if ( boneInverses === undefined ) {
118 | // 如果没有提供骨架位置逆矩阵
119 | // 计算骨架位置逆矩阵
120 | this.calculateInverses();
121 |
122 | } else {
123 | // 如果提供了逆矩阵,并和骨骼数量相等
124 | if ( this.bones.length === boneInverses.length ) {
125 | // 复制骨架的逆矩阵
126 | this.boneInverses = boneInverses.slice( 0 );
127 |
128 | } else {
129 | // 如果提供的骨骼逆矩阵和骨骼数量不一致
130 | // 提示用户骨骼的逆矩阵和骨骼数量不一致
131 | console.warn( 'THREE.Skeleton bonInverses is the wrong length.' );
132 | // 清空骨骼逆矩阵
133 | this.boneInverses = [];
134 | // 并将骨骼逆矩阵和骨骼数量保持不一致
135 | for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
136 |
137 | this.boneInverses.push( new THREE.Matrix4() );
138 |
139 | }
140 |
141 | }
142 |
143 | }
144 |
145 | };
146 | /**
147 | * @desc 方法重新计算骨骼的逆矩阵
148 | */
149 | THREE.Skeleton.prototype.calculateInverses = function () {
150 |
151 | this.boneInverses = [];
152 |
153 | for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
154 |
155 | var inverse = new THREE.Matrix4();
156 |
157 | if ( this.bones[ b ] ) {
158 | // 获得当前骨骼的位置属性的逆矩阵
159 | inverse.getInverse( this.bones[ b ].matrixWorld );
160 |
161 | }
162 | // 返回包含骨骼逆矩阵的Skeleton骨架对象
163 | this.boneInverses.push( inverse );
164 |
165 | }
166 |
167 | };
168 | /**
169 | * @desc 重新计算骨骼的计算本地矩阵,位置,旋转缩放属性
170 | */
171 | THREE.Skeleton.prototype.pose = function () {
172 |
173 | var bone;
174 |
175 | // recover the bind-time world matrices
176 | // 恢复在绑定时的世界坐标矩阵
177 | for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
178 |
179 | bone = this.bones[ b ];
180 |
181 | if ( bone ) {
182 | // 恢复在绑定时的世界坐标矩阵
183 | bone.matrixWorld.getInverse( this.boneInverses[ b ] );
184 |
185 | }
186 |
187 | }
188 |
189 | // compute the local matrices, positions, rotations and scales
190 | // 计算本地矩阵,位置,旋转缩放属性
191 | for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
192 |
193 | bone = this.bones[ b ];
194 |
195 | if ( bone ) {
196 | // 如果骨骼有父级对象
197 | if ( bone.parent ) {
198 | // 求逆父级对象的世界坐标矩阵
199 | bone.matrix.getInverse( bone.parent.matrixWorld );
200 | // 将当前骨骼的矩阵与父级对象的世界坐标矩阵相乘
201 | bone.matrix.multiply( bone.matrixWorld );
202 |
203 | } else {
204 | // 复制自身的世界坐标矩阵
205 | bone.matrix.copy( bone.matrixWorld );
206 |
207 | }
208 | // 调用decompose()方法,重新设置骨骼对象的位置,旋转缩放属性.
209 | bone.matrix.decompose( bone.position, bone.quaternion, bone.scale );
210 |
211 | }
212 |
213 | }
214 |
215 | };
216 | /**
217 | * @function
218 | * @desc 法更新当前骨架的缓冲区数据,并更新纹理标识设置为true
219 | */
220 | THREE.Skeleton.prototype.update = ( function () {
221 |
222 | var offsetMatrix = new THREE.Matrix4();
223 |
224 | return function () {
225 |
226 | // flatten bone matrices to array
227 | // 展开骨骼矩阵到数组
228 | for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
229 |
230 | // compute the offset between the current and the original transform
231 | // 计算当前位置到原始位置的偏移距离
232 | var matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;
233 |
234 | offsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );
235 | // 调用flattenToArrayOffset方法,通过参数offset(b * 16)指定偏移量,将矩阵展开到数组(参数array)中,返回新的数组.
236 | offsetMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
237 |
238 | }
239 | // 如果使用顶点纹理
240 | if ( this.useVertexTexture ) {
241 | // 将更新标识设置为true.
242 | this.boneTexture.needsUpdate = true;
243 |
244 | }
245 |
246 | };
247 |
248 | } )();
249 |
250 |
--------------------------------------------------------------------------------
/core/BufferAttribute.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 |
5 | /**
6 | * @classdesc 属性对象类
7 | * 注释内容部分参照 http://blog.csdn.net/omni360
8 | * @desc 存储于bufferGeometry相关联的属性数据
9 | * @param {array} array 属性数组
10 | * @param {number} itemSize 数组元素尺寸
11 | * @constructor
12 | */
13 | THREE.BufferAttribute = function ( array, itemSize ) {
14 | /**
15 | * @desc 属性数组
16 | * @type {array}
17 | */
18 | this.array = array;
19 | /**
20 | * @desc 数组元素尺寸
21 | * @type {number}
22 | */
23 | this.itemSize = itemSize;
24 | /**
25 | * @desc 是否需要更新标识
26 | * @type {boolean}
27 | */
28 | this.needsUpdate = false;
29 |
30 | };
31 |
32 | THREE.BufferAttribute.prototype = {
33 |
34 | constructor: THREE.BufferAttribute,
35 | /**
36 | * @desc 获得数组长度
37 | * @returns {number}
38 | */
39 | get length () {
40 |
41 | return this.array.length;
42 |
43 | },
44 | /**
45 | * @desc 拷贝数组
46 | * @param {number} index1 目标数组起始索引
47 | * @param {THREE.BufferAttribute} attribute 源数组
48 | * @param {number} index2 源数组起始索引
49 | */
50 | copyAt: function ( index1, attribute, index2 ) {
51 |
52 | index1 *= this.itemSize;
53 | index2 *= attribute.itemSize;
54 |
55 | for ( var i = 0, l = this.itemSize; i < l; i ++ ) {
56 |
57 | this.array[ index1 + i ] = attribute.array[ index2 + i ];
58 |
59 | }
60 |
61 | },
62 | /**
63 | * @desc 重新设置BufferAttribute的属性数组
64 | * @param {THREE.BufferAttribute.array} value 属性数组
65 | * @returns {THREE.BufferAttribute}
66 | */
67 | set: function ( value ) {
68 |
69 | this.array.set( value );
70 |
71 | return this;
72 |
73 | },
74 | /**
75 | * @desc 重新设置含有3个属性相的BufferAttribute属性数组的第一个分量
76 | * setX方法中,属性数组的长度是属性相的长度乘以属性的个数
77 | * 比如要存放100个点的坐标,坐标有3个属性相,那么属性数组的长度是300,如果想改变第30个点的x坐标就将index设为30
78 | * @param {number} index 属性数组的索引
79 | * @param {number} x 属性数组的第一个分量的值
80 | * @returns {THREE.BufferAttribute}
81 | */
82 | setX: function ( index, x ) {
83 |
84 | this.array[ index * this.itemSize ] = x;
85 |
86 | return this;
87 |
88 | },
89 | /**
90 | * @desc 重新设置含有3个属性相的BufferAttribute属性数组的第二个分量
91 | * @param {number} index 属性数组的索引
92 | * @param {number} y 属性数组的第二个分量的值
93 | * @returns {THREE.BufferAttribute}
94 | */
95 | setY: function ( index, y ) {
96 |
97 | this.array[ index * this.itemSize + 1 ] = y;
98 |
99 | return this;
100 |
101 | },
102 | /**
103 | * @desc 重新设置含有3个属性相的BufferAttribute属性数组的第三个分量
104 | * @param {number} index 属性数组的索引
105 | * @param {number} z 属性数组的第三个分量的值
106 | * @returns {THREE.BufferAttribute}
107 | */
108 | setZ: function ( index, z ) {
109 |
110 | this.array[ index * this.itemSize + 2 ] = z;
111 |
112 | return this;
113 |
114 | },
115 | /**
116 | * @desc 重新设置含有3个属性相的BufferAttribute属性数组的第1,2个分量
117 | * @param {number} index 属性数组的索引
118 | * @param {number} x 属性数组的第1个分量的值
119 | * @param {number} y 属性数组的第2个分量的值
120 | * @returns {THREE.BufferAttribute}
121 | */
122 | setXY: function ( index, x, y ) {
123 |
124 | index *= this.itemSize;
125 |
126 | this.array[ index ] = x;
127 | this.array[ index + 1 ] = y;
128 |
129 | return this;
130 |
131 | },
132 | /**
133 | * @desc 重新设置含有3个属性相的BufferAttribute属性数组的第1,2,3个分量
134 | * @param {number} index 属性数组的索引
135 | * @param {number} x 属性数组的第1个分量的值
136 | * @param {number} y 属性数组的第2个分量的值
137 | * @param {number} z 属性数组的第3个分量的值
138 | * @returns {THREE.BufferAttribute}
139 | */
140 | setXYZ: function ( index, x, y, z ) {
141 |
142 | index *= this.itemSize;
143 |
144 | this.array[ index ] = x;
145 | this.array[ index + 1 ] = y;
146 | this.array[ index + 2 ] = z;
147 |
148 | return this;
149 |
150 | },
151 | /**
152 | * @desc 重新设置含有4个属性相的BufferAttribute属性数组的第1,2,3,4个分量
153 | * @param {number} index 属性数组的索引
154 | * @param {number} x 属性数组的第1个分量的值
155 | * @param {number} y 属性数组的第2个分量的值
156 | * @param {number} z 属性数组的第3个分量的值
157 | * @param {number} w 属性数组的第4个分量的值
158 | * @returns {THREE.BufferAttribute}
159 | */
160 | setXYZW: function ( index, x, y, z, w ) {
161 |
162 | index *= this.itemSize;
163 |
164 | this.array[ index ] = x;
165 | this.array[ index + 1 ] = y;
166 | this.array[ index + 2 ] = z;
167 | this.array[ index + 3 ] = w;
168 |
169 | return this;
170 |
171 | },
172 | /**
173 | * @desc 克隆属性对象
174 | * @returns {THREE.BufferAttribute}
175 | */
176 | clone: function () {
177 |
178 | return new THREE.BufferAttribute( new this.array.constructor( this.array ), this.itemSize );
179 |
180 | }
181 |
182 | };
183 |
184 | //
185 | /**********************************************************************************
186 | ****下面这些方法是定义不同数据类型的属性,已经在新版本中删除,这里保留是为了向后兼容.
187 | ***********************************************************************************/
188 | THREE.Int8Attribute = function ( data, itemSize ) {
189 |
190 | console.warn( 'THREE.Int8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
191 | return new THREE.BufferAttribute( data, itemSize );
192 |
193 | };
194 |
195 | THREE.Uint8Attribute = function ( data, itemSize ) {
196 |
197 | console.warn( 'THREE.Uint8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
198 | return new THREE.BufferAttribute( data, itemSize );
199 |
200 | };
201 |
202 | THREE.Uint8ClampedAttribute = function ( data, itemSize ) {
203 |
204 | console.warn( 'THREE.Uint8ClampedAttribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
205 | return new THREE.BufferAttribute( data, itemSize );
206 |
207 |
208 | };
209 |
210 | THREE.Int16Attribute = function ( data, itemSize ) {
211 |
212 | console.warn( 'THREE.Int16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
213 | return new THREE.BufferAttribute( data, itemSize );
214 |
215 | };
216 |
217 | THREE.Uint16Attribute = function ( data, itemSize ) {
218 |
219 | console.warn( 'THREE.Uint16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
220 | return new THREE.BufferAttribute( data, itemSize );
221 |
222 | };
223 |
224 | THREE.Int32Attribute = function ( data, itemSize ) {
225 |
226 | console.warn( 'THREE.Int32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
227 | return new THREE.BufferAttribute( data, itemSize );
228 |
229 | };
230 |
231 | THREE.Uint32Attribute = function ( data, itemSize ) {
232 |
233 | console.warn( 'THREE.Uint32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
234 | return new THREE.BufferAttribute( data, itemSize );
235 |
236 | };
237 |
238 | THREE.Float32Attribute = function ( data, itemSize ) {
239 |
240 | console.warn( 'THREE.Float32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
241 | return new THREE.BufferAttribute( data, itemSize );
242 |
243 | };
244 |
245 | THREE.Float64Attribute = function ( data, itemSize ) {
246 |
247 | console.warn( 'THREE.Float64Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
248 | return new THREE.BufferAttribute( data, itemSize );
249 |
250 | };
251 |
--------------------------------------------------------------------------------
/extras/ImageUtils.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | * @author mrdoob / http://mrdoob.com/
4 | * @author Daosheng Mu / https://github.com/DaoshengMu/
5 | */
6 | /**
7 | * @classdesc 图片对象工具集
8 | * 注释内容部分参照 http://blog.csdn.net/omni360
9 | * @constructor
10 | */
11 | THREE.ImageUtils = {
12 | /**
13 | * @desc 跨域加载
14 | */
15 | crossOrigin: undefined,
16 | /**
17 | * @desc 加载纹理
18 | * @param {string} url 图片url
19 | * @param {number} mapping 图片映射方式
20 | * @param {*} onLoad 加载回调函数
21 | * @param {*} onError 错误回调函数
22 | * @returns {THREE.Texture}
23 | */
24 | loadTexture: function ( url, mapping, onLoad, onError ) {
25 | // 图片加载器
26 | var loader = new THREE.ImageLoader();
27 | loader.crossOrigin = this.crossOrigin;
28 |
29 | // 创建纹理
30 | var texture = new THREE.Texture( undefined, mapping );
31 |
32 | // 加载图片
33 | loader.load( url, function ( image ) {
34 |
35 | texture.image = image;
36 | texture.needsUpdate = true;
37 | // 完成回调
38 | if ( onLoad ) onLoad( texture );
39 |
40 | }, undefined, function ( event ) {
41 | // 错误回调
42 | if ( onError ) onError( event );
43 |
44 | } );
45 | // 图片源路径
46 | texture.sourceFile = url;
47 |
48 | return texture;
49 |
50 | },
51 | /**
52 | * @desc 加载立方体纹理
53 | * @param {string[]} array 图片url
54 | * @param {number} mapping 图片映射方式
55 | * @param {*} onLoad 加载回调函数
56 | * @param {*} onError 错误回调函数
57 | * @returns {THREE.CubeTexture}
58 | */
59 | loadTextureCube: function ( array, mapping, onLoad, onError ) {
60 |
61 | var images = [];
62 |
63 | var loader = new THREE.ImageLoader();
64 | loader.crossOrigin = this.crossOrigin;
65 |
66 | var texture = new THREE.CubeTexture( images, mapping );
67 |
68 | // no flipping needed for cube textures
69 |
70 | texture.flipY = false;
71 |
72 | var loaded = 0;
73 |
74 | var loadTexture = function ( i ) {
75 |
76 | loader.load( array[ i ], function ( image ) {
77 |
78 | texture.images[ i ] = image;
79 |
80 | loaded += 1;
81 |
82 | if ( loaded === 6 ) {
83 |
84 | texture.needsUpdate = true;
85 |
86 | if ( onLoad ) onLoad( texture );
87 |
88 | }
89 |
90 | } );
91 |
92 | }
93 |
94 | for ( var i = 0, il = array.length; i < il; ++ i ) {
95 |
96 | loadTexture( i );
97 |
98 | }
99 |
100 | return texture;
101 |
102 | },
103 | /**
104 | * @ignore
105 | */
106 | loadCompressedTexture: function () {
107 |
108 | console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' )
109 |
110 | },
111 | /**
112 | * @ignore
113 | */
114 | loadCompressedTextureCube: function () {
115 |
116 | console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' )
117 |
118 | },
119 | /**
120 | * @desc 通过参数image(图像对象),参数(深度信息),获得法线贴图
121 | * @param {Image} image 图片对象
122 | * @param {float} depth 深度信息 [0 ,1]
123 | * @returns {THREE.Texture}
124 | */
125 | getNormalMap: function ( image, depth ) {
126 |
127 | // Adapted from http://www.paulbrunt.co.uk/lab/heightnormal/
128 |
129 | var cross = function ( a, b ) {
130 |
131 | return [ a[ 1 ] * b[ 2 ] - a[ 2 ] * b[ 1 ], a[ 2 ] * b[ 0 ] - a[ 0 ] * b[ 2 ], a[ 0 ] * b[ 1 ] - a[ 1 ] * b[ 0 ] ];
132 |
133 | }
134 |
135 | var subtract = function ( a, b ) {
136 |
137 | return [ a[ 0 ] - b[ 0 ], a[ 1 ] - b[ 1 ], a[ 2 ] - b[ 2 ] ];
138 |
139 | }
140 |
141 | var normalize = function ( a ) {
142 |
143 | var l = Math.sqrt( a[ 0 ] * a[ 0 ] + a[ 1 ] * a[ 1 ] + a[ 2 ] * a[ 2 ] );
144 | return [ a[ 0 ] / l, a[ 1 ] / l, a[ 2 ] / l ];
145 |
146 | }
147 |
148 | depth = depth | 1;
149 |
150 | var width = image.width;
151 | var height = image.height;
152 |
153 | var canvas = document.createElement( 'canvas' );
154 | canvas.width = width;
155 | canvas.height = height;
156 |
157 | var context = canvas.getContext( '2d' );
158 | context.drawImage( image, 0, 0 );
159 |
160 | var data = context.getImageData( 0, 0, width, height ).data;
161 | var imageData = context.createImageData( width, height );
162 | var output = imageData.data;
163 |
164 | for ( var x = 0; x < width; x ++ ) {
165 |
166 | for ( var y = 0; y < height; y ++ ) {
167 |
168 | var ly = y - 1 < 0 ? 0 : y - 1;
169 | var uy = y + 1 > height - 1 ? height - 1 : y + 1;
170 | var lx = x - 1 < 0 ? 0 : x - 1;
171 | var ux = x + 1 > width - 1 ? width - 1 : x + 1;
172 |
173 | var points = [];
174 | var origin = [ 0, 0, data[ ( y * width + x ) * 4 ] / 255 * depth ];
175 | points.push( [ - 1, 0, data[ ( y * width + lx ) * 4 ] / 255 * depth ] );
176 | points.push( [ - 1, - 1, data[ ( ly * width + lx ) * 4 ] / 255 * depth ] );
177 | points.push( [ 0, - 1, data[ ( ly * width + x ) * 4 ] / 255 * depth ] );
178 | points.push( [ 1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] );
179 | points.push( [ 1, 0, data[ ( y * width + ux ) * 4 ] / 255 * depth ] );
180 | points.push( [ 1, 1, data[ ( uy * width + ux ) * 4 ] / 255 * depth ] );
181 | points.push( [ 0, 1, data[ ( uy * width + x ) * 4 ] / 255 * depth ] );
182 | points.push( [ - 1, 1, data[ ( uy * width + lx ) * 4 ] / 255 * depth ] );
183 |
184 | var normals = [];
185 | var num_points = points.length;
186 |
187 | for ( var i = 0; i < num_points; i ++ ) {
188 |
189 | var v1 = points[ i ];
190 | var v2 = points[ ( i + 1 ) % num_points ];
191 | v1 = subtract( v1, origin );
192 | v2 = subtract( v2, origin );
193 | normals.push( normalize( cross( v1, v2 ) ) );
194 |
195 | }
196 |
197 | var normal = [ 0, 0, 0 ];
198 |
199 | for ( var i = 0; i < normals.length; i ++ ) {
200 |
201 | normal[ 0 ] += normals[ i ][ 0 ];
202 | normal[ 1 ] += normals[ i ][ 1 ];
203 | normal[ 2 ] += normals[ i ][ 2 ];
204 |
205 | }
206 |
207 | normal[ 0 ] /= normals.length;
208 | normal[ 1 ] /= normals.length;
209 | normal[ 2 ] /= normals.length;
210 |
211 | var idx = ( y * width + x ) * 4;
212 |
213 | output[ idx ] = ( ( normal[ 0 ] + 1.0 ) / 2.0 * 255 ) | 0;
214 | output[ idx + 1 ] = ( ( normal[ 1 ] + 1.0 ) / 2.0 * 255 ) | 0;
215 | output[ idx + 2 ] = ( normal[ 2 ] * 255 ) | 0;
216 | output[ idx + 3 ] = 255;
217 |
218 | }
219 |
220 | }
221 |
222 | context.putImageData( imageData, 0, 0 );
223 |
224 | return canvas;
225 |
226 | },
227 | /**
228 | * @desc 生成DataTexture对象使用的图像数据
229 | * @param {number} width 宽度
230 | * @param {number} height 高度
231 | * @param {THREE.Color} color 颜色
232 | * @returns {THREE.DataTexture}
233 | */
234 | generateDataTexture: function ( width, height, color ) {
235 |
236 | var size = width * height;
237 | var data = new Uint8Array( 3 * size );
238 |
239 | var r = Math.floor( color.r * 255 );
240 | var g = Math.floor( color.g * 255 );
241 | var b = Math.floor( color.b * 255 );
242 |
243 | for ( var i = 0; i < size; i ++ ) {
244 |
245 | data[ i * 3 ] = r;
246 | data[ i * 3 + 1 ] = g;
247 | data[ i * 3 + 2 ] = b;
248 |
249 | }
250 |
251 | var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
252 | texture.needsUpdate = true;
253 |
254 | return texture;
255 |
256 | }
257 |
258 | };
259 |
--------------------------------------------------------------------------------
/math/Triangle.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author bhouston / http://exocortex.com
3 | * @author mrdoob / http://mrdoob.com/
4 | */
5 | /**
6 | * @classdesc 三角形类
7 | * 注释内容部分参照 http://blog.csdn.net/omni360
8 | * @desc 由a,b,c三个向量组成的三角形
9 | * @param {THREE.Vector3} a
10 | * @param {THREE.Vector3} b
11 | * @param {THREE.Vector3} c
12 | * @constructor
13 | */
14 | THREE.Triangle = function ( a, b, c ) {
15 | /**
16 | *
17 | * @type {THREE.Vector3}
18 | */
19 | this.a = ( a !== undefined ) ? a : new THREE.Vector3();
20 | /**
21 | *
22 | * @type {THREE.Vector3}
23 | */
24 | this.b = ( b !== undefined ) ? b : new THREE.Vector3();
25 | /**
26 | *
27 | * @type {THREE.Vector3}
28 | */
29 | this.c = ( c !== undefined ) ? c : new THREE.Vector3();
30 |
31 | };
32 | /**
33 | * @function
34 | * @desc 计算三角形的法线向量
35 | * @param {THREE.Vector3} a
36 | * @param {THREE.Vector3} b
37 | * @param {THREE.Vector3} c
38 | * @param {THREE.Vector3} optionalTarget
39 | * @return {THREE.Vector3}
40 | */
41 | THREE.Triangle.normal = function () {
42 |
43 | var v0 = new THREE.Vector3();
44 |
45 | return function ( a, b, c, optionalTarget ) {
46 |
47 | var result = optionalTarget || new THREE.Vector3();
48 |
49 | result.subVectors( c, b );
50 | v0.subVectors( a, b );
51 | result.cross( v0 );
52 |
53 | var resultLengthSq = result.lengthSq();
54 | if ( resultLengthSq > 0 ) {
55 |
56 | return result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );
57 |
58 | }
59 |
60 | return result.set( 0, 0, 0 );
61 |
62 | };
63 |
64 | }();
65 |
66 | // static/instance method to calculate barycoordinates
67 | // based on: http://www.blackpawn.com/texts/pointinpoly/default.html
68 | /**
69 | * @function
70 | * @desc 算返回参数a,b,c所组成的三角形所在的平面上任意点(参数point)所表示三角形顶点的加权平均值
71 | * 这个权值就是重心坐标
72 | * @param {THREE.Vector3} point 三角平面上任意点
73 | * @param {THREE.Vector3} a
74 | * @param {THREE.Vector3} b
75 | * @param {THREE.Vector3} c
76 | * @param {THREE.Vector3} optionalTarget
77 | */
78 | THREE.Triangle.barycoordFromPoint = function () {
79 |
80 | var v0 = new THREE.Vector3();
81 | var v1 = new THREE.Vector3();
82 | var v2 = new THREE.Vector3();
83 |
84 | return function ( point, a, b, c, optionalTarget ) {
85 |
86 | v0.subVectors( c, a );
87 | v1.subVectors( b, a );
88 | v2.subVectors( point, a );
89 |
90 | var dot00 = v0.dot( v0 );
91 | var dot01 = v0.dot( v1 );
92 | var dot02 = v0.dot( v2 );
93 | var dot11 = v1.dot( v1 );
94 | var dot12 = v1.dot( v2 );
95 |
96 | var denom = ( dot00 * dot11 - dot01 * dot01 );
97 |
98 | var result = optionalTarget || new THREE.Vector3();
99 |
100 | // colinear or singular triangle
101 | if ( denom == 0 ) {
102 | // arbitrary location outside of triangle?
103 | // not sure if this is the best idea, maybe should be returning undefined
104 | return result.set( - 2, - 1, - 1 );
105 | }
106 |
107 | var invDenom = 1 / denom;
108 | var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
109 | var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
110 |
111 | // barycoordinates must always sum to 1
112 | return result.set( 1 - u - v, v, u );
113 |
114 | };
115 |
116 | }();
117 |
118 | /**
119 | * @function
120 | * @desc 判断任意点(参数point)是否在a,b,c所组成的三角形内
121 | * @param {THREE.Vector3} point 三角平面上任意点
122 | * @param {THREE.Vector3} a
123 | * @param {THREE.Vector3} b
124 | * @param {THREE.Vector3} c
125 | * @return {boolean}
126 | */
127 | THREE.Triangle.containsPoint = function () {
128 |
129 | var v1 = new THREE.Vector3();
130 |
131 | return function ( point, a, b, c ) {
132 |
133 | var result = THREE.Triangle.barycoordFromPoint( point, a, b, c, v1 );
134 |
135 | return ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );
136 |
137 | };
138 |
139 | }();
140 |
141 | THREE.Triangle.prototype = {
142 |
143 | constructor: THREE.Triangle,
144 | /**
145 | * @desc 设置三角平面
146 | * @param {THREE.Vector3} a
147 | * @param {THREE.Vector3} b
148 | * @param {THREE.Vector3} c
149 | * @returns {THREE.Triangle}
150 | */
151 | set: function ( a, b, c ) {
152 |
153 | this.a.copy( a );
154 | this.b.copy( b );
155 | this.c.copy( c );
156 |
157 | return this;
158 |
159 | },
160 |
161 | /**
162 | * @desc 通过数组和索引设置三角平面
163 | * @param {THREE.Vector3[]} points
164 | * @param {float} i0
165 | * @param {float} i1
166 | * @param {float} i2
167 | * @returns {THREE.Triangle}
168 | */
169 | setFromPointsAndIndices: function ( points, i0, i1, i2 ) {
170 |
171 | this.a.copy( points[ i0 ] );
172 | this.b.copy( points[ i1 ] );
173 | this.c.copy( points[ i2 ] );
174 |
175 | return this;
176 |
177 | },
178 |
179 | /**
180 | * @desc 拷贝三角平面
181 | * @param {THREE.Triangle} triangle
182 | * @returns {THREE.Triangle}
183 | */
184 | copy: function ( triangle ) {
185 |
186 | this.a.copy( triangle.a );
187 | this.b.copy( triangle.b );
188 | this.c.copy( triangle.c );
189 |
190 | return this;
191 |
192 | },
193 |
194 | /**
195 | * @function
196 | * @desc 计算三角形面他积
197 | * @return {float}
198 | */
199 | area: function () {
200 |
201 | var v0 = new THREE.Vector3();
202 | var v1 = new THREE.Vector3();
203 |
204 | return function () {
205 |
206 | v0.subVectors( this.c, this.b );
207 | v1.subVectors( this.a, this.b );
208 |
209 | return v0.cross( v1 ).length() * 0.5;
210 |
211 | };
212 |
213 | }(),
214 |
215 | /**
216 | * @desc 计算三角形中心
217 | * @param {THREE.Vector3} optionalTarget
218 | * @returns {THREE.Vector3}
219 | */
220 | midpoint: function ( optionalTarget ) {
221 |
222 | var result = optionalTarget || new THREE.Vector3();
223 | return result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );
224 |
225 | },
226 |
227 | /**
228 | * @desc 计算三角形的法向量
229 | * @param {THREE.Vector3} optionalTarget
230 | * @returns {THREE.Vector3}
231 | */
232 | normal: function ( optionalTarget ) {
233 |
234 | return THREE.Triangle.normal( this.a, this.b, this.c, optionalTarget );
235 |
236 | },
237 | /**
238 | * @desc 创建三角形共面的平面Plane对象
239 | * @param {THREE.Plane} optionalTarget
240 | * @returns {THREE.Plane}
241 | */
242 | plane: function ( optionalTarget ) {
243 |
244 | var result = optionalTarget || new THREE.Plane();
245 |
246 | return result.setFromCoplanarPoints( this.a, this.b, this.c );
247 |
248 | },
249 |
250 | /**
251 | * @desc 计算返回当前三角形所在的平面上任意点(参数point)所表示当前三角形顶点的加权平均值
252 | * 这个权值就是重心坐标
253 | * @param {THREE.Vector3} point
254 | * @param {THREE.Vector3} optionalTarget
255 | * @returns {THREE.Vector3}
256 | */
257 | barycoordFromPoint: function ( point, optionalTarget ) {
258 |
259 | return THREE.Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );
260 |
261 | },
262 |
263 | /**
264 | * @desc 计算点是否在三角形内
265 | * @param {THREE.Vector3} point
266 | * @returns {boolean}
267 | */
268 | containsPoint: function ( point ) {
269 |
270 | return THREE.Triangle.containsPoint( point, this.a, this.b, this.c );
271 |
272 | },
273 |
274 | /**
275 | * @desc 计算三角形是否相等
276 | * @param {THREE.Triangle} triangle
277 | * @returns {boolean}
278 | */
279 | equals: function ( triangle ) {
280 |
281 | return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );
282 |
283 | },
284 |
285 | /**
286 | * @desc 克隆三角形
287 | * @returns {THREE.Triangle}
288 | */
289 | clone: function () {
290 |
291 | return new THREE.Triangle().copy( this );
292 |
293 | }
294 |
295 | };
296 |
--------------------------------------------------------------------------------
/objects/MorphAnimMesh.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 | /**
5 | * @classdesc 变形动画网格对象
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @desc 这个对象是专门针对变形动画的,增加了许多角色变形动画的内容
8 | * @param {THREE.Geometry} geometry 几何对象
9 | * @param {THREE.Material} material 材质对象
10 | * @constructor
11 | */
12 | THREE.MorphAnimMesh = function ( geometry, material ) {
13 |
14 | THREE.Mesh.call( this, geometry, material );
15 |
16 | this.type = 'MorphAnimMesh';
17 |
18 | // API
19 | /**
20 | * @desc 周期,单位毫秒,默认初始化为1000毫秒,每帧间隔时长
21 | * @default
22 | * @type {number}
23 | */
24 | this.duration = 1000; // milliseconds
25 | /**
26 | * @desc 镜像循环,看下面的算法,应该是播放完后,回放动画
27 | * @default
28 | * @type {boolean}
29 | */
30 | this.mirroredLoop = false;
31 | /**
32 | * @desc 动画时长
33 | * @default
34 | * @type {number}
35 | */
36 | this.time = 0;
37 |
38 | // internals
39 | /**
40 | * @desc 最后关键帧
41 | * @default
42 | * @type {number}
43 | */
44 | this.lastKeyframe = 0;
45 | /**
46 | * @desc 当前关键帧
47 | * @default
48 | * @type {number}
49 | */
50 | this.currentKeyframe = 0;
51 | /**
52 | * @desc 方向,应该指的是时间轴的方向
53 | * @default
54 | * @type {number}
55 | */
56 | this.direction = 1;
57 | /**
58 | * @desc 时间轴是否是返方向,默认为false
59 | * @default
60 | * @type {boolean}
61 | */
62 | this.directionBackwards = false;
63 | // 创建关键帧动画时间轴,从morphTargets数组创建.
64 | this.setFrameRange( 0, this.geometry.morphTargets.length - 1 );
65 |
66 | };
67 | /**
68 | * @desc MorphAnimMesh从Mesh的原型继承所有属性方法
69 | * @type {THREE.Mesh}
70 | */
71 | THREE.MorphAnimMesh.prototype = Object.create( THREE.Mesh.prototype );
72 | /**
73 | * @desc 创建关键帧动画时间轴,从morphTargets数组创建
74 | * @param {number} start 开始帧
75 | * @param {number} end 结束帧
76 | */
77 | THREE.MorphAnimMesh.prototype.setFrameRange = function ( start, end ) {
78 | /**
79 | * @memberof THREE.MorphAnimMesh
80 | * @desc 开始帧
81 | * @type {number}
82 | */
83 | this.startKeyframe = start;
84 | /**
85 | * @memberof THREE.MorphAnimMesh
86 | * @desc 结束帧
87 | * @type {number}
88 | */
89 | this.endKeyframe = end;
90 | /**
91 | * @memberof THREE.MorphAnimMesh
92 | * @desc 动画长度
93 | * @type {number}
94 | */
95 | this.length = this.endKeyframe - this.startKeyframe + 1;
96 |
97 | };
98 | /**
99 | * @desc 设置关键帧动画正放
100 | */
101 | THREE.MorphAnimMesh.prototype.setDirectionForward = function () {
102 |
103 | this.direction = 1;
104 | this.directionBackwards = false;
105 |
106 | };
107 | /**
108 | * @desc 设置关键帧动画倒放
109 | */
110 | THREE.MorphAnimMesh.prototype.setDirectionBackward = function () {
111 |
112 | this.direction = - 1;
113 | this.directionBackwards = true;
114 |
115 | };
116 | /**
117 | * @desc 从morphTagets数组中解析关键帧动画
118 | */
119 | THREE.MorphAnimMesh.prototype.parseAnimations = function () {
120 |
121 | var geometry = this.geometry;
122 |
123 | if ( ! geometry.animations ) geometry.animations = {};
124 |
125 | var firstAnimation, animations = geometry.animations;
126 |
127 | var pattern = /([a-z]+)_?(\d+)/;
128 |
129 | for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
130 | // 获得单个变形动画关键帧
131 | var morph = geometry.morphTargets[ i ];
132 | var parts = morph.name.match( pattern );
133 |
134 | if ( parts && parts.length > 1 ) {
135 |
136 | var label = parts[ 1 ];
137 | var num = parts[ 2 ];
138 |
139 | if ( ! animations[ label ] ) animations[ label ] = { start: Infinity, end: - Infinity };
140 |
141 | var animation = animations[ label ];
142 |
143 | if ( i < animation.start ) animation.start = i;
144 | if ( i > animation.end ) animation.end = i;
145 |
146 | if ( ! firstAnimation ) firstAnimation = label;
147 |
148 | }
149 |
150 | }
151 | // 设置第一个动画.
152 | geometry.firstAnimation = firstAnimation;
153 |
154 | };
155 | /**
156 | * @desc 从morphTagets数组中设置关键帧动画标签,可以将morphTargets数组中,分成几段动画,分别存放.
157 | * @param {string} label 动画名称
158 | * @param {number} start morphTargets开始索引
159 | * @param {number} end morphTargets结束索引
160 | */
161 | THREE.MorphAnimMesh.prototype.setAnimationLabel = function ( label, start, end ) {
162 |
163 | if ( ! this.geometry.animations ) this.geometry.animations = {};
164 |
165 | this.geometry.animations[ label ] = { start: start, end: end };
166 |
167 | };
168 | /**
169 | * @desc 根据动画的标签名(参数lab)按照指定的速度(参数fps)播放动画
170 | * @param {string} label 动画名称
171 | * @param {number} fps 帧率
172 | */
173 | THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) {
174 |
175 | var animation = this.geometry.animations[ label ];
176 |
177 | if ( animation ) {
178 |
179 | this.setFrameRange( animation.start, animation.end );
180 | this.duration = 1000 * ( ( animation.end - animation.start ) / fps );
181 | this.time = 0;
182 |
183 | } else {
184 |
185 | console.warn( 'animation[' + label + '] undefined' );
186 |
187 | }
188 |
189 | };
190 | /**
191 | * @desc 根据当前时钟频率生成补间动画
192 | * @param {number} delta 时钟频率
193 | */
194 | THREE.MorphAnimMesh.prototype.updateAnimation = function ( delta ) {
195 |
196 | var frameTime = this.duration / this.length;
197 |
198 | this.time += this.direction * delta;
199 |
200 | if ( this.mirroredLoop ) {
201 |
202 | if ( this.time > this.duration || this.time < 0 ) {
203 |
204 | this.direction *= - 1;
205 |
206 | if ( this.time > this.duration ) {
207 |
208 | this.time = this.duration;
209 | this.directionBackwards = true;
210 |
211 | }
212 |
213 | if ( this.time < 0 ) {
214 |
215 | this.time = 0;
216 | this.directionBackwards = false;
217 |
218 | }
219 |
220 | }
221 |
222 | } else {
223 |
224 | this.time = this.time % this.duration;
225 |
226 | if ( this.time < 0 ) this.time += this.duration;
227 |
228 | }
229 |
230 | var keyframe = this.startKeyframe + THREE.Math.clamp( Math.floor( this.time / frameTime ), 0, this.length - 1 );
231 |
232 | if ( keyframe !== this.currentKeyframe ) {
233 |
234 | this.morphTargetInfluences[ this.lastKeyframe ] = 0;
235 | this.morphTargetInfluences[ this.currentKeyframe ] = 1;
236 |
237 | this.morphTargetInfluences[ keyframe ] = 0;
238 |
239 | this.lastKeyframe = this.currentKeyframe;
240 | this.currentKeyframe = keyframe;
241 |
242 | }
243 |
244 | var mix = ( this.time % frameTime ) / frameTime;
245 |
246 | if ( this.directionBackwards ) {
247 |
248 | mix = 1 - mix;
249 |
250 | }
251 |
252 | this.morphTargetInfluences[ this.currentKeyframe ] = mix;
253 | this.morphTargetInfluences[ this.lastKeyframe ] = 1 - mix;
254 |
255 | };
256 | /**
257 | * @desc 根据变形幅度t将morphTaInfluences[a]设置为1-t,morphTaInfluences[b]设置为t.
258 | * @param {number} a 节点a
259 | * @param {number} b 节点b
260 | * @param {float} t 变形幅度
261 | */
262 | THREE.MorphAnimMesh.prototype.interpolateTargets = function ( a, b, t ) {
263 |
264 | var influences = this.morphTargetInfluences;
265 |
266 | for ( var i = 0, l = influences.length; i < l; i ++ ) {
267 |
268 | influences[ i ] = 0;
269 |
270 | }
271 |
272 | if ( a > -1 ) influences[ a ] = 1 - t;
273 | if ( b > -1 ) influences[ b ] = t;
274 |
275 | };
276 | /**
277 | * @desc Three.MorphAnimMesh 克隆函数
278 | * @param {THREE.MorphAnimMesh} object
279 | * @returns {THREE.MorphAnimMesh}
280 | */
281 | THREE.MorphAnimMesh.prototype.clone = function ( object ) {
282 |
283 | if ( object === undefined ) object = new THREE.MorphAnimMesh( this.geometry, this.material );
284 |
285 | object.duration = this.duration;
286 | object.mirroredLoop = this.mirroredLoop;
287 | object.time = this.time;
288 |
289 | object.lastKeyframe = this.lastKeyframe;
290 | object.currentKeyframe = this.currentKeyframe;
291 |
292 | object.direction = this.direction;
293 | object.directionBackwards = this.directionBackwards;
294 |
295 | THREE.Mesh.prototype.clone.call( this, object );
296 |
297 | return object;
298 |
299 | };
300 |
--------------------------------------------------------------------------------
/math/Box2.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author bhouston / http://exocortex.com
3 | */
4 | /**
5 | * @classdesc 2维矩形类
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @param {THREE.Vector2} min 未定义则为无穷大
8 | * @param {THREE.Vector2} max 未定义则为无穷小
9 | * @constructor
10 | */
11 | THREE.Box2 = function ( min, max ) {
12 | /**
13 | * @desc 最小值
14 | * @default ( Infinity, Infinity )
15 | * @type {THREE.Vector2}
16 | */
17 | this.min = ( min !== undefined ) ? min : new THREE.Vector2( Infinity, Infinity );
18 | /**
19 | * @desc 最大值
20 | * @default ( - Infinity, - Infinity )
21 | * @type {THREE.Vector2}
22 | */
23 | this.max = ( max !== undefined ) ? max : new THREE.Vector2( - Infinity, - Infinity );
24 |
25 | };
26 |
27 | THREE.Box2.prototype = {
28 |
29 | constructor: THREE.Box2,
30 | /**
31 | * @desc 设置2维矩形
32 | * @param {THREE.Vector2} min
33 | * @param {THREE.Vector2} max
34 | * @returns {THREE.Box2}
35 | */
36 | set: function ( min, max ) {
37 |
38 | this.min.copy( min );
39 | this.max.copy( max );
40 |
41 | return this;
42 |
43 | },
44 | /**
45 | * @desc 2维坐标数组的外包围盒
46 | * @param {THREE.Vector2[]}points
47 | * @returns {THREE.Box2}
48 | */
49 | setFromPoints: function ( points ) {
50 |
51 | this.makeEmpty();
52 |
53 | for ( var i = 0, il = points.length; i < il; i ++ ) {
54 |
55 | this.expandByPoint( points[ i ] )
56 |
57 | }
58 |
59 | return this;
60 |
61 | },
62 | /**
63 | * @function
64 | * @desc 由中心点和边长设置2维矩形
65 | * @param {THREE.Vector2} center 中心点
66 | * @param {float} size 边长
67 | * @returns {THREE.Box2}
68 | */
69 | setFromCenterAndSize: function () {
70 |
71 | var v1 = new THREE.Vector2();
72 |
73 | return function ( center, size ) {
74 |
75 | var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
76 | this.min.copy( center ).sub( halfSize );
77 | this.max.copy( center ).add( halfSize );
78 |
79 | return this;
80 |
81 | };
82 |
83 | }(),
84 | /**
85 | * @desc 拷贝2维矩形
86 | * @param {THREE.Box2} box
87 | * @returns {THREE.Box2}
88 | */
89 | copy: function ( box ) {
90 |
91 | this.min.copy( box.min );
92 | this.max.copy( box.max );
93 |
94 | return this;
95 |
96 | },
97 | /**
98 | * @desc 设置无效2维矩形
99 | * @returns {THREE.Box2}
100 | */
101 | makeEmpty: function () {
102 |
103 | this.min.x = this.min.y = Infinity;
104 | this.max.x = this.max.y = - Infinity;
105 |
106 | return this;
107 |
108 | },
109 | /**
110 | * @desc 是否是无效2维矩形
111 | * @returns {boolean}
112 | */
113 | empty: function () {
114 |
115 | // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
116 |
117 | return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );
118 |
119 | },
120 | /**
121 | * @desc 获得2维矩形中心点
122 | * @param {THREE.Vector2} optionalTarget
123 | * @returns {THREE.Vector2}
124 | */
125 | center: function ( optionalTarget ) {
126 |
127 | var result = optionalTarget || new THREE.Vector2();
128 | return result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
129 |
130 | },
131 | /**
132 | * @desc 获得2维矩形边界尺寸向量
133 | * @param {THREE.Vector2} optionalTarget
134 | * @returns {THREE.Vector2}
135 | */
136 | size: function ( optionalTarget ) {
137 |
138 | var result = optionalTarget || new THREE.Vector2();
139 | return result.subVectors( this.max, this.min );
140 |
141 | },
142 | /**
143 | * @desc 通过vector2对象(point参数)扩展二维矩形边界的最小值,最大值
144 | * @param {THREE.Vector2} point
145 | * @returns {THREE.Box2}
146 | */
147 | expandByPoint: function ( point ) {
148 |
149 | this.min.min( point );
150 | this.max.max( point );
151 |
152 | return this;
153 | },
154 | /**
155 | * @desc 通过Vector2对象(vector参数)扩展二维矩形边界的最小值,最大值
156 | * @param {THREE.Vector2} vector
157 | * @returns {THREE.Box2}
158 | */
159 | expandByVector: function ( vector ) {
160 |
161 | this.min.sub( vector );
162 | this.max.add( vector );
163 |
164 | return this;
165 | },
166 | /**
167 | * @desc 通过scalar值(scalar参数)扩展二维矩形边界的最小值,最大值
168 | * @param {float} scalar
169 | * @returns {THREE.Box2}
170 | */
171 | expandByScalar: function ( scalar ) {
172 |
173 | this.min.addScalar( - scalar );
174 | this.max.addScalar( scalar );
175 |
176 | return this;
177 | },
178 | /**
179 | * @desc 判断点是否在2维矩形内
180 | * @param {THREE.Vector2} point
181 | * @returns {boolean}
182 | */
183 | containsPoint: function ( point ) {
184 |
185 | if ( point.x < this.min.x || point.x > this.max.x ||
186 | point.y < this.min.y || point.y > this.max.y ) {
187 |
188 | return false;
189 |
190 | }
191 |
192 | return true;
193 |
194 | },
195 | /**
196 | * @desc 判断box是否在当前2维矩形内
197 | * @param {THREE.Box2} box
198 | * @returns {boolean}
199 | */
200 | containsBox: function ( box ) {
201 |
202 | if ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&
203 | ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) ) {
204 |
205 | return true;
206 |
207 | }
208 |
209 | return false;
210 |
211 | },
212 | /**
213 | * @desc 获得参数point(一个Vector2的二维点坐标)在当前二维矩形边界的高宽比
214 | * @param {THREE.Vector2} point
215 | * @param {THREE.Vector2} optionalTarget
216 | * @returns {THREE.Vector2}
217 | */
218 | getParameter: function ( point, optionalTarget ) {
219 |
220 | // This can potentially have a divide by zero if the box
221 | // has a size dimension of 0.
222 |
223 | var result = optionalTarget || new THREE.Vector2();
224 |
225 | return result.set(
226 | ( point.x - this.min.x ) / ( this.max.x - this.min.x ),
227 | ( point.y - this.min.y ) / ( this.max.y - this.min.y )
228 | );
229 |
230 | },
231 | /**
232 | * @desc 判断box是否和当前2维矩形相交
233 | * @param {THREE.Box2} box
234 | * @returns {boolean}
235 | */
236 | isIntersectionBox: function ( box ) {
237 |
238 | // using 6 splitting planes to rule out intersections.
239 |
240 | if ( box.max.x < this.min.x || box.min.x > this.max.x ||
241 | box.max.y < this.min.y || box.min.y > this.max.y ) {
242 |
243 | return false;
244 |
245 | }
246 |
247 | return true;
248 |
249 | },
250 | /**
251 | * @desc 限制参数point在二维矩形边界内.如果point小于min,返回min,如果大于max返回max,否则返回point
252 | * @param {THREE.Vector2} point
253 | * @param {THREE.Vector2} optionalTarget
254 | * @returns {THREE.Vector2}
255 | */
256 | clampPoint: function ( point, optionalTarget ) {
257 |
258 | var result = optionalTarget || new THREE.Vector2();
259 | return result.copy( point ).clamp( this.min, this.max );
260 |
261 | },
262 | /**
263 | * @function
264 | * @desc 边界内一点到最小边界,最大边界的长度
265 | * @param {THREE.Vector2} point
266 | * @return {THREE.Vector2}
267 | */
268 | distanceToPoint: function () {
269 |
270 | var v1 = new THREE.Vector2();
271 |
272 | return function ( point ) {
273 |
274 | var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
275 | return clampedPoint.sub( point ).length();
276 |
277 | };
278 |
279 | }(),
280 |
281 | /**
282 | * @desc 获取box和当前box的相交矩形
283 | * @param {THREE.Box2} box
284 | * @returns {THREE.Box2}
285 | */
286 | intersect: function ( box ) {
287 |
288 | this.min.max( box.min );
289 | this.max.min( box.max );
290 |
291 | return this;
292 |
293 | },
294 |
295 | /**
296 | * @desc 获取box和当前box的相并矩形
297 | * @param {THREE.Box2} box
298 | * @returns {THREE.Box2}
299 | */
300 | union: function ( box ) {
301 |
302 | this.min.min( box.min );
303 | this.max.max( box.max );
304 |
305 | return this;
306 |
307 | },
308 | /**
309 | * @desc 2维矩形的平移
310 | * @param {float} offset
311 | * @returns {THREE.Box2}
312 | */
313 | translate: function ( offset ) {
314 |
315 | this.min.add( offset );
316 | this.max.add( offset );
317 |
318 | return this;
319 |
320 | },
321 |
322 | /**
323 | * @desc 判断box和当前2维矩形是否相等
324 | * @param {THREE.Box2} box
325 | * @returns {boolean}
326 | */
327 | equals: function ( box ) {
328 |
329 | return box.min.equals( this.min ) && box.max.equals( this.max );
330 |
331 | },
332 | /**
333 | * @desc 克隆当前2维矩形
334 | * @returns {THREE.Box2}
335 | */
336 | clone: function () {
337 |
338 | return new THREE.Box2().copy( this );
339 |
340 | }
341 |
342 | };
343 |
--------------------------------------------------------------------------------
/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 | * 注释内容部分参照 http://blog.csdn.net/omni360
52 | * @desc mesh(网格)的phong(冯氏)高光材质类型
53 | * 表面有光泽的材质类型,计算每个像素
54 | * @param {String} parameters 材质参数
55 | * @extends {THREE.Material}
56 | * @constructor
57 | */
58 | THREE.MeshPhongMaterial = function ( parameters ) {
59 |
60 | THREE.Material.call( this );
61 | /**
62 | * @default 'MeshPhongMaterial'
63 | * @type {string}
64 | */
65 | this.type = 'MeshPhongMaterial';
66 |
67 | /**
68 | * @desc 材质颜色
69 | * @default 0xffffff 白色
70 | * @type {THREE.Color}
71 | */
72 | this.color = new THREE.Color( 0xffffff ); // diffuse
73 | /**
74 | * @desc 环境色
75 | * @default 0xffffff 白色
76 | * @type {THREE.Color}
77 | */
78 | this.ambient = new THREE.Color( 0xffffff );
79 | /**
80 | * @desc 自发光(荧光)颜色
81 | * @default 0x000000 黑色
82 | * @type {THREE.Color}
83 | */
84 | this.emissive = new THREE.Color( 0x000000 );
85 | /**
86 | * @desc 高光色
87 | * 默认初始化为0x111111,灰色, 材质发光区域的颜色,
88 | * 比如设置为漫射颜色,亮度加大,材质更像金属,
89 | * 设成灰色,使材质更像塑料.默认是灰色的.
90 | * @default 0x111111 灰色
91 | * @type {THREE.Color}
92 | */
93 | this.specular = new THREE.Color( 0x111111 );
94 | /**
95 | * @desc 高光的强度,数值越大,高光呈现出一个亮点.
96 | * @default
97 | * @type {number}
98 | */
99 | this.shininess = 30;
100 | /**
101 | * @desc 是否是金属
102 | * @default
103 | * @type {boolean}
104 | */
105 | this.metal = false;
106 |
107 | /**
108 | * @desc 是否遮罩
109 | * @default
110 | * @type {boolean}
111 | */
112 | this.wrapAround = false;
113 | /**
114 | * @desc 遮罩颜色
115 | * @default ( 1, 1, 1 )
116 | * @type {THREE.Vector3}
117 | */
118 | this.wrapRGB = new THREE.Vector3( 1, 1, 1 );
119 |
120 | /**
121 | * @desc 纹理贴图
122 | * @default
123 | * @type {THREE.Texture}
124 | */
125 | this.map = null;
126 | /**
127 | * @desc 光照贴图
128 | * @default
129 | * @type {THREE.Texture}
130 | */
131 | this.lightMap = null;
132 |
133 | //所谓纯色的凹凸贴图就是如同浮雕效果一样的图像。其颜色与线框色相同。
134 | // 如果按默认色的话则为黑(白)色(即:黑色屏幕时为白色,白色背景时为黑色。)
135 | // 如下面的浮雕效果,就是白色线框绘出的立方体而凹凸贴图的。
136 | /**
137 | * @desc 凹凸贴图
138 | * @default
139 | * @type {THREE.Texture}
140 | */
141 | this.bumpMap = null;
142 | /**
143 | * @desc 凹凸贴图的纹理大小.
144 | * @default
145 | * @type {float}
146 | */
147 | this.bumpScale = 1;
148 | // 法线贴图就是在原物体的凹凸表面的每个点上均作法线,
149 | // 通过RGB颜色通道来标记法线的方向,
150 | // 你可以把它理解成与原凹凸表面平行的另一个不同的表面,
151 | // 但实际上它又只是一个光滑的平面。
152 | // 对于视觉效果而言,它的效率比原有的凹凸表面更高,
153 | // 若在特定位置上应用光源,
154 | // 可以让细节程度较低的表面生成高细节程度的精确光照方向和反射效果。
155 | /**
156 | * @desc 法线贴图
157 | * @default
158 | * @type {THREE.Texture}
159 | */
160 | this.normalMap = null;
161 | /**
162 | * @desc 法线缩放,指定一个数值,将法线贴图与网格大小进行匹配.
163 | * @default ( 1, 1 )
164 | * @type {THREE.Vector2}
165 | */
166 | this.normalScale = new THREE.Vector2( 1, 1 );
167 |
168 | /**
169 | * @desc 高光贴图
170 | * @default
171 | * @type {THREE.Texture}
172 | */
173 | this.specularMap = null;
174 | /**
175 | * @desc 透明贴图
176 | * @default
177 | * @type {THREE.Texture}
178 | */
179 | this.alphaMap = null;
180 | /**
181 | * @desc 环境贴图
182 | * @default
183 | * @type {THREE.Texture}
184 | */
185 | this.envMap = null;
186 | /**
187 | * @desc 材质混合模式
188 | * @default THREE.MultiplyOperation
189 | * @type {number}
190 | */
191 | this.combine = THREE.MultiplyOperation;
192 | /**
193 | * @desc 反射率
194 | * @default
195 | * @type {float}
196 | */
197 | this.reflectivity = 1;
198 | /**
199 | * @desc 折射率
200 | * @default
201 | * @type {float}
202 | */
203 | this.refractionRatio = 0.98;
204 |
205 | /**
206 | * @desc 雾效,默认开启
207 | * @default
208 | * @type {boolean}
209 | */
210 | this.fog = true;
211 |
212 | /**
213 | * @desc 着色方式
214 | * THREE.SmoothShading平滑着色:用多种颜色进行绘制
215 | * 每个顶点都是单独进行处理的,各顶点和各图元之间采用均匀插值。
216 | * @default
217 | * @type {number}
218 | */
219 | this.shading = THREE.SmoothShading;
220 |
221 | /**
222 | * @desc 是否以线框方式渲染几何体
223 | * @default
224 | * @type {boolean}
225 | */
226 | this.wireframe = false;
227 | /**
228 | * @desc 线框宽度
229 | * @default
230 | * @type {float}
231 | */
232 | this.wireframeLinewidth = 1;
233 | /**
234 | * @desc 线框端点类型,参照LineBasicMaterial的定义
235 | * @default 'round'
236 | * @type {string}
237 | */
238 | this.wireframeLinecap = 'round';
239 | /**
240 | * @desc 线框连接类型,参照LineBasicMaterial的定义
241 | * @default 'round'
242 | * @type {string}
243 | */
244 | this.wireframeLinejoin = 'round';
245 |
246 | /**
247 | * @desc 材质顶点颜色
248 | * @default THREE.NoColors
249 | * @type {number}
250 | */
251 | this.vertexColors = THREE.NoColors;
252 |
253 | /**
254 | * @desc 材质是否使用蒙皮
255 | * @default
256 | * @type {boolean}
257 | */
258 | this.skinning = false;
259 | /**
260 | * @desc 材质是否设定目标变形动画
261 | * @default
262 | * @type {boolean}
263 | */
264 | this.morphTargets = false;
265 | /**
266 | * @desc 材质是否反转(变换)法线
267 | * @default
268 | * @type {boolean}
269 | */
270 | this.morphNormals = false;
271 |
272 | this.setValues( parameters );
273 |
274 | };
275 | /**
276 | * @desc MeshPhongMaterial对象从THREE.Material的原型继承所有属性方法
277 | * @type {THREE.Material}
278 | */
279 | THREE.MeshPhongMaterial.prototype = Object.create( THREE.Material.prototype );
280 | /**
281 | * @desc MeshPhongMaterial材质的克隆函数
282 | * @returns {THREE.MeshPhongMaterial}
283 | */
284 | THREE.MeshPhongMaterial.prototype.clone = function () {
285 |
286 | var material = new THREE.MeshPhongMaterial();
287 |
288 | THREE.Material.prototype.clone.call( this, material );
289 |
290 | material.color.copy( this.color );
291 | material.ambient.copy( this.ambient );
292 | material.emissive.copy( this.emissive );
293 | material.specular.copy( this.specular );
294 | material.shininess = this.shininess;
295 |
296 | material.metal = this.metal;
297 |
298 | material.wrapAround = this.wrapAround;
299 | material.wrapRGB.copy( this.wrapRGB );
300 |
301 | material.map = this.map;
302 |
303 | material.lightMap = this.lightMap;
304 |
305 | material.bumpMap = this.bumpMap;
306 | material.bumpScale = this.bumpScale;
307 |
308 | material.normalMap = this.normalMap;
309 | material.normalScale.copy( this.normalScale );
310 |
311 | material.specularMap = this.specularMap;
312 |
313 | material.alphaMap = this.alphaMap;
314 |
315 | material.envMap = this.envMap;
316 | material.combine = this.combine;
317 | material.reflectivity = this.reflectivity;
318 | material.refractionRatio = this.refractionRatio;
319 |
320 | material.fog = this.fog;
321 |
322 | material.shading = this.shading;
323 |
324 | material.wireframe = this.wireframe;
325 | material.wireframeLinewidth = this.wireframeLinewidth;
326 | material.wireframeLinecap = this.wireframeLinecap;
327 | material.wireframeLinejoin = this.wireframeLinejoin;
328 |
329 | material.vertexColors = this.vertexColors;
330 |
331 | material.skinning = this.skinning;
332 | material.morphTargets = this.morphTargets;
333 | material.morphNormals = this.morphNormals;
334 |
335 | return material;
336 |
337 | };
338 |
--------------------------------------------------------------------------------
/math/Plane.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author bhouston / http://exocortex.com
3 | */
4 | /**
5 | * @classdesc 平面类
6 | * 注释内容部分参照 http://blog.csdn.net/omni360
7 | * @desc 法线向量为normal,从原点到平面的距离为constant的无限延展的2维平面对象
8 | * @param {THREE.Vector3} normal 法线向量
9 | * @param {number} constant 原点到平面的距离
10 | * @constructor
11 | */
12 | THREE.Plane = function ( normal, constant ) {
13 | /**
14 | * @desc 平面法线
15 | * @default (1,0,0)
16 | * @type {THREE.Vector3}
17 | */
18 | this.normal = ( normal !== undefined ) ? normal : new THREE.Vector3( 1, 0, 0 );
19 | /**
20 | * @desc 原点到平面的距离
21 | * @default 0
22 | * @type {float}
23 | */
24 | this.constant = ( constant !== undefined ) ? constant : 0;
25 |
26 | };
27 |
28 | THREE.Plane.prototype = {
29 |
30 | constructor: THREE.Plane,
31 | /**
32 | * @desc 根据 normal 和 constant 设置平面
33 | * @param {THREE.Vector3} normal 法线向量
34 | * @param {float} constant 原点到平面的距离
35 | * @returns {THREE.Plane}
36 | */
37 | set: function ( normal, constant ) {
38 |
39 | this.normal.copy( normal );
40 | this.constant = constant;
41 |
42 | return this;
43 |
44 | },
45 | /**
46 | * @desc 过x,y,z,w分量重新设置二维平面
47 | * @param {float} x 平面法线向量x坐标
48 | * @param {float} y 平面法线向量y坐标
49 | * @param {float} z 平面法线向量z坐标
50 | * @param {float} w 二维平面离原点的距离
51 | * @returns {THREE.Plane}
52 | */
53 | setComponents: function ( x, y, z, w ) {
54 |
55 | this.normal.set( x, y, z );
56 | this.constant = w;
57 |
58 | return this;
59 |
60 | },
61 | /**
62 | * @desc 通过参数normal(平面法线向量)和参数point(共面的点)重新设置二维平面
63 | * @param {THREE.Vector3} normal
64 | * @param {THREE.Vector3} point
65 | * @returns {THREE.Plane}
66 | */
67 | setFromNormalAndCoplanarPoint: function ( normal, point ) {
68 |
69 | this.normal.copy( normal );
70 | this.constant = - point.dot( this.normal ); // must be this.normal, not normal, as this.normal is normalized
71 |
72 | return this;
73 |
74 | },
75 |
76 | /**
77 | * @function
78 | * @desc 通过共面的点a,b,c重新设置二维平面
79 | * @param {THREE.Vector3} a
80 | * @param {THREE.Vector3} b
81 | * @param {THREE.Vector3} c
82 | * @returns {THREE.Plane}
83 | */
84 | setFromCoplanarPoints: function () {
85 |
86 | var v1 = new THREE.Vector3();
87 | var v2 = new THREE.Vector3();
88 |
89 | return function ( a, b, c ) {
90 |
91 | var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();
92 |
93 | // Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
94 |
95 | this.setFromNormalAndCoplanarPoint( normal, a );
96 |
97 | return this;
98 |
99 | };
100 |
101 | }(),
102 |
103 | /**
104 | * @desc 二维平面的拷贝
105 | * @param {THREE.Plane} plane
106 | * @returns {THREE.Plane}
107 | */
108 | copy: function ( plane ) {
109 |
110 | this.normal.copy( plane.normal );
111 | this.constant = plane.constant;
112 |
113 | return this;
114 |
115 | },
116 | /**
117 | * @desc 二维平面的单位化
118 | * 几何意义:单位化法线向量,并调整constant常量的值
119 | * @returns {THREE.Plane}
120 | */
121 | normalize: function () {
122 |
123 | // Note: will lead to a divide by zero if the plane is invalid.
124 |
125 | var inverseNormalLength = 1.0 / this.normal.length();
126 | this.normal.multiplyScalar( inverseNormalLength );
127 | this.constant *= inverseNormalLength;
128 |
129 | return this;
130 |
131 | },
132 | /**
133 | * @desc 获得二维平面的负平面
134 | * 几何意义:获得二维平面的背面
135 | * @returns {THREE.Plane}
136 | */
137 | negate: function () {
138 |
139 | this.constant *= - 1;
140 | this.normal.negate();
141 |
142 | return this;
143 |
144 | },
145 | /**
146 | * @desc 三维空间内一点到Plane二维平面对象表面的最小长度.
147 | * 几何意义:点到面上的投影等于从参数point到平面上的垂距
148 | * @param {THREE.Vector3} point
149 | * @returns {float}
150 | */
151 | distanceToPoint: function ( point ) {
152 |
153 | return this.normal.dot( point ) + this.constant;
154 |
155 | },
156 | /**
157 | * @desc 三维空间内球体到Plane二维平面对象表面的最小长度
158 | * 几何意义:球体到面上的投影等于从球体表面到平面上的最小垂距
159 | * @param {THREE.Sphere} sphere
160 | * @returns {float}
161 | */
162 | distanceToSphere: function ( sphere ) {
163 |
164 | return this.distanceToPoint( sphere.center ) - sphere.radius;
165 |
166 | },
167 | /**
168 | * @desc 三维空间中一点到当前平面的投影
169 | * 几何意义:点到面上的投影等于从参数point到平面上的垂足
170 | * @param {THREE.Vector3} point
171 | * @param {THREE.Vector3} optionalTarget
172 | * @returns {THREE.Vector3}
173 | */
174 | projectPoint: function ( point, optionalTarget ) {
175 |
176 | return this.orthoPoint( point, optionalTarget ).sub( point ).negate();
177 |
178 | },
179 |
180 | /**
181 | * @desc 当前二维平面对象法线向量方向相同,与参数point到平面距离相等大小的向量
182 | * 几何意义:点到面上的投影等于从参数point到平面上的垂足向量
183 | * @param {THREE.Vector3} point
184 | * @param {THREE.Vector3} optionalTarget
185 | * @returns {THREE.Vector3}
186 | */
187 | orthoPoint: function ( point, optionalTarget ) {
188 |
189 | var perpendicularMagnitude = this.distanceToPoint( point );
190 |
191 | var result = optionalTarget || new THREE.Vector3();
192 | return result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );
193 |
194 | },
195 | /**
196 | * @desc 当前二维平面是否与参数line相交
197 | * @param {THREE.Line3} line
198 | * @returns {boolean}
199 | */
200 | isIntersectionLine: function ( line ) {
201 |
202 | // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
203 |
204 | var startSign = this.distanceToPoint( line.start );
205 | var endSign = this.distanceToPoint( line.end );
206 |
207 | return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
208 |
209 | },
210 | /**
211 | * @function
212 | * @desc 当前二维平面与参数line相交的交点
213 | * @param {THREE.Line3} line
214 | * @param {THREE.Vector3} optionalTarget
215 | * @return {THREE.Vector3}
216 | */
217 | intersectLine: function () {
218 |
219 | var v1 = new THREE.Vector3();
220 |
221 | return function ( line, optionalTarget ) {
222 |
223 | var result = optionalTarget || new THREE.Vector3();
224 |
225 | var direction = line.delta( v1 );
226 |
227 | var denominator = this.normal.dot( direction );
228 |
229 | if ( denominator == 0 ) {
230 |
231 | // line is coplanar, return origin
232 | if ( this.distanceToPoint( line.start ) == 0 ) {
233 |
234 | return result.copy( line.start );
235 |
236 | }
237 |
238 | // Unsure if this is the correct method to handle this case.
239 | return undefined;
240 |
241 | }
242 |
243 | var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
244 |
245 | if ( t < 0 || t > 1 ) {
246 |
247 | return undefined;
248 |
249 | }
250 |
251 | return result.copy( direction ).multiplyScalar( t ).add( line.start );
252 |
253 | };
254 |
255 | }(),
256 |
257 | /**
258 | * @desc 当前二维平面的法线向量到当前二维平面投影点
259 | * @param {THREE.Vector3} optionalTarget
260 | * @returns {THREE.Vector3}
261 | */
262 | coplanarPoint: function ( optionalTarget ) {
263 |
264 | var result = optionalTarget || new THREE.Vector3();
265 | return result.copy( this.normal ).multiplyScalar( - this.constant );
266 |
267 | },
268 | /**
269 | * @function
270 | * @desc 通过传递matrix(旋转,缩放,移动等变换矩阵)对当前Plane二维平面对象的法线向量normal和,应用变换.
271 | * @param {THREE.Matrix4} matrix
272 | * @param {THREE.Matrix4} optionalNormalMatrix 若设置了,可以对法线变换
273 | * @return {THREE.Plane}
274 | */
275 | applyMatrix4: function () {
276 |
277 | var v1 = new THREE.Vector3();
278 | var v2 = new THREE.Vector3();
279 | var m1 = new THREE.Matrix3();
280 |
281 | return function ( matrix, optionalNormalMatrix ) {
282 |
283 | // compute new normal based on theory here:
284 | // http://www.songho.ca/opengl/gl_normaltransform.html
285 | var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );
286 | var newNormal = v1.copy( this.normal ).applyMatrix3( normalMatrix );
287 |
288 | var newCoplanarPoint = this.coplanarPoint( v2 );
289 | newCoplanarPoint.applyMatrix4( matrix );
290 |
291 | this.setFromNormalAndCoplanarPoint( newNormal, newCoplanarPoint );
292 |
293 | return this;
294 |
295 | };
296 |
297 | }(),
298 |
299 | /**
300 | * @desc 移动当前二维平面的位置
301 | * @param {THREE.Vector3} offset
302 | * @returns {THREE.Plane}
303 | */
304 | translate: function ( offset ) {
305 |
306 | this.constant = this.constant - offset.dot( this.normal );
307 |
308 | return this;
309 |
310 | },
311 | /**
312 | * @desc 判断二维平面是否相等
313 | * @param plane
314 | * @returns {boolean}
315 | */
316 | equals: function ( plane ) {
317 |
318 | return plane.normal.equals( this.normal ) && ( plane.constant == this.constant );
319 |
320 | },
321 | /**
322 | * @desc 克隆二维平面
323 | * @returns {THREE.Plane}
324 | */
325 | clone: function () {
326 |
327 | return new THREE.Plane().copy( this );
328 |
329 | }
330 |
331 | };
332 |
--------------------------------------------------------------------------------