À partir de la version 36.00, l’UEFN utilise le système de coordonnées LUF pour l’éditeur et toutes les transformations de module /Verse.org. Les transformations de module /UnrealEngine.com et /Fortnite.com utilisent le système de coordonnées XYZ.
Présentation du système de coordonnées LUF
Tous les principaux outils de création de contenu 3D utilisent un système de coordonnées cartésiennes (X, Y et Z) pour positionner les objets et les faire pivoter. Cependant, les interprétations spécifiques des axes (X, Y ou Z) qui représentent les directions (notamment gauche/droite, haut/bas et avant/arrière) sont différentes selon les outils. De plus, le mode de modélisation des rotations (appelé orientation du système de coordonnées) varie aussi selon les différents outils.
Afin de mieux aligner Verse et UEFN sur les normes émergentes en matière de création de contenu 3D et d'autres trousses à outils importantes, nous apportons des modifications fondamentales à la présentation de notre système de coordonnées.
Tout d'abord, au lieu d'étiqueter les axes de coordonnées avec X, Y et Z, nous introduisons des noms d'axes plus descriptifs :
Gauche (anciennement -Y)
Haut (anciennement Z)
Avant (anciennement X)
Le passage des systèmes XYZ et FRU à LUF correspond donc à un changement d’orientation des axes, passant d’un système de coordonnées gaucher (XYZ et FRU) à un système de coordonnées droitier (LUF).
Deuxièmement, les couleurs du gadget du hublot de l’UEFN ont changé pour s'aligner sur celles des autres logiciels de création de contenu 3D :
Gauche : rouge (autrefois vert)
Haut : vert (autrefois bleu)
Avant : bleu (autrefois rouge)
Troisièmement, de nombreuses améliorations ont été apportées au module /Verse.org/SpatialMath :
Les fonctions du module de mathématiques spatiales de Verse utilisent désormais toutes des opérations droitières. Par conséquent, toutes les fonctions comportant des variantes explicites selon le système de coordonnées droitier ont été supprimées et remplacées par des versions reposant par défaut sur un système droitier. Les indicateurs de latéralité droite ont été retirés des noms de fonctions. Pour plus d’informations, consultez la section Système de coordonnées droitier de la page ci-dessous.
Les fonctions de rotation impliquant un paramètre ou une valeur de retour angulaire disposent désormais de variantes acceptant ou renvoyant des valeurs en radians ou en degrés, identifiables par le suffixe
RadiansouDegreesselon le cas.RotateBy,UnrotateByet toutes les fonctions(:rotation).Apply*ont été supprimées au profit d'un opérateur de multiplication qui compose deuxrotationsde gauche à droite. Pour plus d'informations, consultez la section [Ordre de multiplication de la transformation et de la rotation]() de cette page.RotateVectoretUnrotateVectoront été supprimés au profit d'un opérateur de multiplication qui fait pivoter unvector3d'unerotation, dans cet ordre. Pour plus d'informations, consultez la section Modification des opérations mathématiques spatiales de cette page.TransformVectoretTransformVectorNoScaleont été supprimés au profit d'un opérateur de multiplication qui transforme unvector3par unetransformationdans l'ordre suivant : échelle, rotation, translation. Pour plus d'informations, consultez la section Modification des opérations mathématiques spatiales de cette page.
Quatrièmement, les importations par défaut de maillages squelettiques à partir de FBX utilisent désormais l'option permettant d'aligner les axes Haut et Avant afin que tous les maillages squelettiques importés soient orientés vers l'axe Avant.
Impacts de ce changement
Ce changement de système de coordonnées affecte toute personne utilisant l’UEFN ou des transformations dans le module /Verse.org, en particulier, plusieurs aspects de l’UEFN et de Verse, notamment :
Le panneau Détails de l'UEFN
Les hublot et gadget UEFN
La transformation Verse
Il est inutile de modifier le code ou le contenu de vos îles publiées pour qu'elles fonctionnent correctement avec LUF.
Panneau Détails de l’UEFN
Les transformations dans le panneau Détails de l’UEFN affichent désormais les coordonnées en termes de système LUF.
Hublot de l'UEFN
Le mappage entre les axes du gadget et les couleurs a changé dans le hublot de l’UEFN.
Transformations Verse
Les transformations de module /Verse.org utilisent le système LUF. La transformation de module /UnrealEngine.com utilisant le système de coordonnées XYZ existe toujours et est utilisée comme transformation par défaut dans les modules /UnrealEngine.com et /Fortnite.com.
Étant donné que ces deux modules contiennent des types de transformation, gardez à l’esprit les points suivants :
Si vous utilisez dans un même fichier des fonctions d’API faisant appel à la fois aux transformations de module
/Verse.orget/UnrealEngine.com, vous devez qualifier les noms de type avec leur chemin d’accès afin d’éviter toute ambiguïté entre les deux modules. Consultez l'extrait d'exemple ci-dessous.VerseNoms de type qualifiés par cheminusing { /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 utilise les transformations de module
/Verse.org. Autrement dit, Scene Graph utilise désormais uniquement le système de coordonnées LUF.Le Digest Verse utilise des identifiants Verse pleinement qualifiés afin de lever toute ambiguïté entre les types de transformation définis dans les modules UnrealEngine.com/Temporary/SpatialMath et Verse.org/SpatialMath .
Pour en savoir plus sur le système de coordonnées de l'Unreal Engine, consultez la rubrique Système de coordonnées et espaces dans l'Unreal Engine.
Convertir le système XYZ en système LUF
Si vous utilisez une fonction d'API ayant adopté les transformations de module /Verse.org (LUF), vous devez convertir vos transformations /UnrealEngine.com (XYZ) définies par l'utilisateur en système LUF, ou utiliser les fonctions de conversion FromTransform nouvellement créées. Dans cette section, vous trouverez plusieurs problèmes de conversion potentiels et leurs solutions.
Ambiguïté de type constante ou variable
Suite aux récents changements apportés à l'API Verse, /UnrealEngine.com/Temporary/SpatialMath et /Verse.org/SpatialMath définissent les types vector3, rotation et transformation. En conséquence, une ambiguïté de type se produit si vous incluez les deux domaines dans votre fichier Verse.
Exemple d'ambiguïté de type
Le fichier Verse suivant importe à la fois le chemin de module /UnrealEngine.com/Temporary/SpatialMath et le chemin de module /Verse.org/SpatialMath, et la classe définie par l'utilisateur utilise le type non qualifié vector3 :
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.vector3Par conséquent, l'ambiguïté de type entraîne une erreur de compilation si vous tentez de compiler ce fichier, car le compilateur ne sait pas s'il doit compiler MyVectorOne et MyVectorTwo en tant que type /UnrealEngine.com vector3, ou en tant que type /Verse.org vector3. L'utilisateur n'a pas fourni suffisamment d'informations au compilateur pour qu'il sache quel type est indiqué.
Pour résoudre cette erreur de compilation, vous devez qualifier le type de vector3 utilisé par chaque variable. Il existe plusieurs manières de qualifier ces constantes par chemin pour résoudre l'erreur :
Vous pouvez qualifier entièrement n'importe quelle constante ou variable de type vector3, comme indiqué dans l'extrait de code ci-dessous :
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{}Vous pouvez qualifier une constante ou une variable à partir du module /Verse.org, comme indiqué dans l'extrait de code ci-dessous :
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 submoduleVous pouvez qualifier une constante ou une variable à partir du module /UnrealEngine.com, comme indiqué dans l'extrait de code ci-dessous :
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{}Changement de type de Scene Graph
Si vous utilisez les API Scene Graph dans vos fichiers Verse et n'utilisez pas d'autres API faisant appel aux mathématiques spatiales, vous pouvez modifier les types de mathématiques spatiales dans votre code Verse en modifiant le module de mathématiques spatiales que vous importez avec le mot-clé using. Par exemple, si vous avez le code suivant :
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{}Vous pouvez le modifier en :
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 vector2La seule exception est que tous les types vector2 doivent être supprimés ou convertis pour utiliser vector3, car le module /Verse.org ne définit pas actuellement le type vector2.
Incompatibilité de type de fonction
Autre situation dans laquelle vous pourriez devoir qualifier les types par leur chemin ou convertir votre code :
Une fonction appelée ou une variable assignée attend un type du module
/UnrealEngine.com, mais reçoit un type du module/Verse.org.Une fonction appelée ou une variable assignée attend un type du module
/Verse.org, mais reçoit un type du module/UnrealEngine.com.
Exemple d'incompatibilité des types de fonctions
Les deux fichiers Verse suivants existent dans le même projet. FileOne.verse définit une fonction pour afficher une transformation à partir du module /UnrealEngine.com/Temporary/SpatialMath . FileTwo.verse définit une transformation constante à partir du module /Verse.org/SpatialMath et une fonction pour afficher cette valeur qui appelle la fonction à partir de FileOne.verse.
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.Cela entraîne une erreur de compilation, car les types de transformation font référence à deux types distincts, définis dans des modules différents.
Pour corriger cette erreur de compilation, vous devez convertir le type de transformation en type de transformation correct à partir du module approprié. Modifiez le code dans FileTwo.verse pour utiliser la fonction FromTransform, qui convertit une transformation de /Verse.org/SpatialMath en une transformation de /UnrealEngine.com/Temporary/SpatialMath.
Pour obtenir une liste complète des fonctions de conversion disponibles, consultez la section suivante.
# 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 moduleConversion de type de vecteur, de rotation et de transformation
Le module /UnrealEngine.com propose plusieurs fonctions de conversion nouvelles permettant de passer entre les types potentiellement ambigus définis dans les modules /UnrealEngine.com et /Verse.org.
Passer des mathématiques spatiales de l'Unreal Engine aux mathématiques spatiales de Verse
# 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
Passer des mathématiques spatiales de Verse aux mathématiques spatiales de l'Unreal Engine
# 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
Opérations et fonctions mathématiques spatiales Verse
Système de coordonnées droitier
Les fonctions du module de mathématiques spatiales de Verse utilisent désormais toutes des opérations droitières. Par conséquent, toutes les fonctions comportant des variantes explicites selon le système de coordonnées (gaucher ou droitier) ont été supprimées et remplacées par des versions reposant par défaut sur un système droitier. Les indicateurs de latéralité ont été retirés des noms de fonctions. Toutes les opérations offrant un choix de latéralité, comme la multiplication d'un vector3 par une rotation ou la multiplication d'un vector3 par une transformation, sont des opérations droitières.
Par exemple, le code suivant illustre que construire une rotation de 90 degrés positifs autour de l’axe Haut et appliquer cette rotation à un vecteur unitaire Avant donne un vecteur unitaire Gauche :
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}
Ordre de multiplication des transformations et des rotations
On peut considérer que les rotations sont représentées en interne par une matrice. Lorsqu'une rotation R est appliquée à un vecteur v, elles sont appliquées dans l'ordre de multiplication ligne-vecteur. Autrement dit, le vecteur v est un vecteur ligne et, lors d’une rotation, la multiplication s’applique à droite pour obtenir le résultat, v' = v * R. Ici, le vecteur résultant v' est un nouveau vecteur ligne. Cela fonctionne de la même manière pour appliquer une transformation T à un vecteur v, v' = v * T, et le vecteur résultant v' est également un vecteur ligne.
L'ordre est important lors de l'application de rotations et de transformations aux vecteurs. Tenez un objet, comme un livre, dans votre main, le haut vers le haut et la couverture (l’avant) vers vous. En appliquant une rotation positive de 90 degrés vers la droite autour de l'axe Avant, le haut du livre est désormais orienté vers la droite. Ensuite, en appliquant une rotation de 90 degrés autour de l'axe Gauche, l'avant du téléphone est orienté vers le haut et le haut du livre est orienté vers votre droite.
Maintenant, appliquez les mêmes rotations dans l'ordre inverse. Appliquez une rotation de 90 degrés autour de l'axe Gauche, ce qui fait que le haut du livre est orienté vers l'avant et l’avant (la couverture) du livre vers le haut. Ensuite, en appliquant une rotation de 90 degrés autour de l'axe Avant, le haut du livre est orienté vers l'avant et la couverture du livre est orientée vers votre droite. Ce n’est pas la même orientation que l’application des rotations dans l’autre ordre, ce qui illustre que l’ordre des rotations est important.
Dans cet esprit, si vous souhaitez appliquer deux rotations R et R’ à un vecteur v, vous devez veiller à les appliquer dans l’ordre souhaité. Si vous souhaitez appliquer la rotation R avant la rotation R', alors l'ordre correct est v' = v * R * R'.
Le même principe s’applique aux rotations elles-mêmes. Si vous avez une rotation R et que vous souhaitez appliquer une pré-rotation PreR à R, qui a lieu avant la rotation R et une post-rotation PostR qui a lieu après la rotation R, cela se fait dans l'ordre PreR * R * PostR. De même, si vous souhaitez appliquer une pré-transformation PreT et une post-transformation PostT à une transformation T, cela se fait dans l’ordre PreT * T * PostT. Par la suite, l'application de ces éléments à un vecteur v pour obtenir un nouveau vecteur v' se fait comme indiqué ci-dessus, v' = v * PreR * R * PostR ou v' = v * PreT * T * PostT.
L'associativité des transformations et des rotations est également un aspect important. Si vous souhaitez appliquer plusieurs opérations sur un vecteur dans la même ligne de code Verse, comme une transformation, suivie d'une rotation, l'association des opérations est importante. Par exemple, vous pourriez essayer ce qui suit :
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 # compilesCela se compile bien, car cela associe implicitement des opérations comme :
ResultantVector:vector3 = (ForwardVector * ForwardToLeftUpOne) * UpToForward # compiles
Cependant, si vous essayez explicitement de les associer différemment comme :
ResultantVector:vector3 = ForwardVector * (ForwardToLeftUpOne * UpToForward) # error, no operator'*'(:transform,:rotation)
Cela entraîne une erreur. Pour éviter ces erreurs, associez explicitement votre première opération entre un vecteur et une transformation ou un vecteur et une rotation.
ResultantVector:vector3 = (ForwardVector * ForwardToLeftUpOne) * UpToForward # explicitly associated
Modification des opérations mathématiques spatiales
Rotation et multiplication de rotation
RotateBy et UnrotateBy sont supprimés et remplacés par un opérateur de multiplication pour deux rotations.
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 handednessPour inverser une rotation ("unrotate"), inversez d'abord la rotation, puis multipliez les rotations. Pour récupérer la rotation UpToForward depuis UpToLeft, inversez la rotation ForwardToLeft et appliquez-la à droite de la rotation UpToLeft. Ce qui suit montre comment cela est réalisé étape par étape.
# 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 et multiplication de rotation
De même, Rotate et Unrotate sont supprimés et remplacés par un opérateur de multiplication pour un vector3 tourné vers la droite par une rotation.
ForwardVector:vector3 = vector3{Forward:=1.0}
ForwardToLeft:rotation = MakeRotationFromEulerDegrees(0.0, 90.0, 0.0)
LeftVector:vector3 = ForwardVector * ForwardToLeft # Rotate, correcting for handednessPour inverser une rotation (unrotate), inversez d'abord la rotation, puis multipliez la rotation par le vecteur. Pour récupérer le ForwardVector à partir du LeftVector, inversez la rotation ForwardToLeft et appliquez-la à droite au LeftVector
# 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 et multiplication de transformation
TransformVector et TransformVectorNoScale sont supprimés et remplacés par un opérateur de multiplication pour un vector3 transformé à droite par une transformation.
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 # TransformVectorPour effectuer une transformation sans mise à l'échelle, TransformVectorNoScale, laissez la valeur d'échelle par défaut sur la transformation que vous construisez.
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