Page 1 of 1

Documentation of Silent Hill 3D model files

PostPosted: Fri Oct 06, 2017 12:42 pm
by Sparagas
Hello,
I documented what we know about Silent Hill 3D model files.
I want it to be in first page and in one place, so anyone could easily see it. I will keep this post updated.
This post is for documentation only, so please let's keep discussion and other findings in other topics :)
You can suggest me for better formatting and other stuff, to keep this info universal and easily understandable.

There are 4 known 3D model files in Silent Hill: .ILM, .PLM and .IPD are very similar, but not identical. Also there are universal .TMD files, and two animation files: .ANM for character and enemies (includes bones structure) and .DMS for cut-scenes animation

I sugest to download, for better viewing
Download link

UPDATE 1: updated documentation and added info on .ANM and .DMS files

.ILM - character and enemy models with multi sub-mesh models
REVEAL SPOILER
Code: Select all
File Type .ILM
Byte Order - Little Endian
Byte chunk grouping - 4 Byte


Start of Archive Header

   1 chunk
      1st byte - unknown, could be file ID or mark beginning of file, always 30
      2nd byte - unknown, could be file ID or mark beginning of file, always 06
      3rd byte - unknown, could be flag, always 00, changes to 1 when model is loaded into RAM (need more testing)
      4th byte - number of textures (textures are stored in external files)

   1 chunk
      1st - 4th byte - offset pointer to textures (textures are stored in external files)

   1 chunk
      1st - 4th byte - number of sub-meshes in this file
      OR
      1st byte - number of sub-meshes in this file
      2nd - 4th byte - empty space with 00

   1 chunk
      1st - 4th byte - offset pointer to sub-mesh list section

   1 chunk
      1st - 4th byte - offset pointer to mesh order list

End of Archive Header


