在 ThreeJS 中缩放 OBJ 的一部分
Posted
技术标签:
【中文标题】在 ThreeJS 中缩放 OBJ 的一部分【英文标题】:Scale part of an OBJ in ThreeJS 【发布时间】:2018-03-26 16:14:15 【问题描述】:我有一个如下所示的.obj
文件:
我需要做的是仅缩放手柄的特定部分 - 在这种情况下,手柄实际从顶部向下弯曲的点。因此,在这种情况下,我希望能够使它们更长。
有没有人有任何方向或例子来说明如何做到这一点?我看到的所有示例都只是缩放整个模型,而不仅仅是其中的一部分。
我在想我需要根据 obj 中的顶点创建一个样条线,然后操作创建的样条线,但我希望有更简单的选择,因为我不知道如何组合样条线模型
谢谢
编辑 我相信答案不在于样条线 - 实际上在于变形对象的目标属性。当我进一步了解时,我会在这里发帖,或者,如果有人知道我的意思,请指出我正确的方向。
编辑 2 按照 zero 的建议,我尝试将 SkinnedMeshes 与骨骼一起使用。我正试图用Vector4
对象填充skinIndices
和skinWeights
,但Typescript 抛出错误:
'Vector4'
类型的参数不能分配给number
类型的参数
我知道这是一个 Typescript 问题而不是 ThreeJS 问题,但我创建了一个具有相同代码的 jsfiddle,但其中 skinIndices
的数组类型为 Vector4.
我能想到的唯一原因是't 是因为我通过THREE.fromBufferGeometry
函数发送.obj
对象的BufferedGeometry
:
let geometry = new THREE.Geometry().fromBufferGeometry(frontHandle.children[0].geometry);
编辑 3
let geometry = new THREE.Geometry().fromBufferGeometry(frontHandle.children[0].geometry);
for ( let i = 0; i < geometry.vertices.length; i ++ )
let vertex = geometry.vertices[ i ];
let y = (vertex.y + sizing.halfHeight);
let skinIndex = Math.floor( y / sizing.segmentHeight );
let skinWeight = ( y % sizing.segmentHeight ) / sizing.segmentHeight;
let vectorOne = new THREE.Vector4( skinIndex, skinIndex + 1, 0, 0);
let vectorTwo = new THREE.Vector4( 1 - skinWeight, skinWeight, 0, 0);
// Here's where the compliant is
geometry.skinIndices.push(vectorOne);
geometry.skinWeights.push(vectorTwo);
编辑 4
我解决了上面描述的问题,现在有了这个(蓝色手柄是蒙皮网格,里面有很多骨头,垂直的蓝绿色线是骨架助手):
我还添加了 DATGUI 帮助程序,如下所示:
但我似乎仍然无法恰到好处地缩放网格。屏幕截图中手柄的打结部分应始终保持相同大小。当我将它们按比例缩小时,我只需要它们下方的把手部分延伸,并希望当袋子变大时,打结的部分可以横向扩展。
【问题讨论】:
如何添加骨骼,对它们的手柄进行加权,然后将骨骼放大/缩小到您喜欢的大头模式? 我不明白你的意思 - 你能详细说明或提供一个例子的链接吗? Skinned Meshes 允许您对顶点进行分组,而不是单独变换顶点,而是变换骨骼。每个顶点都对骨骼进行加权,如果将多个变换应用于多个骨骼,则顶点会接收两个变换,这些变换都根据其相对于骨骼的权重进行缩放。链接中有演示。 谢谢 - 我现在去看看 @zero298 查看我的第二次编辑 【参考方案1】:据我了解,您正在尝试使网格变形。网格变形主要有两种方式:
-
Morph Targets
Skeletal Animation
变形目标
变形目标允许您定义多个变换“目标”或关键帧,您可以在它们之间混合网格。这通常用于为网格设置动画。变形目标是冗长的。它们基本上是您的网格的复制品,但每个顶点都转换为您希望目标看起来的方式。它们允许对顶点进行非常细粒度的操作,因为您可以指定每个关键帧每个顶点的精确变换。但是,如上所述,它们很冗长。您必须使每个变形目标都以某种方式可用,以便您可以将目标混合在一起。
如果您有 2000 个顶点的多边形和 3 个变形目标,则必须保留 6000 个顶点的定义。
网格皮肤和骨骼
控制顶点变换的另一种方法是使用骨骼。骨骼允许您向一个顶点添加多个变换影响,并且以某种方式将顶点组合在一起,这样您就可以变换骨骼以获得所需的网格变形,而不必手动调整单个顶点。
您仍将定义变换关键帧,但您将为骨骼而不是单个顶点定义它们。这具有节省空间和实现转换重用的好处。您不必为网格中的每个顶点定义新的变换,而是定义将网格绑定到骨架的“皮肤”,并且骨架动画应该适当地动作。
在您的情况下,我不确定哪种技术更适合应用。我认为皮肤会有所帮助,因为您可以设置手柄中要转换为骨骼的所有顶点的权重,然后去掉结和袋子的权重。然后你可以应用你需要做的任何变换。
three.js 支持蒙皮网格。您可以在此处查看 API 和演示:Skinned Meshes。
【讨论】:
以上是关于在 ThreeJS 中缩放 OBJ 的一部分的主要内容,如果未能解决你的问题,请参考以下文章
如何在加载到场景之前将 OBJ/FBX 转换为 GLTF(使用 Threejs)