Difference between revisions of "FVIS (File Format)"

From MK8
Jump to navigation Jump to search
m
(Rewamp format documentation and reuse the Curve structures (conferring with Wexos about the Curve flags))
Line 1: Line 1:
 
{{under-construction}}
 
{{under-construction}}
  
'''FVIS''' files (ca'''F'''e '''VIS'''ibility animation) are visibility animation files. The same format seems to be used for both '''bone''' visibility and '''material''' visibility. They are found into [[BFRES]] files in the '''7:th''' [[index group]] (bone visibility) and the '''8:th''' [[index group]] (material visibility). Unless otherwise noted, all offsets in the file are relative to themselves.
+
'''FVIS''' files (ca'''F'''e '''VIS'''ibility animation) are visibility animation files. The same format seems to be used for both '''bone''' visibility and '''material''' visibility. They are found in [[BFRES]] files in the '''7th''' [[index group]] (bone visibility) and the '''8th''' [[index group]] (material visibility). Unless otherwise noted, all offsets in the file are relative to themselves.
  
== Header ==
+
__TOC__
The file starts with a 0x34 bytes long header.
+
 
 +
= Format =
 +
 
 +
An '''FVIS file''' begins with an '''FVIS header'''. This is then followed by a number of sections pointed to by the header, many of which can occur multiple times. The purpose of these sections is described in the table below.
 +
 
 +
'''FVIS ''' shares many similarities with the '''[[FSKA]]''', '''[[FSHU]]''', '''[[FTXP]]''', '''[[FSHA]]''' and '''[[FSCN]]''' subfiles, which mostly only differ in the structure describing what is changed by animations over time, but reusing the same animation curve and key structures, and even headers being very similar to one another.
 +
 
 +
== Header (FVIS) ==
 +
 
 +
Every FVIS begins with an 0x34 byte '''FVIS header'''.
  
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! Offset !! Type !! Description
+
! Offset !! Size !! Type !! Description
|-
 
| 0x00 || String || '''File magic'''. Always ''FVIS'' in ASCII.
 
|-
 
| 0x04 || Int32 || '''Filename''' offset. The file name of the file without the extension.
 
|-
 
