Jump to content

Colin McRae Rally 3 .STAG and .TAG model files


Go to solution Solved by shak-otay,

Recommended Posts

Posted

I know there's been (hard-to-find) tools for .p3d and other formats but those were made for later games in the series. I need to get models from this game for a mod I am planning to make.

I've attached sample files for both characters and car model files, if it helps.

Auspod.7z Cars.7z

  • Engineers
Posted (edited)

Getting uvs from puma.tag is easy, the mesh looks a little bit strange. Need to check that...

edit: from rear, front and bottom it looks good, from the other 3 sides it's a mess. Maybe the destruction mesh. Single parts follow.

 

puma-tag.png

Edited by shak-otay
  • Engineers
Posted

Do you think you can get the next sub mesh part using the car's top as a reference?

(As you may know I mostly feel finished somehow as soon as the first sub mesh parameters have been found.)

Posted
19 minutes ago, shak-otay said:

Do you think you can get the next sub mesh part using the car's top as a reference?

(As you may know I mostly feel finished somehow as soon as the first sub mesh parameters have been found.)

I ought to have some experience with reading model formats tho.

Is it alright to see how the Colin and Nicky meshes stack up?

  • Engineers
Posted
23 minutes ago, huckleberrypie said:

Is it alright to see how the Colin and Nicky meshes stack up?

(? Can you rephrase that?)

The next vertex block is from 0x39ae0 to 0x3c990, results in

Hex2obj0.25b-puma_sub_mesh_2.png

  • Engineers
  • Solution
Posted

I fear we're all alone here - so you may bump as much as you want.:classic_blink:

You should ask specific question(s) if you want some progress.

Btw, the format is rather low poly thus the general interest is low, too, I guess.

  • Thanks 1
Posted (edited)
2 hours ago, shak-otay said:

I fear we're all alone here - so you may bump as much as you want.:classic_blink:

You should ask specific question(s) if you want some progress.

Btw, the format is rather low poly thus the general interest is low, too, I guess.

Sorry about that. I did get the model to show up using your tools tho so no worries.

Screenshot (741).png

Screenshot (742).png

OK, based on what you dug up with the file, faces are stored as tristrips in 16-bit words. Verts are the usual floats.

0x10 is apparently the submesh count, 0x9C is the face/index count and 0x80 is the vertex count. The lines I highlighted in offset 0x90 hold the addresses for both vertex and index buffers. I guess this should be straightforward enough for a Noesis script?

Screenshot (746).png

Screenshot (747).png

Edited by huckleberrypie
  • Like 1
  • Engineers
Posted (edited)
8 hours ago, huckleberrypie said:

The lines I highlighted in offset 0x90 hold the addresses for both vertex and index buffers. I guess this should be straightforward enough for a Noesis script?

I wouldn't know why not. Just replace the constant values in the script, for example using

vertexCount = bs.readUInt()

in the correct place. Ignore the lines commented out by #.

#sample class
from inc_noesis import *

#indOffsArr = [0x1C00, 0x5100, 0x10100, 0x1B280, 0x26800, 0x31B00, 0x3CE80, 0x42280, 0x4DC00, 0x59800, 0x5D400, 0x69280, 0x74280]
matName = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]

def registerNoesisTypes():
   handle = noesis.register("CMR_Rally3", ".stag")
   noesis.setHandlerTypeCheck(handle, binModCheckType)
   noesis.setHandlerLoadModel(handle, binModLoadModel)
   #noesis.logPopup()

   return 1


def binModCheckType(data):
   td = NoeBitStream(data)
   return 1

