试图将任何网格变形为球体。如何将顶点位置平移到球体上?
Trying to deform any mesh into a sphere. How to translate the vertex position to lie on a sphere?
我正在尝试为 Maya 编写一个变形器脚本,使用 Maya API 通过平移它的顶点将任何网格变形为球体。
我已经拥有的是一个变形器,它以指定的量在其法线方向上平移网格的每个顶点。这是使用以下等式完成的。
point += normals[itGeo.index()] * bulgeAmount * w * env;
其中,点是网格上的顶点。 normals[itGeo.index()] 是一个向量数组,表示每个顶点的法线。 w和env是控制变形和包络的权重。
这段代码主要做的是,它以指定的量沿法线方向平移顶点。虽然这适用于球体,因为球体的顶点法线会指向中心。它不适用于其他网格,因为法线不会指向网格的中心。
float bulgeAmount = data.inputValue(aBulgeAmount).asFloat();
float env = data.inputValue(envelope).asFloat();
MPoint point;
float w;
for (; !itGeo.isDone(); itGeo.next())
{
w = weightValue(data, geomIndex, itGeo.index());
point = itGeo.position();
point += normals[itGeo.index()] * bulgeAmount * w * env;
itGeo.setPosition(point);
}
我最初认为改变翻译方向可以解决问题。就像,如果我们可以找到从网格中心到每个顶点的方向上的矢量,并沿该方向将其平移指定的量即可解决该问题。像这样:
point += (Center - point) * bulgeAmount * w * env;
其中,Center是网格的中心。但这并没有给出预期的结果。我还希望变形器的设置方式使用户可以输入半径 "r" 值,还可以将 amount 属性从 0 更改为 1,以将网格从其原始状态变形为球形。这样他就可以根据她的意愿选择一个介于两者之间的值,并且网格将介于球体和原始形状之间。
这是我在 Whosebug 中的第一个 post。如果格式不符合社区的期望,我深表歉意。对此的任何帮助将不胜感激。
谢谢。
关于方向:
我认为你的台词:
point += (Center - point) * bulgeAmount * w * env;
是一个很好的起点。
但是不要使用 (Center - point),而应该使用它的反义词 (point-Center) 并在使用前对其进行归一化。如果您不使用此(点-中心)向量的规范化版本,每个顶点都会被转换到错误的位置。
关于 0.0(原始)到 1.0(球体)之间的变化:
若Po为原位置
如果Pf是最终位置
如果 d 是点 Po 和中心 C 之间的原始距离:
d=norm(中心-点) = norm(C-Po)
如果 Direction 是 (Center - point)/d(如此归一化,如上所述)
我们想要的:
在 r=0.0 时,您的顶点必须保持在其原始位置:Pf = Center + Direction * d
在 r=1.0 时,您的顶点必须紧贴半径为 R 的球体:Pf = 中心 + 方向 * R
如果我们概括:
Pf = C + 方向 * ( r*R + (1-r)*d )
d = norm(C-Po)
方向 = (C-Po)/d
R 你球体的半径
和 r 之间的用户参数 [0.0; 1.0]
不知道我说的够不够清楚,我不习惯在这里回答:)
最佳
我正在尝试为 Maya 编写一个变形器脚本,使用 Maya API 通过平移它的顶点将任何网格变形为球体。
我已经拥有的是一个变形器,它以指定的量在其法线方向上平移网格的每个顶点。这是使用以下等式完成的。
point += normals[itGeo.index()] * bulgeAmount * w * env;
其中,点是网格上的顶点。 normals[itGeo.index()] 是一个向量数组,表示每个顶点的法线。 w和env是控制变形和包络的权重。
这段代码主要做的是,它以指定的量沿法线方向平移顶点。虽然这适用于球体,因为球体的顶点法线会指向中心。它不适用于其他网格,因为法线不会指向网格的中心。
float bulgeAmount = data.inputValue(aBulgeAmount).asFloat();
float env = data.inputValue(envelope).asFloat();
MPoint point;
float w;
for (; !itGeo.isDone(); itGeo.next())
{
w = weightValue(data, geomIndex, itGeo.index());
point = itGeo.position();
point += normals[itGeo.index()] * bulgeAmount * w * env;
itGeo.setPosition(point);
}
我最初认为改变翻译方向可以解决问题。就像,如果我们可以找到从网格中心到每个顶点的方向上的矢量,并沿该方向将其平移指定的量即可解决该问题。像这样:
point += (Center - point) * bulgeAmount * w * env;
其中,Center是网格的中心。但这并没有给出预期的结果。我还希望变形器的设置方式使用户可以输入半径 "r" 值,还可以将 amount 属性从 0 更改为 1,以将网格从其原始状态变形为球形。这样他就可以根据她的意愿选择一个介于两者之间的值,并且网格将介于球体和原始形状之间。
这是我在 Whosebug 中的第一个 post。如果格式不符合社区的期望,我深表歉意。对此的任何帮助将不胜感激。
谢谢。
关于方向:
我认为你的台词: point += (Center - point) * bulgeAmount * w * env;
是一个很好的起点。 但是不要使用 (Center - point),而应该使用它的反义词 (point-Center) 并在使用前对其进行归一化。如果您不使用此(点-中心)向量的规范化版本,每个顶点都会被转换到错误的位置。
关于 0.0(原始)到 1.0(球体)之间的变化:
若Po为原位置
如果Pf是最终位置
如果 d 是点 Po 和中心 C 之间的原始距离:
d=norm(中心-点) = norm(C-Po)
如果 Direction 是 (Center - point)/d(如此归一化,如上所述)
我们想要的:
在 r=0.0 时,您的顶点必须保持在其原始位置:Pf = Center + Direction * d
在 r=1.0 时,您的顶点必须紧贴半径为 R 的球体:Pf = 中心 + 方向 * R
如果我们概括:
Pf = C + 方向 * ( r*R + (1-r)*d )
d = norm(C-Po)
方向 = (C-Po)/d
R 你球体的半径
和 r 之间的用户参数 [0.0; 1.0]
不知道我说的够不够清楚,我不习惯在这里回答:) 最佳