ZenHAX

Free Game Research Forum | Official QuickBMS support | twitter @zenhax | SSL HTTPS://zenhax.com
It is currently Tue Mar 02, 2021 7:02 am

All times are UTC




Post new topic  Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Platoon 3D Model
PostPosted: Sun Jan 24, 2021 4:46 am 

Joined: Fri Jun 02, 2017 2:15 pm
Posts: 16
Hi Experts,

I'm new to 3D model examining, but have managed to work out some of the models from the game Platoon. A single model seems to be comprised of a number of separate meshes (with separate faces, verts, etc) - all this looks OK, but I'm struggling to get the separate meshes to fit together into the complete model.

See attached for example - it's a tank that's made up of 4 meshes (body, turret, cannon, gun), but I can't seem to get the pieces to fit on top of each other. The OBOX appears to be (at my guess) a set of co-ordinates which I assumed was to position each mesh, but I'm not sure.

Is anyone able to help me with the final bit of understanding here, please?

The specs I have worked out are...

Code:
  // for each block
    4 - Block Name
    4 - Block Length (including these 2 header fields)
   
    if (BlockName = DUMY){
      // Dummy, can contain objects in it
      4 - Object Number (incremental from 0)
      4 - Name Length
      X - Name
      68 - Unknown
      }
    else if (BlockName == OBST){
      // Object
      4 - Object Number (incremental from 0)
      4 - Name Length
      X - Name
      68 - Unknown
      }
    else if (BlockName == MESH){
      // Mesh
      4 - Unknown
      4 - Unknown
      4 - Number of Vertex Points
      }
    else if (BlockName == VERT){
      // Vertex block, contained within a MESH
      4 - Number of Vertex Points
      4 - Unknown
      4 - null
     
      // for each vertex (32 bytes per entry)
        4 - Vertex X
        4 - Vertex Y
        4 - Vertex Z
        4 - Normal X
        4 - Normal Y
        4 - Normal Z
        4 - UV X
        4 - UV Y
       
      4 - Number of Entries? (1)
     
      // for each entry
        4 - Unknown
      }
    else if (BlockName == ISTR){
      // Face Indexs block, contained within a MESH
      4 - Number of Face Indexes
     
      // for each Face Index
        2 - Face Index
      }
    else if (BlockName == FACE){
      // Faces block, contained within a MESH
      4 - Number of Faces
     
      // for each Face
        // LODP entry
      }
    else if (BlockName == LODP){
      // Unknown block, contained within a FACE
      4 - Unknown
      4 - Number of FSEC Entries? (1)
     
      // for each FSEC entry
        // FSEC entry
      }
    else if (BlockName == FSEC){
      // Face Sequence? block, contained within a LODP
      2 - null
      4 - Unknown (0)
      4 - Unknown
      4 - Number of Face Indexes
      4 - Unknown (101)
      4 - First Face Index Number
      4 - Last Face Index Number
      }
    else if (BlockName == OBOX){
      // Object Center Point
        4 - Center Vertex X
        4 - Center Vertex Y
        4 - Center Vertex Z
        4 - Center Normal X
        4 - Center Normal Y
        4 - Center Normal Z
      }
    else if (BlockName == MBOX){
      // Unknown block
      24 - Unknown
      }
    else if (BlockName == TEXT){
      // Unknown block
      4 - null
      4 - String Length
      X - String
      }
    else if (BlockName == MATE){
      // Material block
      4 - Material Number? (0/1)
      4 - Texture Filename Length
      X - Texture Filename
     
      4 - Number of Entries
      96 - Unknown
     
      // for each entry
        20 - Unknown
      }
    else if (BlockName == BLST){
      // Unknown block
      4 - null
      }
    else if (BlockName == ASEL){
      // Unknown block
      4 - Number of Strings
     
      // for each string
        4 - String ID
        4 - Unknown
        4 - String Length
        X - String
      }
    else if (BlockName == ASEC){
      // Unknown block
      4 - null
      }
    else if (BlockName == TIME){
      // Timestamp Block
      24 - Timestamp String
      }


Appreciate your help!


Attachments:
File comment: Model (tank) with 4 mesh pieces in it
SingleTankObject.zip [52.82 KiB]
Downloaded 29 times
Top
   
 Post subject: Re: Platoon 3D Model
PostPosted: Sat Feb 27, 2021 5:05 am 
User avatar

Joined: Fri Aug 08, 2014 12:59 am
Posts: 1
Image
Code:
/*
maxscript for Platoon 3D
by mariokart64n
feb 26 2021
*/
clearlistener()