class binFile:
         
   def __init__(self, bs):
      self.bs = bs

      self.texList  = []
      self.matList  = []
      self.boneList = []
      self.boneMap  = []
      self.offsetList = []
      self.meshOffsets = []
      self.materials = []

   def loadAll(self, bs):
      indexOffset = 0x1e084

      for j in range(0, 1):
        self.materials.append(j)
        #indexOffset = indOffsArr[j]
        #vertCount = bs.readUShort()
        #indexCount =  bs.readUShort()

        #bs.seek(8, NOESEEK_REL)
        bs.seek(indexOffset, NOESEEK_ABS)
        indexCount = 3910
        indBuff = bs.readBytes(indexCount*2)

        vertexOffset = 0x7bc0
        #vertexOffset = indexOffset + indexSize
        bs.seek(vertexOffset, NOESEEK_ABS)
        vertCount = 1522
        vSize = 60
        vertBuff = bs.readBytes(vSize * vertCount)
        rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vSize, 0)

        #uvsOffset = vertexOffset + vertCount * 16
        #bs.seek(uvsOffset, NOESEEK_ABS)
        #UVBuff = bs.readBytes(vertCount * 6)
        #UVBuff = rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_HALFFLOAT, vSize, 12)
        rapi.rpgCommitTriangles(indBuff, noesis.RPGEODATA_USHORT, indexCount, noesis.RPGEO_TRIANGLE_STRIP)
        rapi.rpgSetMaterial(matName[j])
        print("indCnt: %d vertCnt: %d" %(indexCount, vertCount))
        #print("indexOff: 0x%x, cnt: %d, size: 0x%x,  vertOff: 0x%x, cnt: %d, uvsOff: 0x%x" %(indexOffset, indexCount, indexSize, vertexOffset, vertCount, uvsOffset))


def binModLoadModel(data, mdlList):
   ctx = rapi.rpgCreateContext()
   bin = binFile(NoeBitStream(data, NOE_LITTLEENDIAN))
   bin.loadAll(bin.bs)
   try:
      mdl = rapi.rpgConstructModel()
   except:
      mdl = NoeModel()
   mdl.setModelMaterials(NoeModelMaterials(bin.texList, bin.matList))
   mdlList.append(mdl); mdl.setBones(bin.boneList)   
   return 1

 

nicky2-stag.png

Edited by shak-otay
  • Thanks 1
Posted (edited)

Thanks mate, that's very much appreciated.

EDIT: Am I right to assume that the values in the hex offsets are three bytes each?

EDIT 2: Strange, the girl models don't seem to have the proper header values at the usual offsets lmao:

 

Screenshot (760).png

Edited by huckleberrypie
  • Engineers
Posted (edited)
6 hours ago, huckleberrypie said:

Thanks mate, that's very much appreciated.

EDIT: Am I right to assume that the values in the hex offsets are three bytes each?

Puh, you mean because of indexOffset = 0x1e084? That's meant to be 0x0001e084, so 4 bytes. But leading zeroes can be ignored in code. (The 0x stands for hexadecimal, btw.)

A "3 bytes" data type is against the "digital rules", I guess, everything is based on power 2 types in intel's universe at least, afaik.

edit: maybe I misunderstood because I see you had highlighted 4 bytes in one of your previous pictures.

Quote

EDIT 2: Strange, the girl models don't seem to have the proper header values at the usual offsets lmao:

As you may know I'm not a fan of deep data analysation. Almost everything I do depends on pure guesswork.:classic_blink:

There may be different types in this format. Is there other models that have a header similar to the girl's one?

Edited by shak-otay
Posted
1 minute ago, shak-otay said:

Puh, you mean because of indexOffset = 0x1e084? That's meant to be 0x0001e084, so 4 bytes. But leading zeroes can be ignored in code. (The 0x stands for hexadecimal, btw.)

A "3 bytes" data type is against the "digital rules", I guess, everything is based on power 2 types in intel's universe at least, afaik.

As you may know I'm not a fan of deep data analysation. Almost everything I do depends on pure guesswork.:classic_blink:

There may be different types in this format. Is there other models that have a header similar to the girl's one?

Understandable.

And I've attached the race girls meshes in question too.

racegirls.zip

  • Engineers
Posted

0x5CD8 vertices start, 0x19028 start of face indices which can be found at file offsets 0x98 and 0x9C

When you look at offset 0x70 there's 0x74 for nick2 and 0x78 for girl1. Adding 0x20 to it you get the offset you need.

Posted
36 minutes ago, shak-otay said:

0x5CD8 vertices start, 0x19028 start of face indices which can be found at file offsets 0x98 and 0x9C

When you look at offset 0x70 there's 0x74 for nick2 and 0x78 for girl1. Adding 0x20 to it you get the offset you need.

So how do I programmatically determine it in Noesis then?

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...