* feat(image): ImageData::rotate with inverse-map nearest/linear Add CPU pixel rotation on ImageData using destination-to-source inverse mapping (Geometric Tools / standard image processing). Supports nearest and bilinear filters, optional canvas expand to fit the rotated AABB, and matches Math::rotate2* angle convention. Includes unit tests, Font script binding, and docs. Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com> * test(image): assert exact 90° rotate pixel positions Pin nearest+expand 90° mapping of corner markers to (1,2) and (0,0). Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com> * feat(image): implement RotSprite pixel-art rotation filter Add Xenowhirl RotSprite as ImageData::rotate filter "rotsprite": Scale2x×3 with color similarity, best 8×8 sampling offset search, nearest-neighbor rotate+downscale, and single-pixel detail restore. Quarter turns use an exact remapping fast path. Tests cover 90° palette preservation and 45° no-new-colors. Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com> * fix(ci): M_PI on MSVC and GitHub API 403 for asset downloads Windows unit tests failed because test/image.cpp used M_PI without the MSVC fallback used by other test files. macOS build failed when download_skinned_character.sh hit GitHub API 403 during PRE_BUILD; add User-Agent + optional GITHUB_TOKEN auth to asset fetch scripts and pass GITHUB_TOKEN in CI build steps. Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
3.4 KiB
图像模块
脚本入口: eve.Image()
说明 Image 的 C++ 能力与当前 Squirrel 绑定边界;当前脚本入口只公开模块身份查询。
基本用法
当前 eve.Image() 的脚本绑定只公开模块身份查询;newImageData 等 C++ 方法尚未绑定到 Squirrel。游戏脚本可以通过 FontData.newGlyphImageData(...) 获得已绑定的 ImageData;任意图片文件的直接解码目前主要供 C++ 和引擎内部资源加载流程使用:
local image = eve.Image();
print(image.getName() + "\n");
// 若已从 FontData 得到 ImageData,可交给 gfx.newTexture(imageData)。
不要照搬 Image.h 中只面向 C++ 的方法到脚本。需要直接编辑像素时,应先确认目标方法已在 Image::expose 中注册。通过 FontData 暴露的 ImageData 目前支持 getWidth / getHeight / getFormat / getSize / rotate。
对象关系与调用时机
C++ Image 能创建和解码 ImageData,但当前 Image::expose() 仅绑定 getName()。用户文档严格描述脚本可用面,避免把内部接口误写成 Squirrel API。
ImageData::rotate(radians, filter, expand)(C++,脚本经 Font 绑定的 ImageData 也可调用)按逆映射旋转像素:遍历目标图每个像素,用逆旋转矩阵回算源坐标,再按 filter 采样。
| 参数 | 含义 |
|---|---|
radians |
弧度;与 Math.rotate2* 同号(Y 向下时视觉为顺时针,同 LÖVE) |
filter |
"nearest" / "linear" / "rotsprite"(Xenowhirl:Scale2x×3 → 偏移搜索 → 最近邻缩回) |
expand |
true 时画布扩到容纳整图 AABB;false 保持原尺寸(可能裁切) |
返回同格式的新 ImageData(调用方拥有);源范围外采样为透明黑。rotsprite 只挑选已有调色板颜色,不引入插值新色。
目标导向指南
判断脚本能否直接处理图片
先检查 Image::expose:当前脚本侧不能调用 newImageData 解码任意文件。因此普通游戏资源应通过 Tilemap、模型加载器或其他已绑定资源入口载入,不要假设 C++ public 方法可用。
从字体字形创建纹理
通过 FontData.newGlyphImageData(codepoint) 得到已绑定的 ImageData,再传给 gfx.newTexture(imageData)。保留纹理对象,避免每帧重新栅格化同一字形。
常见问题
- 直接调用
image.newImageData():当前会报“方法不存在”。 - 每帧把字形重新转纹理:应缓存 ImageData/Texture。
- 把源码 public 方法当脚本方法:始终核对
expose()。
API 快查
getName():返回模块名。- C++ 侧的
newImageData(...)、isCompressed(...)、newCubeFaces(...)和newVolumeLayers(...)当前不是脚本 API。 ImageData.rotate(radians, filter, expand):CPU 像素旋转(经 Font 绑定的 ImageData);filter为"nearest"/"linear"/"rotsprite"。
使用要点
- 模块对象和它创建的资源对象应保存在全局或实体状态中,不要在每帧重复创建。
- 带
update(dt)的系统应在eve_update调用;绘制方法应在eve_render调用。 - 参数约束、默认值和返回类型以对应模块头文件及
addFunc绑定为准;本文 API 快查与当前源码同步生成。
源码: src/modules/image/
相关测试: 在 test/ 中搜索 image。