GMax B3D Importer Source

Blitz3D Forums/Blitz3D Programming/GMax B3D Importer Source

Vertex(Posted 2004) [#1]
long, long time ago i have started to program a simple *.b3d importer for GMax. Today i given up this shit...

I hate maxscript, yes I hate it.
see my lovely picture:





here the 1337 code for my begin of my importer:
---------------------------------------------------------------------------------------
struct b3dQuat_s
(
	w = 0 as float,
	x = 0 as float,
	y = 0 as float,
	z = 0 as float
)

struct b3dWeight_s
(
	nBoneID = 0 as integer,
	nVertex = 0 as integer,
	fWeight = 0 as float
)

struct b3dBB3D_s
(
	nVersion = 0 as integer
)

struct b3dTEXS_s
(
	sFilename = "" as string,
	nFlags    = 0 as integer,
	nBlend    = 0 as integer,
	fUOffset  = 0 as float,
	fVOffset  = 0 as float,
	fUScale   = 0 as float,
	fVScale   = 0 as float,
	fRotate   = 0 as float
)

struct b3dBRUS_s
(
	nTextureCount = 0 as integer,
	sName         = "" as string,
	fRed          = 0 as float,
	fGreen        = 0 as float,
	fBlue         = 0 as float,
	fAlpha        = 0 as float,
	fShininess    = 0 as float,
	nBlend        = 0 as integer,
	nFX           = 0 as integer,
	textureList   = #()
)

struct b3dVRTS_s
(
	nFlags           = 0 as integer,
	nTexCoordSet     = 0 as integer,
	nTexCoordSetSize = 0 as integer,
	fPosition        = [0, 0, 0],
	fNormal          = [0, 0, 0],
	fRed             = 0 as float,
	fGreen           = 0 as float,
	fBlue            = 0 as float,
	fAlpha           = 0 as float,
	fUVW0            = [0, 0, 0],
	fUVW1            = [0, 0, 0]
)

struct b3dTRIS_s
(
	nBrushID   = 0 as integer,
	vertexList = #()
)

struct b3dMESH_s
(
	nBrushID  = 0 as integer,
	sName     = "" as string,
	fPosition = [0, 0, 0],
	fScale    = [0, 0, 0],
	fRotate   = b3dQuat_s()
)
struct b3dBONE_s
(
	sName      = "" as string,
	nParentID  = 0 as integer,
	nChildID   = 0 as integer,
	fPosition  = [0, 0, 0],
	fScale     = [0, 0, 0],
	fRotate    = b3dQuat_s(),
	keyList    = #(),
	nStartPos  = 0 as integer,
	nEndPos    = 0 as integer
)

struct b3dKEYS_s
(
	nFlags    = 0 as integer,
	nFrame    = 0 as integer,
	fPosition = [0, 0, 0],
	fScale    = [0, 0, 0],
	fRotate   = b3dQuat_s()
)

struct b3dANIM_s
(
	nFlags  = 0 as integer,
	nFrames = 0 as integer,
	fFPS    = 0 as float
)

struct b3dNODE_s
(
	sName     = "" as string,
	fPosition = [0, 0, 0],
	fScale    = [0, 0, 0],
	fRotate   = b3dQuat_s(),
	nStartPos = 0 as integer,
	nEndPos   = 0 as integer
)


global b3dChunkID     = "" as string
global b3dChunkSize   = 0 as integer
global b3dChunkEndPos = 0 as integer

global b3dTEXSList   = #()
global b3dBRUSList   = #()
global b3dVRTSList   = #()
global b3dTRISList   = #()
global b3dBONEList   = #()
global b3dWeightList = #()

global b3dBB3D = b3dBB3D_s()
global b3dNODE = b3dNODE_s()
global b3dMESH = b3dMESH_s()
global b3dANIM = b3dANIM_s()

global b3dNodeStart = 0 as integer
global b3dNodeEnd   = 0 as integer

global maxMesh
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
global sFileName   = "" as string
global sFilePath   = "" as string
global nFileLength = 0 as integer
global nFileStream = 0 as integer
global nFilePos    = 0 as integer
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function b3dReadChunk nStream =
(
	local nI     = 0 as integer
	local sChunk = "" as string

	for nI = 1 to 4 do
	(
		sChunk += bit.intAsChar (readByte nStream #unsigned)
	)

	return sChunk
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function b3dReadBB3D =
(
	b3dBB3D.nVersion = readLong nFileStream
	if b3dBB3D.nVersion != 1 then nFilePos = nFileLength
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function b3dReadTEXS =
(
	if b3dChunkSize > 0 then
	(
		while nFilePos < b3dChunkEndPos do
		(
			local b3dTEXS = b3dTEXS_s()

			b3dTEXS.sFilename = readString nFileStream
			b3dTEXS.nFlags    = readLong nFileStream
			b3dTEXS.nBlend    = readLong nFileStream
			b3dTEXS.fUOffset  = readFloat nFileStream
			b3dTEXS.fVOffset  = readFloat nFileStream
			b3dTEXS.fUScale   = readFloat nFileStream
			b3dTEXS.fVScale   = readFloat nFileStream
			b3dTEXS.fRotate   = readFloat nFileStream

			append b3dTEXSList b3dTEXS
			nFilePos = ftell nFileStream
		)
	)
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function b3dReadBRUS =
(
	local nI            = 0 as integer
	local nTextureCount = 0 as integer

	nTextureCount = readLong nFileStream

	if b3dChunkSize > 4 then
	(
		while nFilePos < b3dChunkEndPos do
		(
			local b3dBRUS = b3dBRUS_s()

			b3dBRUS.nTextureCount = nTextureCount
			b3dBRUS.sName         = readString nFileStream
			b3dBRUS.fRed          = readFloat nFileStream
			b3dBRUS.fGreen        = readFloat nFileStream
			b3dBRUS.fBlue         = readFloat nFileStream
			b3dBRUS.fAlpha        = readFloat nFileStream
			b3dBRUS.fShininess    = readFloat nFileStream
			b3dBRUS.nBlend        = readLong nFileStream
			b3dBRUS.nFX           = readLong nFileStream

			for nI = 1 to b3dBRUS.nTextureCount do
			(
				append b3dBRUS.textureList (readLong nFileStream)
			)

			append b3dBRUSList b3dBRUS
			nFilePos = ftell nFileStream
		)
	)
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function b3dReadVRTS =
(
	local nFlags           = readLong nFileStream
	local nTexCoordSet     = readLong nFileStream
	local nTexCoordSetSize = readLong nFileStream

	if b3dChunkSize > 0 then
	(
		while nFilePos < b3dChunkEndPos do
		(
			local b3dVRTS = b3dVRTS_s()
		
			b3dVRTS.nFlags           = nFlags
			b3dVRTS.nTexCoordSet     = nTexCoordSet
			b3dVRTS.nTexCoordSetSize = nTexCoordSetSize

			b3dVRTS.fPosition.x = readFloat nFileStream
			b3dVRTS.fPosition.y = readFloat nFileStream
			b3dVRTS.fPosition.z = readFloat nFileStream

			if (bit.and b3dVRTS.nFlags 1 == 1) then
			(
				b3dVRTS.fNormal.x   = readFloat nFileStream
				b3dVRTS.fNormal.y   = readFloat nFileStream
				b3dVRTS.fNormal.z   = readFloat nFileStream
			)

			if (bit.and b3dVRTS.nFlags 2 == 2) then
			(
				b3dVRTS.fRed   = readFloat nFileStream
				b3dVRTS.fGreen = readFloat nFileStream
				b3dVRTS.fBlue  = readFloat nFileStream
				b3dVRTS.fAlpha = readFloat nFileStream
			)

			if b3dVRTS.nTexCoordSet > 0 then
			(
				if b3dVRTS.nTexCoordSetSize > 0 then b3dVRTS.fUVW0.x = readFloat nFileStream
				if b3dVRTS.nTexCoordSetSize > 1 then b3dVRTS.fUVW0.y = readFloat nFileStream
				if b3dVRTS.nTexCoordSetSize > 2 then b3dVRTS.fUVW0.z = readFloat nFileStream
			)

			if b3dVRTS.nTexCoordSet > 1 then
			(
				if b3dVRTS.nTexCoordSetSize > 0 then b3dVRTS.fUVW1.x = readFloat nFileStream
				if b3dVRTS.nTexCoordSetSize > 1 then b3dVRTS.fUVW1.y = readFloat nFileStream
				if b3dVRTS.nTexCoordSetSize > 2 then b3dVRTS.fUVW1.z = readFloat nFileStream
			)

			append b3dVRTSList b3dVRTS
			nFilePos = ftell nFileStream
		)
	)
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function b3dReadTRIS =
(
	local b3dTRIS = b3dTRIS_s()
	local nI      = 0 as integer

	b3dTRIS.nBrushID = readLong nFileStream

	if b3dChunkSize > 0 then
	(
		while nFilePos < b3dChunkEndPos do
		(
			local nVertex = [0, 0, 0]

			nVertex.x = readLong nFileStream
			nVertex.y = readLong nFileStream
			nVertex.z = readLong nFileStream

			append b3dTRIS.vertexList nVertex
			nFilePos = ftell nFileStream
		)
		append b3dTRISList b3dTRIS
	)
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function b3dReadMESH =
(
	b3dMESH.nBrushID  = readLong nFileStream
	b3dMESH.sName     = b3dNODE.sName
	b3dMESH.fPosition = b3dNODE.fPosition
	b3dMESH.fScale    = b3dNODE.fScale
	b3dMESH.fRotate   = b3dNODE.fRotate
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function b3dReadBONE = 
(
	local b3dBONE = b3dBONE_s()
	local nI      = 0 as integer
	
	b3dBONE.sName     = b3dNODE.sName
	b3dBONE.fPosition = b3dNODE.fPosition
	b3dBONE.fScale    = b3dNODE.fScale
	b3dBONE.fRotate   = b3dNODE.fRotate

	
	for nI = 1 to (b3dChunkEndPos-nFilePos)/8-1 do
	(
		local b3dWeight = b3dWeight_s()
		
		b3dWeight.nBoneID = b3dBONEList.count
		b3dWeight.nVertex = readLong nFileStream
		b3dWeight.fWeight = readFloat nFileStream

		append b3dWeightList b3dWeight
	)

	b3dBONE.nStartPos = b3dNODE.nStartPos
	b3dBONE.nEndPos   = b3dNODE.nEndPos

	append b3dBONEList b3dBONE
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function b3dReadKEYS = 
(
	local nFlags = 0 as integer

	nFlags = readLong nFileStream

	while nFilePos < b3dChunkEndPos do
	(
		local b3dKEYS = b3dKEYS_s()
		
		b3dKEYS.nFlags = nFlags
		b3dKEYS.nFrame = readLong nFileStream 

		if (bit.and b3dKEYS.nFlags 1 == 1) then
		(
			b3dKEYS.fPosition.x = readFloat nFileStream
			b3dKEYS.fPosition.y = readFloat nFileStream
			b3dKEYS.fPosition.z = readFloat nFileStream
		)

		if (bit.and b3dKEYS.nFlags 2 == 2) then
		(
			b3dKEYS.fScale.x = readFloat nFileStream
			b3dKEYS.fScale.y = readFloat nFileStream
			b3dKEYS.fScale.z = readFloat nFileStream
		)

		if (bit.and b3dKEYS.nFlags 4 == 4) then
		(
			b3dKEYS.fRotate.w = readFloat nFileStream
			b3dKEYS.fRotate.x = readFloat nFileStream
			b3dKEYS.fRotate.y = readFloat nFileStream
			b3dKEYS.fRotate.z = readFloat nFileStream
		)

		append b3dBONEList[b3dBONEList.count].keyList b3dKEYS
		nFilePos = ftell nFileStream
	)
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function b3dReadANIM =
(
	b3dANIM.nFlags  = readLong nFileStream
	b3dANIM.nFrames = readLong nFileStream
	b3dANIM.fFPS    = readFloat nFileStream
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function b3dReadNODE =
(
	b3dNODE.sName       = readString nFileStream
	b3dNODE.fPosition.x = readFloat nFileStream
	b3dNODE.fPosition.y = readFloat nFileStream
	b3dNODE.fPosition.z = readFloat nFileStream
	b3dNODE.fScale.x    = readFloat nFileStream
	b3dNODE.fScale.y    = readFloat nFileStream
	b3dNODE.fScale.z    = readFloat nFileStream
	b3dNODE.fRotate.w   = readFloat nFileStream
	b3dNODE.fRotate.x   = readFloat nFileStream
	b3dNODE.fRotate.y   = readFloat nFileStream
	b3dNODE.fRotate.z   = readFloat nFileStream

	b3dNODE.nStartPos = nFilePos
	b3dNODE.nEndPos   = b3dChunkEndPos
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function b3dOrderBones =
(
	local nCount  = 0 as integer
	local nIndexI = 0 as integer
	local nIndexJ = 0 as integer
	local nStart  = 0 as integer
	local nEnd    = 0 as integer

	nCount = b3dBONEList.count
	if nCount > 0 then
	(
		for nIndexI = 1 to nCount do
		(
			nStart = b3dBONEList[nIndexI].nStartPos
			nEnd   = b3dBONEList[nIndexI].nEndPos

			for nIndexJ = 1 to nCount do
			(
				if nStart < b3dBONEList[nIndexJ].nStartPos and \
				   nEnd > b3dBONEList[nIndexJ].nStartPos then
				(
					b3dBONEList[nIndexI].nChildID  = nIndexJ
					b3dBONEList[nIndexJ].nParentID = nIndexI
				)
			)
			print b3dBONEList[nIndexI]
		)
	)
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
function maxCreateMesh =
(
	local maxVertexList   = #()
	local maxTriangleList = #()
	local maxMaterialList = #()
	local nCount          = 0 as integer
	local nIndex          = 0 as integer

	-- its only a test to show why is maxscript fucking evil

	nCount = b3dVRTSList.count
	for nIndex = 1 to nCount do
	(
		local fPosition = [0, 0, 0]

		fPosition.x = b3dVRTSList[nIndex].fPosition.x*100.0
		fPosition.y = b3dVRTSList[nIndex].fPosition.z*100.0
		fPosition.z = b3dVRTSList[nIndex].fPosition.y*100.0

		append maxVertexList fPosition
	)

	nCount = b3dTRISList.count
	for nIndex = 1 to nCount do
	(
		local nVertex      = [0, 0, 0]
		local nVertexCount = 0 as integer
		local nVertexIndex = 0 as integer

		nVertexCount = b3dTRISList[nIndex].vertexList.count
		for nVertexIndex = 1 to nVertexCount do
		(
			nVertex = b3dTRISList[nIndex].vertexList[nVertexIndex]
			nVertex.x += 1 
			nVertex.y += 1 
			nVertex.z += 1 
			append maxVertexList nVertex
		)
	)

	print maxVertexList
	print maxTriangleList

	maxMesh = mesh vertices:maxVertexList faces:maxTriangleList

	update maxMesh TRUE
)
---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------
utility Blitz3DImporter "Blitz3D Importer" width:160 height:232
(
	bitmap imgLogo "Logo" pos:[8,8] width:144 height:32 fileName:"logo.bmp"
	groupBox grpImport " import " pos:[8,56] width:144 height:168
	button cmdOpen "open..." pos:[16,80] width:128 height:24 toolTip:"open a *.b3d file..."
	checkbox chkImportTetxures "import textures" pos:[16,120] width:128 height:16 checked:true
	checkbox chkImportAnimation "import animation" pos:[16,144] width:128 height:16 checked:true
	progressBar prgState "" pos:[16,200] width:128 height:16 color:(color 30 10 190)
	checkbox chkDebugreport "debugreport" pos:[16,168] width:120 height:16 checked:false
	

	on cmdOpen pressed do
	(
		prgState.value = 0
	
		sFileName = getOpenFileName caption:"load *.b3d file" \
		                            types:"Blitz3D(*.b3d)|*.b3d|All(*.*)|*.*"

		if doesFileExist sFileName then
		(
			sFilePath   = getFilenamePath sFileName
			nFileLength = getFileSize sFileName

			nFileStream = fopen sFileName "rb"

			while nFilePos < nFileLength do
			(
				nFilePos = ftell nFileStream

				b3dChunkID     = b3dReadChunk nFileStream
				b3dChunkSize   = readLong nFileStream
				b3dChunkEndPos = nFilePos + b3dChunkSize + 8

				print b3dChunkID

				case b3dChunkID of
				(
					"BB3D": b3dReadBB3D()
					"TEXS": b3dReadTEXS()
					"BRUS": b3dReadBRUS()
					"VRTS": b3dReadVRTS()
					"TRIS": b3dReadTRIS()
					"MESH": b3dReadMESH()
					"BONE": b3dReadBONE()
					"KEYS": b3dReadKEYS()
					"ANIM": b3dReadANIM()
					"NODE": b3dReadNODE()

					default: fseek nFileStream b3dChunkEndPos #seek_set
				)
				nFilePos = ftell nFileStream
				prgState.value = nFilePos as float / nFileLength as float * 100.0
		
			)

			fclose nFileStream
			b3dOrderBones()

			maxCreateMesh()
		)
		else
		(
			print "file does not exist"
		)
	)
)
---------------------------------------------------------------------------------------



or download it directly from http://vertex.art-fx.org/B3DImporter.zip

a simple code to create a mesh with texture an boneanimation is:
utility Test "Test"
(
	button cmdStart "start" pos:[23,16] width:109 height:28

	on cmdStart pressed do
	(
		-------------------------------------------------------------------------------------
		local texture
		local textureBMP
		local textureMap

		local vertexList     = #()
		local uvwList        = #()
		local faceList       = #()
		local materialIDList = #()

		local testMesh

		local faceIndex

		local testSkin
		local bone1
		local bone2
		-------------------------------------------------------------------------------------

		-------------------------------------------------------------------------------------
		textureBMP = OpenBitmap "C:\\Eigene Dateien\\gmax\\blub.bmp"

		textureMap = bitmapTexture bitmap:textureBMP name:"Texturemap1"

		texture                = standardMaterial Name:"Texture1"
		texture.shaderType     = 1 -- blinn
		texture.diffuseMap     = textureMap

		showTextureMap texture textureMap TRUE
		-------------------------------------------------------------------------------------

		-------------------------------------------------------------------------------------
		append vertexList [-50, 0,  50] -- left  | top
		append vertexList [ 50, 0,  50] -- right | top
		append vertexList [-50, 0, -50] -- left  | bottom
		append vertexList [ 50, 0, -50] -- right | bottom

		append uvwList [0, 1, 0]  -- left  | top
		append uvwList [1, 1, 0]  -- right | top
		append uvwList [0, 0, 0]  -- left  | bottom
		append uvwList [1, 0, 0]  -- right | bottom

		append faceList [4, 2, 1]
		append faceList [1, 3, 4]

		append materialIDList 1
		append materialIDList 1

		testMesh = mesh vertices:vertexList \
				tverts:uvwList \
                                faces:faceList \
		                materialIDs:materialIDList \
                                material:texture

		
		setNormal testMesh 1 [0, -1, 0] -- to front
		setNormal testMesh 2 [0, -1, 0] -- to front
		setNormal testMesh 3 [0, -1, 0] -- to front
		setNormal testMesh 4 [0, -1, 0] -- to front

		buildTVFaces testMesh
		for faceIndex = 1 to faceList.count do
		(
			setTVFace testMesh faceIndex faceList[faceIndex]
		)
		
		meshOps.setVertexColor testMesh 1 1 (Color 255 0 0) 
		meshOps.setVertexColor testMesh 2 1 (Color 255 255 0) 
		meshOps.setVertexColor testMesh 3 1 (Color 255 0 255) 
		meshOps.setVertexColor testMesh 4 1 (Color 0 255 0) 

		update testMesh TRUE
		-------------------------------------------------------------------------------------

		-------------------------------------------------------------------------------------
		bone1 = boneSys.createBone [0, 0, -50] [0, 0,  0] [0, 0, 0]
		bone2 = boneSys.createBone [0, 0,   0] [0, 0, 50] [0, 0, 0]
		bone2.parent = bone1
		
		max modify mode
		select testMesh
		testSkin = skin()
		addModifier testMesh testSkin

		skinOps.addBone testSkin bone1 1
		skinOps.addBone testSkin bone2 1
		
		skinOps.selectBone testSkin 1
		skinOps.setVertexWeights testSkin 1 2 1
		skinOps.setVertexWeights testSkin 2 2 1
		skinOps.setVertexWeights testSkin 3 1 1
		skinOps.setVertexWeights testSkin 4 1 1
		-------------------------------------------------------------------------------------

		-------------------------------------------------------------------------------------
		frameRate = 24
		animationRange = interval 0 99

		animate on
		(
			at time 0
			(
				rotate bone2 (eulerAngles 0 0 -75)
			)

			at time 99
			(
				rotate bone2 (eulerAngles 0 0 150)
			)
		)
		-------------------------------------------------------------------------------------
	)
)


cu olli


jfk EO-11110(Posted 2004) [#2]
hehe, some ppl love max script. i never tried :)


Bob3d(Posted 2004) [#3]
Interesting.