Jak ZenGin trzyma rotację obiektów? 2276 6

O temacie

Autor Mateusz D.

Zaczęty 10.09.2017 roku

Wyświetleń 2276

Odpowiedzi 6

Mateusz D.

Mateusz D.

Użytkownicy
posty3
Propsy3
ProfesjaProgramista
  • Użytkownicy
Witam,
zapisałem plik .ZEN ze światem z gothica jako uncompiled ZEN, przez co plik przybrał w miarę czytelną formę. Chcę teraz przenieść wszystkie obiekty do innego silnika graficznego, ale napotkałem pewien problem. O ile dokładne coordy widzę i jestem w stanie umieścić model we właściwym miejscu, to nie rozumiem jak trzymana jest informacja o rotacji tego modelu... Z niewiadomego mi powodu zamiast drugiego Vectora3 rotacja jest zapisana jako 72 znaki w systemie szesnastkowym, czyli jakieś 288 bitów. Być może zamiast Vectora3 rotacja obiektu jest zapiana jako kwaternion, ale dalej nie mam pojęcia jak z tej wartości uzyskać rotację. Jeśli ktoś miał kiedyś z tym styczność to proszę pomoc. Oczywiście załączam fragment pliku. Interesującą mnie linijkę pozwoliłem sobie pokolorować.

 
Spoiler
      childs7=int:0
      [% oCItem:zCVob 0 9]
         pack=int:0
         presetName=string:
         bbox3DWS=rawFloat:596.871155 -574.235962 -9995.42773 685.693298 -524.45752 -9904.29199
         trafoOSToWSRot=raw:bbf9623f8b2da03e7966aebec68cfebd80de5e3fa5bef33eb515e43ee16ec2be2a8e4f3f
         trafoOSToWSPos=vec3:647.036377 -556.026306 -9950.23828
         vobName=string:ITFO_PLANTS_HERB_01
         visual=string:
         showVisual=bool:0
         visualCamAlign=enum:0
         cdStatic=bool:1
         cdDyn=bool:1
         staticVob=bool:0
         dynShadow=enum:0
         [visual % 0 0]
         []
         [ai % 0 0]
         []
         itemInstance=string:ITFO_PLANTS_HERB_01
      []

Pozdrawiam.
 

Szmyk

Szmyk

Użytkownicy
posty64
Propsy58
Profesjabrak
  • Użytkownicy
Nie zagłębiałem się w to specjalnie, ale najprawdopodobniej jest to 36 bitów:
- w trzech grupach po 12 bitów
- w macierzy 3x3, być może kąty Eulera

Być może jest to zrobione według specyfikacji VRML: http://test.bitmanagement.de/en/support/developer-area/references/vrml97-specification/field-and-event-reference#SFRotation i to by tu chyba najbardziej pasowało.
 


Siemekk

Siemekk

Złote Wrota
posty2143
Propsy1154
ProfesjaProgramista
  • Złote Wrota
Nie wiem, ale może to ci się przyda:
https://pastebin.com/4BBhGFLi
Rotacja i pozycja w klasie zCVob są zapisywane jako zMAT4.
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

Mateusz D.

Mateusz D.

Użytkownicy
posty3
Propsy3
ProfesjaProgramista
  • Użytkownicy
Jestem trochę zagubiony. Myślałem że ta wartość to 9 floatów po 32 bity, ale jeśli dobrze rozumiem i mówicie że to macierz 4x4 to znaczy że jest to 16 liczb?

Mam przykład, z którego chyba wiem co powinno wyjść: 0000803f0000000000000000000000000000803f0000000000000000000000000000803f to chyba bark rotacji we wszystkich osiach. Jak próbuję zamienić to na macierz 4x4 to nic mi z tego nie wychodzi więc zakladam że cos źle zrozumiałem. Jeśli, natomiast jest to 9 floatów to macierz by wyglądała tak:
0000803f   00000000 00000000
00000000 0000803f 00000000
00000000 00000000 0000803f
teraz wartość 0000803f wklejam do online convertera z hexów na floaty https://gregstoll.dyndns.org/~gregstoll/floattohex/ (z klikniętym checkboxem swap endianness), wychodzi 1. Zatem ta macierz to:
1 0 0
0 1 0
0 0 1

