原文链接: 旋转矩阵乘法顺序问题 以及 终于把魔方完成了
上一篇: git 设置常用别名
下一篇: 浏览器查看帧率
终于可以正常旋转了, 吐血, 虽然还有很多问题, 但是基本上算是完成了, 一个小问题花了一个礼拜, 自学这东西确实难受... 不过也因此多写了点demo以及粗看了一本书, 大概知道了这东西再深一点就不是自己能玩的了
可以自定义间距和阶数
之前没能成功是因为矩阵相乘写反了...
应该这么写的, 结果参数写反了, 死活转不出想要的效果
item.model = mat4.mul(
[],
mat4.fromRotation([], (t / AnimeCount) * degreeChange, op.axis),
oldMat[i]
);
基本思路, 做到最后还是把颜色和块绑在一起了, 从定义可以看到基本上没啥, 就是操作数据, 然后绘制出来而已
每个块六个面, 每次旋转完毕后一定要更新块的位置, 不是坐标位置, 而是块所在大立方体的位置, 左上角的块, 旋转后会变成左下角, 这个时候转最下面的面应该转动这个块, 而不是原来那个在这个地方的点, 位置变化全部使用矩阵乘法来, 所以不需要更新位置坐标
// 半排的个数
const half = 3;
// 一排的个数
const count = 2 * half + 1;
// 小方块大小
const boxSize = 0.8;
// 方块边距
const boxGap = 0.1;
// 每个box的uv间隔
const boxUvSize = 1 / count;
// 方块的pos
const cubePosition = [
[-boxSize / 2, +boxSize / 2, +boxSize / 2],
[+boxSize / 2, +boxSize / 2, +boxSize / 2],
[+boxSize / 2, -boxSize / 2, +boxSize / 2],
[-boxSize / 2, -boxSize / 2, +boxSize / 2], // positive z face.
[+boxSize / 2, +boxSize / 2, +boxSize / 2],
[+boxSize / 2, +boxSize / 2, -boxSize / 2],
[+boxSize / 2, -boxSize / 2, -boxSize / 2],
[+boxSize / 2, -boxSize / 2, +boxSize / 2], // positive x face
[+boxSize / 2, +boxSize / 2, -boxSize / 2],
[-boxSize / 2, +boxSize / 2, -boxSize / 2],
[-boxSize / 2, -boxSize / 2, -boxSize / 2],
[+boxSize / 2, -boxSize / 2, -boxSize / 2], // negative z face
[-boxSize / 2, +boxSize / 2, -boxSize / 2],
[-boxSize / 2, +boxSize / 2, +boxSize / 2],
[-boxSize / 2, -boxSize / 2, +boxSize / 2],
[-boxSize / 2, -boxSize / 2, -boxSize / 2], // negative x face.
[-boxSize / 2, +boxSize / 2, -boxSize / 2],
[+boxSize / 2, +boxSize / 2, -boxSize / 2],
[+boxSize / 2, +boxSize / 2, +boxSize / 2],
[-boxSize / 2, +boxSize / 2, +boxSize / 2], // top face
[-boxSize / 2, -boxSize / 2, -boxSize / 2],
[+boxSize / 2, -boxSize / 2, -boxSize / 2],
[+boxSize / 2, -boxSize / 2, +boxSize / 2],
[-boxSize / 2, -boxSize / 2, +boxSize / 2], // bottom face
];
// 小方块uv 前 右 后 左 上 下
const cubeUv = [
[0.0, 0.0],
[1.0, 0.0],
[1.0, 1.0],
[0.0, 1.0], // positive z face.
[0.0, 0.0],
[1.0, 0.0],
[1.0, 1.0],
[0.0, 1.0], // positive x face.
[0.0, 0.0],
[1.0, 0.0],
[1.0, 1.0],
[0.0, 1.0], // negative z face.
[0.0, 0.0],
[1.0, 0.0],
[1.0, 1.0],
[0.0, 1.0], // negative x face.
[0.0, 0.0],
[1.0, 0.0],
[1.0, 1.0],
[0.0, 1.0], // top face
[0.0, 0.0],
[1.0, 0.0],
[1.0, 1.0],
[0.0, 1.0], // bottom face
];
// 小方块对应的六个面
const cubeElements = [
[2, 1, 0],
[2, 0, 3], // positive z face.
[6, 5, 4],
[6, 4, 7], // positive x face.
[10, 9, 8],
[10, 8, 11], // negative z face.
[14, 13, 12],
[14, 12, 15], // negative x face.
[18, 17, 16],
[18, 16, 19], // top face.
[20, 21, 22],
[23, 20, 22], // bottom face
];
// 前 右 后 左 上 下
const faceMap = {
F: 0,
R: 1,
B: 2,
L: 3,
U: 4,
D: 5,
};
enum Face {
F = "F", // front z=1
B = "B", // back z=-1
L = "L", // left x=-1
R = "R", // right x=1
U = "U", // up y=1
D = "D", // down y=-1
M = "M", // middle x=0
E = "E", // Equator y=0
S = "S", // Side z=0
}
type FaceItem = {
color: number[]; // 颜色
texture: Regl.Texture; // 纹理
showColor: boolean;
};
type Faces = Partial<
{
// 每一个面有自己的uv和颜色纹理等, 有纹理的话优先绘制纹理
[k in Face]: FaceItem;
}
>;
type BoxItem = {
p: { x: number; y: number; z: number }; // 实时位置
size: number; // 大小
model: mat4; // 旋转矩阵
faces: Faces;
position: [number, number, number][]; // 顶点数组
};