docs: explain Tessera modules and execution flows in Chinese

This commit is contained in:
2026-11-11 23:36:03 +08:00
parent 4c3fc8b5dd
commit 1fedd21d3c
77 changed files with 1418 additions and 0 deletions
+29
View File
@@ -1,19 +1,26 @@
//! 3D 数学基础:向量、仿射矩阵、摄像机基向量、投影射线和三角形相交。
//! 矩阵组合顺序决定局部变换如何进入父坐标系;接近退化的逆矩阵、法线和射线使用 Option 拒绝无效计算。
//!
use serde::{Deserialize, Serialize};
use std::ops::{Add, Mul, Sub};
#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
/// 三个有限浮点分量的数学向量,不是托管 Vec3 对象。
pub struct Vec3 {
pub x: f32,
pub y: f32,
pub z: f32,
}
impl Vec3 {
/// 构造本类型并初始化其状态;资源建立和默认字段以函数体为准。
pub const fn new(x: f32, y: f32, z: f32) -> Self {
Self { x, y, z }
}
/// 计算向量点积,用于方向投影、光照和相交判断。
pub fn dot(self, b: Self) -> f32 {
self.x * b.x + self.y * b.y + self.z * b.z
}
/// 计算右手叉积,用于摄像机基向量和三角形法线。
pub fn cross(self, b: Self) -> Self {
Self::new(
self.y * b.z - self.z * b.y,
@@ -21,13 +28,16 @@ impl Vec3 {
self.x * b.y - self.y * b.x,
)
}
/// 计算向量长度;归一化前还需检查是否接近零。
pub fn length(self) -> f32 {
self.dot(self).sqrt()
}
/// 仅在长度有效且不退化时返回单位向量,避免除零产生非有限结果。
pub fn normalized(self) -> Option<Self> {
let length = self.length();
(length.is_finite() && length > 1e-6).then(|| self * (1.0 / length))
}
/// 检查数值、几何和资源条件是否满足本类型约束,供上层拒绝非法输入。
pub fn valid(self) -> bool {
[self.x, self.y, self.z]
.iter()
@@ -36,26 +46,31 @@ impl Vec3 {
}
impl Add for Vec3 {
type Output = Self;
/// 按分量执行向量加减或标量乘法,保持数学运算不依赖 VM 状态。
fn add(self, b: Self) -> Self {
Self::new(self.x + b.x, self.y + b.y, self.z + b.z)
}
}
impl Sub for Vec3 {
type Output = Self;
/// 按分量执行向量加减或标量乘法,保持数学运算不依赖 VM 状态。
fn sub(self, b: Self) -> Self {
Self::new(self.x - b.x, self.y - b.y, self.z - b.z)
}
}
impl Mul<f32> for Vec3 {
type Output = Self;
/// 按分量执行向量加减或标量乘法,保持数学运算不依赖 VM 状态。
fn mul(self, b: f32) -> Self {
Self::new(self.x * b, self.y * b, self.z * b)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
/// 仿射 4×4 变换矩阵,支持局部到世界的组合与求逆。
pub struct Matrix(pub [f32; 16]);
impl Default for Matrix {
/// 建立类型约定的初始值,供尚未发布或尚未交互的状态使用。
fn default() -> Self {
Self([
1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.,
@@ -63,6 +78,7 @@ impl Default for Matrix {
}
}
impl Matrix {
/// 求仿射世界矩阵的逆;退化或不可逆时返回空值。
pub fn inverse(self) -> Option<Self> {
let m = self.0;
let determinant = m[0] * (m[5] * m[10] - m[6] * m[9]) - m[1] * (m[4] * m[10] - m[6] * m[8])
@@ -95,6 +111,7 @@ impl Matrix {
out.0[11] = translation.z;
Some(out)
}
/// 组合父子仿射变换,调用顺序决定局部坐标最终落在哪个世界位置。
pub fn compose(self, local: Self) -> Self {
let mut out = [0.; 16];
for row in 0..4 {
@@ -106,6 +123,7 @@ impl Matrix {
}
Self(out)
}
/// 对一个位置应用矩阵,包括平移项;不要用它代替纯方向变换。
pub fn point(self, p: Vec3) -> Vec3 {
Vec3::new(
self.0[0] * p.x + self.0[1] * p.y + self.0[2] * p.z + self.0[3],
@@ -113,6 +131,7 @@ impl Matrix {
self.0[8] * p.x + self.0[9] * p.y + self.0[10] * p.z + self.0[11],
)
}
/// 由平移、角度旋转和缩放构造局部仿射矩阵。
pub fn trs(position: Vec3, rotation: Vec3, scale: Vec3) -> Self {
let (sx, cx) = rotation.x.to_radians().sin_cos();
let (sy, cy) = rotation.y.to_radians().sin_cos();
@@ -140,12 +159,14 @@ impl Matrix {
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
/// 投影策略:透视视场角或正交可见高度。
pub enum Projection {
Perspective { fov: f32 },
Orthographic { height: f32 },
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
/// 原生摄像机描述,包括观察基、近远面和投影参数;宽高比由视口提供。
pub struct Camera {
pub position: Vec3,
pub target: Vec3,
@@ -155,6 +176,7 @@ pub struct Camera {
pub projection: Projection,
}
impl Default for Camera {
/// 建立类型约定的初始值,供尚未发布或尚未交互的状态使用。
fn default() -> Self {
Self {
position: Vec3::new(0., 0., 5.),
@@ -167,18 +189,21 @@ impl Default for Camera {
}
}
#[derive(Debug, Clone, Copy)]
/// 摄像机的右、上、前单位基向量。
pub struct Basis {
pub right: Vec3,
pub up: Vec3,
pub forward: Vec3,
}
impl Camera {
/// 从观察位置、目标和上方向建立正交相机基;方向退化时拒绝。
pub fn basis(self) -> Option<Basis> {
let forward = (self.target - self.position).normalized()?;
let right = forward.cross(self.up).normalized()?;
let up = right.cross(forward).normalized()?;
Some(Basis { right, up, forward })
}
/// 检查数值、几何和资源条件是否满足本类型约束,供上层拒绝非法输入。
pub fn valid(self) -> bool {
self.position.valid()
&& self.target.valid()
@@ -196,10 +221,12 @@ impl Camera {
}
}
}
/// 把世界点投影到相机的右/上/前基向量坐标。
pub fn view(self, basis: Basis, p: Vec3) -> Vec3 {
let p = p - self.position;
Vec3::new(p.dot(basis.right), p.dot(basis.up), p.dot(basis.forward))
}
/// 从视口归一化坐标生成透视或正交射线;宽高比由具体视口提供。
pub fn ray(self, u: f32, v: f32, aspect: f32) -> Option<Ray> {
let basis = self.basis()?;
let (x, y) = (u * 2. - 1., 1. - v * 2.);
@@ -224,11 +251,13 @@ impl Camera {
}
}
#[derive(Debug, Clone, Copy)]
/// 世界坐标中的射线原点与方向,供网格和面板求交。
pub struct Ray {
pub origin: Vec3,
pub direction: Vec3,
}
impl Ray {
/// 求射线与三角形相交距离和重心坐标,拒绝退化三角形及射线起点后方的交点。
pub fn triangle(self, a: Vec3, b: Vec3, c: Vec3) -> Option<(f32, [f32; 3])> {
let ab = b - a;
let ac = c - a;