Skip to content

Desk Pet 3D

轻量、透明、可交互的 Windows 3D 桌面宠物

Version Platform Language raylib License Release

简体中文 | English

Desk Pet 3D 是一个面向 Windows x64 的开源 3D 桌面宠物应用程序。它使用透明、无边框、始终置顶的窗口展示可动画 3D 模型,同时提供像素级点击穿透、鼠标交互、托盘菜单、JSON 配置和图形化配置创建器。

AI 实现声明: 本项目的应用程序代码与工程文档由 OpenAI Codex(GPT-5.6 Sol) 在人类主导的产品设计、需求评审和测试验证下实现。

主要特性

  • 使用 C99、raylib 6.0、cJSON 和 Win32 API 实现,仅面向 Windows x64。
  • 模型窗口透明、无边框、始终置顶,不显示在任务栏或 Alt+Tab 列表中。
  • 透明像素区域支持点击穿透,只有鼠标位于模型实体上时才响应交互。
  • 左键拖动桌宠位置,右键旋转模型,滚轮缩放,中键恢复初始旋转和缩放。
  • 支持随机 IDLE、拖动 MOVE、左键单击和双击动画,并支持动画间隔、平滑过渡和独立动画资源文件。
  • 支持保存模型旋转、缩放和窗口位置,并在下次启动时恢复。
  • 提供中文图形化配置创建器,基础用户无需直接编辑 JSON。
  • 托盘菜单提供模型信息、帮助、关于和退出功能;菜单打开时模型动画不会暂停。
  • 应用图标、关于页面图片、GPL 正文和第三方许可声明均嵌入 EXE。
  • raylib 与 cJSON 通过固定版本的 Git submodule 联合构建,便于复现构建结果。

快速开始

构建环境

  • Git
  • Visual Studio Build Tools,包含 x64 C/C++ 工具链
  • Windows SDK
  • CMake 3.16 或更高版本

克隆仓库时应同时初始化 submodule:

git clone --recurse-submodules https://github.com/woooooooooolf/deskpet3d.git
cd deskpet3d
git submodule update --init --recursive

执行 Release 构建:

build.bat

构建产物位于:

build\deskpet3d.exe

也可以为“特别版”构建增加一个会显示在“关于”窗口标题后的 Unicode 名称:

build.bat "特别版名称"

辅助窗口采用轮廓拖动:按住标题栏时,真实窗口保持原位,只以默认 30 Hz 更新一个不接收输入的轻量边框;松开鼠标后真实窗口一次性移动并重绘。该定时器和轮廓窗口只在拖动期间存在,不影响窗口静止期间的 CPU/GPU 占用,也不会修改 Windows 全局的“拖动时显示窗口内容”设置。需要比较更高轮廓更新率时,可使用第二个构建参数:

build.bat "特别版名称" 60

PowerShell 用户可以直接执行:

.\build.ps1 -EditionName "特别版名称" -CustomDragHz 60

启动方式

程序接收一个 JSON 配置文件路径:

build\deskpet3d.exe config\raylib_robot.json

也可以直接把 JSON 文件拖放到 deskpet3d.exe 图标上。正常启动会通过短生命周期的引导进程创建独立 GUI 进程,因此关闭原来的 Command Prompt 或 PowerShell 窗口不会终止桌宠。

直接双击 EXE 且不提供 JSON 时会打开中文 Startup 窗口,可以进入“创建配置”“帮助”或“关于”。这使用户即使还没有模型和配置文件,也能了解用法并创建第一份配置。

仓库内的 config/raylib_robot.json 使用 raylib submodule 自带的 robot.glb,初始化 submodule 后即可用于验证。该配置的 saved_state.valid 默认是 0,首次启动会采用配置中定义的初始状态。

鼠标操作

操作 功能
左键单击 从 CLICK 动画列表中随机选择一段完整播放
左键双击 从 DOUBLE CLICK 动画列表中随机选择一段完整播放
左键拖动 移动桌宠窗口;实际拖动持续超过 500 ms 后,可循环播放随机 MOVE 动画
右键拖动 旋转模型
鼠标滚轮 缩放模型,放大上限受模型旋转包围范围和窗口尺寸共同保护
中键单击 恢复 JSON 中定义的初始旋转和缩放
托盘图标右键 打开模型信息、帮助、关于和退出菜单

