This page has been translated automatically.
Video Tutorials
Interface
Essentials
Advanced
How To
Basics
Rendering
Professional (SIM)
UnigineEditor
Interface Overview
Assets Workflow
Version Control
Settings and Preferences
Working With Projects
Adjusting Node Parameters
Setting Up Materials
Setting Up Properties
Lighting
Sandworm
Using Editor Tools for Specific Tasks
Extending Editor Functionality
Built-in Node Types
Nodes
Objects
Effects
Decals
Light Sources
Geodetics
World Nodes
Sound Objects
Pathfinding Objects
Players
Programming
Fundamentals
Setting Up Development Environment
Usage Examples
C++
C#
UnigineScript
UUSL (Unified UNIGINE Shader Language)
Plugins
Materials and Shaders
Rebuilding the Engine Tools
GUI
Double Precision Coordinates
API
Animations-Related Classes
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
IG Plugin
CIGIConnector Plugin
Rendering-Related Classes
VR-Related Classes
Content Creation
Content Optimization
Materials
Material Nodes Library
Miscellaneous
Input
Math
Matrix
Textures
Art Samples
Tutorials

Mesh File Formats

UNIGINE supports the following mesh file formats for common and skinned meshes:

  • *.mesh, which is used for static geometry and animated characters.
  • *.anim, which contains animation for a skinned mesh (*.mesh file).

Here are some general notes that are valid for any mesh format.

  • All data is in the little-endian notation.
  • float is a 32-bit IEEE754 floating-point type. It has a range of 3.4 e-38 to 3.4 e+38.
  • int here is a compact signed integer.
    Notice
    To read / write compact integer values use readInt2() / writeInt2() methods respectively.
  • int32 is a signed 32-bit two's complement integer. It has a range of –2,147,483,648 to 2,147,483,647.
  • unsigned short is an unsigned 16-bit integer. It has a range of 0 to 65,535.
  • char is a signed 8-bit two's complement integer. It has a range of -128 to 127.
  • unsigned char is a 8-bit unsigned integer. It has a range of 0 to 255.
  • string must be null terminated. The string size should include this terminating null character.
  • All formats allow multiple surfaces.

The mesh limitations set in UNIGINE:

Maximum number of vertices per mesh 4,294,967,295
Maximum number of surfaces per mesh 32,768
Maximum amount of weights per vertex 4

Compression and Decompression of Tangents#

Compression of normalized floating-point tangents into unsigned short format is performed in the following way:

Source code (UnigineScript)
x = (unsigned short)(clamp((int)((tangent.x * 32767.0f), -32767, 32767)));
y = (unsigned short)(clamp((int)((tangent.y * 32767.0f), -32767, 32767)));
z = (unsigned short)(clamp((int)((tangent.z * 32767.0f), -32767, 32767)));
w = (unsigned short)(clamp((int)((tangent.w * 32767.0f), -32767, 32767)));

Here:

  • tangent is a normalized float tangent.
  • x, y, z and w are unsigned short compressed tangent values.

Decompression of tangents that are compressed into the unsigned short format can be performed as follows:

Source code (UnigineScript)
tangent.x = (compressed_tangent.x / 65535.0f);
tangent.y = (compressed_tangent.y / 65535.0f);
tangent.z = (compressed_tangent.z / 65535.0f);
tangent.w = (compressed_tangent.w / 65535.0f);

Here:

  • compressed_tangent is an unsigned short compressed tangent.
  • tangent is a normalized float tangent.

Compression and Decompression of Weights#

Compression of normalized floating-point weights into unsigned short format is performed in the following way:

Source code (UnigineScript)
w = (unsigned short)clamp((int)((weight * 65535.0f), 0, 65535));

Here:

  • weight is a normalized float weight.
  • w is unsigned short compressed weight.

Decompression of weights that are compressed into the unsigned short format can be performed as follows:

Source code (UnigineScript)
weight = compression_weight / 65535.0f;

Here:

  • compression_weight is an unsigned short compressed weight.
  • weight is a normalized float weight.

Storing Meshes#

MESH is a universal file format for static and skinned geometry.

The skinned meshes can be stored as follows:

  • Containing both mesh data (vertices and their weights) and animation (bones and their transformations). This variant of storing mesh together with animation data in one file is less flexible and more memory consuming. Use it only for small animation sequences.
  • Containing only mesh data, i.e. the bind pose. This approach is useful, if you prefer to put additional animation out to separate files.
Notice
The first animation frame shouldn't contain the bind pose.

