3D относительно абсолютных трансформаций - PullRequest
5 голосов
/ 07 ноября 2011

Я пытаюсь создать граф сцены для моей трехмерной игры, в которой преобразования каждого объекта относительно его родителя. Каждый узел графа имеет вектор вращения, масштабирования и перемещения.

Как правильно комбинировать матрицы относительных преобразований для получения абсолютного преобразования объекта? Я был бы рад, если бы вы могли также объяснить свое решение.


Вот пример того, как это сделать НЕПРАВИЛЬНО:
На самом деле это было решением:

Matrix GetAbsoluteTransformation()
{
    if (!this.IsRoot())
    {
        return this.Transformation * this.Parent.GetAbsoluteTransformation();
    }
    else
    {
        return this.Transformation;
    }
}

В этом случае, когда родительский узел поворачивается, масштабируется или перемещается, дочерний узел трансформируется на ту же величину, что является правильным поведением! Но ребенок будет вращаться только вокруг своего собственного происхождения и не будет двигаться вокруг происхождения родителя.


Применение:

Существует модель автомобиля с четырьмя колесами. Колеса расположены относительно места происхождения автомобиля. Колеса могут вращаться так же, как и настоящие колеса. Если я сейчас поверну машину, колеса должны постоянно оставаться на ней. В этом случае автомобиль - это корень, а колеса - это дочерние узлы.

Другим примером может служить модель солнечной системы. Планеты вращаются вокруг своей оси, движутся вокруг Солнца, а спутники движутся вокруг планет.

Ответы [ 3 ]

3 голосов
/ 07 ноября 2011

Что касается твоего "как сделать это неправильно", я ненавижу рассказывать тебе это, но это не так;скорее он неполонВы должны выполнять такую ​​работу независимо от родительских и дочерних отношений.

Вот пример этого: колесо прикреплено к машине, как вы упомянули.Если вы переводите или вращаете автомобиль, вам не нужно прикасаться к колесам - они находятся в том же месте относительно автомобиля .Однако, когда вы пытаетесь получить новое местоположение колеса в «реальном мире», вы должны пройти по дереву, применяя преобразования матрицы по мере продвижения.Это все работает, верно?

Когда вы вращаете объект, он вращается вокруг своего СОБСТВЕННОГО начала.Таким образом, колесо, вероятно, должно вращаться вокруг своей оси y, а планета - вокруг своей оси z.Но теперь, если вам нужно переместить планету «вокруг Солнца», вы делаете что-то совершенно другое.Это должно быть рассчитано отдельно.Это не значит, что его нельзя будет облегчить, если использовать некоторые из того же матча, который у вас уже есть (хотя я не могу сказать наверняка, не выполняя математические расчеты самостоятельно), но это совсем другое.

Вы смотрите на фактическое изменение состояния объекта.Это красота графа сцены!Если у вас не было графа сцены, вам нужно было бы выяснить все различные значения вплоть до главной сцены, а затем выполнить все виды математики.Здесь вам просто нужно сделать немного триггера и алгебры, чтобы передвигаться по планете (вы можете погуглить небесную механику) и перемещать планету относительно ее звезды.В следующий раз, когда основная сцена спросит, где находится планета, она просто пойдет вниз по графику сцены!: -D

1 голос
/ 07 ноября 2011

Это зависит от того, используете ли вы OpenGL или Direct3D. В OpenGL преобразования применяются справа налево, тогда как в Direct3D они применяются слева направо. Оба они являются совершенно правильными способами проектирования системы преобразования, но это означает, что вы должны думать о них по-разному.

Мне кажется, что проще всего думать в системе OpenGL, но в обратном направлении. Вместо того, чтобы думать о том, как вершины объекта перемещаются при применении преобразований справа налево, я представляю систему координат объекта, преобразуемого в порядке слева направо. Каждое преобразование применяется относительно новой локальной системы координат, а не относительно мира.

В случае колес на автомобиле задействованы три преобразования: положение автомобиля в пространстве, начало колеса относительно автомобиля и ориентация колеса относительно его нейтрального положения. Просто примените их в порядке слева направо (или наоборот для Direct3D). Чтобы нарисовать четыре колеса, сначала примените преобразование автомобиля, затем запомните текущее преобразование, затем примените преобразования местоположения и ориентации по очереди, возвращаясь к запомненному преобразованию автомобиля после каждого.

1 голос
/ 07 ноября 2011

Я думаю, что это правильное поведение.

Я не думаю, что поворот вокруг источника родителя - это то, что может быть достигнуто с помощью простого стека матриц.Я думаю, что вы можете распространять информацию только от родителей к детям.

Вместо этого вы можете попробовать установить относительное вращение и преобразование на основе смещений от абсолютного источника родителя, хотя это гораздо больше вычислений, чем просто добавление в стек матрицы.

Вот аналогичный вопрос: Получение абсолютного положения и поворота из графа сцены?

...