ZenHAX

Free Game Research Forum | Official QuickBMS support | twitter @zenhax | SSL HTTPS://zenhax.com
It is currently Tue Mar 26, 2019 6:13 am

All times are UTC




Post new topic  Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Tue Dec 11, 2018 1:57 am 

Joined: Sat Dec 01, 2018 1:43 pm
Posts: 9
Hi there! I'm attempting to read and convert Crimson Skies' plane models (.x) into a format I can work with (.dae, .obj, .fbx, etc.) This does not appear to be the DirectX .x format, but more than likely something else. I need a way for it to export at least individual sub meshes or have them all in a hierarchy grouped instead of one single mesh with UV maps. Any help with this would be greatly appreciated!

This here is the Cinematic HR Devastator model.
https://www.dropbox.com/s/36ozeub6dlqow ... tor.x?dl=0

And here are textures to use as a reference for getting UV maps working.
https://www.dropbox.com/s/8undw9x8amhft ... r.png?dl=0 Main Texture
https://www.dropbox.com/s/2qf19vm4fizlc ... r.png?dl=0 Propellers texture

Also attached here is a simple Noesis plugin made by another person for reading and exporting .x files, although it does not preview textures, nor export with UV maps, submeshes or textures.
Thanks again for any help!


Attachments:
CrimsonSkies_Xbox_X.zip [1.57 KiB]
Downloaded 25 times
Top
   
PostPosted: Sat Dec 15, 2018 12:29 am 

Joined: Sat Dec 01, 2018 1:43 pm
Posts: 9
Gathered some info on the models.
It appears the game was primarily modelled with Autodesk Maya 2003. I don't have it on my computer right now, but it may be possible to open up the .x models in Maya? I don't think year version differences would matter.


Top
   
PostPosted: Fri Dec 28, 2018 1:48 am 

Joined: Sat Dec 01, 2018 1:43 pm
Posts: 9
Bump. Still looking for help.


Top
   
PostPosted: Wed Jan 16, 2019 12:29 am 

Joined: Sat Dec 01, 2018 1:43 pm
Posts: 9
And yet another bump.


Top
   
PostPosted: Wed Jan 16, 2019 8:55 am 

Joined: Sat Aug 29, 2015 1:13 pm
Posts: 115
links to images are 404.



Code:
#Noesis Python model import+export test module, imports/exports some data from/to a made-up format
import math

from inc_noesis import *

#registerNoesisTypes is called by Noesis to allow the script to register formats.
#Do not implement this function in script files unless you want them to be dedicated format modules!
def registerNoesisTypes():
   handle = noesis.register("Crimson Skies (Xbox)", ".x")
   noesis.setHandlerTypeCheck(handle, noepyCheckType)
   noesis.setHandlerLoadModel(handle, noepyLoadModel) #see also noepyLoadModelRPG

   noesis.logPopup()
   
   return 1


#check if it's this type based on the data
def noepyCheckType(data):
   if len(data) < 8:
      return 0
   return 1

#load the model
def noepyLoadModel(data, mdlList):

   bs = NoeBitStream(data)
   
   fileDir=rapi.getDirForFilePath(rapi.getInputName());
   texDir= os.path.join(fileDir, '../TEXTURE/')
   ctx = rapi.rpgCreateContext()
      
   rapi.rpgSetOption(noesis.RPGOPT_SWAPHANDEDNESS, 1)
      
   bs.seek(32, NOESEEK_ABS)

   nameLength=bs.readInt()
   MeshName = (bs.readBytes(nameLength).decode("ASCII").rstrip("\0"))
   print("MeshName ", MeshName)

   matrix = NoeMat43( (
      NoeVec3( (bs.readFloat(), bs.readFloat(), bs.readFloat()) ),
      NoeVec3( (bs.readFloat(), bs.readFloat(), bs.readFloat()) ),
      NoeVec3( (bs.readFloat(), bs.readFloat(), bs.readFloat()) ),
      NoeVec3( (bs.readFloat(), bs.readFloat(), bs.readFloat()) )
      )
   )
   
   rapi.rpgSetTransform(matrix) 

   bs.seek(24, NOESEEK_REL)#unk

   bs.seek(4, NOESEEK_REL) # 3 ??



   meshes = []
   numMeshesInObj = bs.readInt()
   #for i in range(0, numMeshesInObj):
   #   loadMesh(bs, rapi)

   #print(numMeshesInObj, "numMeshes")

   numChildsInObj= bs.readInt()
   #print(numChildsInObj, "numChildsInObj")
   for i in range(0, numChildsInObj):
      loadObj(bs, rapi)


   mdl = rapi.rpgConstructModel()

   # print(texList)
   # print(matList)

   #mdl.setModelMaterials(NoeModelMaterials(texList, matList))
   mdlList.append(mdl)
   
   rapi.rpgClearBufferBinds()
   return 1



