Gire um objeto para a visão da câmera
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
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()
)