Difference between revisions of "Game.dtz"

From GTAMods Wiki
Jump to navigation Jump to search
m
 
(56 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 +
'''GAME.DTZ''' ('''D'''a'''T'''a '''Z'''lib) is a file in PS2 and PSP versions of [[GTA LCS]] and [[GTA VCS]]. It contains data files, as well as main textures and models analogue to existing 3D era games compiled in binary form. It is compressed using the zlib/deflate algorithm [http://zlib.net/zlib] (max compression). It can be decompressed by any zlib compression/decompression utility, such as offzip [http://aluigi.altervista.org/mytoolz/offzip.zip] and zdrop [https://cdn.discordapp.com/attachments/338352146946981889/442752002993160222/zdrop.exe]. Data can be extracted by [[guard3]]'s DTZpy [http://gtaforums.com/topic/908702-dtzpy/], though textures and some data files can be manipulated with [[Dageron]]'s DTZ Editor [http://www.mediafire.com/file/ubcu958tgb9k79a/DTZ+EDitor.rar]. ''All info provided is about decompressed version''
 +
==Header==
 +
The '''Header''' for both [[GTA LCS]] and [[GTA VCS]] versions is nothing but a standard '''Relocatable Chunk''' header, defined like so:
 +
<nowiki>
 +
struct base::sChunkHeader
 +
{
 +
uint32 ident;
 +
uint32 shrink;
 +
uint32 fileEnd;
 +
uint32 dataEnd;
 +
uint32 relocTab;
 +
uint32 numRelocs;
 +
uint32 globalTab;
 +
uint16 numClasses;
 +
uint16 numFuncs;
 +
};</nowiki>
 +
More info on [[Relocatable chunk]]
 +
===LCS Version===
 
{{stub}}
 
{{stub}}
{{lowercase}}
 
'''DTZ''' - a memory dump console packaged with a lossless compression algorithm  deflate/[http://zlib.net/ zlib]. You can pack and unpack, for example, by using [[DTZ Editor]].
 
  
==GAME.DTZ==
+
===VCS Version===
 +
<nowiki>
 +
0x20  paths
 +
0x24  offset to "Buildings" info
 +
0x28  offset to "Treadables" info
 +
0x2C  offset to "Dummys" info
 +
0x30  offset to "EntryInfoNode" info
 +
0x34  offset to "PtrNode" info
 +
0x38  number of offsets in IDE table
 +
0x3C  offset to IDE table
 +
0x40  offset to car class table 1
 +
0x44  offset to car class table 2
 +
0x48  offset to GTA3.ZON
 +
0x4C  0, ?
 +
0x50  0, ?
 +
0x54  number of 2dfx data "lines"
 +
0x58  offset to 2dfx data
 +
0x5C  ? (has to do with model indices)
 +
0x60  offset to "Texlist" info
 +
0x64  0, ?
 +
0x68  ?
 +
0x6C  0, ?
 +
0x70  ?
 +
0x74  offset to OBJECT.DAT
 +
0x78  ?
 +
0x7C  offset to GTA3PS2.DIR
 +
0x80  offset to animation data
 +
0x84  offset to FISTFITE.DAT
 +
0x88  offset to PED.DAT offset table
 +
0x8C  offset to PEDSTATS.DAT offset table
 +
0x90  offset to car colours data
 +
0x94  ?
 +
0x98  number of CULL.IPL "lines"
 +
0x9C  offset to CULL.IPL
 +
0xA0  number of OCCLU.IPL �lines� (0 in VCS)
 +
0xA4  offset to OCCLU.IPL (0 in VCS)
 +
0xA8  offset to WATERPRO.DAT
 +
0xAC  offset to weather types table
 +
0xB0  offset to SURFACE.DAT
 +
0xB4  offset to TIMECYC.DAT
 +
0xB8  offset to PEDGRP.DAT
 +
0xBC  offset to PARTICLE.CFG
 +
0xC0  offset to WEAPON.DAT
 +
0xC4  0, ?
 +
0xC8  offset to models offset table
 +
0xCC  offset to MOCAPPS2.DIR
 +
0xD0  ?
 +
0xD4  0, ?
 +
0xD8  ?
 +
0xDC  0, ?
 +
0xE0  offset to MENU.XTX (zlib/deflate compressed)
 +
0xE4  ?
 +
0xE8  ?
 +
0xEC  ?
 +
0xF0  ?
 +
0xF4  offset to font data
 +
0xF8  size of decompressed FSFONTS.XTX
 +
0xFC  offset to FSFONTS.XTX (zlib/deflate compressed)
 +
0x100 offset to radar textures offset table</nowiki>
  
{|{{Prettytable}}
+
==Data Formats==
! Description
+
===IPL===
! Analogy
+
====IPL Info====
! Offset
+
The header of GAME.DTZ points to 5 IPL info tables: Buildings, Treadables, Dummys, EntryInfoNode and PtrNode. The first 3 are 16 bytes in size and are defined like so:
! Notes
+
<nowiki>
|-
+
4b int Offset to IPL data
| colspan="4" | <b>Textures</b>
+
4b int  ?
|-
+
4b int  Number of IPL lines
| textures of menu
+
4b int  ?
| frontend.txd
+
16 char Name of IPL info (Buildings, Treadables, etc...)</nowiki>
| <code> LCS PS2: 0x4E4A30 </code>
+
''Need more info on EntryInfoNode and PtrNode''
<code> LCS PSP: 0x4DA830 </code>
+
====IPL Structure====
 +
The IPL data is structured like so:
 +
<nowiki>
 +
4b float m00
 +
4b float m10
 +
4b float m20
 +
4b float Unk1
 +
4b float m01
 +
4b float m11
 +
4b float m21
 +
4b float Unk2
 +
4b float m02
 +
4b float m12
 +
4b float m22
 +
4b float Unk3
 +
4b float Position-X
 +
4b float Position-Y
 +
4b float Position-Z
 +
4b float Unk4
 +
24b ?
 +
2b int  Corresponding Model ID
 +
6b ?</nowiki>
 +
The IPL is basically a matrix:
 +
<nowiki>
 +
[m00,  m01,  m02,  Position-X]
 +
[m10,  m11,  m12,  Position-Y]
 +
[m20,  m21,  m22,  Position-Z]
 +
[unk1, unk2, unk3, unk4      ]</nowiki>
 +
The bottom row is Leeds Engine stuff, not useful for generating IPL. They only matter in memory. ''Someone may provide more info''
 +
====Generating IPL in text format====
 +
In order to calculate the original rotation values, this algorythm comes in handy:
 +
<source lang="java">
 +
float tr = m00 + m11 + m22
  
<code> VCS PS2: 0x581330 </code>
+
if (tr > 0) {
 +
  float S = sqrt(tr+1.0) * 2; // S=4*qw
 +
  qw = 0.25 * S;
 +
  qx = (m21 - m12) / S;
 +
  qy = (m02 - m20) / S;
 +
  qz = (m10 - m01) / S;
 +
} else if ((m00 > m11)&(m00 > m22)) {
 +
  float S = sqrt(1.0 + m00 - m11 - m22) * 2; // S=4*qx
 +
  qw = (m21 - m12) / S;
 +
  qx = 0.25 * S;
 +
  qy = (m01 + m10) / S;
 +
  qz = (m02 + m20) / S;
 +
} else if (m11 > m22) {
 +
  float S = sqrt(1.0 + m11 - m00 - m22) * 2; // S=4*qy
 +
  qw = (m02 - m20) / S;
 +
  qx = (m01 + m10) / S;
 +
  qy = 0.25 * S;
 +
  qz = (m12 + m21) / S;
 +
} else {
 +
  float S = sqrt(1.0 + m22 - m00 - m11) * 2; // S=4*qz
 +
  qw = (m10 - m01) / S;
 +
  qx = (m02 + m20) / S;
 +
  qy = (m12 + m21) / S;
 +
  qz = 0.25 * S;
 +
}</source>
 +
And finally, since 3DS Max that originally created IPL negates X,Y,Z:
 +
<nowiki>
 +
Rotation X = -qx
 +
Rotation Y = -qy
 +
Rotation Z = -qz
 +
Rotation W = qw</nowiki>
  
<code> VCS PSP: 0x51D95C </code>
+
===IDE===
| contain texture of menu, packed deflate/zlib algorithm (*)
+
On both LCS and VCS, 0x3C points to a table containing offsets to IDE lines and 0x38 specifies the number of values in the table. Each value-offset is assigned an ID, starting from 0. If it so happens and the value-offset is 0x00000000, then the ID isn't assigned to any object. The structure is like so:
|-
+
====LCS====
| texture of fonts
+
<nowiki>
| fonts.txd
+
8b -
| <code> LCS PS2: 0x4EF4D8 </code>
+
4b int Name of the object (CRC32 Hash encryption)
<code> LCS PSP: 0x4E2B1C </code>
+
4b -
 +
1b int Type (1: objs, 3:tobj, 4:weap, 5:hier, 6:cars, 7:ped)
 +
1b int Count 2dfx (ex. if 2dfxID=8 and Count2dfx=4, then the assigned IDs are 8, 9, 10, 11)
 +
1b int Collision in .DTZ (boolean, 0:not in DTZ, 1:in DTZ)
 +
1b -   Padding
 +
4b int offset to collision (.col2)
 +
2b int 2dfx ID
 +
2b int Object.DAT ID
 +
2b -
 +
2b int Texture ID
 +
4b int Type (CRC32 Hash encryprion)
 +
4b int offset to model (if no .mdl exists in .DTZ, then it's 0)</nowiki>
 +
'''Type 1''' OBJS:
 +
<nowiki>
 +
4b float Draw Distance 1
 +
4b float Draw Distance 2
 +
4b float Draw Distance 3 (if object is LOD, then disappearing distance)
 +
1b int  Mesh Count
 +
1b int  ?
 +
2b int  Flags
 +
4b int  if object is LOD, offset to IDE ID of original object, otherwise =0</nowiki>
 +
'''Type 3''' TOBJ:
 +
<nowiki>
 +
4b float Draw Distance 1
 +
4b float Draw Distance 2
 +
4b float Draw Distance 3 (if object is LOD, then disappearing distance)
 +
1b int  Mesh Count
 +
1b int  ?
 +
2b int  Flags
 +
4b int  if object is LOD, offset to IDE ID of original object, otherwise =0
 +
4b int  Time On
 +
4b int  Time Off</nowiki>
 +
'''Type 4''' WEAP:
 +
<nowiki>
 +
4b float Draw Distance 1
 +
4b float Draw Distance 2
 +
4b float Draw Distance 3 (if object is LOD, then disappearing distance)
 +
1b int  Mesh Count
 +
1b int  ?
 +
2b int  Flags
 +
4b int  Weapon.DAT ID
 +
4b int  Animation ID</nowiki>
  
<code> VCS PS2: 0x57BE4C </code>
+
====VCS====
 +
<nowiki>
 +
8b -
 +
4b int Name of the object (CRC32 Hash encryption)
 +
4b -
 +
1b int Type (1: objs, 3:tobj, 4:weap, 5:hier, 6:cars, 7:ped)
 +
1b int Count 2dfx (ex. if 2dfxID=8 and Count2dfx=4, then the assigned IDs are 8, 9, 10, 11)
 +
1b int Collision in .DTZ (boolean, 0:not in DTZ, 1:in DTZ)
 +
1b -  Padding
 +
4b int offset to collision (.col2)
 +
2b int 2dfx ID
 +
2b int Object.DAT ID
 +
2b -
 +
2b int Texture ID
 +
2b ?
 +
2b -
 +
4b int Type (CRC32 Hash encryprion)
 +
4b int offset to model (if no .mdl exists in .DTZ, then it's 0)</nowiki>
 +
'''Type 1''' OBJS:
 +
<nowiki>
 +
4b float Draw Distance 1
 +
4b float Draw Distance 2
 +
4b float Draw Distance 3 (if object is LOD, then disappearing distance)
 +
1b int  Mesh Count
 +
1b int  ?
 +
2b int  Flags
 +
4b int  if object is LOD, offset to IDE ID of original object, otherwise =0</nowiki>
 +
'''Type 3''' TOBJ:
 +
<nowiki>
 +
4b float Draw Distance 1
 +
4b float Draw Distance 2
 +
4b float Draw Distance 3 (if object is LOD, then disappearing distance)
 +
1b int  Mesh Count
 +
1b int  ?
 +
2b int  Flags
 +
4b int  if object is LOD, offset to IDE ID of original object, otherwise =0
 +
4b int  Time On
 +
4b int  Time Off</nowiki>
 +
''More info soon''
 +
===Car class tables===
 +
Each table has as many elements as there are vehicle classes: 11 for LCS and 13 for VCS. Each element is given an ID:
 +
<nowiki>
 +
0: normal
 +
1: poorfamily
 +
2: richfamily
 +
3: executive
 +
4: worker
 +
5: big
 +
6: taxi
 +
7: moped
 +
8: motorbike
 +
9: leisureboat
 +
10: workerboat</nowiki>
 +
VCS has 2 extra (they are used for some boats, their exact names are unknown since they're not present in other games)
 +
====Table 1====
 +
Each table element is an array of the IDs of the vehicle models in that class.
 +
<nowiki>
 +
4b int ID of a vehicle</nowiki>
 +
Each table element has 100 bytes allocated, thus the maximum number of vehicles per class is 25. If there are fewer than 25 vehicles in the class, the rest of the array is uninitialized. The format is the same for both LCS and VCS.
 +
====Table 2====
 +
Each table element is the number of vehicles in each class.
 +
<nowiki>
 +
4b int Number of vehicles in the class</nowiki>
 +
Again, same case for both LCS and VCS.
 +
===2DFX===
 +
'''2DFX''' data is read directly from DTZ header. Each line is 64 bytes (depending on the 2DFX type, padding is used at the end). 24 bytes are common for all types (only 0, 1 and 3 are used). Each line is assigned an ID, counting from 0.
 +
<nowiki>
 +
4b float Position X (relative to centre of the object)
 +
4b float Position Y (relative to centre of the object)
 +
4b float Position Z (relative to centre of the object)
 +
4b float Position W (relative to centre of the object)
 +
1b int  Colour R
 +
1b int  Colour G
 +
1b int  Colour B
 +
1b int  Unknown (usually 200.0, like in Vice City)
 +
4b int  Type
 +
</nowiki>
 +
'''Type 0''' Lights:
 +
<nowiki>
 +
4b float View Distance
 +
4b float Outer Range
 +
4b float Size
 +
4b float Inner Range
 +
1b int  Flash
 +
1b int  Wet
 +
1b int  Flare
 +
1b int  Shadow Intensity
 +
4b int  Flags
 +
4b int  Offset to corona texture
 +
4b int  Offset to shadow texture
 +
8b -    Padding</nowiki>
 +
'''Type 1''' Particles:
 +
<nowiki>
 +
4b int  Particle Type
 +
4b float Strength X
 +
4b float Strength Y
 +
4b float Strength Z
 +
4b float Scale
 +
20b -    Padding</nowiki>
 +
'''Type 2''' Peds investigate:
 +
<nowiki>
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
1b int  ?
 +
1b int  ?
 +
26b -    Padding</nowiki>
 +
'''Type 3''' Peds:
 +
<nowiki>
 +
4b float Rotation X
 +
4b float Rotation Y
 +
4b float Rotation Z
 +
4b float Rotation X (again)
 +
4b float Rotation Y (again)
 +
4b float Rotation Z (again)
 +
4b int  Behaviour
 +
12b -    Padding</nowiki>
 +
The format is the same as the plain text version of III and VC. More info can be found on: [[2DFX]]
  
<code> VCS PSP: 0x530AFC </code>
+
===OBJECT.DAT===
| also packed deflate/zlib algorithm (*)
+
It's read directly from DTZ header. Each line is given an ID counting from 0.
|-
+
====LCS====
| texture of particle effects
+
''116 entries''
| particle.txd
+
<nowiki>
|
+
4b float B Mass
| contain all textures of particle effect (*)
+
4b float C TurnMass
|-
+
4b float D Air Resistance
| generic-textures
+
4b float E Elasticity
| generic.txd, wheels.txd, vehicle.txd
+
4b float F Bouyance
|
+
4b float G Uproot Limit
| contains general textures for cars and all the textures of wheels (*)
+
4b float H Collision Damage Multiplier
|-
+
1b int  I Collision Damage Effect
| radar icons
+
1b int  J Special Collision Response Cases
| hud.txd
+
1b int  K Camera to avoid this object
|
+
1b -     Padding</nowiki>
| contain textures for hud (*)
+
Notes about actual values (what is expected to be in original file):
|-
+
<nowiki>
| texture of radar
+
Bouyance = 0.8 * Mass / Bouyance</nowiki>
| radarNN.txd
 
|
 
| only in [[GTA VCS]]
 
|-
 
| colspan="4" | <b>Animation</b>
 
|-
 
| ?
 
| ped.ifp
 
|
 
|
 
|-
 
| ?
 
| swim.ifp
 
|
 
| only in [[GTA VCS]]
 
|-
 
| ?
 
| fight.ifp
 
|
 
| only in [[GTA VCS]]
 
|-
 
| ?
 
| driveby.ifp
 
|
 
| only in [[GTA VCS]]
 
|-
 
! [[IMG|DIR]]-files
 
|-
 
| for cuts.img
 
| cuts.dir
 
|
 
| not working
 
|-
 
| for GTA3PS2.IMG
 
| GTA3PS2.dir
 
|
 
| specifi? for stories, doesn't contain the names.
 
|-
 
| colspan="4" | <b>Collision</b>
 
|-
 
| ?
 
| peds.col
 
|
 
| peds.col2
 
|-
 
| ?
 
| vehicles.col
 
|
 
| vehicles.col2
 
|-
 
| ?
 
| weapons.col
 
|
 
| weapons.col2
 
|-
 
| colspan="4" | <b>Models</b>
 
|-
 
| model of plane
 
| air_vlo.dff
 
|
 
| air_vlo.mdl
 
|-
 
| model of arrow
 
| arrow.dff
 
|
 
| arrow.mdl
 
|-
 
| model of wheels
 
| wheels.dff
 
|
 
|
 
|-
 
| model of marker (zone)
 
| zonecylb.dff
 
|
 
|
 
|-
 
| colspan="4" | <b>IDE / IPL / DAT</b>
 
|-
 
| [[IDE]]
 
| *.ide
 
|
 
| contain all name of models and textures.
 
|-
 
| [[IPL]]
 
| *.ipl
 
|
 
| contains all the coordinates for the placement of collisions in the game.
 
|-
 
| colors of cars
 
| carcols.dat
 
|
 
|-
 
| cullzone data
 
| cullzone.dat
 
|
 
|-
 
| fistfite data
 
| fistfite.dat
 
|
 
|
 
|-
 
| handling data
 
| handling.dat
 
| <code>LCS PS2: 0x1647A0</code>
 
<code>LCS PSP: 0x50190</code>
 
  
<code>VCS PS2: 0x4C2A10</code>
+
====VCS====
 +
''140 entries''
 +
<nowiki>
 +
4b float B Mass
 +
4b float C TurnMass
 +
4b float D Air Resistance
 +
4b float E Elasticity
 +
4b float F Bouyance
 +
4b float G Uproot Limit
 +
4b float H Collision Damage Multiplier
 +
1b int  ?
 +
1b int  ? (J Special Collision Response Cases?)
 +
1b int  ? (K Camera to avoid this object?)
 +
1b int  ?
 +
1b int  ?
 +
3b -    Padding</nowiki>
 +
Notes about actual values (what is expected to be in original file):
 +
<nowiki>
 +
Bouyance = 0.8 * Mass / Bouyance</nowiki>
  
<code>VCS PSP: 0x3AF30F</code>
+
===PEDSTATS.DAT===
| LCS and VCS have different structure of handling
+
The GAME.DTZ header redirects to a table which contains 4byte values, each one being an offset to each PEDSTATS.DAT line. Each line is defined as so:
|-
+
====LCS====
|
+
{{stub}}
| info.zon
+
====VCS====
|
+
<nowiki>
|
+
4b int    ID
|-
+
4b float B Flee Distance
|
+
4b float C Heading Change Rate
| map.zon
+
4b float H Attack Strength
|
+
4b float I Attack Weakness
|
+
2b int  J Flags
|-
+
1b int  D Fear
| object data
+
1b int  E Temper
| object.dat
+
1b int  F Lawfulness
|
+
1b int  G Sexiness
|
+
26b char A Name</nowiki>
|-
+
===PARTICLE.CFG===
| particle data
+
====LCS====
| particle.dat
+
{{stub}}
|
+
====VCS====
|
+
<nowiki>
|-
+
4b int      ID
| pedstats data
+
20b int  A  Name
| pedstats.dat
+
4b float CR Create Range
|
+
4b float E  Default Initial Radius
|
+
4b float F  Expansion Rate
|-
+
2b int  H  Fade Time
| timecyc data
+
2b int  G  Initial Intensity
| timecyc.dat
+
2b int  I  Fade Amount
|
+
2b int  GA Initial Intensity
|
+
2b int  HA Fade Time
|-
+
2b int  IA Fade Amount
| data about waters surfaces
+
1b int  K  Start Animation Frame
| waterpro.dat
+
1b int  L  Final Anim Frame
|
+
1b int  J  Anim Speed
|
+
1b -       Padding
|-
+
4b int  M  Rotation Speed
| weapon data
+
4b float N  Gravitational Acceleration
| [[weapon.dat]]
+
4b int  O  Friction Decceleration
| <code>VCS PS2: 0x3D7530</code>
+
4b int  P  Default Life Span
<code>VCS PSP: 0x2E8B60</code>
+
4b float Q  Position Random Error
|
+
4b float R  Velocity Random Error
|-
+
4b float S  Expansion Rate Error
| colspan="4" | <b>Other</b>
+
4b int  T  Rotation Rate Error
|-
+
4b int  U  Life Soan Error Shape
| [[SDT]]-files.
+
4b float V  Trail Length Multiplier
|
+
4b int  Z  Flags
|
+
1b int  B  Render Colouring R
| only in PSP versions
+
1b int  C  Render Colouring G
|}
+
1b int  D  Render Colouring B
<b>Notes:</b><br/>
+
1b -       Padding
* Offset is specified for the unpacked game.dtz
+
4b int  CV Initial Color Variation
* * - Data marked with (*) are opened by [[GTA Stories Texture Explorer]].
+
1b int  B2 Fade Destination Colour R
 +
1b int  C2 Fade Destination Colour G
 +
1b int  D2 Fade Destination Colour B
 +
1b -       Padding
 +
4b int  FT Colour Fade Time
 +
4b float WX x-axis Stretch Value
 +
4b float WY y-axis Stretch Value
 +
4b float WI Wind Factor
 +
4b ?        ?
 +
4b ?        ?</nowiki>
 +
 
 +
=== weapons data ===
  
==weapons data==
+
Analog of weapons.dat
{{stub}}
 
  
<!--
+
==== Structure of LCS version ====
TODO: FIX
 
  
Analog of weapons.dat. Basic differences - configuration has binary view.
+
Total number of records: 38
It consists of two tables with identical structure. Addresses structure and algorithms for reading weapons data for LCS and VCS are differents.
 
  
Offset of second table (VCS PS2): 4027696 (Offset for unpacked GAME.DTZ)
 
 
Number of notes: 40
 
  
VCS version structure :
 
 
<source lang="cpp">
 
<source lang="cpp">
  struct weapondata{
+
typedef struct vFireOffset{
     DWORD       dwType;  
+
    float      x;
     int         iFireType;
+
    float      y;  
     float       fRange;
+
    float      z;       
     int         iFiringRate;
+
};
     int         iReload;
+
 
     int         iAmountOfAmmunition;
+
typedef struct vTimeStrc{
     int         iDamage;
+
     float      a;
     float       fSpeed;
+
    float       b;
     float       fRadius;
+
    float      c;       
     float       fLifeSpan;
+
};
     float       fSpread;
+
 
     DWORD       dwPadding;   //padding (0xAA)
+
typedef struct weapondata{
     vFireOffset m_vFireOffset; //vector 
+
     int FireType;
     DWORD       _f3C;   //always zero
+
     float Range;
     DWORD       _f40;   //
+
     int FiringRate;
     DWORD      _f44;   //DWORD ? unknown
+
     int Reload;
     vFireOffset m_vFireOffset; //vector
+
     int AmountOfAmmunition;
     vFireOffset m_vFireOffset; //vector
+
     int Damage;
     DWORD       _f60;  
+
     float Speed;
     DWORD       _f64;
+
     float Radius;
     DWORD       _f68;   //weapon slot?
+
     float LifeSpan;
     DWORD       _f6C;   //padding (0xAA)     
+
     float Spread;
};
+
    DWORD padding1;
 +
     DWORD padding2;
 +
     vFireOffset FireOffset;
 +
     DWORD zero;
 +
     DWORD anim_id;
 +
     vTimeStrc time1;
 +
     vTimeStrc time2;
 +
     float unk;
 +
     DWORD ModelID;
 +
     DWORD ModelID2;
 +
     DWORD weapon_slot;
 +
     DWORD Flags <format=hex>;
 +
};
 
</source>
 
</source>
--!>
 
  
==handling data==
+
==== Structure of VCS version ====
 +
0xC0 points to the offset of a value, and that value is the offset of weapon data. Each "line" is given an ID starting from 0 (that ID is linked to weapon IDE). There are 40 weapon IDs in total.
 +
<nowiki>
 +
4b int a Flags
 +
4b int B Fire type
 +
4b float C Range
 +
4b int D Firing Rate
 +
4b int E Reload
 +
4b int F Amount of Ammunition
 +
4b int G Damage
 +
4b float H Speed
 +
4b float I Radius
 +
4b float J Life span
 +
4b float K Spread
 +
4b - Padding
 +
4b float L Fire offset X
 +
4b float M Fire offset Y
 +
4b float N Fire offset Z
 +
4b float Fire offset W
 +
4b int P Anim ID
 +
4b float R * animation loop start
 +
4b float S * animation loop end
 +
4b float T * point in animation where weapon is fired
 +
4b float U * animation2 loop start
 +
4b float V * animation2 loop end
 +
4b float W * point in animation2 where weapon is fired
 +
4b float X * point in anim where we can breakout of anim/attack and run away
 +
4b int Y model id (IDE)
 +
4b int Z model id 2 (IDE)
 +
4b int b Weapon Slot
 +
4b - Padding</nowiki>
 +
 
 +
Data marked with * needs to be multiplied by 30.0 to get original value
 +
 
 +
===HANDLING.CFG===
 +
====LCS====
 
{{stub}}
 
{{stub}}
  
[[Category: GTA_LCS]] [[Category: GTA_VCS]]
+
====VCS====
 +
HANDLING.CFG data is read from the IDE section of each vehicle. There are 6 types of handling (to be found). Type 1 (or the common one) is presented.
 +
''This is very likely to be wrong :) Need help!''
 +
<nowiki>
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
4b float fEngineAcceleration
 +
4b float TransmissionData.fEngineInertia
 +
4b float ?
 +
4b float ?
 +
4b float ?
 +
1b char  TransmissionData.nDriveType
 +
1b char  TransmissionData.nEngineType
 +
1b int  TransmissionData.nNumberOfGears
 +
1b int  Padding
 +
4b float fBrakeDeceleration
 +
4b float fBrakeBias
 +
4b float fSteeringLock
 +
4b float fTractionLoss
 +
4b float fTractionBias
 +
4b float fSuspensionForceLevel
 +
4b float fSuspensionDampingLevel
 +
4b float suspension upper limit
 +
4b float suspension lower limit
 +
4b float suspension bias between front and rear
 +
4b float suspension anti-dive multiplier
 +
4b float fSeatOffsetDistance
 +
4b int  nMonetaryValue
 +
1b int  front lights
 +
1b int  rear lights
 +
2b int  Padding
 +
4b float fDragMult
 +
4b      ? (Probably padding)
 +
4b float CentreOfMass.x (CVuVector X)
 +
4b float CentreOfMass.y (CVuVector Y)
 +
4b float CentreOfMass.z (CVuVector Z)
 +
4b float -              (CVuVector W)
 +
4b int  nPercentSubmerged
 +
4b float ?
 +
4b float TransmissionData.fMaxVelocity
 +
4b float fMass
 +
4b float fTurnMass
 +
4b float fTractionMultiplier
 +
4b float fCollisionDamageMultiplier
 +
4b int  ?
 +
4b int  ?
 +
12b ?</nowiki>
 +
 
 +
Notes about actual values (what is expected to be in original file):
 +
<nowiki>
 +
fEngineAcceleration = fEngineAcceleration *12500(*2 for nDriveType = '4'))
 +
fBrakeDeceleration = fBrakeDeceleration*2500)
 +
fCollisionDamageMultiplier = fMass/2000*fCollisionDamageMultiplier</nowiki>
 +
===Font Data===
 +
This section seems to be present only in VCS, and has info about spliting font textures to individual character sprites, as well as character spacing. 0xF4 points to an array of pointers, 3 on PSP and 4 on PS2 (PS2 has the additional PagerText font). Each pointer points to an info section for each fonts. This info section looks like this:
 +
<nowiki>
 +
2b int Total number of characters
 +
2b int Number of Controller Button Characters
 +
2b int ? (Number of some character types)
 +
2b int ? (Number of some character types)
 +
4b int Offset to Character Data 1
 +
4b int Offset to Character Data 2
 +
1b int Font ID
 +
3b Uninitialised Data (??)
 +
4b int ?
 +
4b int ?
 +
4b int ?
 +
4b float ?
 +
4b int ?
 +
4b int ?
 +
20b string Font Name
 +
4b ? ?
 +
4b ? ?
 +
4b ? ?
 +
4b int ?</nowiki>
 +
Character Data 1 has as many entries as there are characters for that specific font and has this format:
 +
<nowiki>
 +
2b int ?
 +
2b int Bottom Right X (pixel)
 +
2b int ?
 +
2b int Bottom Right Y (pixel)
 +
2b string Character
 +
2b int Top Left X (pixel)
 +
2b int Top Left Y (pixel)</nowiki>
 +
 
 +
==Sources==
 +
http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
 +
 
 +
{{N|VCS|LCS}}

Latest revision as of 23:11, 12 January 2021

GAME.DTZ (DaTa Zlib) is a file in PS2 and PSP versions of GTA LCS and GTA VCS. It contains data files, as well as main textures and models analogue to existing 3D era games compiled in binary form. It is compressed using the zlib/deflate algorithm [1] (max compression). It can be decompressed by any zlib compression/decompression utility, such as offzip [2] and zdrop [3]. Data can be extracted by guard3's DTZpy [4], though textures and some data files can be manipulated with Dageron's DTZ Editor [5]. All info provided is about decompressed version

Header

The Header for both GTA LCS and GTA VCS versions is nothing but a standard Relocatable Chunk header, defined like so:

struct base::sChunkHeader
{
	uint32 ident;
	uint32 shrink;
	uint32 fileEnd;
	uint32 dataEnd;
	uint32 relocTab;
	uint32 numRelocs;
	uint32 globalTab;
	uint16 numClasses;
	uint16 numFuncs;
};

More info on Relocatable chunk

LCS Version

VCS Version

0x20  paths
0x24  offset to "Buildings" info
0x28  offset to "Treadables" info
0x2C  offset to "Dummys" info
0x30  offset to "EntryInfoNode" info
0x34  offset to "PtrNode" info
0x38  number of offsets in IDE table
0x3C  offset to IDE table
0x40  offset to car class table 1
0x44  offset to car class table 2
0x48  offset to GTA3.ZON
0x4C  0, ?
0x50  0, ?
0x54  number of 2dfx data "lines"
0x58  offset to 2dfx data
0x5C  ? (has to do with model indices)
0x60  offset to "Texlist" info
0x64  0, ?
0x68  ?
0x6C  0, ?
0x70  ?
0x74  offset to OBJECT.DAT
0x78  ?
0x7C  offset to GTA3PS2.DIR
0x80  offset to animation data
0x84  offset to FISTFITE.DAT
0x88  offset to PED.DAT offset table
0x8C  offset to PEDSTATS.DAT offset table
0x90  offset to car colours data
0x94  ?
0x98  number of CULL.IPL "lines"
0x9C  offset to CULL.IPL
0xA0  number of OCCLU.IPL �lines� (0 in VCS)
0xA4  offset to OCCLU.IPL (0 in VCS)
0xA8  offset to WATERPRO.DAT
0xAC  offset to weather types table
0xB0  offset to SURFACE.DAT
0xB4  offset to TIMECYC.DAT
0xB8  offset to PEDGRP.DAT
0xBC  offset to PARTICLE.CFG
0xC0  offset to WEAPON.DAT
0xC4  0, ?
0xC8  offset to models offset table
0xCC  offset to MOCAPPS2.DIR
0xD0  ?
0xD4  0, ?
0xD8  ?
0xDC  0, ?
0xE0  offset to MENU.XTX (zlib/deflate compressed)
0xE4  ?
0xE8  ?
0xEC  ?
0xF0  ?
0xF4  offset to font data
0xF8  size of decompressed FSFONTS.XTX
0xFC  offset to FSFONTS.XTX (zlib/deflate compressed)
0x100 offset to radar textures offset table

Data Formats

IPL

IPL Info

The header of GAME.DTZ points to 5 IPL info tables: Buildings, Treadables, Dummys, EntryInfoNode and PtrNode. The first 3 are 16 bytes in size and are defined like so:

4b int Offset to IPL data
4b int  ?
4b int  Number of IPL lines
4b int  ?
16 char Name of IPL info (Buildings, Treadables, etc...)

Need more info on EntryInfoNode and PtrNode

IPL Structure

The IPL data is structured like so:

4b float m00
4b float m10
4b float m20
4b float Unk1
4b float m01
4b float m11
4b float m21
4b float Unk2
4b float m02
4b float m12
4b float m22
4b float Unk3
4b float Position-X
4b float Position-Y
4b float Position-Z
4b float Unk4
24b ?
2b int   Corresponding Model ID
6b ?

The IPL is basically a matrix:

[m00,  m01,  m02,  Position-X]
[m10,  m11,  m12,  Position-Y]
[m20,  m21,  m22,  Position-Z]
[unk1, unk2, unk3, unk4      ]

The bottom row is Leeds Engine stuff, not useful for generating IPL. They only matter in memory. Someone may provide more info

Generating IPL in text format

In order to calculate the original rotation values, this algorythm comes in handy:

float tr = m00 + m11 + m22

if (tr > 0) { 
  float S = sqrt(tr+1.0) * 2; // S=4*qw 
  qw = 0.25 * S;
  qx = (m21 - m12) / S;
  qy = (m02 - m20) / S; 
  qz = (m10 - m01) / S; 
} else if ((m00 > m11)&(m00 > m22)) { 
  float S = sqrt(1.0 + m00 - m11 - m22) * 2; // S=4*qx 
  qw = (m21 - m12) / S;
  qx = 0.25 * S;
  qy = (m01 + m10) / S; 
  qz = (m02 + m20) / S; 
} else if (m11 > m22) { 
  float S = sqrt(1.0 + m11 - m00 - m22) * 2; // S=4*qy
  qw = (m02 - m20) / S;
  qx = (m01 + m10) / S; 
  qy = 0.25 * S;
  qz = (m12 + m21) / S; 
} else { 
  float S = sqrt(1.0 + m22 - m00 - m11) * 2; // S=4*qz
  qw = (m10 - m01) / S;
  qx = (m02 + m20) / S;
  qy = (m12 + m21) / S;
  qz = 0.25 * S;
}

And finally, since 3DS Max that originally created IPL negates X,Y,Z:

Rotation X = -qx
Rotation Y = -qy
Rotation Z = -qz
Rotation W = qw

IDE

On both LCS and VCS, 0x3C points to a table containing offsets to IDE lines and 0x38 specifies the number of values in the table. Each value-offset is assigned an ID, starting from 0. If it so happens and the value-offset is 0x00000000, then the ID isn't assigned to any object. The structure is like so:

LCS

8b -
4b int Name of the object (CRC32 Hash encryption)
4b -
1b int Type (1: objs, 3:tobj, 4:weap, 5:hier, 6:cars, 7:ped)
1b int Count 2dfx (ex. if 2dfxID=8 and Count2dfx=4, then the assigned IDs are 8, 9, 10, 11)
1b int Collision in .DTZ (boolean, 0:not in DTZ, 1:in DTZ)
1b -   Padding
4b int offset to collision (.col2)
2b int 2dfx ID
2b int Object.DAT ID
2b -
2b int Texture ID
4b int Type (CRC32 Hash encryprion)
4b int offset to model (if no .mdl exists in .DTZ, then it's 0)

Type 1 OBJS:

4b float Draw Distance 1
4b float Draw Distance 2
4b float Draw Distance 3 (if object is LOD, then disappearing distance)
1b int   Mesh Count
1b int   ?
2b int   Flags
4b int   if object is LOD, offset to IDE ID of original object, otherwise =0

Type 3 TOBJ:

4b float Draw Distance 1
4b float Draw Distance 2
4b float Draw Distance 3 (if object is LOD, then disappearing distance)
1b int   Mesh Count
1b int   ?
2b int   Flags
4b int   if object is LOD, offset to IDE ID of original object, otherwise =0
4b int   Time On
4b int   Time Off

Type 4 WEAP:

4b float Draw Distance 1
4b float Draw Distance 2
4b float Draw Distance 3 (if object is LOD, then disappearing distance)
1b int   Mesh Count
1b int   ?
2b int   Flags
4b int   Weapon.DAT ID
4b int   Animation ID

VCS

8b -
4b int Name of the object (CRC32 Hash encryption)
4b -
1b int Type (1: objs, 3:tobj, 4:weap, 5:hier, 6:cars, 7:ped)
1b int Count 2dfx (ex. if 2dfxID=8 and Count2dfx=4, then the assigned IDs are 8, 9, 10, 11)
1b int Collision in .DTZ (boolean, 0:not in DTZ, 1:in DTZ)
1b -   Padding
4b int offset to collision (.col2)
2b int 2dfx ID
2b int Object.DAT ID
2b -
2b int Texture ID
2b ?
2b -
4b int Type (CRC32 Hash encryprion)
4b int offset to model (if no .mdl exists in .DTZ, then it's 0)

Type 1 OBJS:

4b float Draw Distance 1
4b float Draw Distance 2
4b float Draw Distance 3 (if object is LOD, then disappearing distance)
1b int   Mesh Count
1b int   ?
2b int   Flags
4b int   if object is LOD, offset to IDE ID of original object, otherwise =0

Type 3 TOBJ:

4b float Draw Distance 1
4b float Draw Distance 2
4b float Draw Distance 3 (if object is LOD, then disappearing distance)
1b int   Mesh Count
1b int   ?
2b int   Flags
4b int   if object is LOD, offset to IDE ID of original object, otherwise =0
4b int   Time On
4b int   Time Off

More info soon

Car class tables

Each table has as many elements as there are vehicle classes: 11 for LCS and 13 for VCS. Each element is given an ID:

0: normal
1: poorfamily
2: richfamily
3: executive
4: worker
5: big
6: taxi
7: moped
8: motorbike
9: leisureboat
10: workerboat

VCS has 2 extra (they are used for some boats, their exact names are unknown since they're not present in other games)

Table 1

Each table element is an array of the IDs of the vehicle models in that class.

4b int ID of a vehicle

Each table element has 100 bytes allocated, thus the maximum number of vehicles per class is 25. If there are fewer than 25 vehicles in the class, the rest of the array is uninitialized. The format is the same for both LCS and VCS.

Table 2

Each table element is the number of vehicles in each class.

4b int Number of vehicles in the class

Again, same case for both LCS and VCS.

2DFX

2DFX data is read directly from DTZ header. Each line is 64 bytes (depending on the 2DFX type, padding is used at the end). 24 bytes are common for all types (only 0, 1 and 3 are used). Each line is assigned an ID, counting from 0.

4b float Position X (relative to centre of the object)
4b float Position Y (relative to centre of the object)
4b float Position Z (relative to centre of the object)
4b float Position W (relative to centre of the object)
1b int   Colour R
1b int   Colour G
1b int   Colour B
1b int   Unknown (usually 200.0, like in Vice City)
4b int   Type

Type 0 Lights:

4b float View Distance
4b float Outer Range
4b float Size
4b float Inner Range
1b int   Flash
1b int   Wet
1b int   Flare
1b int   Shadow Intensity
4b int   Flags
4b int   Offset to corona texture
4b int   Offset to shadow texture
8b -     Padding

Type 1 Particles:

4b int   Particle Type
4b float Strength X
4b float Strength Y
4b float Strength Z
4b float Scale
20b -    Padding

Type 2 Peds investigate:

4b float ?
4b float ?
4b float ?
1b int   ?
1b int   ?
26b -    Padding

Type 3 Peds:

4b float Rotation X
4b float Rotation Y
4b float Rotation Z
4b float Rotation X (again)
4b float Rotation Y (again)
4b float Rotation Z (again)
4b int   Behaviour
12b -    Padding

The format is the same as the plain text version of III and VC. More info can be found on: 2DFX

OBJECT.DAT

It's read directly from DTZ header. Each line is given an ID counting from 0.

LCS

116 entries

4b float B Mass
4b float C TurnMass
4b float D Air Resistance
4b float E Elasticity
4b float F Bouyance
4b float G Uproot Limit
4b float H Collision Damage Multiplier
1b int   I Collision Damage Effect
1b int   J Special Collision Response Cases
1b int   K Camera to avoid this object
1b -     Padding

Notes about actual values (what is expected to be in original file):

Bouyance = 0.8 * Mass / Bouyance

VCS

140 entries

4b float B Mass
4b float C TurnMass
4b float D Air Resistance
4b float E Elasticity
4b float F Bouyance
4b float G Uproot Limit
4b float H Collision Damage Multiplier
1b int   ?
1b int   ? (J Special Collision Response Cases?)
1b int   ? (K Camera to avoid this object?)
1b int   ?
1b int   ?
3b -     Padding

Notes about actual values (what is expected to be in original file):

Bouyance = 0.8 * Mass / Bouyance

PEDSTATS.DAT

The GAME.DTZ header redirects to a table which contains 4byte values, each one being an offset to each PEDSTATS.DAT line. Each line is defined as so:

LCS

VCS

4b int     ID
4b float B Flee Distance
4b float C Heading Change Rate
4b float H Attack Strength
4b float I Attack Weakness
2b int   J Flags
1b int   D Fear
1b int   E Temper
1b int   F Lawfulness
1b int   G Sexiness
26b char A Name

PARTICLE.CFG

LCS

VCS

4b int      ID
20b int  A  Name
4b float CR Create Range
4b float E  Default Initial Radius
4b float F  Expansion Rate
2b int   H  Fade Time
2b int   G  Initial Intensity
2b int   I  Fade Amount
2b int   GA Initial Intensity
2b int   HA Fade Time
2b int   IA Fade Amount	
1b int   K  Start Animation Frame
1b int   L  Final Anim Frame
1b int   J  Anim Speed
1b -        Padding
4b int   M  Rotation Speed
4b float N  Gravitational Acceleration
4b int   O  Friction Decceleration
4b int   P  Default Life Span
4b float Q  Position Random Error
4b float R  Velocity Random Error	
4b float S  Expansion Rate Error
4b int   T  Rotation Rate Error
4b int   U  Life Soan Error Shape
4b float V  Trail Length Multiplier
4b int   Z  Flags
1b int   B  Render Colouring R
1b int   C  Render Colouring G
1b int   D  Render Colouring B
1b -        Padding
4b int   CV Initial Color Variation
1b int   B2 Fade Destination Colour R
1b int   C2 Fade Destination Colour G
1b int   D2 Fade Destination Colour B
1b -        Padding
4b int   FT Colour Fade Time
4b float WX x-axis Stretch Value
4b float WY y-axis Stretch Value
4b float WI Wind Factor	
4b ?        ?
4b ?        ?

weapons data

Analog of weapons.dat

Structure of LCS version

Total number of records: 38


typedef struct vFireOffset{
    float       x;
    float       y;  
    float       z;        
};

typedef struct vTimeStrc{
    float       a;
    float       b;  
    float       c;        
};

typedef struct weapondata{
    int		FireType;
    float	Range;
    int		FiringRate;
    int		Reload;
    int		AmountOfAmmunition;
    int		Damage;
    float	Speed;
    float	Radius;
    float	LifeSpan;
    float	Spread;
    DWORD	padding1;
    DWORD	padding2;
    vFireOffset	FireOffset;
    DWORD	zero;
    DWORD	anim_id;
    vTimeStrc	time1;
    vTimeStrc	time2;
    float	unk;
    DWORD	ModelID;
    DWORD	ModelID2;
    DWORD	weapon_slot;
    DWORD	Flags <format=hex>;
};

Structure of VCS version

0xC0 points to the offset of a value, and that value is the offset of weapon data. Each "line" is given an ID starting from 0 (that ID is linked to weapon IDE). There are 40 weapon IDs in total.

4b	int	a	Flags
4b	int	B	Fire type
4b	float	C	Range
4b	int	D	Firing Rate
4b	int	E	Reload
4b	int	F	Amount of Ammunition
4b	int	G	Damage
4b	float	H	Speed
4b	float	I	Radius
4b	float	J	Life span
4b	float	K	Spread
4b	-		Padding
4b	float	L	Fire offset X
4b	float	M	Fire offset Y
4b	float	N	Fire offset Z
4b	float		Fire offset W
4b	int	P	Anim ID
4b	float	R	* animation loop start
4b	float	S	* animation loop end
4b	float	T	* point in animation where weapon is fired
4b	float	U	* animation2 loop start
4b	float	V	* animation2 loop end
4b	float	W	* point in animation2 where weapon is fired
4b	float	X	* point in anim where we can breakout of anim/attack and run away
4b	int	Y	model id (IDE)
4b	int	Z	model id 2 (IDE)
4b	int	b	Weapon Slot
4b	-		Padding

Data marked with * needs to be multiplied by 30.0 to get original value

HANDLING.CFG

LCS

VCS

HANDLING.CFG data is read from the IDE section of each vehicle. There are 6 types of handling (to be found). Type 1 (or the common one) is presented. This is very likely to be wrong :) Need help!

4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float ?
4b float fEngineAcceleration
4b float TransmissionData.fEngineInertia
4b float ?
4b float ?
4b float ?
1b char  TransmissionData.nDriveType
1b char  TransmissionData.nEngineType
1b int   TransmissionData.nNumberOfGears
1b int   Padding
4b float fBrakeDeceleration
4b float fBrakeBias
4b float fSteeringLock
4b float fTractionLoss
4b float fTractionBias
4b float fSuspensionForceLevel
4b float fSuspensionDampingLevel
4b float suspension upper limit
4b float suspension lower limit
4b float suspension bias between front and rear
4b float suspension anti-dive multiplier
4b float fSeatOffsetDistance
4b int   nMonetaryValue
1b int   front lights
1b int   rear lights
2b int   Padding
4b float fDragMult
4b       ? (Probably padding)
4b float CentreOfMass.x (CVuVector X)
4b float CentreOfMass.y (CVuVector Y)
4b float CentreOfMass.z (CVuVector Z)
4b float -              (CVuVector W)
4b int   nPercentSubmerged
4b float ?
4b float TransmissionData.fMaxVelocity
4b float fMass
4b float fTurnMass
4b float fTractionMultiplier
4b float fCollisionDamageMultiplier
4b int   ?
4b int   ?
12b ?

Notes about actual values (what is expected to be in original file):

fEngineAcceleration = fEngineAcceleration *12500(*2 for nDriveType = '4'))
fBrakeDeceleration = fBrakeDeceleration*2500)
fCollisionDamageMultiplier = fMass/2000*fCollisionDamageMultiplier

Font Data

This section seems to be present only in VCS, and has info about spliting font textures to individual character sprites, as well as character spacing. 0xF4 points to an array of pointers, 3 on PSP and 4 on PS2 (PS2 has the additional PagerText font). Each pointer points to an info section for each fonts. This info section looks like this:

2b	int	Total number of characters
2b	int	Number of Controller Button Characters
2b	int	? (Number of some character types)
2b	int	? (Number of some character types)
4b	int	Offset to Character Data 1
4b	int 	Offset to Character Data 2
1b	int	Font ID
3b		Uninitialised Data (??)
4b	int	?
4b	int	?
4b	int	?
4b	float	?
4b	int	?
4b	int	?
20b	string	Font Name
4b	?	?
4b	?	?
4b	?	?
4b	int	?

Character Data 1 has as many entries as there are characters for that specific font and has this format:

2b	int	?
2b	int	Bottom Right X (pixel)
2b	int	?
2b	int	Bottom Right Y (pixel)
2b	string	Character
2b	int 	Top Left X (pixel)
2b	int	Top Left Y (pixel)

Sources

http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm