mcpField
X
xmath-usage

xmath-usage

github.com/indiesoftby开发10445 次安装27 周前更新
代码仓库

关于 xmath-usage

面向依赖 xmath 的 Defold 项目,介绍如何使用该库。指南通过原地执行向量、四元数和矩阵运算,复用已分配对象,减少高频循环中的分配。

主要功能

  1. 01确认项目依赖 xmath
  2. 02原地修改数学对象
  3. 03预分配可复用临时变量
  4. 04向量与四元数运算
  5. 05矩阵变换与插值

适用场景

  1. 01减少 update 循环中的分配
  2. 02复用临时向量值
  3. 03计算四元数旋转
  4. 04构建投影矩阵和视图矩阵

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/indiesoftby/defold-agent-config --skill xmath-usage

安装后在 Claude Code 中输入/xmath-usage确认已加载。

详细介绍

在 Defold 中使用 xmath 实现零分配数学运算

前提条件:验证 xmath 依赖项

应用本指南中的任何建议之前,必须确认项目使用了 xmath。检查 game.project 文件,查看是否包含依赖 URL thejustinwalsh/defold-xmath(例如 dependencies#N = https://github.com/thejustinwalsh/defold-xmath/archive/...)。或者,检查 .deps/ 目录中是否存在 xmath/。

如果在 game.project 中找不到 xmath 依赖项,也没有本地 xmath 模块,请勿应用本指南。告知用户该项目未使用 xmath,并建议添加此依赖项:

[project]
dependencies#N = https://github.com/thejustinwalsh/defold-xmath/archive/refs/heads/main.zip

核心概念:通过就地修改消除堆分配

标准 vmath 会在每次运算时创建新的 Lua 对象,导致热循环持续产生 GC 压力:

-- BAD: vmath allocates 3 new objects every frame
function update(self, dt)
    local v = self.dir * 5 * dt    -- alloc #1
    local pos = go.get_position()  -- alloc #2
    local result = pos + v         -- alloc #3
    go.set_position(result)
end

xmath 会就地修改现有变量,将结果写入第一个参数。只需分配一次,即可重复使用:

-- GOOD: xmath reuses pre-allocated variables, zero allocations per frame
go.property("dir", vmath.vector3(0, 1, 0))

local v = vmath.vector3()  -- allocate ONCE at module scope

function update(self, dt)
    local pos = go.get_position()
    xmath.mul(v, self.dir, 5 * dt)  -- writes into v
    xmath.add(v, pos, v)            -- writes into v
    go.set_position(v)
end

关键规则

  1. 在模块作用域或 init() 中预先分配临时变量——绝不要在 update() 或 on_message() 中分配。
  2. 输出变量始终是第一个参数——这是与 vmath 调用约定的根本区别。
  3. 函数不返回任何值——无法链式调用。每一步都使用一个临时变量。
  4. 使用 vmath 创建初始对象——通过 vmath.vector3()、vmath.vector4()、vmath.quat()、vmath.matrix4() 分配临时缓冲区,然后使用 xmath 对其进行运算。
  5. 类型多态——xmath.lerp 等函数会根据输出参数的类型,对 vector3、vector4 和 quaternion 执行相应操作。

优化模式

-- Scratch variables — allocated once
local temp_v = vmath.vector3()
local temp_q = vmath.quat()

function update(self, dt)
    -- Instead of: local dir = vmath.normalize(target - pos)
    xmath.sub(temp_v, self.target, self.pos)
    xmath.normalize(temp_v, temp_v)  -- can use same variable as both input and output

    -- Instead of: local rot = vmath.quat_rotation_z(angle)
    xmath.quat_rotation_z(temp_q, self.angle)

    -- Instead of: local rotated = vmath.rotate(rot, dir)
    xmath.rotate(temp_v, temp_q, temp_v)
end

完整 API 参考

所有函数都会将结果写入第一个参数。不返回任何值。

向量运算(vector3 / vector4)
函数等价写法说明
xmath.add(out, v1, v2)out = v1 + v2将两个向量相加
xmath.sub(out, v1, v2)out = v1 - v2将两个向量相减
xmath.mul(out, v, n)out = v * n将向量乘以标量
xmath.div(out, v, n)out = v / n将向量除以标量
xmath.cross(out, v1, v2)out = cross(v1, v2)叉积(仅适用于 vector3)
xmath.mul_per_elem(out, v1, v2)out.x = v1.x * v2.x, ...逐元素相乘
xmath.normalize(out, v)out = normalize(v)归一化向量
xmath.rotate(out, q, v)out = rotate(q, v)用四元数旋转 vector3
xmath.vector(out)out = (0,0,0)重置为零向量
插值(vector3 / vector4 / quaternion)
函数等价写法说明
xmath.lerp(out, t, v1, v2)out = lerp(t, v1, v2)线性插值
xmath.slerp(out, t, v1, v2)out = slerp(t, v1, v2)球面插值
四元数运算
函数说明
xmath.quat(out)重置为单位四元数 (0, 0, 0, 1)
xmath.conj(out, q)四元数的共轭
xmath.quat_axis_angle(out, axis, angle)根据轴和角度生成四元数
xmath.quat_basis(out, x, y, z)根据 3 个基向量(vector3)生成四元数
xmath.quat_from_to(out, v1, v2)从 v1 到 v2 的旋转四元数
xmath.quat_rotation_x(out, angle)绕 X 轴旋转
xmath.quat_rotation_y(out, angle)绕 Y 轴旋转
xmath.quat_rotation_z(out, angle)绕 Z 轴旋转
矩阵运算(matrix4)
函数说明
xmath.matrix(out [, m1])重置为单位矩阵或从 m1 复制
xmath.matrix_axis_angle(out, axis, angle)根据轴和角度生成旋转矩阵
xmath.matrix_from_quat(out, q)根据四元数生成矩阵
xmath.matrix_frustum(out, left, right, bottom, top, near, far)视锥投影矩阵
xmath.matrix_inv(out, m)矩阵逆矩阵
xmath.matrix_look_at(out, eye, look_at, up)视图矩阵
xmath.matrix4_orthographic(out, left, right, bottom, top, near, far)正交投影
xmath.matrix_ortho_inv(out, m)正交逆矩阵
xmath.matrix4_perspective(out, fov, aspect, near, far)透视投影
xmath.matrix_rotation_x(out, angle)绕 X 轴旋转
xmath.matrix_rotation_y(out, angle)绕 Y 轴旋转
xmath.matrix_rotation_z(out, angle)绕 Z 轴旋转
xmath.matrix_translation(out, position)根据 vector3/vector4 生成平移矩阵

评论

支持 Markdown