模型窗口使用低分辨率 Alpha 掩码判断可交互像素。透明区域中的鼠标事件会传递给桌面或下层应用程序,模型可见区域才会接收上述操作。input.hit_test_fpsinput.hit_test_downsampleinput.hit_test_alpha_threshold 可用于平衡命中精度与资源消耗。

启用双击动画时,程序会按 Windows 的系统双击时间和距离判断连续点击,因此单击动画最多会延迟一个系统双击判定周期。点击动画可以被新的单击或双击动画覆盖,也可以被拖动触发的 MOVE 动画打断;MOVE 结束后会重新进入 IDLE。点击动画正常结束后先等待 idle_interval_seconds,再恢复随机 IDLE。

图形化配置创建器

直接双击 deskpet3d.exe,然后选择“创建配置”。创建器可以:

  • 选择 GLB/glTF、IQM、M3D、OBJ 或 VOX 模型;
  • 读取所选模型内置的动画名称和索引;
  • 分别多选最多 32 个 IDLE、MOVE、单击和双击动画;
  • 设置 animation_blend_seconds 控制动画切换的平滑过渡时间;
  • 设置模型显示比例、窗口尺寸、锚点、帧率、命中检测和托盘图标等参数;
  • 使用四列动画选择和双列参数布局,无需滚动窗口即可访问全部配置项;
  • 对所有可编辑数值执行范围检查;
  • 将模型和 ICO 路径尽可能保存为相对 JSON 文件的相对路径;
  • 以 UTF-8 原子写入 JSON,并使用与主程序相同的解析器重新验证。

创建器生成的是单模型基础配置。需要独立动画文件、具名动画源或更复杂规则时,可以继续手动编辑 JSON。

JSON 配置

下面是一个不依赖仓库测试模型名称的基础示例:

{
  "model": {
    "path": "../assets/character.glb",
    "idle_animations": ["Idle", "Wave"],
    "move_animations": ["Walk"],
    "click_animations": ["React", "Wave"],
    "double_click_animations": ["Dance", "Jump"],
    "animation_fps": 30.0,
    "idle_interval_seconds": 2.0,
    "animation_blend_seconds": 0.12,
    "height_fraction": 0.92,
    "width_fraction": 0.92,
    "vertical_offset_fraction": 0.0,
    "initial_yaw": 0.0,
    "initial_pitch": 0.0,
    "initial_zoom": 1.0,
    "min_zoom": 0.35,
    "max_zoom": 3.0
  },
  "window": {
    "width": 300,
    "height": 420,
    "anchor": "bottom_right",
    "offset_x": -24,
    "offset_y": -24,
    "target_fps": 60
  },
  "input": {
    "rotation_speed": 0.35,
    "zoom_speed": 0.12,
    "hit_test_fps": 30,
    "hit_test_downsample": 2,
    "hit_test_alpha_threshold": 16
  },
  "tray": {
    "icon": "../assets/character.ico"
  },
  "saved_state": {
    "valid": 0
  }
}

所有相对模型、动画和托盘图标路径均以 JSON 文件所在目录为基准解析,而不是以当前工作目录为基准。tray.icon 可以指定外部 .ico;路径为空、文件不存在或格式无效时会回退到内嵌的 assets/deskpet3d.ico。托盘提示文字固定为 Desk Pet 3D,不能通过 JSON 修改。

窗口锚点支持 bottom_rightbottom_lefttop_righttop_leftcenter,偏移量在锚定之后应用。

模型与动画格式

GLB/glTF 是本项目推荐并重点验证的动画模型格式。raylib 6.0 还可以通过 LoadModelAnimations() 从 IQM 和 M3D 加载骨骼动画。OBJ 和 VOX 可用于静态模型,但不能通过该接口提供动画片段。当前程序支持骨骼变换动画,不支持 Morph Target 或材质动画。

Windows 下的 raylib 文件读取已通过应用层回调转换为 UTF-16,因而 GLB/glTF、IQM、M3D、VOX、独立动画源以及 glTF 外部 buffer/纹理可以放在含中文、空格、括号或 Emoji 的路径中。动画模型仍推荐使用与 JSON 同目录部署的单文件 GLB,它对路径兼容和资源完整性最稳定。

