English version

前言

对 3D 环境的最初兴趣来自 Croquet 团队的这篇论文.

从 Alan Kay 那里学到这样的一种视角来看待交互式图形计算: 桌面隐喻/GUI 的力量是心理层面的, 它们为用户制造了一种"幻觉", 仿佛事物就在屏幕那里, 因此用户可以将他们在现实世界的经验迁移过来, 就像与物理对象打交道一样, 与屏幕上的虚拟对象打交道.

沿着这个视角, 我们自然会渴望 3D 环境, 因为它能够进一步增强这种"用户幻觉", 事物存在于一个虚拟的 3 维空间里, 而不是一个 2 维的"桌面"上, 这样一来, 用户能够更多地迁移他们在现实世界(3 维空间)的经验.

这些想法的背后是让计算适应人类, 而不是让人类适应计算.

将 3D 环境引入 Snap!

Snap! 提供的舞台区通常用于制作 2D 项目. 我渴望将 3D 环境引入到 Snap! 中.

有许多方法可以达成目标:

我一直渴望更加通用和非侵入的方案, 最好 “只是一个普通的 Snap! 项目”.

前段时间完成的通用 iframe 库提供了这种可能性.

大体来说, 我的想法是这样的:

  • 通过 iframe 库将基于 web 的 3D 环境引入 Snap!.
  • 通过 postMessage API, Snap! 可以与 iframe 中的 3D 环境通信
    • 在 postMessage 之上构建 dynatalk, Snap! 就能够与这些 3D 环境进行同步或异步的互操作, 仿佛它们由同一个引擎驱动.

我打算挑选一个 3D 引擎来演示如何实施以上想法. 一番比较之后, 最终选择了 Spline, 它是我了解的 3D 工具中最简单易用的.Spline 和 Scratch 有很多相似性, 它极大降低了 3D 项目的制作难度。

理论上, 我们有可能基于 threejsbabylonjs 为 Snap! 制作一个 3D 编辑器, 就像 Snap! 的像素编辑器/矢量编辑器 那样, 深度整合到 Snap! 中, 这样做的坏处是, 工程量巨大无比, 是否易用也值得怀疑. 我最终放弃了这个想法, 转而去思考:

哪个 3D 编辑器非常易用, 而且暴露出了与之互操作的 API ? 如果有这样的项目, 我们可以将其视为 Snap! 的 “外部编辑器”

我选择了 Spline(还有很多其他的潜在选项).

Spline 负责制作 3D 项目, 并暴露出 API, 而编程和控制的的部分, 由 Snap! 负责。 在 Snap! 中操作 Spline 项目, 很像在 Snap! 操作 MicroBlocks 项目. Spline 和 MicroBlocks 用于编写项目的"内核", 对外提供出服务, Snap! 则作为客户端使用这些服务.

Snap! 中的 Spline 库

查看具体例子之前, 可以看下 演示视频

demo 1

示例项目(点击运行)

演示使用的 Spline 项目, 修改自 Little World Kawaii Pig

填写在 Snap! 中 world url 是 https://prod.spline.design/s7FG1KdbdsyW8yOY/scene.splinecode (FAQ 里介绍了如何获取项目的 world url)

demo 2

示例项目(点击运行)

演示使用的 Spline 项目, 修改自 Mini House - Conditional Logic

填写在 Snap! 中 world url 是 https://prod.spline.design/nO5gRl8xdZ5gp4UJ/scene.splinecode

demo3: 修改变量

示例项目(点击运行)

演示使用的 Spline 项目, 修改自 3D Text - Blue

填写在 Snap! 中 world url 是 https://prod.spline.design/CJdfFOXzOrARU5Nz/scene.splinecode

关于变量在 Spline 中的用法, 参考 这个教程

FAQ

如何获取 world url

如何自托管项目文件?

以 demo 2 https://prod.spline.design/dP5NwOaNd2IR5Npm/scene.splinecode 为例, 你可以将其下载下来, 存放在自己的服务器上(我把它放在:https://wwj718.github.io/post/img/scene.splinecode), 然后加载它.

示例项目(点击运行)

open world url 积木是如何工作的?

open world url 积木接收 Spline 项目的地址, 形如 https://prod.spline.design/nO5gRl8xdZ5gp4UJ/scene.splinecode, 你可以从项目的 export 中找到它.

open world url 内部, 它会将 Spline 项目的地址传递给这个 iframe 页面: https://wwj718.github.io/Snap-Spline-Demo?project=https://prod.spline.design/nO5gRl8xdZ5gp4UJ/scene.splinecode

iframe 页面的源代码在这里:Snap-Spline-Demo.

Spline 对外暴露了哪些 API?

这儿给出了完整的 API 描述.

这些 API 决定了外部系统 (如 Snap!) 可以以哪些方式操作 Spline 项目.

dynatalk-over-postmessage 在这里有什么用?

架构将掌控材料 – Alan Kay

浏览器提供了 postMessage API , 用于与 iframe 页面进行通信, 这是一种异步通信(pub/sub)方式. 有时候我们想要同步通信(如 Spline 库的 ask _ for _ 积木), 类似 RPC 或者函数调用, dynatalk 能够做到这点.

制作 dynatalk-over-postmessage, 所需的工作并不多, 只需将消息管道从 MQTT 切换到 postMessage 即可, 具体而言, 需要调整接收和发送消息的机制. 其他的代码一行未改, 全都可以复用.

如何将其转化为标准的 Snap! 库?

目前 Spline 库 已成为了 Snap! 中文版 内置库.

更多细节参考 如何将其转化为标准的 Snap! 库?

参考