Gire um objeto para a visão da câmera

Aug 20 2020

Tento deixar isso o mais claro possível:

Ponto de partida

Coloco um objeto no centro (0,0,0) da cena. Em seguida, coloco uma câmera com um raio fixo em um hemisfério ao redor do objeto (e uso Restrições para que sempre olhe para o objeto) e renderizo a imagem. Exporto o objeto como .stl com y-up e menos-z-forward, a fim de abri-lo com outra biblioteca que usa essa convenção diferente.

Problema

Gostaria de girar o objeto de forma que corresponda à visualização da imagem renderizada.

Abordagem

Os ângulos para azimute e elevação são conhecidos. Então, calculo a matriz de rotação dados os dois ângulos (preciso de uma matriz de rotação homogênea, acrescentando os 0s e 1).

def angles_to_matrix(phi, theta):
    # phi describes the azimuth
    azi = phi
    # theta describes the inclination angle, thus:
    ele = radians(90) - theta
    rol = 0
    
    e1 = cos(rol) * cos(azi) - sin(rol) * cos(ele) * sin(azi)
    e2 = sin(rol) * cos(azi) + cos(rol) * cos(ele) * sin(azi)
    e3 = sin(ele) * sin(azi)
    e4 = -cos(rol) * sin(azi) - sin(rol) * cos(ele) * cos(azi)
    e5 = -sin(rol) * sin(azi) + cos(rol) * cos(ele) * cos(azi)
    e6 = sin(ele) * cos(azi)
    e7 = sin(rol) * sin(ele)
    e8 = -cos(rol) * sin(ele)
    e9 = cos(ele)
    
    return np.array(((e1, e2, e3, 0), (e4, e5, e6, 0), (e7, e8, e9,0 ), (0, 0, 0, 1)))

A rotação não parece correta. E sinto que pode haver várias coisas erradas:

  • Perdi algo sobre a mudança da orientação do eixo?
  • É possível usar os mesmos ângulos para calcular as coordenadas da esfera para calcular a rotação do objeto?

Você tem alguma ideia?

Respostas

1 batFINGER Aug 25 2020 at 21:33

Alinha o objeto à câmera

Isso dará o mesmo resultado que adicionar um objeto na visualização da câmera e usar ALIGN to VIEW

Por padrão, um objeto do blender está virado para -Y e tem Z para cima. A câmera, por outro lado, olha para baixo -Z com Y para cima.

Pode decompor uma matriz de objetos em sua localização, rotação e escala, e então recompor.

Neste caso, obtenha a parte de rotação do mundo da matriz da câmera, transformada em -Y para a frente e Z para cima e então recomposta no objeto com sua escala e translação originais.

import bpy
from mathutils import Vector, Matrix
from bpy import context
from bpy_extras.io_utils import axis_conversion

scene = context.scene
cam_ob = scene.camera
ob = context.object

A = axis_conversion(
        from_forward='Z',
        from_up='-Y',
        to_forward='Y',
        to_up='Z').to_4x4()

loc, rot, scale = cam_ob.matrix_world.decompose()

ob.matrix_world = (
    Matrix.Translation(ob.matrix_world.to_translation()) @
   (rot.to_matrix().to_4x4() @ A) @
    Matrix.Diagonal(ob.matrix_world.to_scale()).to_4x4()
    )