Nvidia's .nmb model

Post questions about game models here, or help out others!
Post Reply
djoscar
beginner
Posts: 30
Joined: Thu Dec 17, 2009 9:59 am

Nvidia's .nmb model

Post by djoscar » Sat Jul 17, 2010 1:18 pm

The contents of this post was deleted because of possible forum rules violation.

grotesque
advanced
Posts: 54
Joined: Wed Mar 17, 2010 9:12 pm
Has thanked: 2 times

Re: Nvidia's .nmb model

Post by grotesque » Sun Jul 18, 2010 12:02 am

I'm looking for this converter too!
Sorry bad english, I'm italian!

User avatar
Wobble
ultra-veteran
ultra-veteran
Posts: 584
Joined: Tue Jan 04, 2005 9:47 pm
Has thanked: 43 times
Been thanked: 112 times

Re: Nvidia's .nmb model

Post by Wobble » Sun Jul 18, 2010 5:59 pm

[out]
Last edited by Wobble on Sun Mar 12, 2017 12:23 pm, edited 1 time in total.

User avatar
CMihai
veteran
Posts: 131
Joined: Sun Jul 05, 2009 12:58 pm
Has thanked: 13 times
Been thanked: 1 time

Re: Nvidia's .nmb model

Post by CMihai » Mon Jul 19, 2010 6:48 am

Found something that converted the model into alot of .obj's, you had to import all of them, really pain in the ass >_> I'll look for it again, If I find it I'll let you know.

mariokart64n
ultra-veteran
ultra-veteran
Posts: 567
Joined: Sun Jun 05, 2005 12:00 pm
Location: Ontario, Canada
Has thanked: 34 times
Been thanked: 200 times

Re: Nvidia's .nmb model

Post by mariokart64n » Thu Jul 22, 2010 6:16 am

SBibi's docs were kinda of thick to read. and his first assumptions about the file structure seemed way off O_o

I don't get why he thought FFFF was a starting tag, since almost always it's used as a closer or terminator to chunk based formats.
anyway I tried to read through the NMB in the Adrianne demo. since it has no scene information, just direct mesh info.

and got a crude import through maxscripitng
Image

I'm not sure exactly how SBibi got the strips to import correctly, so I'll have to read further through his docs

my maxscript only works on Adrianne at the moment. but here's the script, just encase I never get around to it again.

I have to get around to investigating as many IDs as possible, otherwise I need to write a skip from FFFF to FFFF to skip each unknown chunk

EDIT - nevermind, its because I was reading the trilist data as strips.. Adrianne should import now

Code: Select all

fsource = GetOpenFileName \
caption:"nmb thingy" types: \
"NMB(*.nmb)|*.nmb|All files (*.*)|*.*|"
f = fopen fsource "rb"
fname = getFilenameFile fsource
fext = getFilenameType fsource
fpath = getFilenamePath fsource
-- f = fopen "G:\\Program Files\\NVidia Corporation\\NVidia Demos\\Adrianne\\models\\geo_model_sample.nmb" "rb"
-- fpath="G:\\Program Files\\NVidia Corporation\\NVidia Demos\\Adrianne\\models\\"