Start of Directory

   6 chunks x (number of textures (textures are stored in external files)
      1st - 24th byte - name of textures in text form (textures are stored in external files)
      OR
      1st - 8th byte - name of textures in text form (textures are stored in external files)
      9th - 24th byte - empty space with 00

   4 chunks x (number of sub-meshes in this file)
      1st - 2nd chunks
         1st - 2nd - bone ID in text form
         3rd - 8th byte - name of sub-mesh in text form
      3rd chunk
         1st - 4th byte - unknown data
      4th chunk
         1st - 4th byte - offset pointer to sub-mesh section

   1 byte x (number of sub-meshes in this file) (rounded to fit in chunks)
      1st chunk
         any byte - filled with 00, could be flags to loaded meshes

   1 byte x (number of sub-meshes in this file) (rounded to fit in chunks)
      1st chunk
         any byte - mesh order counting from 0, unknown purpose, if number of sub-meshes in this file does not divide from 4, then last bytes in chunks are filled with 00 and will be ignored

End of Directory


Start of Sub-Mesh Section x (number of sub-meshes in this file)

   Start of Sub-Mesh Header

      1 chunk
         1st byte - number of polygons of this sub-mesh
         2nd byte - number of vertices of this sub-mesh
         3rd byte - number of unknown data in section 3 of this sub-mesh
         4th byte - number of unknown data in section 4 of this sub-mesh, looks like always 0

      1 chunk
         1st - 4th byte - offset pointer to polygons data

      1 chunk
         1st - 4th byte - offset pointer to vertices of XY axis (need to confirm if this is really XY)

      1 chunk
         1st - 4th byte - offset pointer to vertices of Z axis (need to confirm if this is really Z)

      1 chunk
         1st - 4th byte - offset pointer to unknown data section 3

      1 chunk
         1st - 4th byte - offset pointer to unknown data section 4 (because it looks like number is always 0, so it points to the start of next data outside this mesh)

   End of Sub-Mesh Header

   Start of Sub-Mesh Data

      Polygon section
      20 bytes x (number of polygons of this sub-mesh)
         1st chunk
            1st byte - U1 coordinate
            2nd byte - V1 coordinate
            3rd byte - unknown, could be palette info
            4th byte - unknown, could be palette info
         2nd chunk
            1st byte - U2 coordinate
            2nd byte - V2 coordinate
            3rd byte - unknown, could be palette info, almost always 00
            4th byte - unknown, could be palette info, almost always 00
         3rd chunk
            1st byte - U3 coordinate
            2nd byte - V3 coordinate
            3rd byte - U4 coordinate, exist only if there is F4, otherwise it is 00 and is ignored
            4th byte - V4 coordinate, exist only if there is F4, otherwise it is 00 and is ignored
         4th chunk
            1st byte - F1 face index
            2nd byte - F2 face index
            3rd byte - F3 face index
            4th byte - F4 face index, strip triangle (if exist, uses F2, F3 and F4). If doesn't exist, then it is FF and is ignored
         5th chunk
            1st - 4th byte - unknown data

      XY Vertices section
      4 bytes x (number of vertices of this sub-mesh)
         1st chunk
            1st - 2nd byte - X axis vertex coordinate
            3rd - 4th byte - Y axis vertex coordinate

      Z Vertices section
      2 bytes x (number of vertices of this sub-mesh) (rounded to fit in chunks)
         1st chunk
            1st - 2nd byte - Z axis vertex coordinate
            3rd - 4th byte - Z axis vertex coordinate, if there is odd number of vertices, then it will be 00 00 and will be ignored

      Unknown section 3
      4 bytes x (number of unknown data in section 3 of this sub-mesh)
         1st chunk
            1st - 4th byte - unknown data

      Unknown section 4
      1 byte x (number of unknown data in section 4 of this sub-mesh) (rounded to fit in chunks)
         1st chunk
            any byte - unknown data, if number of unknown data does not divide from 4, then last bytes will be filled with 00 and will be ignored

   End of Sub-Mesh Data

End of Sub-Mesh Section


Start of Footer Section

   any chunk
      any byte - unused garbage data, usually copy of the beginning of the file

End of Footer Section


.IPD - regional environment objects that also use meshes from .PLM files
REVEAL SPOILER
Code: Select all
File Type .IPD
Byte Order - Little Endian
Byte chunk grouping - 4 Byte


Start of 1st Archive Part

   1 chunk
      1st byte - unknown, could be file ID or mark beginning of file, always 14
      2nd byte - unknown, could be file ID or mark beginning of file, always 00
      3rd byte - unknown
      4th byte - unknown

   1 chunk
      1st - 4th byte - offset pointer to 2nd Archive Header

   all remaining chunks
      any byte - Undocumented, there are names of sub-meshes in text form from this file and corresponding global .PLM file. Looks like it has coordinates for sub-meshes


End of 1st Archive Part


Start of 2nd Archive Header (offsets are counted from 2nd Archive Header)

   1 chunk
      1st byte - unknown, could be file ID or mark beginning of file, always 30
      2nd byte - unknown, could be file ID or mark beginning of file, always 06
      3rd byte - unknown, could be flag, always 00, changes to 1 when model is loaded into RAM (need more testing)
      4th byte - number of textures (textures are stored in external files)

   1 chunk
      1st - 4th byte - offset pointer to textures (textures are stored in external files)

   1 chunk
      1st - 4th byte - number of sub-meshes in this file
      OR
      1st byte - number of sub-meshes in this file
      2nd - 4th byte - empty space with 00

   1 chunk
      1st - 4th byte - offset pointer to sub-mesh list section

   1 chunk
      1st - 4th byte - offset pointer to mesh order list

End of 2nd Archive Header


Start of Directory

   6 chunks x (number of textures (textures are stored in external files))
      1st - 24th byte - name of textures in text form (textures are stored in external files)
      OR
      1st - 8th byte - name of textures in text form (textures are stored in external files)
      9th - 24th byte - empty space with 00

   4 chunks x (number of sub-meshes in this file)
      1st - 2nd chunks
         1st - 8th byte - name of sub-mesh in text form
      3rd chunk
         1st - 4th byte - unknown data
      4th chunk
         1st - 4th byte - offset pointer to sub-mesh section

   1 byte x (number of sub-meshes in this file) (rounded to fit in chunks)
      1st chunk
         any byte - filled with 00, could be flags to loaded meshes

   1 byte x (number of sub-meshes in this file) (rounded to fit in chunks)
      1st chunk
         any byte - mesh order counting from 0, unknown purpose, if number of sub-meshes in this file does not divides from 4, then last bytes in chunks are filled with 00 and will be ignored

End of Directory


Start of Sub-Mesh Section x (number of sub-meshes in this file)

   Start of Sub-Mesh Header

      1 chunk
         1st byte - number of polygons in this sub-mesh
         2nd byte - number of vertices in this sub-mesh
         3rd byte - number of unknown data in section 3 of this sub-mesh
         4th byte - number of unknown data in section 4 of this sub-mesh

      1 chunk
         1st - 4th byte - offset pointer to polygons data

      1 chunk
         1st - 4th byte - offset pointer to vertices of XY axis (need to confirm if this is really XY)

      1 chunk
         1st - 4th byte - offset pointer to vertices of Z axis (need to confirm if this is really Z)

      1 chunk
         1st - 4th byte - offset pointer to unknown data in section 3

      1 chunk
         1st - 4th byte - offset pointer to unknown data in section 4

   End of Sub-Mesh Header

   Start of Sub-Mesh Data

      Polygon section
      20 bytes x (number of polygons of this sub-mesh)
         1st chunk
            1st byte - U1 coordinate
            2nd byte - V1 coordinate
            3rd byte - unknown, could be palette info
            4th byte - unknown, could be palette info
         2nd chunk
            1st byte - U2 coordinate
            2nd byte - V2 coordinate
            3rd byte - unknown, could be palette info, almost always 00
            4th byte - unknown, could be palette info, almost always 00
         3rd chunk
            1st byte - U3 coordinate
            2nd byte - V3 coordinate
            3rd byte - U4 coordinate, exist only if there is F4, otherwise it is 00 and is ignored
            4th byte - V4 coordinate, exist only if there is F4, otherwise it is 00 and is ignored
         4th chunk
            1st byte - F1 face index
            2nd byte - F2 face index
            3rd byte - F3 face index
            4th byte - F4 face index, strip triangle (if exist, uses F2, F3 and F4). If doesn't exist, then it is FF and is ignored
         5th chunk
            1st - 4th byte - unknown data

      XY Vertices section
      4 bytes x (number of vertices of this sub-mesh)
         1st chunk
            1st - 2nd byte - X axis vertex coordinate
            3rd - 4th byte - Y axis vertex coordinate

      Z Vertices section
      2 bytes x (number of vertices of this sub-mesh) (rounded to fit in chunks)
         1st chunk
            1st - 2nd byte - Z axis vertex coordinate
            3rd - 4th byte - Z axis vertex coordinate, if there is odd number of vertices, then it will be 00 00 and will be ignored

      Unknown section 3
      4 bytes x (number of unknown data in section 3 of this sub-mesh)
         1st chunk
            1st - 4th byte - unknown data

      Unknown section 4
      1 byte x (number of unknown data in section 4 of this sub-mesh) (rounded to fit in chunks)
         1st chunk
            any byte - unknown data, if number of unknown data does not divide from 4, then last bytes will be filled with 00 and will be ignored

   End of Sub-Mesh Data

End of Sub-Mesh Section


Start of Footer Section

   any chunk
      any byte - unused garbage data, usually copy of the beginning of the file

End of Footer Section


.PLM
- 3D objects that attaches to .IPD and HERO.ILM
REVEAL SPOILER
Code: Select all
File Type .PLM
Byte Order - Little Endian
Byte chunk grouping - 4 Byte


Start of Archive Header

   1 chunk
      1st byte - unknown, could be file ID or mark beginning of file, always 30
      2nd byte - unknown, could be file ID or mark beginning of file, always 06
      3rd byte - unknown, could be flag, always 00, changes to 1 when model is loaded into RAM (need more testing)
      4th byte - number of textures (textures are stored in external files)

   1 chunk
      1st - 4th byte - offset pointer to textures (textures are stored in external files)

   1 chunk
      1st - 4th byte - number of sub-meshes in this file
      OR
      1st byte - number of sub-meshes in this file
      2nd - 4th byte - empty space with 00

   1 chunk
      1st - 4th byte - offset pointer to sub-mesh list section

   1 chunk
      1st - 4th byte - offset pointer to mesh order list

End of Archive Header


Start of Directory

   6 chunks x (number of textures (textures are stored in external files)
      1st - 24th byte - name of textures in text form (textures are stored in external files)
      OR
      1st - 8th byte - name of textures in text form (textures are stored in external files)
      9th - 24th byte - empty space with 00

   4 chunks x (number of sub-meshes in this file)
      1st - 2nd chunks
         1st - 8th byte - name of sub-mesh in text form
      3rd chunk
         1st - 4th byte - unknown data
      4th chunk
         1st - 4th byte - offset pointer to sub-mesh section

   1 byte x (number of sub-meshes in this file) (rounded to fit in chunks)
      1st chunk
         any byte - filled with 00, could be flags to loaded meshes

   1 byte x (number of sub-meshes in this file) (rounded to fit in chunks)
      1st chunk
         any byte - mesh order counting from 0, unknown purpose, if number of sub-meshes in this file does not divides from 4, then last bytes in chunks are filled with 00 and will be ignored

End of Directory


Start of Sub-Mesh Section x (number of sub-meshes in this file)

   Start of Sub-Mesh Header

      1 chunk
         1st byte - number of polygons in this sub-mesh
         2nd byte - number of vertices in this sub-mesh
         3rd byte - number of unknown data in section 3 of this sub-mesh
         4th byte - number of unknown data in section 4 of this sub-mesh

      1 chunk
         1st - 4th byte - offset pointer to polygons data

      1 chunk
         1st - 4th byte - offset pointer to vertices of XY axis (need to confirm if this is really XY)

      1 chunk
         1st - 4th byte - offset pointer to vertices of Z axis (need to confirm if this is really Z)

      1 chunk
         1st - 4th byte - offset pointer to unknown data in section 3

      1 chunk
         1st - 4th byte - offset pointer to unknown data in section 4

   End of Sub-Mesh Header


   Start of Sub-Mesh Data

      Polygon section
      20 bytes x (number of polygons of this sub-mesh)
         1st chunk
            1st byte - U1 coordinate
            2nd byte - V1 coordinate
            3rd byte - unknown, could be palette info
            4th byte - unknown, could be palette info
         2nd chunk
            1st byte - U2 coordinate
            2nd byte - V2 coordinate
            3rd byte - unknown, could be palette info, almost always 00
            4th byte - unknown, could be palette info, almost always 00
         3rd chunk
            1st byte - U3 coordinate
            2nd byte - V3 coordinate
            3rd byte - U4 coordinate, exist only if there is F4, otherwise it is 00 and is ignored
            4th byte - V4 coordinate, exist only if there is F4, otherwise it is 00 and is ignored
         4th chunk
            1st byte - F1 face index
            2nd byte - F2 face index
            3rd byte - F3 face index
            4th byte - F4 face index, strip triangle (if exist, uses F2, F3 and F4). If doesn't exist, then it is FF and is ignored
         5th chunk
            1st - 4th byte - unknown data

      XY Vertices section
      4 bytes x (number of vertices of this sub-mesh)
         1st chunk
            1st - 2nd byte - X axis vertex coordinate
            3rd - 4th byte - Y axis vertex coordinate

      Z Vertices section
      2 bytes x (number of vertices of this sub-mesh) (rounded to fit in chunks)
         1st chunk
            1st - 2nd byte - Z axis vertex coordinate
            3rd - 4th byte - Z axis vertex coordinate, if there is odd number of vertices, then it will be 00 00 and will be ignored

      Unknown section 3
      4 bytes x (number of unknown data in section 3 of this sub-mesh)
         1st chunk
            1st - 4th byte - unknown data

      Unknown section 4
      1 byte x (number of unknown data in section 4 of this sub-mesh) (rounded to fit in chunks)
         1st chunk
            any byte - unknown data, if number of unknown data does not divide from 4, then last bytes will be filled with 00 and will be ignored

   End of Sub-Mesh Data

End of Sub-Mesh Section


Start of Footer Section

   any chunk
      any byte - unused garbage data, usually copy of the beginning of the file

End of Footer Section