1 /** 2 * Hilo 3 * Copyright 2015 alibaba.com 4 * Licensed under the MIT License 5 */ 6 7 /** 8 * @class Camera3d 伪3D虚拟摄像机。 9 * @module hilo/game/Camera3d 10 * @requires hilo/core/Hilo 11 * @requires hilo/core/Class 12 * @property {Number} fv 镜头视点距离(屏幕视点相对眼睛距离,绝对了坐标缩放比例) 13 * @property {Number} fx 镜头视点X(屏幕视点相对屏幕左上角X距离) 14 * @property {Number} fy 镜头视点Y(屏幕视点相对屏幕左上角Y距离) 15 * @property {Object} stage 3D对象所在容器,可以是stage或container,结合ticker时是必须参数,用来Z深度排序 16 * @property {Number} x 镜头三维坐标x 17 * @property {Number} y 镜头三维坐标y 18 * @property {Number} z 镜头三维坐标z 19 * @property {Number} rotationX X轴旋转角度 20 * @property {Number} rotationY Y轴旋转角度 21 * @property {Number} rotationZ Z轴旋转角度 22 */ 23 var Camera3d = (function(){ 24 25 var degtorad = Math.PI / 180; 26 27 //向量旋转 28 function rotateX(x, y, z, ca, sa) {//绕X轴旋转 29 return { 30 x: x, 31 y: y * ca - z * sa, 32 z: y * sa + z * ca 33 }; 34 } 35 function rotateY(x, y, z, ca, sa) {//绕Y轴旋转 36 return { 37 x: x * ca - z * sa, 38 y: y, 39 z: x * sa + z * ca 40 }; 41 } 42 function rotateZ(x, y, z, ca, sa) {//绕Z轴旋转 43 return { 44 x: x * ca - y * sa, 45 y: x * sa + y * ca, 46 z: z 47 }; 48 } 49 50 var Camera3d = Class.create(/** @lends Camera3d.prototype */{ 51 52 constructor: function(properties){ 53 properties.x = properties.x || 0; 54 properties.y = properties.y || 0; 55 properties.z = properties.z || 0; 56 properties.rotationX = properties.rotationX || 0; 57 properties.rotationY = properties.rotationY || 0; 58 properties.rotationZ = properties.rotationZ || 0; 59 60 Hilo.copy(this, properties); 61 }, 62 63 /** 64 * 仿射矩阵位移变换,不同于直接修改Camera3d.x/y/z. 是在Camera3d依次做坐标位移 - 旋转变换 后,再加上一个位移变换。主要功能可以做Zoomin/out 功能 65 * @param {Number} x坐标 66 * @param {Number} y坐标 67 * @param {Number} z坐标 68 */ 69 translate : function(x,y,z){ 70 this.tx = x; 71 this.ty = y; 72 this.tz = z; 73 }, 74 75 /** 76 * 旋转X轴方向角度,相当于欧拉角系统的 beta 77 * @param {Number} X旋转角度 78 */ 79 rotateX : function(angle){ 80 this.rotationX = angle; 81 }, 82 83 /** 84 * 旋转Y轴方向角度,相当于欧拉角系统的 gamma 85 * @param {Number} Y旋转角度 86 */ 87 rotateY : function(angle){ 88 this.rotationY = angle; 89 }, 90 91 /** 92 * 旋转Z轴方向角度,相当于欧拉角系统的 alpha 93 * @param {Number} Z旋转角度 94 */ 95 rotateZ : function(angle){ 96 this.rotationZ = angle; 97 }, 98 99 /** 100 * 将三维坐标转换投影为二维坐标,同时返回Z轴深度,和投影显示的缩放比例 101 * @param {object} 三维坐标对象 102 * @param {object} Hilo.View对象,用于自动转换坐标 103 */ 104 project : function(vector3D, view){ 105 106 var rx = this.rotationX * degtorad, 107 ry = this.rotationY * degtorad, 108 rz = this.rotationZ * degtorad, 109 110 cosX = Math.cos(rx), sinX = Math.sin(rx), 111 cosY = Math.cos(ry), sinY = Math.sin(ry), 112 cosZ = Math.cos(rz), sinZ = Math.sin(rz), 113 114 // 旋转变换前的 仿射矩阵位移, 115 dx = vector3D.x - this.x, 116 dy = vector3D.y - this.y, 117 dz = vector3D.z - this.z, 118 119 // 旋转矩阵变换 120 vector = rotateZ(dx, dy, dz, cosZ, sinZ); 121 vector = rotateY(vector.x, vector.y, vector.z, cosY, sinY); 122 vector = rotateX(vector.x, vector.y, vector.z, cosX, sinX); 123 124 // 最后的仿射矩阵变换 125 if(this.tx) vector.x -= this.tx; 126 if(this.ty) vector.y -= this.ty; 127 if(this.tz) vector.z -= this.tz; 128 129 var perspective = this.fv / (this.fv + vector.z), 130 _x = vector.x * perspective, 131 _y = -vector.y * perspective; 132 133 if(view) { 134 view.x = _x + this.fx; 135 view.y = _y + this.fy; 136 view.z = -vector.z; 137 view.scaleX = perspective; 138 view.scaleY = perspective; 139 } else { 140 return { 141 x : _x + this.fx, 142 y : _y + this.fy, 143 z : -vector.z, 144 scale : perspective 145 }; 146 } 147 }, 148 149 /** 150 * Z深度排序 151 */ 152 sortZ : function(){ 153 this.stage.children.sort(function(view_a, view_b){ 154 return view_a.z > view_b.z; 155 }); 156 }, 157 158 /** 159 * Ticker 轮询使用 160 */ 161 tick : function(){ 162 this.sortZ(); 163 } 164 165 }); 166 167 return Camera3d; 168 169 })();