| 0x08 || Int32 || '''[[BFRES#String Table|String table]] end''' offset. Points to the end of the [[BFRES#String Table|string table]].
 
|-
 
| 0x0C || UInt16 || Flags.
 
{| class="wikitable"
 
|-
 
! Bit (MSB) !! Size (in bits) !! Description
 
|-
 
| 0x0D || 0x01 || Loops.
 
|}
 
|-
 
| 0x0E || UInt16 || Number of '''[[BFRES (File Format)#User Data|user data]]''' entries.
 
|-
 
| 0x10 || UInt32 || Number of '''frames''' in this animation.
 
|-
 
| 0x14 || UInt16 || Number of '''material targets''' or '''bone targets'''.
 
|-
 
| 0x16 || UInt16 || '''Unknown'''.
 
|-
 
| 0x18 || UInt32 || '''Unknown'''.
 
|-
 
| 0x1C || UInt32 || '''Unknown'''.
 
|-
 
| 0x20 || Int32 || Offset to an '''structure''' with '''unknown purpose'''. There is a UInt16 foreach material or bone.
 
|-
 
| 0x24 || Int32 || '''String list''' offset. Points to a list of offsets which points to the names of the materials or bones.
 
 
|-
 
|-
| 0x28 || Int32 || '''Animation data''' offset. Points to the first animation data. It is unknown exactly how it works when there is more than one animation.
+
| 0x00 || 4 || Char[4] || "'''FVIS'''" file identifier, ASCII string.
 
|-
 
|-
| 0x2C || Int32 || Offset to an '''unknown structure'''.
+
| 0x04 || 4 || Int32 || '''File name''' offset (without file extension).
 
|-
 
|-
| 0x30 || Int32 || '''[[BFRES (File Format)#User Data|User data]] [[index group]] offset.
+
| 0x08 || 4 || Int32 || '''File path''' offset, the path of the file this data was originally created from. Stripped in [[Mario Kart 8]] files, always pointing to an empty string at the end of the BFRES [[BFRES (File Format)#String Table|string table]].
|}
 
 
 
== Animation Data ==
 
{| class="wikitable"
 
 
|-
 
|-
! Offset !! Type !! Description
+
| 0x0C || 2 || UInt16 || '''Flags'''. Set of bits packed as '''xxxxxxxT xxxxxLxB''', controlling how to play the animation and what data is stored. The following flags are possible:
 +
* '''B''' determines whether curve data is baked; baked if set.
 +
* '''L''' determines whether the animation is looping; looping if set.
 +
* '''T''' specifies the type of visibility stored; Material Visibility if set, otherwise Bone Visibility.
 
|-
 
|-
| 0x00 || UInt16 || Flag.
+
| 0x0E || 2 || UInt16 || '''[[User Data]] entry count'''.
{| class="wikitable"
 
 
|-
 
|-
! Bit (MSB) !! Size (in bits) !! Description
+
| 0x10 || 4 || Int32 || '''Frame count'''.
 
|-
 
|-
| 0x02 || 0x02 || Pre wrap. 0 = Clamp, 1 = Repeat, 2 = Mirror.
+
| 0x14 || 2 || UInt16 || '''Animation count''', the number of Bone or Material animations.
 
|-
 
|-
| 0x06 || 0x02 || Post wrap. 0 = Clamp, 1 = Repeat, 2 = Mirror.
+
| 0x16 || 2 || UInt16 || '''[[#Curve|Curve]] count''', the total number of Curve structures in all Animations.
|}
 
 
|-
 
|-
| 0x02 || UInt16 || Number of '''key frames'''.
+
| 0x18 || 4 || UInt32 || '''Baked length'''.
 
|-
 
|-
| 0x04 || UInt32 || '''Unknown'''.
+
| 0x1C || 4 || Int32 || '''[[FMDL|Model]]''' offset. Points to the affected FMDL model.
 
|-
 
|-
| 0x08 || Float || '''Min frame'''. Value of the smallest frame index.
+
| 0x20 || 4 || Int32 || '''[[#Bind Indices|Bind index]] array''' offset.
 
|-
 
|-
| 0x0C || Float || '''Max frame'''. Value of the largest frame index.
+
| 0x24 || 4 || Int32 || '''Name array''' offset. Points to a list of offsets which point to the names of the materials or bones.
 
|-
 
|-
| 0x10 || UInt32 || '''Unknown'''.
+
| 0x28 || 4 || Int32 || '''[[#Curve|Curve]] array''' offset.
 
|-
 
|-
| 0x14 || UInt32 || '''Unknown'''.
+
| 0x2C || 4 || Int32 || '''Base Value array''' offset. Is of '''Ceil(AnimationCount / 8)''' bytes size, as each bit controls the initial visibility of a corresponding Bone or Material.
 
|-
 
|-
| 0x18 || UInt32 || '''Unknown'''.
+
| 0x30 || 4 || Int32 || '''[[User Data]] [[index group]]''' offset.
 
|-
 
|-
| 0x1C || Int32 || Offset to the '''[[#Key Frames|key frames]]'''.
+
| 0x34 || colspan="3" {{Unknown|End of FVIS header}}
|-
 
| 0x20 || Int32 || Offset to the '''[[#Value Data|value data]]'''.
 
 
|}
 
|}
  
=== Key Frames ===
+
{{NW4FCurve}}
It is unknown how the key frames are stored. Sometimes it is just a byte[] of indices. This is of course not possible if the frame count is larger than 0xFF.
+
=== Target ===
 
+
The Curve targets which control what exactly is animated over time are not yet known.
=== Value Data ===
 
It is unknown how the value data is stored.
 
  
 
[[Category:File Format]]
 
[[Category:File Format]]

Revision as of 13:12, 31 May 2017

Under Construction
This article is not finished. Help improve it by adding accurate information or correcting grammar and spelling.

FVIS files (caFe VISibility animation) are visibility animation files. The same format seems to be used for both bone visibility and material visibility. They are found in BFRES files in the 7th index group (bone visibility) and the 8th index group (material visibility). Unless otherwise noted, all offsets in the file are relative to themselves.

Format

An FVIS file begins with an FVIS header. This is then followed by a number of sections pointed to by the header, many of which can occur multiple times. The purpose of these sections is described in the table below.

FVIS shares many similarities with the FSKA, FSHU, FTXP, FSHA and FSCN subfiles, which mostly only differ in the structure describing what is changed by animations over time, but reusing the same animation curve and key structures, and even headers being very similar to one another.

Header (FVIS)

Every FVIS begins with an 0x34 byte FVIS header.

Offset Size Type Description
0x00 4 Char[4] "FVIS" file identifier, ASCII string.
0x04 4 Int32 File name offset (without file extension).
0x08 4 Int32 File path offset, the path of the file this data was originally created from. Stripped in Mario Kart 8 files, always pointing to an empty string at the end of the BFRES string table.
0x0C 2 UInt16 Flags. Set of bits packed as xxxxxxxT xxxxxLxB, controlling how to play the animation and what data is stored. The following flags are possible:
  • B determines whether curve data is baked; baked if set.
  • L determines whether the animation is looping; looping if set.
  • T specifies the type of visibility stored; Material Visibility if set, otherwise Bone Visibility.
0x0E 2 UInt16 User Data entry count.
0x10 4 Int32 Frame count.
0x14 2 UInt16 Animation count, the number of Bone or Material animations.
0x16 2 UInt16 Curve count, the total number of Curve structures in all Animations.
0x18 4 UInt32 Baked length.
0x1C 4 Int32 Model offset. Points to the affected FMDL model.
0x20 4 Int32 Bind index array offset.
0x24 4 Int32 Name array offset. Points to a list of offsets which point to the names of the materials or bones.
0x28 4 Int32 Curve array offset.
0x2C 4 Int32 Base Value array offset. Is of Ceil(AnimationCount / 8) bytes size, as each bit controls the initial visibility of a corresponding Bone or Material.
0x30 4 Int32 User Data index group offset.
0x34 End of FVIS header


Curve

Curves store how animations are performed over time and store the required keys and values for this. They appear in multiple animation subfiles, and their header is of 0x24 bytes size (for BFRES versions earlier than 3.4.0.0, they are of 0x20 bytes size).

Offset Size Type Description
0x00 2 UInt16 Flags. Sets of bits packed as xxxxxxxx xCCCKKFF.
  • FF determines the data type of frames in the Frame array.
Value Size Type
0 4 Single
1 2 16-bit fixed point value (1 bit sign, 10 bits integral and 5 bits fractional).
  • To convert to Single, use Float(x) / (1 << 5).
  • To retrieve from Single, use Round(x * (1 << 5))
2 1 Byte
  • KK determines the data type of keys in the Key array.
Value Size Type
0 4 Single
1 2 Int16
2 1 SByte
  • CCC determines what kind of curve data is stored, resulting in a different number of elements stored per Key. They are used to set the key values and control the interpolation from one key to the next.
Value Description Elements per Key
0 Cubic Single 4 (hermite interpolation)
1 Linear Single 2 (linear interpolation)
2 Baked Single 1 (no interpolation)
4 Step Integer 1 (no interpolation)
5 Baked Integer 1 (no interpolation)
6 Step Boolean 1 (no interpolation)
7 Baked Boolean 1 (no interpolation)
0x02 2 UInt16 Key count.
0x04 4 UInt32 Target Offset, an offset in bytes into the corresponding Animation Data structure to animate the field at that relative address.
0x08 4 Single Start frame, the first frame at which a key is placed.
0x0C 4 Single End frame, the last frame at which a key is placed.
0x10 4 Int32 / Single Data scale, multiplier to the raw key values to get the final result. Together with Data offset, it is chosen carefully to consider an optimal granularity between the stored values.
0x14 4 Single Data offset, added to the raw values (after multiplying them with Data scale) to get the final key value.
if BFRES version >= 3.4.0.0
0x18 4 Single Data delta, stores the difference between the first and last key value.
0x1C 4 Int32 Frame array offset.
0x20 4 Int32 Key array offset.
0x24 End of Curve
else
0x18 4 Int32 Frame array offset.
0x1C 4 Int32 Key array offset.
0x20 End of Curve

Frames

The Curve header points to a Frame array which stores values controlling at which frame a Key from the Key array is placed. Thus, the array has as many elements as specified in Key count. The data type of the frames is given in the Curve's Flags.

The end of the array is aligned to 4 bytes.

Keys

The Curve header points to a Key array which stores the key values and additional values to interpolate the curve from one point to the next. Thus, the array has as many elements as specified in Key count, multiplied by the number of elements stored per key (depending upon the CCC Curve Type bits in the Curve Flags as described above). The data type of each element is given by the KK Key Type bits in the Curve Flags.

The end of the array is aligned to 4 bytes.

Step Curves

The elements apparently represent the key values directly.

Linear Curves

For linearly interpolated curves, 2 elements are stored per key:

  1. Value at which the key is set. To get the final value, scale and then offset it.
  2. Delta to value at next frame to which the curve linearly runs. To get the final value, scale it. If there is no next frame, this is always 0.

A key can be discarded by the next key if that one is stored at the same frame. In that case, only the value of the next key is stored, and the delta of the previous key is adjusted to run to the value of the now discarded key.

This example curve's keys are stored as SByte elements. The curve scale was computed as 2, the offset as 200 and the curve delta (if available in the BFRES version) as 300. Due to the lower key in frame 20 being discarded in favor of the higher key, only 3 keys are stored in 6 elements as follows.

NW4FCurveExampleLinear.png
Point Array Index Raw Value *2 (Scale) +200 (Offset) Notes
0,0 0 -100 -200 0 Initial key with value 0.
(20,254) 1 127 254 - Delta to end value of initial key at next frame.
20,254 - - - - This key is discarded in favor of the next.
20,400 2 100 200 400 Overrides previous key.
(30,300) 3 -50 -100 - End value of overriding key at next frame.
30,300 4 50 100 300 Value of fourth (but third stored) key.
(end) 5 0 0 - Since no frame follows, always 0.


Hermite Curves

For hermite curves, 4 elements are stored for each key. It is unclear how to exactly interprete them to form the curve out of it.

Target

The Curve targets which control what exactly is animated over time are not yet known.