JSR-184 (Mobile 3D Graphics API) 採用矩陣堆疊與 Transform 物件控制相機,而 Mascot Capsule v3 沿用傳統 lookAt(position, direction, upVector) 介面。為實現跨引擎相容,Digital Chocolate 封裝了統一的 setLookAt() 方法,同時支援兩種渲染後端。
給定:
構建右手座標系基向量:
[ Sx Uy -Lx Ex ]
[ Sy Uy -Ly Ey ]
[ Sz Uz -Lz Ez ]
[ 0 0 0 1 ]
public static final void setLookAt(float posX, float posY, float posZ,
float lookX, float lookY, float lookZ,
float upX, float upY, float upZ) {
// 假設 USE_M3G 常數控制後端切換
if (USE_M3G) {
// 1. 計算 Side 向量 (叉積)
float sideX = lookY * upZ - lookZ * upY;
float sideY = lookZ * upX - lookX * upZ;
float sideZ = lookX * upY - lookY * upX;
// 2. 正規化 Side
float invLen = 1.0f / (float) Math.sqrt(sideX*sideX + sideY*sideY + sideZ*sideZ);
sideX *= invLen; sideY *= invLen; sideZ *= invLen;
// 3. 重新計算正交 Up 向量
upX = sideY * lookZ - sideZ * lookY;
upY = sideZ * lookX - sideX * lookZ;
upZ = sideX * lookY - sideY * lookX;
// 此時 up 已為單位向量,因 side ⟂ look
// 4. 填充 4x4 矩陣 (column-major 順序)
sm_mtx[0] = sideX; sm_mtx[1] = upX; sm_mtx[2] = -lookX; sm_mtx[3] = posX;
sm_mtx[4] = sideY; sm_mtx[5] = upY; sm_mtx[6] = -lookY; sm_mtx[7] = posY;
sm_mtx[8] = sideZ; sm_mtx[9] = upZ; sm_mtx[10] = -lookZ; sm_mtx[11] = posZ;
sm_mtx[12] = 0.0f; sm_mtx[13] = 0.0f; sm_mtx[14] = 0.0f; sm_mtx[15] = 1.0f;
// 5. 套用至 M3G Transform 物件
sm_m3gTransform.set(sm_mtx);
}
// Mascot Capsule v3 後端 (整數定點數運算)
if (USE_MASCOT) {
sm_mascotTmpVectorA.set((int)posX, (int)posY, (int)posZ);
sm_mascotTmpVectorB.set((int)(lookX * MASCOT_ONE),
(int)(lookY * MASCOT_ONE),
(int)(lookZ * MASCOT_ONE));
sm_mascotTmpVectorC.set(0, MASCOT_ONE, 0); // 世界上方向
sm_mascotAffineTrans.lookAt(sm_mascotTmpVectorA,
sm_mascotTmpVectorB,
sm_mascotTmpVectorC);
}
}
look 與 up 向量必須預先正規化Transform.set(float[]) 採 column-major (OpenGL 風格),非 row-major-look 代表相機朝向 -Z 軸 (右手系)MASCOT_ONE = 65536),浮點乘轉換時注意精度CameraHelper.setLookAt()此方案完美解決了 JSR-184 與傳統 3D 引擎相機控制 API 的互操作難題,是跨平台 3D 遊戲移植的關鍵基建模組。