petventh18 wrote:shakotay2 wrote:...here's some simple script for beginners with some Noesis/python knowledge:
http://forum.xentax.com/viewtopic.php?f ... an#p141865
(ah, see, there's some math with the face indices buffer, feel free to ask, why, that's a matter of the format, not of python)....
But for hundreds of *.mesh files you might prefer this one (cmd line tool, GUI pops up and exits):
Thanks a lot for the info and for the tool update... it'll save me lots of time to sort through those models...
I wasn't sure if it would work for 100s of models...
You mentioned that the UVs is 2 bytes off... so restart the tool and type in the new value on the editbox... then load the same mesh again, correct?
Forget about that; that's for the old version with auto calculation of addresses; sometimes it gave incorrect values (2 bytes off for example) for the uvs' start.
The cmdline version gets all values from the magic table at 0x90 (counts and addresses) now. But it "relies" on a 12 bytes offset in the uvs' block (3 floats to be skipped before the uv data).
btw: this format is a very good start to be used with a Noesis script (you don't need the face indices buffer math in my previous linked sample).
The codelines for getting the face indices should look like this (untested):
faceBuff = bs.readBytes(faceCount*3*4)
rapi.rpgCommitTriangles(faceBuff, noesis.RPGEODATA_UINT, faceCount*3, noesis.RPGEO_TRIANGLE, 1)
UINT because of DWord face indices
and you don't need this weird
b = struct.pack('H' * len(idxBuf), *idxBuf) for this format
here's a working Noesis script, tested with 00000161.mesh:
Code: Select all
from inc_noesis import *
import noesis
import rapi
def registerNoesisTypes():
handle = noesis.register("JX3", ".mesh")
noesis.setHandlerTypeCheck(handle, noepyCheckType)
noesis.setHandlerLoadModel(handle, noepyLoadModel)
return 1
def noepyCheckType(data):
bs = NoeBitStream(data)
bs.seek(0x54, NOESEEK_ABS)
idstring = bs.readUInt()
if idstring != 0x4D455348:
print("not a JX3 file!")
return 0
return 1
def noepyLoadModel(data, mdlList):
ctx = rapi.rpgCreateContext()
bs = NoeBitStream(data)
#rapi.rpgClearBufferBinds()
bs.seek(0x90, NOESEEK_ABS)
vertsCount = bs.readUInt()
faceCount = bs.readUInt()
bs.seek(0xA8, NOESEEK_ABS)
uvAddr = bs.readUInt()
uvAddr += 12
bs.seek(0xB4, NOESEEK_ABS)
FIaddr = bs.readUInt()
bs.seek(0x12C, NOESEEK_ABS)
VertBuf = bs.readBytes(vertsCount * 6)
bs.seek(uvAddr, NOESEEK_ABS)
uv1Buf = bs.readBytes(vertsCount * 6)
bs.seek(FIaddr, NOESEEK_ABS)
idxBuf = bs.readBytes(faceCount*3*4)
rapi.rpgBindPositionBufferOfs(VertBuf, noesis.RPGEODATA_USHORT, 6, 0)
rapi.rpgBindUV1Buffer(uv1Buf, noesis.RPGEODATA_USHORT, 6)
rapi.rpgCommitTriangles(idxBuf, noesis.RPGEODATA_UINT, faceCount*3, noesis.RPGEO_TRIANGLE, 1)
mdl = rapi.rpgConstructModel()
mdlList.append(mdl)
return 1
(Maybe I should have used some NOESEEK_REL constants but I'm too lazy to calculate the required offsets.
)
edit: attaching above mentioned sample, in case it's not available any more:
00000161.zip
Also I didn't care for the normals buffer, as always.
addr can be found in the magic table; refer to the struct that Bigchillghost posted.