首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#和XNA在保持偏移量的情况下围绕另一个对象旋转对象(或者如何对随机点和随机骨骼进行蒙皮)

C#和XNA在保持偏移量的情况下围绕另一个对象旋转对象(或者如何对随机点和随机骨骼进行蒙皮)
EN

Stack Overflow用户
提问于 2013-07-12 00:31:47
回答 3查看 1.7K关注 0票数 0

我有一个对象X,它位于世界空间中,由它的四元数表示,让我们称后者为X_Base。我有另一个对象Y,它从对象X偏移,由它的四元数矩阵Y_Base表示。

这是它们在时间0的位置,在时间1,它们改变了位置。物体Y围绕它的轴旋转了一定角度,我知道它是一个新的四元数,它是Y_New。X相对于Y旋转,以使偏移保持在时间0处。我需要的基本上是X_New。

在英语中,我正在尝试手动设置模型的皮肤。我有一个从骨骼偏移一段距离的网格,当骨骼旋转时,我需要它来保持这个偏移。为什么我找不到一个明确的答案,我需要使用什么公式。

如果您有任何建议,我们将不胜感激。

更多的澄清:

想象一个太阳系,地球围绕太阳和它的轴自转。让我们这样做:月球不会围绕地球旋转,但它与地球的偏移量是不变的,并且无论你如何改变地球的位置,偏移量都保持不变。我需要的是找出月球在time1的位置,同时知道它在time0的位置,以及地球在time0和time1的位置。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-17 02:22:35

我可以给我的模型换皮了。下面是我所做的:

  1. “太阳”是我的模型的骨骼。它可以平移(在世界空间中)和旋转。“地球”是模型上的一个自定义的点,它随着模型的旋转/平移而移动,因为我的目标是,我不能只是选择任何点并给它换皮,我需要后者来移动模型。
  2. 我的应用程序中有两个方法:一个启动一次(初始化),另一个启动每帧(更新)。在Initialize方法中,我把太阳和地球的位置读取为2,XNA Matrix.
  3. In,

在Initialize I分解太阳矩阵以获得纯太阳的旋转矩阵(没有平移)中,Vector3差= TPoseEarth.Translation - TPoseSun.Translation;

  • Finally。我这样做是因为我的模型的骨骼Sun显然有一个非单位矩阵分配给它,即使在T-Pose。如下所示:

Vector3 scale;四元数旋转;out;TPoseSun.Decompose(out scale,out rotation,out tra);BaseSunRot = Vector3更新方法我得到了地球和太阳的当前世界位置。我分解太阳矩阵以获得纯旋转(再一次!)

Vector3 scale;四元数旋转;Vector3 tra;Sun.Decompose(输出缩放,输出旋转,输出tra);SunRot SunRot=矩阵通过将基础旋转的倒数乘以新旋转来计算唯一的骨骼-太阳旋转:

矩阵UniqueRot = Matrix.Invert(BaseSunRot) *SunRot;

  • 我将地球的平移设置为(太阳的T姿态位置和地球的T姿态位置之间的差):

矩阵地球=太阳;Difference;

  • I =Matrix.Identity乘以地球矩阵的唯一骨骼(太阳的)旋转:

Earth *= UniqueRot;

  • I添加太阳的当前位置,以提供帧之间可能的平移:

地球Sun.Translation;

  • The +=结束。地球矩阵包含有关蒙皮顶点的所有必要信息。

我不是100%确定,但我觉得这基本上是一本关于如何在世界上任何骨骼上对任何给定点进行蒙皮的手册(即旋转/平移,保持初始偏移量)。问题是,代码没有优化:)。如果任何人有任何关于如何优化它的想法,我将非常感谢。

特别是,我想知道是否可以跳过双矩阵分解,简单地将完整的ScaleRotationTranslation矩阵相乘?我正在尝试,但没有任何成功。

票数 1
EN

Stack Overflow用户

发布于 2013-07-12 17:20:45

你可能会在“四元数”中迷惑我,但我已经看过很多关于这个问题的2D示例,并且总是有一个简单的方法来解决它:

基本上,您需要为两个对象使用完全相同的originrotation,以便它们之间自动保持恒定的偏移量。

票数 0
EN

Stack Overflow用户

发布于 2013-07-12 17:23:02

首先,我认为如果你使用矩阵而不是四元数,你会发现这个问题要简单得多。四元数只包含旋转,因此您需要在向量中单独存储平移(位置),而矩阵包含旋转和平移。

对于太阳系,您将为太阳和地球指定一个世界矩阵。太阳的位置是这样的,它的中心位于世界原点0,0,0。太阳的矩阵将包含围绕y轴的旋转(使其旋转)。

代码语言:javascript
复制
sun.World = Matrix.CreateRotationY(angle);

地球将有一个相对太阳的位置。该值将保持不变,并用于创建转换矩阵。如果你将这个矩阵与太阳的世界矩阵相乘,你就会得到地球的世界矩阵:

代码语言:javascript
复制
earth.World =
    Matrix.CreateTranslation(earth.Position) *
    sun.World;

注意矩阵乘法的顺序很重要。随着时间的推移,这将使地球围绕太阳旋转。旋转也可以应用于地球,使其绕轴旋转,如下所示:

代码语言:javascript
复制
earth.World =
    Matrix.CreateRotationY(angle) *
    Matrix.CreateTranslation(earth.Position) *
    sun.World;

要将月球定位在绕地球运行的轨道上,可以应用相同的原理:

代码语言:javascript
复制
moon.World =
    Matrix.CreateTranslation(moon.Position) *
    earth.World;

如果需要使用四元数,可以将它们与矩阵相互转换:

代码语言:javascript
复制
Quaternion quaternion = Quaternion.CreateFromRotationMatrix(matrix);
Vector3 translation = matrix.Translation;

Matrix matrix = Matrix.CreateFromQuaternion(quaternion);
matrix = Matrix.CreateTranslation(translation) * matrix;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17598793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档