Here it is, if anyone wants to export the materials in Max 2009, many, many years later, when all download links are dead.
(doublepost due to char limit)
function StringRead f =(
s = ""
len = readshort f
for i = 0 to len - 1 do (
n = readbyte f
s += bit.intAsChar n
)
return s
)
FormatVer = 0
struct g3d_header (
Sign = "", --: array[0..7]of char; // "B3D 1.1 "
Unknown1 = 0, --: byte;
Unknown2 = 0, --: byte;
Unknown3 = 0, --: byte; //Header ID??
GlobalScaleFactor= 0.0, --: single;
Unknown4 = 0, --: byte; //Header ID??
CoordinateScale = 0.0, --: single;
Unknown5 = 0, --: byte; //Header ID??
CoordinateSystem = "", --: TCharArray;
Unknown6 = 0, --: byte;
Unknown7 = 0, --: longword;
function ReadFromFile f =
(
for i = 0 to 7 do (
n = readbyte f
Sign += bit.intAsChar n
)
Unknown2 = readbyte f
if Unknown2 == 3 then ( print "a"; FormatVer = 1; for i = 1 to 2 do readbyte f )
else ( for i = 1 to 4 do readbyte f )
GlobalScaleFactor = readfloat f
CoordinateScale = readfloat f
CoordinateSystem = StringRead f
Unknown6 = readbyte f; Unknown7 = readlong f
)
)
Model_Vertex_Position = #()
Model_Vertex_Texcoords = #()
Model_Vertex_Normal = #()
Model_Faces_Index = #()
Model_Faces_Mats = #()
Txs = #()
TexturesDir = ""
Vertex_Type_Flag = 0
Bones_Flag = 0
FS = 0
Zone_Flag = 0;
struct TVertex64 (
Coordinate = Point3 0.0 0.0 0.0, --: array[0..2]of single;
Normal = Point3 0.0 0.0 0.0, --: array[0..2]of single;
Color = Point4 0.0 0.0 0.0 0.0, --: array[0..3]of single;
Unknown1 = Point2 0.0 0.0, --: array[0..1]of single;
Unknown2 = Point3 0.0 0.0 0.0, --: array[0..1]of single;
Unknown3 = Point2 0.0 0.0, --: array[0..1]of single;
function ReadFromFile f = (
Coordinate.x = readfloat f; Coordinate.z = readfloat f; Coordinate.y = readfloat f
Model_Vertex_Position[Model_Vertex_Position.count + 1] = Coordinate
Model_Vertex_Texcoords[Model_Vertex_Texcoords.count +1] = Unknown2
Normal.x = readfloat f; Normal.y = readfloat f; Normal.z = readfloat f
Model_Vertex_Normal[Model_Vertex_Normal.count + 1] = Normal
Color.x = readfloat f; Color.y = readfloat f; Color.z = readfloat f; Color.w = readfloat f
--TexCoords
Unknown1.x = readlong f
for i = 1 to Unknown1.x do
(
if i==1 then
(
Unknown2.x = readfloat f
Unknown2.y = 1 - readfloat f
Model_Vertex_Texcoords[Model_Vertex_Position.count] = Unknown2
)
else
(
readfloat f
readfloat f
)
)
Unknown1.x = readlong f
for i = 1 to Unknown1.x do (readfloat f; readfloat f;)
)
)
struct TVertex44 (
Coordinate = Point3 0.0 0.0 0.0, -- Eii?aeiaoa oi?ee (x, y, z: single)
Normal = Point3 0.0 0.0 0.0, -- Ii?iaeu oi?ee (x, y, z: single)
Color = #(0, 0, 0, 0), -- Oaao oi?ee (r, g, b, a: byte)
TextureCoord = Point3 0.0 0.0 0.0, -- Oaenoo?iua eii?aeiaou (s, t: single);
Unknown1 = #(), -- Iaecaanoii
function ReadFromFile f = (
Coordinate.x = readfloat f; Coordinate.z = readfloat f; Coordinate.y = readfloat f
Model_Vertex_Position[Model_Vertex_Position.count + 1] = Coordinate
Normal.x = readfloat f; Normal.y = readfloat f; Normal.z = readfloat f
Model_Vertex_Normal[Model_Vertex_Normal.count + 1] = Normal
for i = 1 to 4 do Color[i] = readbyte f
TextureCoord.x = readfloat f; TextureCoord.y = 1 - readfloat f
Model_Vertex_Texcoords[Model_Vertex_Texcoords.count + 1] = TextureCoord
Unknown1[1] = readlong f; Unknown1[2] = readlong f
)
)
struct TVert_Bones_Data (
Bone = 0, --: longword
Weight = 0.0, --: single
function ReadFromFile f = (
Bone = readlong f
Weight = readfloat f
)
)
struct TMaterial_Data44 (
Name = "",
Mtl_ID = "",
Unknown1 = 0.0,
BLEND_STATE = "",
MATERIAL_TYPE = "",
Unknown2 = 0,
Zone = "",
Unknown3 = 0,
function ReadFromFile f = (
Name = StringRead f; Mtl_ID = StringRead f
for i = 0 to 16 do Unknown1 = readfloat f
BLEND_STATE = StringRead f; MATERIAL_TYPE = StringRead f
a = readlong f; print a
for i = 1 to 16 do ( Unknown2 = readlong f; if Unknown2 == 1 then
(
Zone = StringRead f;
tm = bitmaptexture()
tm.alphasource = 2
tm.filename = TexturesDir + Zone
Txs[Txs.count + 1] = standardMaterial diffuseMap:tm showInViewport:true
Unknown2 = readlong f;
for i = 1 to Unknown2 do StringRead f;
exit;
)
)
)
)
struct TMaterial_Data (
Name = "", --: TCharArray;
Mtl_ID = "", --: TCharArray;
Unknown1 = 0.0, --: array[0..16]of single; //Most likely Ambient, Diffuse, Emissive, Specular, Shininess, and Alpha
BLEND_STATE = "", --: TCharArray;
MATERIAL_TYPE = "", --: TCharArray;
Unknown2 = 0, --: array[0..63]of byte; //Flags??
Zone = "", --: TCharArray;
Unknown3 = 0, --: longword;
function ReadFromFile f = (
Unknown3 = readlong f
Name = StringRead f
a = readlong f; for i = 1 to a do Mtl_ID = StringRead f
tm = bitmaptexture()
tm.alphasource = 2
if Mtl_ID != "" then tm.filename = TexturesDir + Mtl_ID
Txs[Txs.count + 1] = standardMaterial diffuseMap:tm showInViewport:true
local kk = 0
readbyte f; readlong f; kk = readlong f; print kk
for i = 1 to kk/3 do (
a = 0; a = readlong f
b = 0; b = readlong f
c = 0; c = readlong f
a = a + 1; b = b + 1; c = c + 1;
Model_Faces_Index[Model_Faces_Index.count + 1] = [b, a, c]
Model_Faces_Mats[Model_Faces_Mats.count + 1] = Txs.count ;
)
for i = 1 to kk do (Unknown2 = readbyte f)
)
)
struct TVertex_Node (
Unknown1 = 0,
Unknown2 = 0,
VertexTypeFlag = 0,
NumberVerts = 0,
SizeOfVerts = 0,
Unknown3 = #(),
IsBones = 0,
BonesPerVert = 0,
NumberMaterial = 0,
function ReadFromFile f = (
Unknown1 = readbyte f;
Unknown2 = readbyte f;
format "VertNode U1 % U2 %\n" Unknown1 Unknown2;
if FormatVer == 0 then
(
VertexTypeFlag = readbyte f;
Vertex_Type_Flag = VertexTypeFlag
)
else Vertex_Type_Flag = 0
NumberVerts = readlong f;
format "Vertex count - %\n" NumberVerts
format "Vertex_Type_Flag - %\n" Vertex_Type_Flag
if Vertex_Type_Flag == 1 then (
SizeOfVerts = readlong f;
format "SizeOfVerts - %\n" SizeOfVerts
for i = 1 to NumberVerts do (Vertex44 = TVertex44(); Vertex44.ReadFromFile f)
for i = 1 to 6 do (Unknown3[i] = readfloat f); IsBones = readbyte f
if IsBones == 1 then
(
BonesPerVert = readlong f
format "BonesPerVert - %\n" BonesPerVert
for i = 1 to NumberVerts * BonesPerVert do (VBD = TVert_Bones_Data(); VBD.ReadFromFile f;)
)
NumberMaterial = readlong f
format "NumberMaterial - %\n" NumberMaterial
for i = 1 to NumberMaterial do (MD = TMaterial_Data44(); MD.ReadFromFile f; print MD)
--for i = 1 to NumberMaterial do (
-- Zone = ""; S = ""
-- for j = 1 to Zone_Flag + 1 do (
-- S = StringRead f; Zone += S
-- )
-- print Zone
-- pos = ftell f; print Pos
--)
--StringRead f
for i = 1 to NumberMaterial do (StringRead f)
--StringRead f
Mat_list = #()
NumVert = 0; NumTri = 0
for i = 1 to NumberMaterial do (a = readlong f; Mat_list[Mat_list.count+1] = a )
for i = 1 to NumberMaterial do (a = readlong f; NumVert +=a; )
print "NumVert"; print NumVert; print "NumTri"; print NumTri;
NumTri = NumTri / 3;
for j = 1 to NumberMaterial do (
for i = 1 to (Mat_list[j]/3) do (
a = 0; a = readshort f #unsigned;
b = 0; b = readshort f #unsigned;
c = 0; c = readshort f #unsigned;
a = a + 1; b = b + 1; c = c + 1;
Model_Faces_Index[Model_Faces_Index.count + 1] = [c, b, a];
Model_Faces_Mats[Model_Faces_Mats.count + 1] = j;
--print Model_Faces_Index[Model_Faces_Index.count]
))
--k = readlong f;
--for i = 1 to k do ( l = StringRead f; print l; )
) else (
for i = 1 to NumberVerts do (Vertex64 = TVertex64(); Vertex64.ReadFromFile f)
pos = ftell f; print pos
NumberMaterial = readlong f
format "NumberMaterial - %\n" NumberMaterial
for i = 1 to NumberMaterial do (MD = TMaterial_Data(); MD.ReadFromFile f; print MD)
--k = readlong f;
--for i = 1 to k do ( l = StringRead f; print l; )
)
-- Print Model_Vertex_Position
)
)
struct TBone (
Name = "",
Unknown1 = 0, --: word;
Flag = 0, --: byte; //Header ID?? For "Transform"
Translation = point3 0.0 0.0 0.0, --: array[0..2]of single;
Rotation = quat 0.0 0.0 0.0 0.0, --: array[0..3]of single;
function ReadFromFile f = (
Name = StringRead f; Unknown1 = readshort f; Flag = readbyte f
if Flag != 0 then
(
Translation.x = readfloat f; Translation.z = readfloat f; Translation.y = readfloat f;
if Flag == 3 then (Rotation.x = readfloat f; Rotation.z = readfloat f; Rotation.y = readfloat f; Rotation.w = readfloat f)
if Flag == 2 then readfloat f
)
)
)
struct TColor (
r = 0, g = 0, b = 0, a = 0,
function ReadFromFile f = (r = readfloat f; g = readfloat f; b = readfloat f; a = readfloat f
)
)
struct TMater (
Ambient = TColor(),
Diffuse = TColor(),
Emissive = TColor(),
Specular = TColor(),
Shininess = 0,
Alpha = 0,
function ReadFromFile f = (
Ambient.ReadFromFile f; Diffuse.ReadFromFile f
Emissive.ReadFromFile f; Specular.ReadFromFile f
Shininess = readfloat f; Alpha = readfloat f
)
)
struct TMaterials (
Mtl_ID = "",
Name = "",
Mater = TMater(),
BLEND_STATE = "",
MATERIAL_TYPE = "",
Flag_1 = 0,
Flag_2 = 0,
function ReadFromFile f = (
Mtl_ID = StringRead f; Name = StringRead f
Mater.ReadFromFile f
BLEND_STATE = StringRead f; MATERIAL_TYPE = StringRead f
Flag_1 = readlong f; Flag_2 = readlong f
)
)
struct TTextures (
Unknown1 = 0, --: byte;
Name = "", --: TCharArray;
FileName = "", --: TCharArray;
Width = 0, --: longword;
Height = 0, --: longword;
function ReadFromFile f = (
Unknown1 = readbyte f; Name = StringRead f; FileName = StringRead f
Width = readlong f; Height = readlong f
)
)
struct TNodes (
Unknown1 = 0, --: byte;
Name = "", --: TCharArray;
function ReadFromFile f = (
Unknown1 = readbyte f; Name = StringRead f
)
)
struct TMat_Data (
Unknown1 = 0, --: array[0..2]of byte;
Name = "", --: TCharArray;
TextureOn = 0, --: longword;
Texture = "", --: TCharArray;
Unknown3 = 0, --: longword;
Unknown4 = 0, --: byte;
NumOfPoints = 0, --: longword;
function ReadFromFile f = (
for i = 0 to 2 do (Unknown1 = readbyte f)
Name = StringRead f
print Name
TextureOn = readlong f
if TextureOn != 0 then Texture = StringRead f
Unknown3 = readlong f
Unknown4 = readbyte f
NumOfPoints = readlong f
print NumOfPoints
)
)
-- Points : array of longword;
-- MatID : array of byte;
struct TMaterial_Node (
NumberMaterialNodes = 0, --: longword;
Unknown1 = 0, --: byte;
function ReadFromFile f = (
NumberMaterialNodes = readlong f
Unknown4 = readbyte f
format "MaterialNode - NumberMaterialNodes = %d\n" NumberMaterialNodes
)
-- Mat_Data : array of TMat_Data;
)
function FileSizeGet f = (
fseek f 0 #seek_end
size = ftell f
return size
)
function FilePosGet f = (
pos = ftell f
return pos
)
function main f asmooth dir = (
print f
TexturesDir = dir
local FileSize = 0
local FilePos = 0
FileSize = FileSizeGet f
FS = FileSize
fseek f 0 #seek_set
g3d_head = g3d_header(); g3d_head.ReadFromFile f; print "head"; print g3d_head; print "head_end"
Material_Node = TMaterial_Node()
do (
b = 0; b = readbyte f
case b of (
0x07: (Materials = TMaterials(); Materials.ReadFromFile f; print "Materials"; print Materials; pos = ftell f; print pos)
0x08: (Textures = TTextures(); Textures.ReadFromFile f; print "Textures"; print Textures; pos = ftell f; print pos)
0x0A: (Nodes = TNodes(); Nodes.ReadFromFile f; print "Nodes"; print Nodes; pos = ftell f; print pos)
0x0E: (Bones_Flag = 1; Bone1 = TBone(); Bone1.ReadFromFile f; print "Bones"; print Bone1; pos = ftell f; print pos)
0x0F: (Vertex_Node = TVertex_Node(); Vertex_Node.ReadFromFile f; print "VertexNodes"; pos = ftell f; print pos)
default: exit
)
FilePos = FilePosGet f
)
while FilePos != FileSize
print (FilePosGet f);
local obj
obj = Editable_Mesh()
obj.material = multimaterial numsubs:Txs.count
print "tx count"; print Txs.count
for i = 1 to Txs.count do
(
obj.material.materialList[i] = Txs[i]
meditMaterials[i] = Txs[i]
)
obj.mesh.numverts = Model_Vertex_Position.count
obj.mesh.numfaces = Model_Faces_Index.count
obj.mesh.numtverts = Model_Vertex_Position.count
format "tx count %\n" Model_Vertex_Texcoords.count
format "vert count %\n" Model_Vertex_Position.count
format "faces count %\n" Model_Faces_Index.count
for i = 1 to obj.mesh.numverts do
SetVert obj.mesh i Model_Vertex_Position[i]
for i = 1 to obj.mesh.numfaces do
SetFace obj.mesh i Model_Faces_Index[i]
for i = 1 to obj.mesh.numtverts do
SetTVert obj.mesh i Model_Vertex_Texcoords[i]
buildTVFaces obj.mesh false
for i = 1 to obj.mesh.numfaces do
(
setTVFace obj.mesh i Model_Faces_Index[i]
setFaceMatID obj.mesh i Model_Faces_Mats[i]
)
meshop.weldVertsByThreshold obj.mesh #{1..obj.mesh.numverts} 0.001
meshop.autoSmooth obj.mesh #{1..obj.mesh.numfaces} asmooth
addmodifier obj (Unwrap_UVW())
update obj
)
m_roll=newrolloutfloater "G3D Importer" 400 130
rollout G3DImport "G3D Import" width:400 height:104
(
edittext filename "File:" pos:[8,8] width:312 height:17
button OpenBtn "Open" pos:[326,7] width:56 height:21 enabled:true
button ImportBtn "Import" pos:[8,72] width:80 height:21
spinner asmooth "Auto Smooth: " pos:[32,39] width:160 height:16 range:[0,180,0] scale:0.1
on G3DImport open do
(
ASmooth.value = 45.0
)
on OpenBtn pressed do
(
s = GetOpenFileName types:"G3D file(*.g3d)|*.g3d" historyCategory:"G3DImports"
if s != undefined do
(
filename.text = s
)
)
on ImportBtn pressed do
(
if FileName.text != "" do
(
main (fopen FileName.text "rb") ASmooth.value (getFilenamePath FileName.text)
fclose FileName
closeRolloutFloater m_roll
)
)
)
addrollout G3DImport m_roll