fn ReadFixedString bstream fixedLen = (
	local str = ""
	for i = 1 to fixedLen do
	(
		str += bit.intAsChar (ReadByte bstream #unsigned)
	)
	str
)

uknblock=false


-- Main NMB Header

version=readlong f #unsigned -- always seems to be 01
ukn1=readlong f #unsigned	-- 0x01=SkyBox | 0x04=Effects | 0x0A=Model | 0x0B=Morphs | 0x0C=Animation
itmCount=readlong f #unsigned	-- 48 ?? Count
-- itmCount=1
-- SubHeader

itmArray=#()
datArray=#()
for itm=1 to itmCount do (
PRINT "OK"


wh=ftell f
print wh
blockID=readshort f #unsigned -- 0x31 defines new mesh group / name
blockFormat=readshort f #unsigned -- 
ukn=readlong f #unsigned	-- -1?
chrLength=readlong f #unsigned
	print chrLength
if chrLength>=100 do(
chrLength=20

PRINT "CRAP!1"
wh=ftell f
print wh
		)
objName=ReadFixedString f chrLength
pad=readbyte f #unsigned -- either 1 or 0

pathflag=bit.swapBytes (bit.swapBytes (readlong f #unsigned) 1 4) 2 3
print pathflag
if pathflag!=1 do(
fseek f -1 #seek_cur
chrLength=readlong f #unsigned
	if chrLength>=100 do(
chrLength=20
PRINT "CRAP2!"
wh=ftell f
print wh
		)
filePath=ReadFixedString f chrLength
donno1=readlong f #unsigned -- count? usually 1
donno2=readlong f #unsigned -- size?
donno3=readlong f #unsigned -- 2?
donno4=readlong f #unsigned -- 0?
)
ukn=readlong f #unsigned	-- 10000

subBlockCount=readlong f #unsigned
--subBlockCount=1
append itmArray objName
	
-- DataBlocks
uvwArray=#()
faceArray=#()
vertArray=#()

for dat=1 to subBlockCount do (
PRINT "OK"


wh=ftell f
print wh
blockID=readshort f #unsigned -- 0x22=Vertices | 0x25=Normals | 0x24=UVs | 0x31=MeshGroup
blockFormat=readshort f #unsigned --? 100
ukn=readlong f #unsigned	-- 0?
chrLength=readlong f #unsigned;print chrLength
if chrLength>=100 do(
chrLength=20
PRINT "CRAP3!"
wh=ftell f
print wh
		)
blockName=ReadFixedString f chrLength

ukn5=readlong f #unsigned -- ?count 1
ukn6=readlong f #unsigned -- ?count -1
ukn7=readlong f #unsigned -- ?count 2

entryCount=readlong f #unsigned
	
append datArray blockName
		
if blockID==0x01 do( --Colour Values?
fseek f 44 #seek_cur
terminator=readlong f #unsigned --? always FF
)

if blockID==0x02 do( --Texture List?
fseek f -12 #seek_cur
	
-- do(
-- chrLength=readlong f #unsigned
-- fseek f chrLength #seek_cur
-- ukn5=readlong f #unsigned
-- )
-- while ukn5>=0xFFFFFFFC

)
	
if blockID==0x20 do( --Bone Indecies??
for c = 1 to entryCount do(
bn1=readfloat f
	)
terminator=readlong f #unsigned --? always FF
)


if blockID==0x21 do( --Bone Indecies??
for c = 1 to entryCount do(
bn1=readfloat f
bn1=readfloat f
	)
terminator=readlong f #unsigned --? always FF
)


if blockID==0x22 do(
	uknblock=true
for c = 1 to entryCount do(
vX=readfloat f
vY=readfloat f
vZ=readfloat f;vZ=-vZ
append vertArray[vX,vZ,vY]
	)
terminator=readlong f #unsigned --? always FF
)

if blockID==0x23 do( --Bone Weights
for c = 1 to entryCount do(
bn1=readfloat f
bn2=readfloat f
bn3=readfloat f
bn4=readfloat f
	)
terminator=readlong f #unsigned --? always FF
)

if blockID==0x24 do(
for c = 1 to entryCount do(
tu=readfloat f
tv=readfloat f--;vZ=-vZ
append uvwArray[tu,tv,0]
	)
terminator=readlong f #unsigned --? always FF
	)
	
if blockID==0x25 do(
for c = 1 to entryCount do(
nX=readfloat f
nY=readfloat f
nZ=readfloat f
	)
terminator=readlong f #unsigned --? always FF
)





)-- End of MainHeader







if uknblock==true do(

blockID=readlong f #unsigned -- always 2?
entries=readlong f #unsigned -- ? 2
	
for c = 1 to entries do(
ukn2=readlong f #unsigned -- ? size?
pad=readlong f #unsigned -- ? 0's Padding?
triFormat=readlong f #unsigned -- ? 5
ukn4=readlong f #unsigned -- ? 1
loopCount=(readlong f #unsigned);print loopCount -- ? number of entries
	
--if loopCount>=60000 do loopCount=600000 --Safety precaution, anything more may freeze your PC
PRINT "face data?"
wh=ftell f
print wh

	
if triFormat==3 do(
for c = 1 to loopCount/3 do(
fa=readshort f #unsigned+1
fb=readshort f #unsigned+1
fc=readshort f #unsigned+1
append faceArray [fa,fb,fc]
	)
)

if triFormat==5 do(
	
 StartDirection = -1
f1 = (readshort f #unsigned) + 1
f2 = (readshort f #unsigned) + 1
FaceDirection = StartDirection
IndexCounter = 2
Do (
f3 = (readshort f #unsigned)
IndexCounter += 1
if (f3==0xFFFF) then (
f1 = (readshort f #unsigned) + 1
f2 = (readshort f #unsigned) + 1
FaceDirection = StartDirection
IndexCounter += 2
) else (
f3 += 1
FaceDirection *= -1
if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then (
if FaceDirection > 0 then append faceArray [f1,f2,f3]
else append faceArray [f1,f3,f2]
)
f1 = f2
f2 = f3
)
) 
while IndexCounter !=loopCount
)






terminator=readlong f #unsigned --? always FF	
)


)


if uvwArray.count == 0 then(
	
msh = mesh vertices:vertArray faces:faceArray   --build mesh
msh.numTVerts = vertArray.count
buildTVFaces msh
msh.name=objName
for j = 1 to vertArray.count     do setTVert  msh j vertArray[j]
for j = 1 to faceArray.count   do setTVFace msh j faceArray[j]
)
else(


msh = mesh vertices:vertArray faces:faceArray   --build mesh
msh.numTVerts = uvwArray.count
buildTVFaces msh
msh.name=objName
for j = 1 to uvwArray.count     do setTVert  msh j uvwArray[j]
for j = 1 to faceArray.count   do setTVFace msh j faceArray[j]
)

terminator=readlong f #unsigned --? always FF

 ) -- End of SubHeaders



	
	

-- print itmArray
-- print datArray

-- if ukn8 !=4096 do(
-- 	
-- 	
-- 	
-- 	
-- StartDirection = -1
-- f1 = (ReadBEword f) + 1
-- f2 = (ReadBEword f) + 1  
-- FaceDirection = StartDirection
-- Do (
-- f3 = (ReadBEword f)
-- if (f3==0xFFFF) then (
-- f1 = (ReadBEword f) + 1
-- f2 = (ReadBEword f) + 1
-- FaceDirection = StartDirection   
-- ) else (
-- f3 += 1
-- FaceDirection *= -1
-- if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then (
-- if FaceDirection > 0 then append faceArray [f1,f2,f3]
-- else append faceArray [f1,f3,f2]
-- )
-- f1 = f2
-- f2 = f3
-- )  
-- )while (ftell f) != 0x8ADAF









-- 	)


print "Where Am I?"
wh=ftell f
print wh




print "DONE!!"




gc()
fclose f



Maxscript and other finished work I've done can be found on my DeviantArt account

Post Reply