conseguir que los objetos miren correctamente hacia lo normal

Dec 16 2020

Escribí este pequeño complemento: https://gist.github.com/SuddenDevelopment/16df6602a2ecab06f56dc8a2c7e4c9e0

y al principio pensé que lo estaba haciendo muy bien, pero encontré un montón de escenarios en los que las luces del área miran en la dirección incorrecta.

Intento obtener las normales para una cara, mover, rotar la luz para que coincida con esa cara y luego mirarla hacia la normal, pero funciona para aproximadamente la mitad de las caras cuando se trata de mirar en la dirección correcta. Si juego con qué ejes están en la rotación por cuartos obtengo diferentes que son correctos, también probé.inverted()

Ni siquiera sé si voy en la dirección correcta. ayuda apreciada.

Respuestas

2 batFINGER Dec 16 2020 at 21:52

Enfoque centrado en la matriz

Código para colocar un objeto de lámpara en el centro de cada cara seleccionada de una malla, con el eje -Z local de luz apuntando en la dirección de la cara normal.

Encuentre la dirección global de una cara normal multiplicándola previamente con la matriz de rotación global de los objetos. (Sin escala).

import bpy
import bmesh
context = bpy.context

ob = context.edit_object
mw = ob.matrix_world
me = ob.data
bm = bmesh.from_edit_mesh(me)

faces = [f for f in bm.faces if f.select]

while faces:
    f = faces.pop()
    light = bpy.data.lights.new(
            f"Face{f.index}",
            type='AREA',
            )
    light.size = 1
    light_ob = bpy.data.objects.new(
            f"Face{f.index}",
            light,
            )
    M = mw.normalized() @ f.normal.to_track_quat('-Z', 'Y').to_matrix().to_4x4()
    M.translation = mw @ f.calc_center_median()
    light_ob.matrix_world = M
    context.collection.objects.link(light_ob)

Local con crianza de los hijos.

El código anterior agrega las luces en la escena en la orientación global de la cara. Si la malla se mueve, las luces no la acompañan.

Otra opción sería usar solo coordenadas locales y hacer que cada luz sea un hijo de la malla.

Escalado para adaptarse a la cara.

Parece que también está escalando la luz del área para que se ajuste a la cara. Hacer esto cuando el eje no está alineado es un poco más profundo que encontrar ejes mínimos / máximos. La OMI posiblemente justifique otra pregunta.

Algunos ejemplos que usan otro vector para alinear. La cara tiene algunos métodos de calc tangente, basados ​​en aristas de borde más largo. Se puede ajustar girando la luz alrededor de su eje z local (la cara normal) para que coincida con la tangente. De esta manera, tenga un eje conocido alineado con un borde y pueda escalar para coincidir.

https://blender.stackexchange.com/a/94047/15543

Alinee una cara normal al eje Z.

https://blender.stackexchange.com/a/121227/15543

De manera similar, en este, los ángulos interiores de polietileno mapean las vértices de las esquinas en 2d. De manera similar, aquí, si la normal de la cara está alineada con un eje, las coordenadas se pueden asignar a 2d.

https://blender.stackexchange.com/a/203355/15543

Si las coordenadas están en 2d, existen algunos métodos auxiliares (principalmente para UV) que se ajustan a los rectángulos.

Usando mathutils.geometry.box_fit_2d