36.00 sürümünden itibaren, UEFN’de editör ve tüm /Verse.org modül dönüşümleri için LUF koordinat sistemi kullanılmaya başladı. /UnrealEngine.com ve /Fortnite.com modül dönüşümleri ise XYZ koordinat sistemini kullanır.
LUF Koordinat Sistemine Giriş
Tüm başlıca 3D içerik oluşturma araçları, Objeleri konumlandırmak ve döndürmek için bir Kartezyen koordinat sistemi (X, Y ve Z) kullanır. Hangi eksenlerin (X, Y veya Z) hangi yönleri temsil ettiği (sol/sağ, yukarı/aşağı ve ön/arka gibi), araçlar arasında farklı yorumlanır. Ayrıca, dönüşlerin modellenme şekli (koordinat sisteminin sağlak mı yoka solak mı olduğu; el tercihi olarak da adlandırılır) farklı araçlar arasında değişir.
Verse ve UEFN’i 3D içerik oluşturma konusunda yükselen standartlara ve önde gelen araç takımlarıyla daha uyumlu hale getirmek için koordinat sistemi sunumunda iki temel değişiklik yapıyoruz.
Öncelikle, koordinat eksenlerini X, Y ve Z ile etiketlemek yerine daha açıklayıcı eksen adları getiriyoruz:
Sol (eski -Y)
Yukarı (eski Z)
İleri (eski X)
Bu nedenle, XYZ ve FRU’dan LUF koordinat sistemine geçiş, solak bir koordinat sisteminden (XYZ ve FRU) sağlak bir koordinat sistemine (LUF) değişiklik anlamına geliyor.
İkinci olarak, UEFN görünüm penceresi gizmo renklerini diğer 3D içerik üretim yazılımlarıyla uyumlu olacak şekilde değiştiriyoruz:
Sol: Kırmızı (yeşildi)
Yukarı: Yeşil (maviydi)
İleri: Mavi (kırmızıydı)
Üçüncü olarak, /Verse.org/SpatialMath modülünde birçok iyileştirme yapıldı:
Verse uzamsal matematik modülü fonksiyonlarının tümü artık sağlak işlemlerdir. Sonuç olarak, açık sağlak varyantlara sahip tüm fonksiyonlar kaldırıldı ve varsayılan olarak sağlak olan işlemlere sahip sürümlerle değiştirildi. Ayrıca fonksiyon adlarından sağlaklık göstergeleri çıkarıldı. Daha fazla bilgi için aşağıdaki sayfada Sağlaklık bölümünü inceleyebilirsin.
Bir açı parametresi veya dönüş değeri içeren dönüş fonksiyonlarının şimdi radyan veya derece kabul eden veya döndüren sürümleri bulunuyor. İlgili sürümler
RadyanveyaDerecesoneklerini taşıyor.RotateBy,UnrotateByve tüm(:rotation).Apply*fonksiyonları, soldan sağa ikidönüşoluşturan bir çarpım işleci için kaldırıldı. Daha fazla bilgi için bu sayfadaki [Dönüşüm ve Dönüş Çarpım Sırası]() bölümünü inceleyebilirsin.RotateVectorveUnrotateVector,vector3’ü sırasıyla birdönüşile döndüren çarpım işleci için kaldırıldı. Daha fazla bilgi için bu sayfadaki Mekânsal Matematik İşlemlerinde Değişiklikler bölümünü inceleyebilirsin.TransformVectorveTransformVectorNoScale,vector3’ü ölçek, dönüş, yer değiştirme sırasını takip eden birdönüşümile dönüştüren bir çarpma işleci için kaldırıldı. Daha fazla bilgi için bu sayfadaki Mekânsal Matematik İşlemlerinde Değişiklikler bölümünü inceleyebilirsin.
Dördüncü olarak, FBX’ten iskelet örgülerin varsayılan içe aktarma işlemlerinde artık, içe aktarılan tüm iskelet örgülerin ileri eksene bakması için Yukarı ve İleri eksenleri hizalama seçeneği kullanılıyor.
Bunların Etkileri
Bu koordinat sistemi değişikliği, UEFN kullanan veya /Verse.org modülündeki dönüşümleri kullanan herkesi etkiliyor. Özellikle aşağıdakiler dahil olmak üzere UEFN ve Verse’ün birçok unsuru bu değişiklikten etkileniyor:
UEFN ayrıntılar paneli
UEFN görünüm penceresi ve gizmo
Verse dönüşümü
Yayınladığın adaların LUF ile doğru bir şekilde çalışması için kod veya içerikte değişiklik yapmana gerek yoktur.
UEFN Ayrıntılar Paneli
UEFN ayrıntılar panelindeki dönüşümler artık koordinatları LUF sistemiyle gösteriyor.
UEFN Görünüm Penceresi
UEFN görünüm penceresinde gizmo eksenleri ile renkler arasındaki eşleşme değişti.
Verse Dönüşümleri
/Verse.org modül dönüşümleri LUF sistemini kullanıyor. XYZ koordinat sistemini kullanan /UnrealEngine.com modül dönüşümü hâlâ mevcut ve bu modül dönüşümü/UnrealEngine.com ve /Fortnite.com modüllerinde varsayılan dönüşüm olarak kullanılmaya devam ediyor.
Bu modüllerin her ikisi de dönüşüm türleri içerdiğinden aşağıdakileri unutmamak önemlidir:
/Verse.orgmodül dönüşümlerini ve/UnrealEngine.commodül dönüşümlerini aynı dosyada kullanan API fonksiyonlarını kullanıyorsan iki modül arasında belirsizlik oluşmasını önlemek için tür adlarını kendi yollarına göre nitelemelisin. Bu, aşağıdaki örnek kod parçasında gösterilmiştir.VerseYola göre nitelenen tür adlarıusing { /UnrealEngine.com/Temporary/SpatialMath } using { /Verse.org/SpatialMath } my_class := class: MyUnrealEngineVector:(/UnrealEngine.com/Temporary/SpatialMath:)vector3 = (/UnrealEngine.com/Temporary/SpatialMath:)vector3{} MyVerseVector:(/Verse.org/SpatialMath:)vector3 = (/Verse.org/SpatialMath:)vector3{}Scene Graph,
/Verse.orgmodül dönüşümlerini kullanır. Bu da Scene Graph’ın artık yalnızca LUF koordinat sistemini kullandığı anlamına gelir.Verse Özeti, UnrealEngine.com/Temporary/SpatialMath ve Verse.org/SpatialMath modüllerinde tanımlanan dönüşüm türleri arasındaki belirsizliği gidermek için tam nitelikli Verse tanımlayıcılarını kullanır.
Unreal Engine koordinat sistemi hakkında bilgi edinmek için Unreal Engine’da Koordinat Sistemi ve Alanlar dokümantasyonuna bakabilirsin.
XYZ’den LUF’a Dönüştürme
/Verse.org modül dönüşümlerine (LUF) geçen mevcut API fonksiyonlarını kullanıyorsan kullanıcı tanımlı /UnrealEngine.com dönüşümlerini (XYZ) LUF’a dönüştürmen veya yeni oluşturulan FromTransform dönüştürme fonksiyonlarını kullanman gerekir. Bu bölümde, karşılaşabileceğin bazı dönüştürme sorunlarını ve bunların çözümlerini bulabilirsin.
Sabit veya Değişken Tür Belirsizliği
Verse API’sinde yapılan son değişikliklerle birlikte hem /UnrealEngine.com/Temporary/SpatialMath hem de /Verse.org/SpatialMath modüllerinde vector3, dönüş ve dönüşüm türleri tanımlanır. Sonuç olarak, her iki etki alanını da Verse dosyana dahil edersen tür belirsizliği ortaya çıkacaktır.
Tür Belirsizliği Örnek
Aşağıdaki Verse dosyası, hem UnrealEngine.com/Temporary/SpatialMath hem de /Verse.org/SpatialMath modül yollarını içe aktarır ve kullanıcı tanımlı sınıf vector3 niteliksiz türünü kullanır:
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/SpatialMath }
my_class := class:
MyVectorOne:vector3 = vector3{}
#Compile Error: Identifier vector3 could be one of many types: UnrealEngine.com.Temporary.SpatialMath.vector3 or Verse.org.SpatialMath.vector3
MyVectorTwo:vector3 = vector3{}
#Compile Error: Identifier vector3 could be one of many types: UnrealEngine.com.Temporary.SpatialMath.vector3 or Verse.org.SpatialMath.vector3Sonuç olarak, derleyici MyVectorOne ve MyVectorTwo’yu bir /UnrealEngine.com vector3 türü veya bir /Verse.org vector3 türü olarak derlemesi gerekip gerekmediğini bilmediğinden bu dosyayı derlemeye çalıştığında bu belirsizlik bir derleme hatasına neden olur. Kullanıcı, derleyiciye hangi türün belirtildiğini bilmesi için yeterli bilgi vermemiştir.
Bu derleme hatasını çözmek için her değişkenin kullandığı vector3 türünün yolunu belirterek nitelemesini yapmalısın. Hatayı çözmek için bu sabitleri yol ile nitelemenin birkaç farklı yolu vardır:
vector3 türündeki herhangi bir sabiti veya değişkeni aşağıdaki kod parçacığında gösterildiği gibi tam olarak niteleyebilirsin:
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/SpatialMath }
my_class := class:
MyVectorOne:(/UnrealEngine.com/Temporary/SpatialMath:)vector3 = (/UnrealEngine.com/Temporary/SpatialMath:)vector3{}
MyVectorTwo:(/Verse.org/SpatialMath:)vector3 = (/Verse.org/SpatialMath:)vector3{}/Verse.org modülünden bir sabiti veya değişkeni aşağıdaki kod parçacığında gösterildiği gibi niteleyebilirsin:
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org } # Change the module path to avoid import ambiguity
my_class := class:
MyVectorOne:vector3 = vector3{}
MyVectorTwo:SpatialMath.vector3 = SpatialMath.vector3{} # Specify the submodule/UnrealEngine.com modülünden bir sabiti veya değişkeni aşağıdaki kod parçacığında gösterildiği gibi niteleyebilirsin:
using { /UnrealEngine.com/Temporary } # Change the module path to avoid import ambiguity
using { /Verse.org/SpatialMath }
my_class := class:
MyVectorOne:SpatialMath.vector3 = SpatialMath.vector3{} # Specify the submodule
MyVectorTwo:vector3 = vector3{}Scene Graph Tür Değişikliği
Verse dosyalarında Scene Graph API’lerini kullanıyorsan ve mekânsal matematik kullanan başka API kullanmıyorsan using anahtar sözcüğüyle içe aktardığın modülü değiştirerek Verse kodundaki mekânsal matematik türlerini değiştirebilirsin. Örneğin, aşağıdaki koda sahipse:
using { /UnrealEngine.com/Temporary/SpatialMath }
my_component := class<final_super>(component):
@editable # This change will work regardless of this field being editable or not
MyVector3:vector3 = vector3{}
MyVector2:vector2 = vector2{}Bunu şöyle değiştirebilirsin:
using { /Verse.org/SpatialMath } # Changed the module path
my_component := class<final_super>(component):
@editable # This change will work regardless of this field being editable or not
MyVector:vector3 = vector3{} # All transform types now use /Verse.org/SpatialMath
# MyVector2:vector2 = vector2{} Removed since /Verse.org/SpatialMath does not define a vector2Burada tek istisna olarak, /Verse.org modülü şu anda vector2 türünü tanımlamadığı için tüm vector2 türlerinin kaldırılması veya vector3 kullanılacak şekilde dönüştürülmesi gerekir.
İşlev Türü Uyuşmazlığı
Diğer bir senaryoda, aşağıdaki durumlarda türleri yoluyla nitelemen veya kodunu dönüştürmen gerekecektir:
Çağrılan fonksiyon veya atanan değişken,
/UnrealEngine.commodülünden bir tür bekler ancak/Verse.orgmodülünden bir tür sağlanır.Çağrılan fonksiyon veya atanan bir değişken,
/Verse.orgmodülünden bir tür bekler ancak/UnrealEngine.commodülünden bir tür sağlanır.
İşlev Türü Uyumsuzluğu Örneği
Aşağıdaki iki verse dosyası aynı proje içinde bulunur. FileOne.verse dosyası, /UnrealEngine.com/Temporary/SpatialMath modülünden bir dönüşümü yazdırmak için bir fonksiyon belirler. FileTwo.verse dosyası, /Verse.org/SpatialMath modülünden bir sabit dönüşüm ve bu değeri yazdırmak için FileOne.verse dosyasındaki fonksiyonu çağıran bir fonksiyon tanımlar.
using { /UnrealEngine.com/Temporary/SpatialMath }
PrintTransform(T:transform):void=
Print("T: {T}")using { /Verse.org/SpatialMath }
my_class := class:
T:transform = transform{}
DoPrint():void=
PrintTransform(T) # Compile error: This function parameter expects a value of type (/UnrealEngine.com/Temporary/SpatialMath:)transform, but this argument is an incompatible value of type (/Verse.org/SpatialMath:)transform.Bu durum, dönüşüm türlerinin farklı modüllerde tanımlanmış iki farklı dönüşüm türüne karşılık gelmesinden dolayı bir derleme hatasına yol açar.
Bu derleme hatasını düzeltmek için dönüşüm türünü uygun modülden doğru dönüşüm türüne dönüştürmeniz gerekir. FileTwo.verse dosyasındaki kodu, /Verse.org/SpatialMath modülünden bir dönüşümü /UnrealEngine.com/Temporary/SpatialMath modülünden bir dönüşüme dönüştüren FromTransform fonksiyonunu kullanacak şekilde düzenle.
Kullanılabilir dönüştürme fonksiyonlarının tam listesi için sonraki bölüme bakın.
# Include /UnrealEngine.com to access conversion functions
using { /UnrealEngine.com }
using { /Verse.org/SpatialMath }
my_class := class:
T:transform = transform{}
DoPrint():void=
PrintTransform(Temporary.SpatialMath.FromTransform(T)) # Compile error fixed after converting transform to the correct type from the proper moduleVektör, Dönüş ve Dönüşüm Türü Dönüştürme
/UnrealEngine.com modülü, /UnrealEngine.com modülünde ve /Verse.org modülünde tanımlanan potansiyeli olarak belirsizlik türler arasında dönüştürmek için birkaç yeni dönüştürme fonksiyonu sunar.
Unreal Engine Mekânsal Matematiğinden Verse Mekânsal Matematiğine
# Util function for converting a `vector3` from /UnrealEngine.com/Temporary/SpatialMath to a `vector3` from /Verse.org/SpatialMath.
FromVector3<public>(InVector3:(/UnrealEngine.com/Temporary/SpatialMath:)vector3)<reads>:(/Verse.org/SpatialMath:)vector3
# Util function for converting a `rotation` from /UnrealEngine.com/Temporary/SpatialMath to a `rotation` from /Verse.org/SpatialMath
FromRotation<public>(InRotation:(/UnrealEngine.com/Temporary/SpatialMath:)rotation)<reads>:(/Verse.org/SpatialMath:)rotation
# Util function for converting a `transform` from /UnrealEngine.com/Temporary/SpatialMath to a `transform` from /Verse.org/SpatialMath.
FromTransform<public>(InTransform:(/UnrealEngine.com/Temporary/SpatialMath:)transform)<reads>:(/Verse.org/SpatialMath:)transform
Verse Mekânsal Matematiğinden Unreal Engine Mekânsal Matematiğine
# Util function for converting a `vector3` from /Verse.org/SpatialMath to a `vector3` from /UnrealEngine.com/Temporary/SpatialMath.
FromVector3<public>(InVector3:(/Verse.org/SpatialMath:)vector3)<reads>:(/UnrealEngine.com/Temporary/SpatialMath:)vector3
# Util function for converting a `rotation` from /Verse.org/SpatialMath to a `rotation` from /UnrealEngine.com/Temporary/SpatialMath.
FromRotation<public>(InRotation:(/Verse.org/SpatialMath:)rotation)<reads>:(/UnrealEngine.com/Temporary/SpatialMath:)rotation
# Util function for converting a `transform` from /Verse.org/SpatialMath to a `transform` from /UnrealEngine.com/Temporary/SpatialMath.
FromTransform<public>(InTransform:(/Verse.org/SpatialMath:)transform)<reads>:(/UnrealEngine.com/Temporary/SpatialMath:)transform
Verse Mekânsal Matematik İşlemleri ve Fonksiyonları
Sağlaklık
Verse uzamsal matematik modülü fonksiyonlarının tümü artık sağlak işlemlerdir. Sonuç olarak, açık sağlak veya solak varyantlara sahip tüm fonksiyonlar kaldırıldı ve varsayılan olarak sağlak olan işlemlere sahip sürümlerle değiştirildi. Ayrıca fonksiyon adlarından sağlaklık ve solaklık göstergeleri çıkarıldı. Bir vector3’ün bir dönüşle çarpılması veya bir vector3’ün bir dönüşümle çarpılması gibi sağlaklık veya solaklık tercihi yapılan tüm işlemler sağlak işlemlerdir.
Örneğin aşağıdaki kod, yukarı ekseninde pozitif 90 derecelik bir dönüş oluşturup bu dönüşü bir birim ileri vektöre uygulamanın bir birim sol vektör elde edeceğini gösterir:
ForwardToLeft:rotation = MakeRotationFromEulerDegrees(0.0, 90.0, 0.0)
ForwardVector:vector3 = vector3{Forward := 1.0}
ResultantVector:vector3 = ForwardVector * ForwardToLeft # Apply rotation on the right of the multiplication operator
Print("{ResultantVector}") # {Forward = 0.000000, Left = 1.000000, Up = 0.000000} = {Forward = 1.000000, Left = 0.000000, Up = 0.000000} * {Axis = {Forward = 0.000000, Left = 0.000000, Up = 1.000000}, Angle = 90.000000}
Dönüşüm ve Döndürme Çarpım Sırası
Dönüşlerin dahili olarak bir matris tarafından temsil edildiğini düşünebilirsin. Bir v vektörüne R dönüşü uygulandığında, bunlar satır-vektör çarpım sırasıyla uygulanır. Diğer bir deyişle, v vektörü bir satır vektörüdür ve bir vektör döndürüldüğünde, v’ = v * R sonucunu elde etmek için çarpma işlemi sağ tarafa uygulanır. Burada, v’ sonuç vektörü yeni bir satır vektörüdür. Bu işlem, T dönüşümünü bir v vektörüne uygularken de benzer şekilde çalışır. v’ = v * T olur ve elde edilen v’ sonuç vektörü başka bir satır vektörüdür.
Vektörlere dönüş ve dönüşümler uygulanırken sıra önemlidir. Elinebir kitap gibi bir nesne alıp üstü yukarı ve önü/kapağı size bakacak şekilde tut. İleri eksende sağa pozitif 90 derecelik bir dönüş uygulamak, kitabın üst kısmının sağa bakmasını sağlar. Sonra, sol eksende etrafında 90 derecelik bir dönüş uyguladığında kitabın önü yukarıya ve üst kısmı sağına bakar.
Şimdi aynı dönüşleri ters sırada uygula. Sol eksende 90 derecelik dönüş uyguladığında kitabın üst kısmı ileriye, ön kısmı ise yukarıya bakar. Sonrasında, ileri eksende 90 derecelik bir dönüş yaptığında, kitabın üst kısmı ileriye, ön kısmı ise sağına bakar. Bu, dönüşleri diğer sıralamayla uyguladığında elde ettiğin yönle aynı değildir. Bu da dönüş sırasının önemli olduğunu gösterir.
Bunu aklında bulundurarak, vektör v’ye R ve R’ olmak üzere iki adet dönüş uygulamak istiyorsan bunları istediğin sırayla uygulamaya özen göstermelisin. R dönüşünü R’ dönüşünden önce uygulamak istersen doğru sıra v’ = v * R * R’ şeklinde olmalıdır.
Aynı ilke dönüşlerin kendisi için de geçerlidir. R dönüşün varsa ve bu R dönüşüne R dönüşünden önce gerçekleşen bir PreR ön dönüşü ve R dönüşünden sonra gerçekleşen bir PostR son dönüşü eklemek istiyorsan bu işlem PreR * R * PostR sırasıyla yapılır. Benzer şekilde, bir T dönüşümüne bir PreT ön dönüşümü ve bir PostT son dönüşümü uygulamak istersen bunu PreT * Dönüşüm * PostT sırasıyla yapabilirsin. Daha sonra, yeni bir v’ vektörü elde etmek için bunları bir v vektörüne uygulamak için, yukarıdaki gibi v’ = v * PreR * R * PostR veya v’ = v * PreT * T * PostT işlemleri yapılır.
Dönüşümlerin ve dönüşlerin ilişkilendirilebilirliği de önemlidir. Verse kodunda aynı satırdaki bir vektöre birden fazla işlem (dönüşüm ve sonrasında döndürme gibi) uygulamak istiyorsan işlemlerin sırası önemlidir. Örneğin, şunları deneyebilirsin:
ForwardVector:vector3 = vector3{Forward := 1.0}
ForwardToLeftUpOne:transform = transform:
Translation := vector3{Up := 1.0}
Rotation := MakeRotationFromEulerDegrees(0.0, 90.0, 0.0)
UpToForward:rotation = MakeRotationFromEulerDegrees(90.0, 0.0, 0.0)
ResultantVector:vector3 = ForwardVector * ForwardToLeftUpOne * UpToForward # compilesİşlemleri dolaylı olarak şu şekilde ilişkilendirdiği için sorunsuz bir şekilde derlenir:
ResultantVector:vector3 = (ForwardVector * ForwardToLeftUpOne) * UpToForward # compiles
Ancak şöyle açıkça farklı şekilde ilişkilendirmeye çalışırsan:
ResultantVector:vector3 = ForwardVector * (ForwardToLeftUpOne * UpToForward) # error, no operator'*'(:transform,:rotation)
Bu bir hatayla sonuçlanır. Bu hatalardan kaçınmak için ilk işlemini bir vektör ile bir dönüşüm veya bir vektör ile bir rotasyon arasında açıkça ilişkilendirmelisin.
ResultantVector:vector3 = (ForwardVector * ForwardToLeftUpOne) * UpToForward # explicitly associated
Mekânsal Matematik İşlemlerindeki Değişiklikler
Dönüş ve Dönüş Çarpımı
RotateBy ve UnrotateBy kaldırıldı ve yerine iki dönüş için bir çarpma işleci eklendi.
ForwardToLeft:rotation = MakeRotationFromEulerDegrees(0.0, 90.0, 0.0)
UpToForward:rotation = MakeRotationFromEulerDegrees(90.0, 0.0, 0.0)
UpToLeft:rotation = UpToForward * ForwardToLeft # RotateBy, correcting for handednessBir dönüşü geri almak için (“unrotate”) için önce dönüşü tersine çevir, ardından dönüşleri çarp. UpToLeft’ten UpToForward dönüşünü almak için ForwardToLeft dönüşünü tersine çevir ve bunu UpToLeft dönüşünün sağına uygula. Aşağıda bunun nasıl adım adım gerçekleştirildiği gösteriliyor.
# The following comments show the steps involved to reach the desired result.
# This involves multiplication on the right by the inverse, associativity, existence and definition of inverse rotation, and existence and definition of identity rotation
# Pseudocode Steps:
# UpToLeft * ForwardToLeft.Invert() = (UpToForward * ForwardToLeft) * ForwardToLeft.Invert() # multiply on the right by the same expression on both sides of the equality operator
# UpToLeft * ForwardToLeft.Invert() = UpToForward * (ForwardToLeft * ForwardToLeft.Invert()) # reassociate
# UpToLeft * ForwardToLeft.Invert() = UpToForward * IdentityRotation() # rotation * inverse = identity
# UpToLeft * ForwardToLeft.Invert() = UpToForward # rotation * identity = rotation
UpToForwardAgain:rotation = UpToLeft * ForwardToLeft.Invert() # UnrotateBy, correcting for handednessVector3 ve Dönüş Çarpanı
Benzer şekilde, Rotate ve Unrotate de kaldırıldı ve yerine bir dönüş ile sağa döndürülen bir vector3 için bir çarpma işleci getirildi.
ForwardVector:vector3 = vector3{Forward:=1.0}
ForwardToLeft:rotation = MakeRotationFromEulerDegrees(0.0, 90.0, 0.0)
LeftVector:vector3 = ForwardVector * ForwardToLeft # Rotate, correcting for handednessBir dönüşü geri almak (unrotate) için önce dönüşü tersine çevir, ardından dönüşü vektörle çarp. LeftVector’den ForwardVector’ü almak için ForwardToLeft dönüşünü tersine çevir ve bunu LeftVector’ün sağına uygula.
# The steps involved in achieving this calculation are very similar to the steps shown above for obtaining the correct expression for unrotating by a rotation
ForwardVectorAgain:vector3 = LeftVector * ForwardToLeft.Invert() # Unrotate, correcting for handednessVector3 ve Dönüşüm Çarpımı
TransformVector ve TransformVectorNoScale kaldırıldı ve yerine bir dönüşüm ile sağda dönüştürülen bir vector3 için bir çarpma işleci getirildi.
DoubleLengthForwardToLeftTranslateUp := transform:
Translation := vector3{Left := 0.0, Up := 1.0, Forward := 0.0}
Rotation := MakeRotationFromEulerDegrees(0.0, 90.0, 0.0)
Scale := vector3{Left := 2.0, Up := 2.0, Forward := 2.0}
ForwardVector:vector3 = vector3{Forward:=1.0}
ResultantVector:vector3 = ForwardVector * DoubleLengthForwardToLeftTranslateUp # TransformVectorÖlçeklendirme olmadan bir TransformVectorNoScale dönüşümü yapmak için, oluşturduğun dönüşümün varsayılan ölçek değerini bırak.
ForwardToLeftTranslateUpNoScale := transform:
Translation := vector3{Left := 0.0, Up := 1.0, Forward := 0.0}
Rotation := MakeRotationFromEulerDegrees(0.0, 90.0, 0.0)
ForwardVector:vector3 = vector3{Forward:=1.0}
ResultantVector:vector3 = ForwardVector * ForwardToLeftTranslateUpNoScale # TransformVectorNoScale