OBJ 是已知例外:raylib/tinyobj 的外部 MTL 和纹理读取仍可能经过窄字符文件 API,因此不能保证 Unicode 目录中的完整 OBJ 资源链可用。拆分的 .gltf + .bin + 图片 必须保留所有文件并准确匹配 URI;百分号编码 URI、NFC/NFD 等 Unicode 规范化差异、Windows 非法或保留文件名以及所有超长路径情形不在当前兼容承诺内。手动编辑 JSON 时,反斜杠必须写为 \\,也可以使用 /。建议始终使用相对 JSON 的简单资源文件名。

默认情况下,动画从 model.path 加载。模型和动画分开保存时,可以配置 1 至 16 个 model.animation_sources

"model": {
  "path": "../assets/character.glb",
  "animation_sources": [
    { "id": "base", "path": "../assets/character.glb" },
    { "id": "motions", "path": "../assets/character_motions.glb" }
  ],
  "idle_animations": [
    { "source": "base", "name": "Idle" },
    { "source": "base", "name": "Wave" }
  ],
  "move_animations": [
    { "source": "motions", "name": "Walk" },
    { "source": "motions", "index": 1 }
  ],
  "click_animations": [
    { "source": "motions", "name": "React" }
  ],
  "double_click_animations": [
    { "source": "motions", "name": "Dance" }
  ]
}

动画项可以使用名称、从零开始的索引,或者包含 sourcename/index 的对象。程序会调用 raylib 的骨架兼容性检查过滤动画;raylib 6.0 的公开检查主要比较骨骼数量,因此资产制作者仍需保证骨骼顺序和语义一致。

IDLE 列表为空时不调度待机动画。列表有效时,程序随机选择一个动画完整播放,然后保持末帧并等待 idle_interval_seconds,再选择下一段动画;有多个选项时会避免立即重复。MOVE、CLICK 或 DOUBLE CLICK 列表为空、缺失或没有兼容动画时,对应交互不会切换当前动画。

click_animationsdouble_click_animations 使用与 MOVE 相同的动画项语法。点击动作一次性完整播放,结束后进入 IDLE 等待;新点击动作可以覆盖正在播放的点击动作,MOVE 则可以打断任意点击动作。animation_blend_seconds 的有效范围为 0..1 秒,默认值为 0.12;程序使用 raylib 6.0 的 UpdateModelAnimationEx() 在旧姿态和新动画之间混合,并同时使用小数帧插值。设置为 0 可关闭切换过渡。

缩放与窗口保护

加载模型时,程序根据模型 AABB 的旋转半径和 window.widthwindow.height 计算一次固定的旋转安全缩放上限。之后旋转模型不会自动改变当前缩放,滚轮放大则同时受该安全上限和 model.max_zoom 限制。

model.min_zoom 始终作为缩放下限。如果 JSON 设置的窗口过小,无法同时满足缩放下限和完整旋转包围范围,程序会保留下限并允许边缘裁切,而不会继续强制缩小模型。

状态保存

saved_state 由程序管理。将 saved_state.valid 设置为 0,可以忽略历史状态并使用模型默认旋转、缩放和窗口锚点:

"saved_state": {
  "valid": 0
}

完成旋转、缩放或窗口移动后,程序会写入 yawpitchzoomwindow_xwindow_y。异常、越界或完全位于屏幕外的状态会被拒绝,程序将恢复默认状态并尽力把字段更正为 {"valid": 0}。只读文件和其它写入失败会被静默忽略。

性能与事件响应

模型绘制与 Alpha 掩码读取采用内容驱动策略。动画姿态、旋转、缩放或重置发生变化时才标记内容需要更新;静态 IDLE 间隔会复用上一帧,不重复绘制模型,也不重复执行 GPU 到 CPU 的掩码读取。

鼠标、托盘和 Win32 消息仍按 window.target_fps 持续处理,因此静态节能不会阻塞交互。托盘弹出菜单运行在短生命周期的 UI 辅助线程中,保持菜单打开不会阻塞模型动画、渲染或输入轮询。

部署形式

Release 构建会静态链接 raylib、cJSON 和 Microsoft C Runtime(/MT)。EXE 内嵌默认图标、关于页面图片、GPLv3 正文和第三方许可声明,不需要项目专用 DLL、Visual C++ Redistributable、许可文本或关于页面图片作为运行时旁文件。