def loadObj(bs, rapi):
   nameLength=bs.readInt()
   MeshName = (bs.readBytes(nameLength).decode("ASCII").rstrip("\0"))
   #print("MeshName ", MeshName)

   matrix = NoeMat43( (
      NoeVec3( (bs.readFloat(), bs.readFloat(), bs.readFloat()) ),
      NoeVec3( (bs.readFloat(), bs.readFloat(), bs.readFloat()) ),
      NoeVec3( (bs.readFloat(), bs.readFloat(), bs.readFloat()) ),
      NoeVec3( (bs.readFloat(), bs.readFloat(), bs.readFloat()) )
      )
   )

   rapi.rpgSetTransform(matrix) 
   #print (matrix)

   bs.seek(24, NOESEEK_REL)#unk

   bs.seek(4, NOESEEK_REL) # 3 ??

   meshes = []
   numMeshesInObj = bs.readInt()
   #print(numMeshesInObj, "numMeshes")
   for i in range(0, numMeshesInObj):
      loadMesh(bs, rapi,i,MeshName)

      extraSomeBlocks= bs.readShort()   
      #print (extraSomeBlocks,"extraSomeBlocks")
      bs.seek(extraSomeBlocks * 2, NOESEEK_REL)

      whoKnows= bs.readByte()
      #print (whoKnows,"who")
      
      if whoKnows == 1:
         size=16
         numberOfUnk= bs.readInt()
      else:
         size=28
         numberOfUnk= bs.readShort()

      #print (numberOfUnk *size)

      bs.seek( numberOfUnk *size, NOESEEK_REL)

      

   numChildsInObj= bs.readInt()

   print("Obj :" ,MeshName,"numMeshes",numMeshesInObj, "numChildsInObj",numChildsInObj)   
   #print(bs.tell() ," POS PRE CHILD")

   #print(numChildsInObj, "numChildsInObj")
   for i in range(0, numChildsInObj):
      loadObj(bs, rapi)

   return 1   
   

def loadMesh(bs, rapi,matID,name):
   bs.seek(15, NOESEEK_REL)#unk

   typeText= bs.readByte()

   #exceptions
   if typeText == 17:
      typeText=3
   elif typeText == 19:
      typeText=7
   elif typeText == 23:
      typeText=15


   #print(typeText, "numofText1")
   numberOfText=math.log(typeText+1,2)
   #print(numberOfText, "numofText2")

   for i in range(0, int(numberOfText)):
      nameLength=bs.readInt()
      MaterialName = (bs.readBytes(nameLength).decode("ASCII").rstrip("\0"))
      #print(MaterialName, "MaterialName")

   numBlocks= bs.readShort()
   print(numBlocks, "numBlocks")

   tell=bs.tell()
   uvbuffer=bytes()
   for m in range(numBlocks*16):
      sh=bs.readShort()/32768.0
      uvbuffer+=struct.pack("f",sh)
      
   
   bs.seek(tell)
   VertBuff = bs.readBytes(numBlocks * 32)
   bs.seek(16, NOESEEK_REL)#uuid┬┐?

   extraInfo= bs.readByte()
   #print(bs.tell() ,"pos")
   if extraInfo>0:
      bs.seek(bs.readShort() * 12 * 4, NOESEEK_REL)
   #print(bs.tell() ,"pos")   
   numTris= bs.readShort()
   #print(numTris, "numTris")
   #print(bs.tell() ,"pos")
   TrisBuff =   bs.readBytes(numTris * 2)
   
   rapi.rpgSetMaterial(name+str(matID))

   rapi.rpgBindPositionBufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, 32, 0)
   rapi.rpgBindUV1BufferOfs(uvbuffer, noesis.RPGEODATA_FLOAT,64,32)

   rapi.rpgCommitTriangles(TrisBuff, noesis.RPGEODATA_USHORT, numTris, noesis.RPGEO_TRIANGLE, 1)

   

   bs.seek(2, NOESEEK_REL) #FF
   #print(bs.tell() ,"pos")
   return 1




Attachments:
plane.jpg [358.08 KiB]
Not downloaded yet
Top
   
PostPosted: Mon Jan 28, 2019 4:43 pm 

Joined: Mon Jan 28, 2019 2:10 pm
Posts: 3
Yup, 404 for me as well, so it isn't a temporary issue. It's a shame since I'm on the hunt for good plane models, and the Crimson Skies games were among my favorites.


Top
   
PostPosted: Fri Mar 15, 2019 5:01 am 

Joined: Sat Dec 01, 2018 1:43 pm
Posts: 9
Same here. Afraid I still don't have a real solution to extracting the models w/ uvs and hierachy submeshes though, but that noesis .x plugin update works really well!


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 7 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