简介
与节点属性相关的几个核心变量_trs、_matrix、_worldMatrix、_localMatDirty、_worldMatDirty。
_trs:存储节点的position、rotation、scale
_matrix:存储节点的缩放、位移、旋转三者合一的变化矩陈(仿射矩陈)
_worldMatrix:存储节点的世界矩陈。本地矩陈与父节点的世界矩陈相乘而来
_localMatDirty:本地脏数据的标记 当你修改position、rotation、scale、anchor时会进行对应的标记。它是个二进制数表示。根据标记更新_matrix。
_worldMatDirty:当你修改节点的position、rotation、scale、anchor属性时 都会标记为true。它是个Boolean值。true 时,会重新计算时间矩阵,并所有子节点的世界矩阵也会标记为脏
这些值的初始化:
Mat4.identity(this._matrix); //单位向量
Mat4.identity(this._worldMatrix);//单位向量
this._localMatDirty = LocalDirtyFlag.ALL;
this._worldMatDirty = true;
let trs = this._trs = spaceInfo.trs;
trs[0] = 0; // position.x
trs[1] = 0; // position.y
trs[2] = 0; // position.z
trs[3] = 0; // rotation.x
trs[4] = 0; // rotation.y
trs[5] = 0; // rotation.z
trs[6] = 1; // rotation.w
trs[7] = 1; // scale.x
trs[8] = 1; // scale.y
trs[9] = 1; // scale.z
position 修改
_trs: 0/1/2 索引的值
_localMatDirty:添加 ALL_POSITION
_worldMatDity:true
_renderFlag:添加 LAG_WORLD_TRANSFORM
scale 修改
_trs: 7/8/9 索引的值
_localMatDirty:添加 ALL_SCALE
_worldMatDity:true
_renderFlag:添加 FLAG_TRANSFORM
rotation 修改
_trs:3/4/5/6 索引的值
_localMatDirty:添加 ALL_ROTATION
_worldMatDity:true
_renderFlag:添加 FLAG_TRANSFORM
特殊值处理
size
size 大小变化时,只更新到临时变量
anchor
_localMatDirty:添加 ALL_POSITION
_worldMatDity:true
_renderFlag:添加 FLAG_WORLD_TRANSFORM
本地矩陈(防射矩陈)
本地矩阵主要描述了节点的位置、旋转、缩放的三者合一的矩阵。一般用于获取节点的世界矩阵,使用本地矩阵乘以父节点的世界矩阵即可获得自己的世界矩阵。二维矩阵(绕z轴旋转)
世界矩陈
世界矩阵是通过本地矩阵乘以父节点的世界矩阵而来。世界矩阵可以把节点的局部坐标转换成世界坐标。
矩阵应用
convertToWorldSpaceAR 将节点坐标系下的一个节点转换成世界坐标系
convertToWorldSpaceAR (nodePoint, out) {
this._updateWorldMatrix(); //更新世界矩阵
if (nodePoint instanceof cc.Vec2) {
out = out || new cc.Vec2();
return Vec2.transformMat4(out, nodePoint, this._worldMatrix);
}
else {
out = out || new cc.Vec3();
return Vec3.transformMat4(out, nodePoint, this._worldMatrix);
}
}
例如:节点A坐标Point 如何得到世界坐标?
const worldPoint = A.parent.convertToWorldSpaceAR(Point);
convertToNodeSpaceAR 将节点的世界坐标转换到节点坐标系下
convertToNodeSpaceAR (worldPoint, out) {
this._updateWorldMatrix();
Mat4.invert(_mat4_temp, this._worldMatrix); //求世界矩阵的逆矩阵
if (worldPoint instanceof cc.Vec2) {
out = out || new cc.Vec2();
return Vec2.transformMat4(out, worldPoint, _mat4_temp);
}
else {
out = out || new cc.Vec3();
return Vec3.transformMat4(out, worldPoint, _mat4_temp);
}
},
例如:节点A的世界坐标worldPoint ,如何得到它在父节点坐标系的坐标?
const point = A.parent.convertToNodeSpaceAR(worldPoint);
总结
- 节点属性(sacle、rotation)修改都需要更新自身的本地矩阵。
- 本地矩阵是相对于父节点的坐标系的,同时本地矩阵是缩放、旋转、位移三个矩阵合一的仿射矩阵。
- 世界矩阵 可以通过本地矩阵乘以父节点矩阵而来,节点坐标乘以父节点的世界矩阵即可得到世界坐标
- 世界逆矩阵 对世界矩阵求逆,然后把世界坐标转换成节点坐标