模型、JSON、外部纹理、独立动画文件以及 JSON 指定的个性化 ICO 仍是外部资产。对于内嵌纹理和动画的 GLB,最小部署形式是:

deskpet3d.exe
configuration.json
character.glb

推送与 CMakeLists.txt 版本一致的 V*.*.* 标签时,GitHub Actions 会在 Windows x64 环境中执行全新构建并创建 Release。工作流只上传形如 deskpet3d_v1.1.1_windows_amd64.exe 的单文件二进制;源码 ZIP/TAR 由 GitHub 根据标签自动生成,不再重复打包。GitHub 自动源码包不展开 submodule 内容,需要完整构建环境时应使用 git clone --recurse-submodules

运行环境

  • Windows 10 x64 或 Windows 11 x64
  • 支持 OpenGL 3.3 或更高版本的显卡驱动
  • 不需要单独安装 Visual C++ Redistributable

Windows 7 和 Windows 8.1 已结束生命周期,本项目不支持也不测试这些系统。底层 raylib/GLFW 可能仍包含旧系统兼容路径,但这不构成产品级兼容性保证。

项目结构

deskpet3d/
|-- assets/                  # 内嵌图标和关于页面图片
|-- config/                  # 可运行的 raylib robot 示例配置
|-- docs/                    # 开源合规说明
|-- src/                     # C99 与 Win32 源码
|-- test/                    # 静态、运行时和生成物检查
|-- third_party/
|   |-- raylib/              # raylib 6.0 submodule
|   `-- cjson/               # cJSON v1.7.19 submodule
|-- CMakeLists.txt
|-- build.bat
`-- build.ps1

测试

执行完整回归测试:

powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\test\run_all.ps1

只执行静态检查:

powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\test\static_checks.ps1

测试用例、执行方式和 Windows 自动化中的已知注意事项记录在 test/TEST_CASES.md

参与贡献与支持

欢迎提交可复现的错误报告、范围明确的功能建议和经过验证的 PR。请先阅读 CONTRIBUTING.mdSUPPORT.md,安全漏洞按照 SECURITY.md 私密报告,参与行为遵循 CODE_OF_CONDUCT.md

项目由人类确定需求方向,并主要依赖 OpenAI Codex(GPT-5.6 Sol) 实现;后续 Issue 分析、开发、测试和文档迭代也会继续使用 AI。请勿提交秘密、个人敏感信息、保密资料或无权分享并交由 AI 处理的素材。

受维护精力和项目计划限制,我们无法保证及时回复、实现、Review 或合并,对可能造成的等待深表歉意,也感谢你的理解。

AI 实现与项目归属

Desk Pet 3D 的需求方向、产品设计和验收反馈由项目设计者提供;应用程序代码、构建系统、测试工具和工程文档由 OpenAI Codex(GPT-5.6 Sol) 根据这些要求实现。本声明用于透明披露 AI 在项目中的实质性实现角色,不改变项目文件的 GPL-3.0-only 许可,也不替代人工评审、测试和发布责任。

开源依赖与许可

Desk Pet 3D 自有源代码、构建脚本和文档采用 GNU General Public License version 3 only,SPDX 标识为 GPL-3.0-only。使用、修改和再发布时必须遵守 GPLv3,并按要求提供对应源代码。本软件不提供任何担保。

  • raylib 6.0 使用 zlib/libpng 许可证。
  • cJSON v1.7.19 使用 MIT 许可证。
  • assets/deskpet3d.ico 是项目自有素材,随项目以 GPL-3.0-only 发布。
  • assets/codex.pngassets/raylib.png 用于归属展示,其产品名称、标志和商标权利仍归各自权利人所有。

完整第三方声明见 THIRD_PARTY_NOTICES.txt,发布合规清单见 docs/OPEN_SOURCE_COMPLIANCE.md

致谢

Thanks to the raylib project.

Thanks to the cJSON project.

About

把3D模型变成桌宠吧!借助Raylib、cJSON和AI的力量,将所喜欢的角色放在随处可见的地方。这主要是个人用途的小工具,虽然开源且支持贡献,但是如果带来太多ISSUE/PR等压力的话,我也会很困扰的!但我只是希望你也可以用的到~

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages