Цитата:
Сообщение от AlexLucas
Но при вращении придётся вращать каждый элемент вокруг своей оси и вокруг центра тяжести группы (который можно будет перетаскивать), что обещает доставить немало хлопот.
|
Почему? Это банальное домножение матриц трансформации на одну и ту же матрицу. Если не ошибаюсь, домножать нужно будет слева.
Цитата:
|
У меня вопрос - какой из вариантов будет жрать меньше ресурсов? Конечно многое зависит от реализации, но всё же?
|
Сколько у вас будет элементов? Групп? Глубина вложенных групп? Количество перемещений? Количество вращений? У меня есть сильные подозрения, что основные проблемы доставит рендеринг вашего хозяйства на экран после перемещения, а не сам проход по элементам в группе (если там сильно не накосячить). А разницы между движением через спрайт и каждого отдельного спрайта особой не будет. Там в одном случае умножение на матрицу-трансформатор будет делать флеш-плеер, а во втором - то же самое вы вручную. В общем, на отдельных объектах будет на одно умножение меньше (что не принципиальнь, если только у вас нет вложенности в несколько тысяч групп, на дне которой всего один элемент). Ну и техники вроде cacheAsBitmap вы для группы использовать не сможете на отдельных спрайтах.
В вашем случае правильное решение не заботится пока о быстродействии отрисовки, но принять меры для возможности замены способа отображения (спрайт или отедльные спрайты на экране) без изменения остальной логики. Простыми словами, отделить Model+Controller от View. Model от изменения способа отображения у вас измениться не должен. А потом уже по месту решать, что делать со view.
Цитата:
|
И может есть третий вариант, который намного проще и я попусту бьюсь головой об батарею?
|
Ну так матрицы же. Ключевые слова: линейная алгебра, аналитическая геометрия, линейное пространство, операторы над линейными пространствами. Первый курс (технические вузы). ЛинАл и АнГем в нужном объеме идут обычно в одном учебнике. Какие-то вещи можно пропустить (не нужны определители, метрические пространства и все, что с ними связано, кривые второго порядка).
Все ваши действия делаются элементарным домножением слева на матрицу трансформации. Т.е. была у объекта матрица Mo, стала Mt*Mo, где Mt - матрица преобразования. Для поворотов/сдвигов строится легко. Для перекоса (skew) повернутой группы (в координатах группы) чуть-чуть сложнее (добавится обратная матрица текущего преобразования группы). Соответственно, если у вас объекты собраны в одну группу, умножается только матрица группы. Если разобрана - матрицы отдельных элементов группы. Mt в этом случае - одна для всех таких элементов вне зависимости от вложенности!
Ну и на всякий случай - никакой магии там нет. Эффективная матрица для объектов в группе строится путем умножения на внешние матрицы групп

. Т.е. в одном случае у вас было Mg1*Mg2*Mob=Mobj1 (g1, g2 - группы, Mob- матрица трансформации объекта в группе g2, Mg2 - трансформация группы g2 относительно g1, Mg1 - трансформация g1 относительно сцены, Mobj1 - трансформация объекта относительно сцены). Очевидно, что из этого следует, что (Mt*Mg1)*(Mg2*Mob)=Mt*(Mg1*Mg2*Mob)=Mt*Mobj1, так что с точки зрения чистой математики без разницы, кого на что домножать.
С точки зрения реализации я бы хранил отдельные матрицы трансформации для групп и объектов внутри группы. Для визуализации - как угодно. Можно складывать в спрайты (может быть, ставить им cacheAsBitmap). Можно раскладывать индивидуальные листья, вычисляя эффективную матрицу. Для трансформаций есть небольшое отличие, связанное с точностью вычислений. При использовании индивидуальных матриц из-за потери точности объекты внутри группы могут начать "разъезжаться" относительно друг друга. Т.е. после какого-то количества поворотов, например, квадрат перекосится. Причем вернуть объекты "в исходное состояние" уже не получится. А в группе (с отдельной матрицей) можно будет сбросить трансформацию группы и объекты станут квадратными. Хотя вы артефакты из-за точности вряд ли заметите, чтобы что-то накопилось, нужно быть или очень везучим (чтобы сразу создать матрицу трансформации, которая даст артефакт), или очень долго и нудно крутить объект (миллионы и миллиарды раз).
Всякие rotation/scaleX/scaleY/x/y у визуального объекта вам не нужны. Совсем. Вам нужны матрицы. При желании преводить координаты из одних систем в другие (ну мало ли где нужно, для вывода на экран, например) используются те же матрицы преобразования объектов. В матрицах все прекрасно пишется и работает. Прием все операции (повотот, сдвиг, масштабирование, перекос (skew)) - все это домножения на матрицы, только матрицы разные. Соответственно, выбор и формирование матрицы делается при выборе операции, а затем на модель просто применяется операция (applyTransform(Matrix), например).