2013-04-01 3 views
3

Я работаю над пониманием семантики использования Scene Kit для связанных с преобразованием свойств для узлов. В частности, свойство pivot на узле не является одной точкой, а полной матрицей преобразования, и я не нашел ссылки на что-либо сопоставимое в спецификации Collada или другой документации.Какова семантика матрицы поворота Scene Kit?

Есть ли у кого-нибудь опыт с использованием матрицы поворота в наборе сцен или свойства с аналогичной семантикой? может ли кто-нибудь дать краткое объяснение/пример того, как это используется, или указатель на соответствующую документацию? Это похоже на потенциально полезный подход, но я бы предпочел не перепроектировать его, если я смогу его избежать.

Редактировать: Основываясь на ответе ОМЗ, казалось бы, что ось может быть просто еще одним слоем в дереве преобразований. Однако, если это так, как бы это было иначе, чем просто добавить промежуточный узел? Каким будет bais для определения того, где приложение, которое преобразуется?

ответ

3

Я опробовал идею @ omz. но идут некоторые противоречивые результаты, поэтому я вникнул в это еще несколько интересных результатов.

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

В частности, если я начинаю с родительского узла с преобразованием P и дочернего узла с преобразованием C, они объединяются для преобразования мира W = CATransform3DConcat (C, P). То же мировое преобразование W получается путем установки поворота родительского узла в обратный к C, а не установки преобразования для дочернего элемента.

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

Вот результат тестирования этого вывод:

Set parent rotation and node position. 

Transform: 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 1.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 1.00, 2.00, 3.00, 1.00 } 

Pivot: 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 1.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 0.00, 0.00, 0.00, 1.00 } 

World Transform: 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 0.00, -1.00, 0.00, 0.00 } 
{ 1.00, -3.00, 2.00, 1.00 } 
2013-04-04 13:49:55.453 Model Importer[43504:303] 

CATransform3DConcat(node.transform, node.parentNode.transform)] 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 0.00, -1.00, 0.00, 0.00 } 
{ 1.00, -3.00, 2.00, 1.00 } 
2013-04-04 13:49:55.454 Model Importer[43504:303] 

Set parent rotation and parent.pivot to inverse position. 

Transform: 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 1.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 0.00, 0.00, 0.00, 1.00 } 

Pivot: 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 1.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 0.00, 0.00, 0.00, 1.00 } 

World Transform: 
{ 1.00, 0.00, 0.00, 0.00 } 
{ 0.00, 0.00, 1.00, 0.00 } 
{ 0.00, -1.00, 0.00, 0.00 } 
{ 1.00, -3.00, 2.00, 1.00 } 

Вот код:

// Verification 
    SCNVector3 v3 = {1.0, 2.0, 3.0}; 
    SCNVector4 v4 = {1.0, 0, 0, M_PI/2.0}; 
    node.parentNode.rotation = v4; 
    node.position = v3; 
    NSLog(@"\n\nSet parent rotation and node position.%@", 
      [self transformsForNodeToString:node]); 
    // 
    // Verify match with CATransform3DConcat 
    NSLog(@"\n\nCATransform3DConcat(node.transform, node.parentNode.transform)]%@", 
      [self transformToString:CATransform3DConcat(node.transform, node.parentNode.transform)]); 
    // 
    // Clear the child node transform and put the inverse in the parent's pivot. 
    CATransform3D position = node.transform; 
    CATransform3D inversePosition = CATransform3DInvert(position); 

    node.transform = CATransform3DIdentity; 
    node.parentNode.pivot = inversePosition; 
    NSLog(@"\n\nSet parent rotation and parent.pivot to inverse position.%@", 
      [self transformsForNodeToString:node]); 
    node.parentNode.pivot = CATransform3DIdentity; 
    node.parentNode.transform = CATransform3DIdentity; 


+ (NSString*)transformsForNodeToString: (SCNNode*)node { 
    NSString* result = @"\n"; 
    result = [result stringByAppendingFormat: 
      @"\nTransform:%@\nPivot:%@\nWorld Transform:%@", 
      [self transformToString:node.transform], 
      [self transformToString:node.pivot], 
      [self transformToString:[node worldTransform]]]; 
    return result; 
} 

+ (NSString*)transformToString: (CATransform3D)transform { 
    NSString* result = @"\n"; 
    result = [result stringByAppendingFormat: 
       @"{ % .2f, % .2f, % .2f, % .2f }\n", transform.m11, transform.m12, transform.m13, transform.m14]; 
    result = [result stringByAppendingFormat: 
       @"{ % .2f, % .2f, % .2f, % .2f }\n", transform.m21, transform.m22, transform.m23, transform.m24]; 
    result = [result stringByAppendingFormat: 
       @"{ % .2f, % .2f, % .2f, % .2f }\n", transform.m31, transform.m32, transform.m33, transform.m34]; 
    result = [result stringByAppendingFormat: 
       @"{ % .2f, % .2f, % .2f, % .2f }\n", transform.m41, transform.m42, transform.m43, transform.m44]; 
    return result; 
} 

Комментарии приветствуются!

2

У меня нет опыта работы с SceneKit, но в приложениях 3D-моделирования довольно часто используется точка, которую можно поворачивать (иногда ее называют локатором). Это позволяет вам, например, сделать объект более удобным для вращения вокруг своей оси (что не обязательно соответствует мировой оси).

Для поворота, который не вращается, матрица будет равна CATransform3DMakeTranslation(x, y, z).

РЕДАКТИРОВАТЬ: Я считаю, что тот факт, что стержень задан как полная матрица, объясняется тем, что он является удобной структурой данных и согласуется с остальной частью модели. Я не могу думать о ситуации, когда вы хотите масштабировать ось, но представляя ее как матрицу, упрощает работу с ней с помощью обычных функций манипуляции с матрицами.

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

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

+0

Спасибо за ваш ответ! Я все еще запутался в семантике, хотя, когда pivot указывает полную матрицу. Я попробовал поиск по локатору, но, как и в случае поворота, использование этого термина кажется неоднозначным, и никто не соответствует тому, что вы описываете, или тому, что я вижу в Scene Kit. Вы случайно знаете какие-либо ссылки или ссылки? –

+0

Я немного изменил свой вопрос на основе вашего ответа. –

+0

Смотрите мое редактирование, я надеюсь, что это делает вещи немного яснее. – omz

1

Я думаю, вы найдете некоторые соответствующие образцы в материале Core Animation. pivot из SCNNode определяется как CATransform3D, который используется во время основной анимации как на Mac, так и на iOS.

Я так и не выкопал в «Сценарий», чтобы быть авторитетным. Но я нашел this post by Brad Larson: «Структура CATransform3D, предоставляемая Core Animation для выполнения манипуляций с CALayers, идентична структуре матрицы представления модели в OpenGL».

На GitHub, https://github.com/honcheng/CATransform3D-Test, есть отличный инструмент визуализации. Демо-версия Honcheng - только iPad, но я думаю, что все же полезно.

+0

Спасибо за ссылку на демо-версию GitHub. похоже, что это хороший ресурс. Тем не менее, я знаю, как преобразования работают в целом, но я пытаюсь понять намерение этого конкретного свойства узлов в Scene Kit, тем более, что я не вижу, как он сопоставляется с спецификацией Collada, так как большинство других функций в Scene Кит. –

Смежные вопросы