fn read file = (
   
   local f = try(fopen file "rb")catch(undefined)
   local blockArray = #()
   local OBSTArray = #()
   if f != undefined then (
      
      delete $*
      
      local fsize = getFileSize file
      local b = datablock()
      local vertArray = #()
      local tvertArray = #()
      local colrArray = #()
      local normArray = #()
      local i = 1
      local vertex_count = 0
      local vertex_buffer_size = 0
      local vertex_stride = 0
      local face_count = 0
      local faceArray = #()
      local msh = undefined
      local faceArray2 = #()
      local matidArray = #()
      local v = 1
      local material_count = 0
      local msh_name = ""
      local msh_pos = [0.0, 0.0, 0.0]
      unk009 = 0
      unk010 = 0
      unk011 = 0
      unk012 = 0
      unk013 = 0
      unk014 = 0
      
      local stype = ""
      while ftell f < fsize do (
         stype = bit.IntAsChar (readByte f #unsigned)
         stype += bit.IntAsChar (readByte f #unsigned)
         stype += bit.IntAsChar (readByte f #unsigned)
         stype += bit.IntAsChar (readByte f #unsigned)
         format "BlockRead:\t%\n" stype
         case stype of (
            "OBST": (
               readLong f #unsigned
               readLong f #unsigned
               
               for i = 1 to (readLong f #unsigned) do (
                  msh_name += bit.IntAsChar (readByte f #unsigned)
                  )
               print (readLong f #unsigned)
               
               print (readFloat f)
               
               
               msh_pos += [readFloat f, readFloat f, readFloat f]
               
               
               
               print [readFloat f, readFloat f, readFloat f] -- rotation
               print (readFloat f)
                  
               print [readFloat f, readFloat f, readFloat f] -- scale
               
               print [readFloat f, readFloat f, readFloat f] -- 000
               print (readFloat f)
               readLong f
               
               )
            "DUMY": (
               fseek f ((readLong f #unsigned) - 8) #seek_cur
               )
            "MESH": (
               readLong f
               readLong f
               readLong f
               readLong f
               readLong f
               vertex_buffer_size = readLong f
               vertex_count = readLong f
               readLong f
               readLong f
               i = 1
               vertArray = #()
               tvertArray = #()
               colrArray = #()
               normArray = #()
               
               vertex_stride = ((vertex_buffer_size - 28) / vertex_count) as integer
               
               format "vertex_count:\t%\n" vertex_count
               format "vertex_stride:\t%\n" vertex_stride
               case vertex_stride of (
                  32: (
                     for i = 1 to vertex_count do (
                        append vertArray [readFloat f, readFloat f, readFloat f]
                        append normArray [readFloat f, readFloat f, readFloat f]
                        append tvertArray [readFloat f, readFloat f, 0.0]
                        )
                     )
                  36: (
                     for i = 1 to vertex_count do (
                        append vertArray [readFloat f, readFloat f, readFloat f]
                        append normArray [readFloat f, readFloat f, readFloat f]
                        append colrArray #(readByte f #unsigned, readByte f #unsigned, readByte f #unsigned, readByte f #unsigned)
                        append tvertArray [readFloat f, readFloat f, 0.0]
                        )
                     )
                  default: (
                     format "invalid vertex stride [%]\n" vertex_stride
                     exit
                     )
                  )
               fseek f ((readLong f) * 4) #seek_cur
               
               format "LastRead:\t%\n" (bit.IntAsHex((ftell f) as integer))
               )
            "ISTR": (
               readLong f
               face_count = readLong f / 3
               faceArray = #()
               --format "face_count:\t%\n" face_count
               for i = 1 to face_count do (
                  append faceArray ([readShort f #unsigned, readShort f #unsigned, readShort f #unsigned] + 1)
                  )
               )
            "FACE": (
               
               msh = undefined
               faceArray2 = #()
               matidArray = #()
               v = 1
               
               readLong f
               material_count = readLong f #unsigned
               for i = 1 to material_count do (
                  readLong f
                  readLong f
                  readFloat f
                  readLong f
                  readFloat f
                  readLong f
                  readShort f
                  unk009 = readLong f -- mesh type?
                  
                  unk010 = readLong f
                  unk011 = readLong f -- read
                  unk012 = readLong f -- 101
                  unk013 = readLong f -- pos
                  unk014 = readLong f -- end pos (pos + read)
                  --format "%\t%\t%\t%\t%\t%\n" unk009 unk010 unk011 unk012 unk013 unk014
                  --print (((unk013 / 3)) + ((unk011 / 3)))
                  if i == 1 do ( -- just read first LOD
                     for v = 1 to (((unk011 / 3) as integer)) do (
                        append faceArray2 (faceArray[v + ((unk013 / 3) as integer)])
                        append matidArray i
                        )
                     )
                  )
               
               msh = mesh vertices:vertArray faces:faceArray2-- materialIDs:matidArray
               --msh.material = MultiMaterial numSubs:material_count
               msh.name = msh_name
               msh.position = msh_pos
               msh.wirecolor = random white black
               --for i = 1 to material_count do (msh.material[i].Diffuse = random white black)
               select msh
               )
            "OBOX": (
               readLong f #unsigned
               [readFloat f, readFloat f, readFloat f]
               [readFloat f, readFloat f, readFloat f]
               )
            "ASEC": (
               fseek f ((readLong f #unsigned) - 8) #seek_cur
               )
            default:(
               format "Unknown Type [%], Reading Halted @\t0x%\n" \
                  stype (bit.IntAsHex((ftell f - 4) as integer))
               exit
               )
            )
         )
      
      ) else (format "failed to open file\n")
   )
read (
   "C:\\Users\\Corey\\Downloads\\SingleTankObject\\SingleTankObject.OBST"
   )


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 2 posts ] 

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Limited