Jump to content

Crimson Skies: High Road to Revenge (DirectX *.x)


Recommended Posts

Posted (edited)

attaching one more just to make sure - Final_Boss has several .x models that contain multiple UV maps, namely ss_boss_zep.x and zep_pandora.x (the one w/ the stretched UVs) - ss_boss_zep has converted objs with fixed uv scaling, though i have noticed that there are parts like on the rear fuselage where uvs are seemingly broken on one side (highlighted)

A4swN8d.png

in any case, here's how ss_boss_zep should roughly look - it's missing the logos due to not having a second uv set on fbx or obj at the moment but h3x3r's comment above yours shows how it should look

qNTyblC.png

uvset.jpg

 

https://zippyshare.day/pdhI5N1B0QnZjeL/file

hope you can figure this out!

Edited by notameowcelot
Link to comment
Share on other sites

1 hour ago, Durik256 said:

structure where uvScale is located. I'll look into it then.)

Just right after vertex block. There are 4 floats. First of them is uvScale.

uvScale.jpg

  • Like 1
Link to comment
Share on other sites

On 5/19/2024 at 1:22 PM, Durik256 said:

Hello. I haven't been following this topic. post it again (files model, texture). screenshot of what the current uv is and what it should be. structure where uvScale is located. I'll look into it then.)

hey @Durik256 - wanted to check and see if there was any progress on this front 🙂 

Link to comment
Share on other sites

Posted (edited)

hey @Durik256i noticed as well that there's a second UV map for overlays like logos on zeppelins and such - is there any chance you can include that? you should have .xs that have it, specifically zep_pandora and ss_boss_zep - that alongside the bones and mesh weights and this could be considered complete 🙂 

 

edit: h3x3r figured out the second uv part, but logos aren't correctly aligned or positioned for some reason. not sure why

 

def fixUVs(vbuf, uvScale):
    bs = NoeBitStream(vbuf)
    uvbuf = b''
    uvbuf1 = b''
    for x in range(len(vbuf)//32):
        bs.seek(16,1)
        u,v = bs.read('2h')
        u1,v1 = bs.read('2h')
        bs.seek(8,1)
        uvbuf += noePack('2f', u*uvScale, v*uvScale)
        uvbuf1 += noePack('2f', u1*uvScale, v1*uvScale)
        
    rapi.rpgBindUV1Buffer(uvbuf, noesis.RPGEODATA_FLOAT, 8)
    rapi.rpgBindUV2Buffer(uvbuf1, noesis.RPGEODATA_FLOAT, 8)

edit 2:

 

got the UV part fixed we think - all's left is skinning the bone fix.

full current code:

 

#by Durik256
from inc_noesis import *

def registerNoesisTypes():
    handle = noesis.register("Crimson Skies: High Road to Revenge (Retail, 2003)", ".x")
    noesis.setHandlerTypeCheck(handle, noepyCheckType)
    noesis.setHandlerLoadModel(handle, noepyLoadModel)
    noesis.logPopup()
    return 1

def noepyCheckType(data):
    return 1

def noepyLoadModel(data, mdlList):
    ctx = rapi.rpgCreateContext()
    bs = NoeBitStream(data)
    rapi.rpgSetOption(noesis.RPGOPT_SWAPHANDEDNESS, 1)
    
    global nodes, materials
    nodes, materials = [], []
    
    bs.seek(32)
    readNode(bs)
    
    try:
        mdl = rapi.rpgConstructModel()
    except:
        mdl = NoeModel()
    
    #if nodes:
    #    nodes = rapi.multiplyBones(nodes)
    
    mdl.setBones(nodes)
    mdl.setModelMaterials(NoeModelMaterials([], materials))
    mdlList.append(mdl)
    return 1
    
def readNode(bs,parent=None,ptrfm=None):
    name = readString(bs)
    trfm = NoeMat43.fromBytes(bs.read(48)).transpose()
    if ptrfm:
        trfm *= ptrfm
    bbox = bs.read('6f')
    bs.read(4)# 3
    
    rapi.rpgSetName(name)
    rapi.rpgSetTransform(trfm) 
    for x in range(bs.readUInt()):
        readMesh(bs)
    
    nodes.append(NoeBone(len(nodes),name,trfm,parent))
    
    for x in range(bs.readUInt()):
        readNode(bs,name,trfm)
    
counter = 0
def readMesh(bs):
    global counter
    u0 = bs.readUInt()
    clr = bs.read('4B')
    u1 = bs.readUInt()
    u2 = bs.read('>i')[0]

    mat_name = 'mat_%i'%len(materials)
    mat = NoeMaterial(mat_name, '')
    mat.setDiffuseColor(NoeVec4([clr[0]/255,clr[1]/255,clr[2]/255,clr[3]/255]))

    dict = {0:0, 1:1, 3:2, 7:3, 17:2, 15:4, 19:3, 23:4, 31:5}
    numTx = dict[u2]
    
    for x in range(numTx):
        tx_name = readString(bs)
        if not x: mat.setTexture(tx_name)
    
    materials.append(mat)
    print('vstart:',bs.tell())
    vnum = bs.readShort()
    vbuf = bs.read(vnum*32)
    print('vend:',bs.tell())
    #bs.read('16B')
    _f = bs.read('4f')
    print(counter,'_f:',_f)#
    print('_f:',"%.6f" % _f[0])
    counter += 1
    if bs.readUByte():
        bs.seek(bs.readShort() * 12 * 4, 1)
       
    inum = bs.readShort()
    ibuf = bs.read(inum*2)
    
    rapi.rpgSetMaterial(mat_name)
    rapi.rpgBindPositionBuffer(vbuf, noesis.RPGEODATA_FLOAT, 32)
    #rapi.rpgBindUV1BufferOfs(vbuf, noesis.RPGEODATA_USHORT, 32, 16)
    fixUVs(vbuf, _f[0])
    fixUVs1(vbuf, _f[1])
    rapi.rpgCommitTriangles(ibuf, noesis.RPGEODATA_USHORT, inum, noesis.RPGEO_TRIANGLE)
    rapi.rpgClearBufferBinds()

    bs.seek(2, 1) #FF
    strip = bs.readUShort()
    bs.seek(strip*2, 1)

    if bs.readByte() == 1:
        size=16
        numUnk= bs.readInt()
    else:
        size=28
        numUnk= bs.readShort()
    bs.seek(numUnk*size, 1)
   
def fixUVs(vbuf, uvScale):
    bs = NoeBitStream(vbuf)
    uvbuf = b''
    for x in range(len(vbuf)//32):
        bs.seek(16,1)
        u,v = bs.read('2h')
        bs.seek(12,1)
        uvbuf += noePack('2f', u*uvScale, v*uvScale)

    rapi.rpgBindUV1Buffer(uvbuf, noesis.RPGEODATA_FLOAT, 8)

def fixUVs1(vbuf, uvScale):
    bs = NoeBitStream(vbuf)
    uvbuf1 = b''
    for x in range(len(vbuf)//32):
        bs.seek(20,1)
        u1,v1 = bs.read('2h')
        bs.seek(8,1)
        uvbuf1 += noePack('2f', u1*uvScale, v1*uvScale)

    rapi.rpgBindUV2Buffer(uvbuf1, noesis.RPGEODATA_FLOAT, 8)
    
def readString(bs):
    return bs.read(bs.readUInt()).split(b'\x00')[0].decode('ascii', 'ignore')

 

Edited by notameowcelot
Link to comment
Share on other sites

  • 1 month later...

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...