sprawienie, by przedmioty były właściwie skierowane w stronę normalnych

Dec 16 2020

Napisałem ten mały dodatek: https://gist.github.com/SuddenDevelopment/16df6602a2ecab06f56dc8a2c7e4c9e0

i na początku myślałem, że to świetnie, ale znalazłem kilka scenariuszy, w których światła obszarowe są skierowane w niewłaściwym kierunku.

Próbuję uzyskać normalne dla twarzy, obracam światło, aby dopasować je do tej twarzy, a następnie skieruj je w kierunku normalnym, ale działa to w przypadku mniej więcej połowy twarzy, gdy przychodzi skierowanie we właściwym kierunku. Jeśli gram z jaką osią w rotacji o ćwiartkę, otrzymuję różne, które są poprawne, też próbowałem.inverted()

Nie wiem nawet, czy idę w dobrym kierunku. doceniona pomoc.

Odpowiedzi

2 batFINGER Dec 16 2020 at 21:52

Podejście skoncentrowane na macierzy

Kod umożliwiający umieszczenie obiektu lampy w środku każdej wybranej ściany siatki, z jasną lokalną osią -Z skierowaną w kierunku normalnej ściany.

Znajdź globalny kierunek normalnej twarzy, mnożąc wstępnie z macierzą globalnego obrotu obiektów. (Brak skali).

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)

Lokalne z rodzicielstwem.

Powyższy kod dodaje światła w scenie przy globalnej orientacji twarzy. Jeśli siatka zostanie przesunięta, światła nie będą z nią współpracować.

Inną opcją byłoby użycie tylko lokalnych współrzędnych i uczynienie każdego światła dzieckiem siatki.

Skalowanie w celu dopasowania do twarzy.

Wygląda na to, że skalujesz również obszar światła, aby pasował do twarzy. Aby to zrobić, gdy oś nie jest wyrównana, jest nieco głębsza niż znajdowanie minimów / maksimów osi. IMO całkiem możliwe, że uzasadnia inne pytanie

Kilka przykładów wykorzystujących inny wektor do wyrównywania. Ściana ma kilka metod stycznych obliczeniowych, opartych na najdłuższej krawędzi, krawędziach. Można regulować, obracając światło wokół jego lokalnej osi z (normalna twarzy), aby dopasować się do stycznej. W ten sposób jedna znana oś jest wyrównana z krawędzią i można ją skalować w celu dopasowania.

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

Wyrównaj powierzchnię normalną do osi Z.

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

podobnie w tym przypadku poli wewnętrzne kąty odwzorowują narożniki na 2d. Podobnie tutaj, jeśli normalna ściany jest wyrównana do osi, współrzędne można odwzorować na 2d.

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

Jeśli współrzędne są w 2d, istnieje kilka metod pomocniczych (głównie dla UV), które pasują do prostokątów.

Korzystanie z mathutils.geometry.box_fit_2d