MESH File Format#

  1. File format identifier (int32 "ms13" ('m' | ('s' << 8) | ('1' << 16) | ('1' << 24)))
  2. Bounding volume of the whole mesh:

    • Mesh bounding box minimum (float[3])
    • Mesh bounding box maximum (float[3])
    • Mesh bounding sphere center (float[3])
    • Mesh bounding sphere radius (float)
  3. Number of bones (int)
  4. Header information for each bone:

    • Name of the bone. It is a null-terminated string that contains:

      1. The number of characters in the string including the null character (int).
      2. Bone name of the specified length (char[length]).
    • Parent of the bone. If case of the root bone without a parent, -1 is used. (short)
  5. Number of surfaces (int)
  6. Header information for each surface:

    • Name of the surface. It is a null-terminated string that contains:

      1. The number of characters in the string including the null character (int).
      2. Surface name of the specified length (char[length])
    • UV channel used for the surface lightmap (unsigned char)
    • Surface lightmap resolution (unsigned char)
    • Surface bounding box minimum (float[3])
    • Surface bounding box maximum (float[3])
    • Surface bounding sphere center (float[3])
    • Surface bounding sphere radius (float)
    • Number of the surface morph targets (int)
    • Header information for each morph target:

      1. Name of the morph target. It is a null-terminated string that contains:
        • The number of characters in the string including the null character (int).
        • Morph target name of the specified length (char[length])
  7. File format identifier (int32 "ms13" ('m' | ('s' << 8) | ('1' << 16) | ('1' << 24)))
  8. For each bone:

    • Bone position along X, Y, Z axes (float[3])
    • Bone rotation quaternion (float[4])
    • Bone scale in all directions(float[3])
  9. Data on each surface geometry:

    • Data on each morph target of the surface:

      1. Number of vertices in the morph target (int)
      2. Vertices of the morph target (float[3*length])
      3. Number of tangents (int)
      4. For each tangent:

        • X, Y, Z, and W components are of the short type and represent a quaternion.
    • Number of surface weights (int)
    • For each surface weight:

      1. Number of bones that affect the vertex (the maximum value is 4) (unsigned char)
      2. For each bone that affects the vertex:

        • Bone index (short)
        • Bone weight (unsigned short)
    • Number of texture coordinates in the 1st UV set (int)
    • For each of texture coordinates:

      1. 1st UV texture coordinates(float[2])
    • Number of texture coordinates in the 2nd UV set (int)
    • For each of texture coordinates:

      1. 2nd UV texture coordinates (float[2])
    • Number of 8-bit vertex colors (int).
    • For each color:

      1. Color value (unsigned char[4])
    • Number of coordinate indices (int)
    • Сoordinate indices for each vertex of the surface:

      1. If the zero morph target contains less than 256 coordinate vertices, all the indices are unsigned char[length]
      2. If the zero morph target contains less than 65536 coordinate vertices, all the indices are unsigned short[length]
      3. Otherwise, all the indices are int32[length]
    • Number of triangle indices (int)
    • Triangle indices for each vertex of the surface:

      1. If the zero morph target contains less than 256 triangle vertices, all the indices are unsigned char[length]
      2. If the zero morph target contains less than 65536 triangle vertices, all the indices are unsigned short[length]
      3. Otherwise, all the indices are int32[length]
  10. File format identifier (int32 "ms13" ('m' | ('s' << 8) | ('1' << 16) | ('1' << 24)))

Storing Skinned Mesh Animation#

Skinned mesh animation format contains only animation for skinned mesh *.mesh files. They are useless without a "base" skinned mesh in its bind pose that contains vertices and their weights.

*.anim files store animation data more efficiently than one skinned mesh *.mesh file containing both a mesh and bones transformations. That is the reason why *.anim files are ideal for long animations.

If you need to load such a file in a script or save it, treat it like a *.mesh animation file.

ANIM File Format#

  1. File format identifier (int32 "an11" ('a' | ('n' << 8) | ('1' << 16) | ('0' << 24)))
  2. Number of bones in skinned animation (int)
  3. Header information for each bone:

    • Name of the bone. It is a null-terminated string that contains:

      1. The number of characters in the string including the null character (int).
      2. Bone name of the specified length (char[length])
    • Parent of the bone (short)
  4. File format identifier (int32 "an11" ('a' | ('n' << 8) | ('1' << 16) | ('0' << 24)))
  5. For each bone:

    • Bone position along X, Y, Z axes (float[3])
    • Bone rotation quaternion (float[4])
    • Bone scale in all directions(float[3])
  6. Number of animation bones (int)
  7. Indices of the bones taking part in the animation (short[length])
  8. Number of animation frames (int)
  9. Flag (unsigned char), each 8 bits of which determine if the animations should store translation, scale or rotation components for bones taking part in the animations.
  10. Transformation data for each bone in each frame:

    • Flag (unsigned char), each 8 bits of which determine if the current frame should store new translation, scale or rotation components for the bone. If these components have not changed since the previous frame, new data is not stored. Instead, data from the previous frame is used, which maximizes the efficiency of memory usage.
    • If the data is flagged as changed, for each component of the bone:

      1. Translation of the bone along axes X, Y, Z (float[3])
      2. Rotation quaternion (float[4])
      3. Bone scaling along axes X, Y, Z (float[3])

      These position and rotation values are specified inside of the calculated bounding box: as a coordinate between its minimum and its maximum (a value in range from 0 to 65535).

  11. File format identifier (int32 "an11" ('a' | ('n' << 8) | ('1' << 16) | ('0' << 24)))
Last update: 2024-12-26
Build: ()