/** * Hilo * Copyright 2015 alibaba.com * Licensed under the MIT License */ /** * @class Camera3d 伪3D虚拟摄像机。 * @module hilo/game/Camera3d * @requires hilo/core/Class * @requires hilo/util/util * @property {Number} fv 镜头视点距离(屏幕视点相对眼睛距离,绝对了坐标缩放比例)。 * @property {Number} fx 镜头视点X(屏幕视点相对屏幕左上角X距离)。 * @property {Number} fy 镜头视点Y(屏幕视点相对屏幕左上角Y距离)。 * @property {Object} stage 3D对象所在容器,可以是stage或container,结合ticker时是必须参数,用来Z深度排序。 * @property {Number} x 镜头三维坐标x。 * @property {Number} y 镜头三维坐标y。 * @property {Number} z 镜头三维坐标z。 * @property {Number} rotationX X轴旋转角度。 * @property {Number} rotationY Y轴旋转角度。 * @property {Number} rotationZ Z轴旋转角度。 */ var Camera3d = (function(){ var degtorad = Math.PI / 180; //Rotate the axis. function rotateX(x, y, z, ca, sa) {//rotate x return { x: x, y: y * ca - z * sa, z: y * sa + z * ca }; } function rotateY(x, y, z, ca, sa) {//rotate y return { x: x * ca - z * sa, y: y, z: x * sa + z * ca }; } function rotateZ(x, y, z, ca, sa) {//rotate z return { x: x * ca - y * sa, y: x * sa + y * ca, z: z }; } var Camera3d = Class.create(/** @lends Camera3d.prototype */{ constructor: function(properties){ properties.x = properties.x || 0; properties.y = properties.y || 0; properties.z = properties.z || 0; properties.rotationX = properties.rotationX || 0; properties.rotationY = properties.rotationY || 0; properties.rotationZ = properties.rotationZ || 0; util.copy(this, properties); }, /** * 仿射矩阵位移变换,不同于直接修改Camera3d.x/y/z. 是在Camera3d依次做坐标位移 - 旋转变换 后,再加上一个位移变换。主要功能可以做Zoomin/out 功能 * @param {Number} x x坐标 * @param {Number} y y坐标 * @param {Number} z z坐标 */ translate : function(x,y,z){ this.tx = x; this.ty = y; this.tz = z; }, /** * 旋转X轴方向角度,相当于欧拉角系统的 beta。 * @param {Number} angle 旋转角度。 */ rotateX : function(angle){ this.rotationX = angle; }, /** * 旋转Y轴方向角度,相当于欧拉角系统的 gamma。 * @param {Number} angle 旋转角度。 */ rotateY : function(angle){ this.rotationY = angle; }, /** * 旋转Z轴方向角度,相当于欧拉角系统的 alpha。 * @param {Number} angle 旋转角度。 */ rotateZ : function(angle){ this.rotationZ = angle; }, /** * 将三维坐标转换投影为二维坐标。 * @param {object} vector3D 三维坐标对象,必须含有x, y, z属性。 * @param {View} view Hilo.View对象,用于自动转换坐标。 * @returns {Object} 二维坐标对象,包括缩放和z属性,例子:{x:x, y:y, z:z, scale} */ project : function(vector3D, view){ var rx = this.rotationX * degtorad, ry = this.rotationY * degtorad, rz = this.rotationZ * degtorad, cosX = Math.cos(rx), sinX = Math.sin(rx), cosY = Math.cos(ry), sinY = Math.sin(ry), cosZ = Math.cos(rz), sinZ = Math.sin(rz), // 旋转变换前的 仿射矩阵位移, dx = vector3D.x - this.x, dy = vector3D.y - this.y, dz = vector3D.z - this.z; // 旋转矩阵变换 var vector = rotateZ(dx, dy, dz, cosZ, sinZ); vector = rotateY(vector.x, vector.y, vector.z, cosY, sinY); vector = rotateX(vector.x, vector.y, vector.z, cosX, sinX); // 最后的仿射矩阵变换 if(this.tx) vector.x -= this.tx; if(this.ty) vector.y -= this.ty; if(this.tz) vector.z -= this.tz; var perspective = this.fv / (this.fv + vector.z), _x = vector.x * perspective, _y = -vector.y * perspective; var result = { x : _x + this.fx, y : _y + this.fy, z : -vector.z, scale : perspective }; if(view){ view.x = result.x; view.y = result.y; view.z = result.z; view.scaleX = result.scale; view.scaleY = result.scale; } return result; }, /** * Z深度排序。 */ sortZ : function(){ this.stage.children.sort(function(view_a, view_b){ return view_a.z > view_b.z; }); }, /** * Ticker 轮询使用。 */ tick : function(){ this.sortZ(); } }); return Camera3d; })();