Dla mnie nie wygląda to źle, ale szczerze mówiąc nie znam się na tym. Idę w dobrą stronę, czy coś sknociłem? I najważniejsze pytanie; co ja mam dalej z tym zrobić żeby uzyskać normalną rotację w kątach eulera (x,y,z)?
 

Siemekk

Siemekk

Złote Wrota
posty2143
Propsy1154
ProfesjaProgramista
  • Złote Wrota
Większość matematyki w zEngine.
Nie znam się w ogóle na macierzach i rotacji, ale to może chyba pomóc.
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

Mateusz D.

Mateusz D.

Użytkownicy
posty3
Propsy3
ProfesjaProgramista
  • Użytkownicy
Cytuj
Nie znam się w ogóle na macierzach i rotacji, ale to może chyba pomóc.
Wow, to nie tyle pomogło, co rozwiązało całą sprawę. Dzięki.

Jakby ktoś kiedyś miał podobny problem oto szczegóły:
Rotacja zdaje się być zapisywana jako matrix 3x3 (zMAT3); oto kawałek kodu ZenLib'a, link do githuba podesłał inż. Avallach (https://github.com/degenerated1123/ZenLib/blob/master/zenload/zCVob.h)
Spoiler
struct packedVobData
{
   ZMath::float3   bbox3DWS[2];
   ZMath::float3   positionWS;
   zMAT3         trafoRotWS;

   struct packedBitField
   {
      uint8_t      showVisual         : 1;      
      uint8_t      visualCamAlign      : 2;
      uint8_t      cdStatic         : 1;
      uint8_t      cdDyn            : 1;
      uint8_t      staticVob         : 1;
      uint8_t      dynShadow         : 2;
      uint8_t      hasPresetName      : 1;
      uint8_t      hasVobName         : 1;
      uint8_t      hasVisualName      : 1;
      uint8_t      hasRelevantVisualObject   : 1;
      uint8_t      hasAIObject         : 1;
      uint8_t      hasEventManObject   : 1;      
      uint8_t      physicsEnabled      : 1;      
      uint8_t      visualAniMode      : 2;
      uint8_t      zbias            : 5;   
      uint8_t      bAmbient         : 1;
   } bitfield;
   float         visualAniStrength;
   float         vobFarClipZ;
};
Tak więc 288 bitów to 9 floatów. Następnie zamieniamy macierz na kwaterniona używając funkcji z biblioteki matematycznejz poprzedniego posta:
Spoiler
INLINE void zCQuat::Matrix3ToQuat(zMAT3 const& mat)
{
   float dig = mat[0][0] + mat[1][1] + mat[2][2];
   if(dig > 0)
   {
       float kf = sqrt(dig + 1.0);
       qt[3] = kf * 0.5;
       kf = 0.5 / kf;
       qt[0] = (mat[1][2] - mat[2][1]) * kf;
       qt[1] = (mat[2][0] - mat[0][2]) * kf;
       qt[2] = (mat[0][1] - mat[1][0]) * kf;
       return;
   }
   int k = 0;
   if(mat[1][1] > mat[0][0])
       k = 1;
   if(mat[2][2] > mat[k][k])
       k = 2;
   int r[3] = { 1, 2, 0 };
   float kf = sqrt(mat[k][k] - (mat[r[r[k]]][r[r[k]]] + mat[r[k]][r[k]]) + 1.0);
   qt[k] = kf * 0.5;
   if(kf != 0)
       kf = 0.5 / kf;
   qt[3] = (mat[r[k]][r[r[k]]] - mat[r[r[k]]][r[k]]) * kf;
   qt[r[k]] = (mat[k][r[k]] + mat[r[k]][k]) * kf;
   qt[r[r[k]]] = (mat[k][r[r[k]]] + mat[r[r[k]]][k]) * kf;
}
Jak mówiłem nie znam się na tym i ta funkcja to dla mnie magia, ale ta funckja po prostu działa. Obróciłem za jej pomocą pare obiektów i wszystkie rotacje wyglądały prawidłowo. Dziękuję wszystkim za pomoc, temat do zamknięcia.
 


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry