Вращающиеся объекты, прикрепленные к другим объектам
У меня есть вопрос, касающийся одной сетки (здания), которая содержит коллекцию анимированных объектов (эти объекты составляют законченное здание, поднимаясь над землей, когда оно строится, с разными скоростями и вращениями).
Все анимированные объекты в сетке имеют свои собственные дорожки анимации положения и вращения. Я экспортирую его из 3DS Max как ASE, конвертирую в подходящий формат и использую в своем игровом движке.
Итак, на данный момент я могу успешно отображать анимированные позиции всех анимированных объектов в сетке. Делать следующее:
Переменные масштаба, поворота и перевода - это информация о преобразовании здания. Это действительно для всех подобъектов. Переменная pos указывает положение подобъектов относительно центра здания.
foreach (GeometricObject geoObject in mesh.GeoObjects)
{
Vector3 pos = geoObject.AnimationData.PositionTrack[(int)m_keyFrameTime];
Vector3 translatedPos = new Vector3(translation.X + pos.X,
translation.Y + pos.Y,
translation.Z + pos.Z)
_eRenderer.ActiveCamera.World = Matrix.CreateScale(scale) *
Matrix.CreateFromQuaternion(rotation) *
Matrix.CreateTranslation(translatedPos);
}
Это прекрасно отображает анимированное здание (поднимающееся с земли), и все субобъекты находятся в правильных положениях.
Теперь проблема возникает, когда я пытаюсь повернуть подчиненные объекты. Я испробовал несколько разных подходов, но перевод подобъектов всегда, кажется, запутался после того, как я повернул подобъект. Это то, что у меня есть в настоящее время, но оно все еще запутано:
foreach (GeometricObject geoObject in mesh.GeoObjects)
{
Vector3 pos = geoObject.AnimationData.PositionTrack[(int)m_keyFrameTime];
Vector3 translatedPos = new Vector3(translation.X, translation.Y, translation.Z)
Matrix rotateSubObjects;
rotateSubObjects = Matrix.CreateTranslation(new Vector3(pos.X, pos.Y, pos.Z));
rotateSubObjects *= Matrix.CreateFromQuaternion(geoObject.AnimationData.RotationTrack[(int)m_keyFrameTime]);
_eRenderer.ActiveCamera.World = Matrix.CreateScale(scale) *
Matrix.CreateFromQuaternion(rotation) *
Matrix.CreateTranslation(translatedPos) *
rotateSubObjects;
}
Я читал, что мне может понадобиться перевести субобъекты обратно в их источник, чтобы они вращались вокруг своего источника, а затем перевести его обратно в свое мировое положение, но я не уверен, как это сделать в этом случае.
У меня нет идей, любая помощь будет оценена! С уважением, Риан.
1 ответ
Преобразование, которое вы ищете, таково:
Matrix positionRotationMatrix = Matrix.CreateTranslation(-parentPosition)
* Matrix.CreateFromQuaternion(parentRotation)
* Matrix.CreateTranslation(parentPosition);
Vector3 translation = Vector3.Transform(parentPosition + relativePosition,
positionRotationMatrix);
Вы определяете свою мировую матрицу с новой позицией подобъектов (translation
переменная):
Matrix worldMatrix = Matrix.CreateScale(scale)
* Matrix.CreateFromQuaternion(rotation)
* Matrix.CreateFromQuaternion(parentRotation)
* Matrix.CreateTranslation(translation);
Чтобы продемонстрировать, вот куб (родитель), который вращается вокруг своей позиции со стрелкой, положение и вращение которой определены относительно его родительской позиции и вращения. Стрелка следует за вращением куба и вращается вокруг своей оси Z независимо.
Значения, использованные для демонстрации:
parentPosition = Vector3(-1.1f, 0f, -2); //cube
relativePosition = Vector3(0, 0, -3); //arrow
parentRotation = Quaternion.CreateFromRotationMatrix(
Matrix.CreateRotationZ(angle)
* Matrix.CreateRotationY(angle)
* Matrix.CreateRotationX(0.5f));
rotation = Quaternion.CreateFromYawPitchRoll(0f, 0f, angle);
angle += 0.05f;