笔记, threejs 和 glTF 的一些 tips – 题叶 – SegmentFault 思否

glTF 查看工具的实现

完整的 glTF 3D 模型查看工具的例子:

https://github.com/donmccurdy…

Object3D 获取中心点和尺寸

Object3D 物体可以获取一个包含物体的 Box, 这个 Box 有一些功能, 比如获取中心点:

https://github.com/donmccurdy…

<code class="js"><span class="hljs-keyword">const</span> box = <span class="hljs-keyword">new</span> THREE.Box3().setFromObject(object);</code>

const center = box.getCenter(new THREE.Vector3());

<code class="js"></code>

也可以用了获取物体的大小:

<code class="ts" style="white-space: initial;"><span class="hljs-keyword">const</span> size = box.getSize(<span class="hljs-keyword">new</span> THREE.Vector3()).length();</code>

获取中心点的主要目的是处理模型本身的偏移, 模型文件未必是把模型放在正中间的.
这时就需要手动查询物体在坐标系当中的中心点, 然后通过容器改变整个的位置.
需要引入容器是因为旋转, 没有容器的话, 旋转时有偏离的物体的原点依然是偏移的, 影响旋转的效果.

Orbit Control 如何移动 Camera

一般旋转相对的对物体做四元数的旋转, 或者欧拉角的旋转,
欧拉角的旋转在物体旋转到一定程度后会变得很反直觉, 而四元数旋转的倾斜不好控制,
所以还有一个版本是旋转 Camera 来的找到一个好的位置. 而且 Camera 的上方始终保持.

旋转摄影机, 自己实现其实还好. 大致的代码就是角度和三角函数:

https://threejs.org/examples/…

<code class="ts"><span class="hljs-keyword">this</span>.camera.position.set(</code>

this.props.radius * Math.sin(toRadians(this.props.polarAngle)) * Math.cos(toRadians(this.props.equatorAngle)),

<code class="ts"></code>

this.props.radius * Math.cos(toRadians(this.props.polarAngle)),

<code class="ts"></code>

this.props.radius * Math.sin(toRadians(this.props.polarAngle)) * Math.sin(toRadians(this.props.equatorAngle))

<code class="ts"></code>

);

<code class="ts"></code>

this.camera.lookAt(new Three.Vector3(0, 0, 0));

<code class="ts"></code>

角度是基于球面坐标得到的, 除了半径 r 之外用两个角度表示,
与 Z 轴的夹角控制在 (0, Math.PI) 之间(不需要 Math.PI 以上的部分),
XY 平面上与 X 轴的角度在 (0, 2 * Math.PI) 之间

https://en.wikipedia.org/wiki…

自己试过一遍, 后面就知道为什么的 Oribt Control 到 90 度就邪乎了,
到了 90 度的地方 camera 会出现一次翻转. 似乎 camera 是自动校正”上”这个方向的.
我当前的做法是把角度控制在 (0.01, 180 - 0.01) 之间的, 免得出问题.

glTF 存储格式和转换

glTF 文件格式有 .gltf.glb 两种.
GLTF 文件的 buffer 部分在 .gltf 里是用 Base64 编码保存的,
有时候也会被抽出来保存为 .bin 文件, 导致最后其实有两个文件,
这对于上传文件预览来说是一个坑, 需要指定使用 Embedded 模式生成文件才可以
否则会看到 GLTFLoader 尝试去获取一个 .bin 文件然后请求失败,
当然用 .bin 存的二进制在传输和性能上肯定是比用 Base64 要好的.

The Basic Structure of glTF
https://github.com/KhronosGro…

关于 GLTF 的介绍还可以看这个图 GLTF 概览.

关于格式转化, 比如 .obj 转换到 .gltf, 找到个命令行工具:
https://github.com/Analytical…

.stl 文件转换过来似乎没有直接可以用的, 但是可能转化到 .obj, 两份代码没有确认过:
https://gist.github.com/wills…

来源URL:https://segmentfault.com/a/1190000015169256