Na pierwszym rysunku widzimy normalne dla sfery. Na drugim normalne sfery zmapowane obiekt-świat błędnie, za pomocą takiej samej metody jak dla punktów intersekcji. Na trzecim widzimy to co chcielibyśmy uzyskać.
Weźmy prostą w 2D $\mathbf{f=ax}$, jej pochodna $\mathbf{f'=a}$, jej normalna (nazwijmy ją tak) $\mathbf{f''=-a}$. Teraz tak jak na naszym rysunku skalujemy zwężając dwukrotnie w osi Y. Równanie naszej prostej $\mathbf{f=\frac{1}{2}ax}$, zaś normalnej $\mathbf{f''=-\frac{1}{2}a}$. Załóżmy teraz dwukrotnie rozciągamy w osi X. Równanie naszej prostej, pochodnej i normalnej zmienia się podobnie. Czyli skalując o a skalujemy normalną o $\mathbf{\frac{1}{2}}$. Podobnie moglibyśmy wykazać wychodząc z definicji pochodnej.
Czyli jeśli nasza macierz skalowania to $\mathbf{S}$, to musimy ją zastąpić w macierzy transformacji obiekt-świat macierzą $\mathbf{S^{-1}}$. Translację powinniśmy pominąć, gdyż mamy do czynienia nie z punktem, a z wektorem. Rotację musimy zachować. Jeśli macierz naszej transformacji dla wierzchołków ma postać $\mathbf{M=TRS}$, to dla normalnych będzie miała postać $\mathbf{M=(TRS^{-1})_{ROT}=RS^{-1}}$
Przy okazji zauważmy, że mając macierz obiekt-świat: $\mathbf{M=TRS}$, macierz transformacji normalnej możemy zapisać jako:
$\begin{split}MN &= (TRS^{-1})_{ROT} \\
&= ((T^{-1})^{T}(R^{-1})^{T}(S^{-1})^T)_{ROT} \\
&= (((XRS)^{-1})^T)_{ROT} \\
&= ((M^{-1})^T)_{ROT} \\
&= ((M^{T})^{-1})_{ROT} \end{split}$
&= ((T^{-1})^{T}(R^{-1})^{T}(S^{-1})^T)_{ROT} \\
&= (((XRS)^{-1})^T)_{ROT} \\
&= ((M^{-1})^T)_{ROT} \\
&= ((M^{T})^{-1})_{ROT} \end{split}$
W przekształceniach skorzystaliśmy z faktu, że macierz odwrotna macierzy rotacji jest równa jej transpozycji, macierz transponowana macierzy skalowania jest równa jej samej. X to przekształcona macierz transpozycji. Ponieważ bierzemy część rotacji X ulega ona zniesieniu, równie dobrze możemy wpisać dowolną macierz która w części rotacyjnej 3x3 jest macierzą jednostkową, w szczególności T. Zauważmy, że elementy macierzy T nie wpływają na elementy macierzy rotacji 3x3 w macierzy S i R, ani ich iloczynu. Tak więc macierz transpozycji obiekt-świat dla normalnych jest równa odwrotnej transponowanej macierzy obiekt-świat dla wierzchołków, albo jak kto woli odwrotnej transponowanej macierzy obiekt-świat dla wierzchołków. Czasami może nam się to przydać jeśli nie wiemy jak taka macierz została złożona.
Przykład kodu:
private void UpdateTransformationMatrices() { m_local_to_world = Matrix4.CreateTranslation(Pos) * new Matrix4(Right, Up, Forward) * Matrix4.CreateScale(Scale); m_world_to_local = m_local_to_world.Inverted; m_local_to_world_normal = m_world_to_local.Transposed.Rotation; }
Brak komentarzy:
Prześlij komentarz