433 lines
12 KiB
Markdown
433 lines
12 KiB
Markdown
3D基本变换
|
||
===============
|
||
|
||
## 3D矩阵(Matrix4_4) ##
|
||
|
||
* Matrix4_4 类表示一个转换矩阵,该矩阵描述了三维 (3D) 显示对象的缩放/旋转/位移
|
||
* 该矩阵可以追加转换功能,包括缩放/旋转/位移
|
||
* Matrix4_4 类可用于视锥投影,这会将 3D 坐标空间中的点映射到二维 (2D) 视图,常用有透视投影和正交投影
|
||
* 单一矩阵可以将多个转换组合在一起,并一次性对 3D 显示对象应用这些转换
|
||
* 例如,可以将一个矩阵应用于 3D 坐标,以便依次执行旋转和平移
|
||
|
||
---------
|
||
|
||
* lookAt:从3D坐标点A观察坐标点B,设定观察视角的正上方,获得满足这个条件的矩阵
|
||
* 可以用于控制相机或者显示对象的方向,使面向目标
|
||
* egret3d.Camera3D和egret3d.Object3D已经封装过该函数,你只需要调用camera3D.lookAt()或者object3D.lookAt()
|
||
|
||
----------
|
||
|
||
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
var eyePosition: egret3d.Vector3D = new egret3d.Vector3D(0, 0, 0);
|
||
var atPosition: egret3d.Vector3D = new egret3d.Vector3D(100, 20, 40);
|
||
matrix.lookAt(eyePosition, atPosition, egret3d.Vector3D.Y_AXIS);
|
||
|
||
//matrix
|
||
//[0] 0.3713906705379486 Number
|
||
//[1] -0.16951587796211243 Number
|
||
//[2] 0.9128709435462952 Number
|
||
//[3] 0 Number
|
||
//[4] 0 Number
|
||
//[5] 0.9831920862197876 Number
|
||
//[6] 0.18257418274879455 Number
|
||
//[7] 0 Number
|
||
//[8] -0.9284766912460327 Number
|
||
//[9] -0.06780634820461273 Number
|
||
//[10] 0.3651483654975891 Number
|
||
//[11] 0 Number
|
||
//[12] 0 Number
|
||
//[13] 0 Number
|
||
//[14] 0 Number
|
||
//[15] 1 Number
|
||
|
||
----------
|
||
|
||
* multiply:矩阵相乘
|
||
* 矩阵A和矩阵B相乘的得到矩阵C
|
||
* 一个3D对象,先使用矩阵A进行转换,然后用矩阵B进行转换,其结果与直接用C矩阵转换是等价的操作
|
||
* 注意前乘和后乘的区别,矩阵相乘不满足交换律
|
||
|
||
----------
|
||
|
||
var matrix1: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
var matrix2: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
matrix1.multiply(matrix2);
|
||
|
||
----------
|
||
|
||
* perspective:生成一个透视投影矩阵
|
||
* 通过设定视锥体的空间数据,包括远近裁剪面距离/观察范围夹角/屏幕横纵比,获得矩阵
|
||
* egret3d.Camera3D封装有该矩阵的方法调用,通过设定CameraType即可自动构造透视投影矩阵
|
||
* 3D场景渲染中会使用到该功能
|
||
|
||
----------
|
||
|
||
var projectMatrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
var fovY:number = 60;
|
||
var aspectRatio:number = 3/4;
|
||
var near:number = 1;
|
||
var far:number = 10000;
|
||
//构造透视投影矩阵
|
||
projectMatrix.perspective(fovY, aspectRatio, near, far);
|
||
|
||
----------
|
||
|
||
* ortho:生成一个正交投影矩阵
|
||
* 通过设定视锥体的空间数据,包括远近裁剪面距离/屏幕宽度和高度
|
||
* egret3d.Camera3D封装有该矩阵的方法调用,通过设定CameraType即可自动构造正交投影矩阵
|
||
* GUI和HUD的渲染会使用到该功能
|
||
|
||
----------
|
||
|
||
var projectMatrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
var width:number = 1024;
|
||
var height:number = 768;
|
||
var near:number = 1;
|
||
var far:number = 10000;
|
||
//构造正交投影矩阵
|
||
projectMatrix.ortho(fovY, aspectRatio, near, far);
|
||
|
||
----------
|
||
|
||
* fromToRotation:获得一个矩阵,使他能够将A向量变换成B向量
|
||
|
||
----------
|
||
|
||
var matrix:egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
var direction1:egret3d.Vector3D = new egret3d.Vector3D(-1,0,2,1);
|
||
var direction2:egret3d.Vector3D = new egret3d.Vector3D(10,5,1,1);
|
||
direction1.normalize();
|
||
direction2.normalize();
|
||
//求出模型矩阵
|
||
matrix.fromToRotation(direction1, direction2);
|
||
|
||
---------
|
||
|
||
|
||
* append:矩阵前乘
|
||
* 与multiply相同
|
||
|
||
----------
|
||
|
||
var matrix1: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
var matrix2: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
matrix1.append(matrix2);
|
||
|
||
----------
|
||
|
||
* appendRotation:获得一个矩阵,该矩阵描述着绕设定的旋转轴旋转一定的角度
|
||
|
||
----------
|
||
|
||
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
var axis: egret3d.Vector3D = new egret3d.Vector3D(1, -1, 10, 1);
|
||
axis.normalize();
|
||
//围绕axis指定的方向,旋转45度角
|
||
matrix.appendRotation(45, axis);
|
||
|
||
----------
|
||
|
||
* appendScale:追加三轴缩放值
|
||
* 将当前的矩阵追加xyz三个方向缩放值
|
||
|
||
----------
|
||
|
||
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
var scaleX:number = 0.5;
|
||
var scaleY:number = 1.5;
|
||
var scaleZ:number = 2.5;
|
||
//X Y Z 方向分别缩放 0.5 1.5 2.5
|
||
matrix.appendScale(scaleX, scaleY, scaleZ);
|
||
|
||
//matrix
|
||
//[0] 0.5 Number
|
||
//[1] 0 Number
|
||
//[2] 0 Number
|
||
//[3] 0 Number
|
||
//[4] 0 Number
|
||
//[5] 1.5 Number
|
||
//[6] 0 Number
|
||
//[7] 0 Number
|
||
//[8] 0 Number
|
||
//[9] 0 Number
|
||
//[10] 2.5 Number
|
||
//[11] 0 Number
|
||
//[12] 0 Number
|
||
//[13] 0 Number
|
||
//[14] 0 Number
|
||
//[15] 1 Number
|
||
|
||
----------
|
||
|
||
* appendTranslation:追加平移数据
|
||
* 将当前的矩阵追加xyz三个方向平移数据
|
||
|
||
----------
|
||
|
||
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
var offsetX:number = 0.5;
|
||
var offsetY:number = 1.5;
|
||
var offsetZ:number = 2.5;
|
||
//X Y Z 方向分别平移 0.5 1.5 2.5
|
||
matrix.appendTranslation(offsetX, offsetY, offsetZ);
|
||
|
||
//matrix
|
||
//[0] 1 Number
|
||
//[1] 0 Number
|
||
//[2] 0 Number
|
||
//[3] 0 Number
|
||
//[4] 0 Number
|
||
//[5] 1 Number
|
||
//[6] 0 Number
|
||
//[7] 0 Number
|
||
//[8] 0 Number
|
||
//[9] 0 Number
|
||
//[10] 1 Number
|
||
//[11] 0 Number
|
||
//[12] 0.5 Number
|
||
//[13] 1.5 Number
|
||
//[14] 2.5 Number
|
||
//[15] 1 Number
|
||
|
||
----------
|
||
|
||
|
||
* decompose:分解一个矩阵,获得缩放/平移/旋转数据
|
||
* 分解得出的结果为egret3D.Vector3D的数组中,长度为3.其中第一个记录平移数据,第二个记录旋转数据,第三个记录缩放数据
|
||
* 需要指定旋转数据格式,请参照egret3d.Orientation3D中枚举出的3个值
|
||
|
||
----------
|
||
|
||
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
|
||
var offsetX:number = 0.2;
|
||
var offsetY:number = 0.4;
|
||
var offsetZ:number = 0.6;
|
||
//X Y Z 方向分别平移 0.2 0.4 0.6
|
||
matrix.appendTranslation(offsetX, offsetY, offsetZ);
|
||
|
||
var scaleX:number = 0.5;
|
||
var scaleY:number = 1.5;
|
||
var scaleZ:number = 2.5;
|
||
//X Y Z 方向分别缩放 0.5 1.5 2.5
|
||
matrix.appendScale(scaleX, scaleY, scaleZ);
|
||
|
||
var axis: egret3d.Vector3D = new egret3d.Vector3D(1, -1, 10, 1);
|
||
axis.normalize();
|
||
//围绕axis指定的方向,旋转45度角
|
||
matrix.appendRotation(45, axis);
|
||
|
||
//拆分矩阵
|
||
var result:egret3d.Vector3D[] = matrix.decompose(egret3d.Orientation3D.QUATERNION);
|
||
var pos:egret3d.Vector3D = result[0];
|
||
var rot:egret3d.Vector3D = result[1];
|
||
var scale:egret3d.Vector3D = result[2];
|
||
|
||
//<-0.41275760531425476, 0.34762030839920044, 1.5260378122329712>
|
||
//<0.03789130620377082, -0.037891307211827124, 0.37891307413438385, 0.9238795211721623>
|
||
//<0.5000000018751693, 1.5000000284558414, 2.49999994435313>
|
||
|
||
|
||
----------
|
||
|
||
* deltaTransformVector:按照该矩阵所包含的旋转信息,变换另外一个向量
|
||
* 向量没有平移信息
|
||
|
||
----------
|
||
|
||
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
|
||
var offsetX:number = 0.2;
|
||
var offsetY:number = 0.4;
|
||
var offsetZ:number = 0.6;
|
||
//X Y Z 方向分别平移 0.2 0.4 0.6
|
||
matrix.appendTranslation(offsetX, offsetY, offsetZ);
|
||
|
||
var scaleX:number = 0.5;
|
||
var scaleY:number = 1.5;
|
||
var scaleZ:number = 2.5;
|
||
//X Y Z 方向分别缩放 0.5 1.5 2.5
|
||
matrix.appendScale(scaleX, scaleY, scaleZ);
|
||
|
||
var axis: egret3d.Vector3D = new egret3d.Vector3D(1, -1, 10, 1);
|
||
axis.normalize();
|
||
//围绕axis指定的方向,旋转45度角
|
||
matrix.appendRotation(45, axis);
|
||
|
||
//给定原向量
|
||
var direction:egret3d.Vector3D = new egret3d.Vector3D(10, 10, -5, 1);
|
||
direction.normalize();
|
||
|
||
matrix.deltaTransformVector(direction, direction);
|
||
|
||
//w 0 Number
|
||
//x -0.43193634599447245 Number
|
||
//y 1.024675299723943 Number
|
||
//z -0.75433882077535 Number
|
||
|
||
----------
|
||
|
||
* transformVector:使用当前矩阵变换另外一个位置点
|
||
* 初始位置被变换之后,得到的结果为按照当前矩阵所给定的数据获得的新位置
|
||
* 坐标数据不包含缩放/旋转信息
|
||
|
||
----------
|
||
|
||
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
|
||
var offsetX:number = 0.2;
|
||
var offsetY:number = 0.4;
|
||
var offsetZ:number = 0.6;
|
||
//X Y Z 方向分别平移 0.2 0.4 0.6
|
||
matrix.appendTranslation(offsetX, offsetY, offsetZ);
|
||
|
||
var scaleX:number = 0.5;
|
||
var scaleY:number = 1.5;
|
||
var scaleZ:number = 2.5;
|
||
//X Y Z 方向分别缩放 0.5 1.5 2.5
|
||
matrix.appendScale(scaleX, scaleY, scaleZ);
|
||
|
||
var axis: egret3d.Vector3D = new egret3d.Vector3D(1, -1, 10, 1);
|
||
axis.normalize();
|
||
//围绕axis指定的方向,旋转45度角
|
||
matrix.appendRotation(45, axis);
|
||
|
||
//给定原向量
|
||
var direction:egret3d.Vector3D = new egret3d.Vector3D(10, 10, -5, 1);
|
||
direction.normalize();
|
||
|
||
matrix.transformVector(direction, direction);
|
||
|
||
//w 1 Number
|
||
//x -0.8446939513087273 Number
|
||
//y 1.3722956081231434 Number
|
||
//z 0.7716989914576212 Number
|
||
|
||
----------
|
||
|
||
* invert:获取当前矩阵的逆矩阵
|
||
* 理想状态下,矩阵和逆矩阵的乘积为单位矩阵
|
||
* 不是所有的矩阵都有逆矩阵
|
||
|
||
----------
|
||
|
||
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
|
||
var offsetX:number = 0.2;
|
||
var offsetY:number = 0.4;
|
||
var offsetZ:number = 0.6;
|
||
//X Y Z 方向分别平移 0.2 0.4 0.6
|
||
matrix.appendTranslation(offsetX, offsetY, offsetZ);
|
||
|
||
var scaleX:number = 0.5;
|
||
var scaleY:number = 1.5;
|
||
var scaleZ:number = 2.5;
|
||
//X Y Z 方向分别缩放 0.5 1.5 2.5
|
||
matrix.appendScale(scaleX, scaleY, scaleZ);
|
||
|
||
var axis: egret3d.Vector3D = new egret3d.Vector3D(1, -1, 10, 1);
|
||
axis.normalize();
|
||
//围绕axis指定的方向,旋转45度角
|
||
matrix.appendRotation(45, axis);
|
||
|
||
//给定原向量
|
||
var direction:egret3d.Vector3D = new egret3d.Vector3D(10, 10, -5, 1);
|
||
direction.normalize();
|
||
|
||
var enable:boolean = matrix.invert();
|
||
|
||
//enable : true
|
||
|
||
//[0] 1.4199564456939697 Number
|
||
//[1] -0.46867436170578003 Number
|
||
//[2] -0.016519593074917793 Number
|
||
//[3] 0 Number
|
||
//[4] 1.394537091255188 Number
|
||
//[5] 0.47331884503364563 Number
|
||
//[6] -0.03949161246418953 Number
|
||
//[7] 0 Number
|
||
//[8] 0.19745805859565735 Number
|
||
//[9] 0.027532655745744705 Number
|
||
//[10] 0.39770281314849853 Number
|
||
//[11] 0 Number
|
||
//[12] -0.20000006258487701 Number
|
||
//[13] -0.4000000059604645 Number
|
||
//[14] -0.6000000238418579 Number
|
||
//[15] 1 Number
|
||
|
||
|
||
----------
|
||
|
||
* makeTransform:输入缩放/旋转/位移信息,生成一个矩阵
|
||
* 旋转数据为四元数格式
|
||
|
||
----------
|
||
|
||
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
|
||
var pos:egret3d.Vector3D = new egret3d.Vector3D(0.2, 0.4, 0.6, 1);
|
||
var scale:egret3d.Vector3D = new egret3d.Vector3D(0.5, 1.5, 2.5, 1);
|
||
var rot:egret3d.Quaternion = new egret3d.Quaternion(-1, 2, 10, 1);
|
||
rot.normalize();
|
||
//组装
|
||
matrix.makeTransform(pos, scale, rot);
|
||
|
||
//[0] -0.4811320900917053 Number56939697 Number
|
||
//[1] 0.07547169923782348 Number6170578003 Number
|
||
//[2] -0.11320754885673523 Number93074917793 Number
|
||
//[3] 0 Number
|
||
//[4] -0.3396226465702057 Number1255188 Number
|
||
//[5] -1.3584905862808227 Number503364563 Number
|
||
//[6] 0.5377358198165893 Number1246418953 Number
|
||
//[7] 0 Number
|
||
//[8] -0.37735849618911743 Number859565735 Number
|
||
//[9] 0.9905660152435303 Number5745744705 Number
|
||
//[10] 2.264151096343994 Number314849853 Number
|
||
//[11] 0 Number
|
||
//[12] 0.20000000298023224 Number6258487701 Number
|
||
//[13] 0.4000000059604645 Number059604645 Number
|
||
//[14] 0.6000000238418579 Number238418579 Number
|
||
//[15] 1 Number
|
||
|
||
----------
|
||
|
||
|
||
* recompose:输入缩放/旋转/位移信息,重组矩阵
|
||
* 旋转数据为欧拉角格式
|
||
* 该函数先将欧拉角转化成四元数,然后调用makeTransform方法实现
|
||
|
||
----------
|
||
|
||
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
|
||
var pos:egret3d.Vector3D = new egret3d.Vector3D(0.2, 0.4, 0.6, 1);
|
||
var scale:egret3d.Vector3D = new egret3d.Vector3D(0.5, 1.5, 2.5, 1);
|
||
var rot:egret3d.Vector3D = new egret3d.Vector3D(-1, 2, 10, 1);
|
||
rot.normalize();
|
||
//组装
|
||
matrix.recompose([pos, rot, scale]);
|
||
|
||
----------
|
||
|
||
* transpose:转置一个矩阵,使矩阵按照右上和左下角互换规则交换所有数据
|
||
|
||
----------
|
||
|
||
![](transpose.jpg)
|
||
|
||
----------
|
||
|
||
* lerp:矩阵插值操作
|
||
* 从矩阵A到矩阵B通过输入0-1之间的一个时间作为插值系数,进行平滑插值
|
||
|
||
----------
|
||
|
||
var matrixA: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
var matrixB: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
|
||
var result: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
|
||
var t:number = 0.2;
|
||
result.lerp(matrixA, matrixB, t);
|
||
|
||
----------
|
||
|