|
@@ -0,0 +1,819 @@
|
|
|
+-------------------------------------------------------------------------------------
|
|
|
+-- ThreeJSExporter.ms
|
|
|
+-- Exports geometry from 3ds max to Three.js models in ASCII JSON format
|
|
|
+-- By alteredq / http://alteredqualia.com
|
|
|
+-------------------------------------------------------------------------------------
|
|
|
+
|
|
|
+rollout ThreeJSExporter "ThreeJSExporter"
|
|
|
+(
|
|
|
+ -- Variables
|
|
|
+
|
|
|
+ local ostream,
|
|
|
+
|
|
|
+ headerFormat = "// Converted from: %
|
|
|
+// vertices: %
|
|
|
+// normals: %
|
|
|
+// uvs: %
|
|
|
+// triangles: %
|
|
|
+// materials: %
|
|
|
+//
|
|
|
+// Generated with 3ds max ThreeJSExporter
|
|
|
+// http://github.com/alteredq/three.js/blob/master/utils/exporters/max/ThreeJSExporter.ms
|
|
|
+
|
|
|
+
|
|
|
+",
|
|
|
+
|
|
|
+ vertexFormat = "%,%,%",
|
|
|
+
|
|
|
+ vertexNormalFormat = "%,%,%",
|
|
|
+ UVFormat = "%,%",
|
|
|
+
|
|
|
+ triFormat = "%,%,%, %",
|
|
|
+ triUVFormat = "%,%,%, %, %,%,%",
|
|
|
+ triNFormat = "%,%,%, %, %,%,%",
|
|
|
+ triUVNFormat = "%,%,%, %, %,%,%, %,%,%",
|
|
|
+
|
|
|
+ footerFormat = "}\n\npostMessage( model );"
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- User interface
|
|
|
+
|
|
|
+ group "ThreeJSExporter v0.1"
|
|
|
+ (
|
|
|
+
|
|
|
+ label msg "Exports meshes in Three.js ascii JSON format" align:#left
|
|
|
+ hyperLink lab1 "Original source can be found here" address:"https://github.com/mrdoob/three.js" align:#left
|
|
|
+
|
|
|
+ checkbox flipYZ "Flip YZ" checked:true enabled:true
|
|
|
+ checkbox flipUV "Flip UV" checked:true enabled:true
|
|
|
+ checkbox flipFace "Flip faces" checked:false enabled:true
|
|
|
+ checkbox exportNormal "Export normals" checked:true enabled:true
|
|
|
+ checkbox smoothNormal "Use vertex normals" checked:true enabled:true
|
|
|
+ checkbox exportUv "Export uvs" checked:true enabled:true
|
|
|
+ checkbox exportColor "Export vertex colors" checked:false enabled:false
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ button btn_export "Export selected objects"
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Dump vertices
|
|
|
+
|
|
|
+ function DumpVertices src =
|
|
|
+ (
|
|
|
+
|
|
|
+ Format "'vertices': [" to:ostream
|
|
|
+
|
|
|
+ num = src.count
|
|
|
+
|
|
|
+ if num > 0 then
|
|
|
+ (
|
|
|
+
|
|
|
+ for i = 1 to num do
|
|
|
+ (
|
|
|
+
|
|
|
+ vert = src[i]
|
|
|
+
|
|
|
+ if flipYZ.checked then
|
|
|
+ (
|
|
|
+ x = vert.x
|
|
|
+ y = vert.z
|
|
|
+ z = vert.y
|
|
|
+
|
|
|
+ z *= -1
|
|
|
+
|
|
|
+ )
|
|
|
+ else
|
|
|
+ (
|
|
|
+
|
|
|
+ x = vert.x
|
|
|
+ y = vert.y
|
|
|
+ z = vert.z
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ Format vertexFormat x y z to:ostream
|
|
|
+
|
|
|
+ if i < num then Format ", " to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ Format "],\n\n" to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Dump normals
|
|
|
+
|
|
|
+ function DumpNormals src =
|
|
|
+ (
|
|
|
+
|
|
|
+ Format "'normals': [" to:ostream
|
|
|
+
|
|
|
+ num = src.count
|
|
|
+
|
|
|
+ if num > 0 and exportNormal.checked then
|
|
|
+ (
|
|
|
+
|
|
|
+ for i = 1 to num do
|
|
|
+ (
|
|
|
+
|
|
|
+ normal = src[i]
|
|
|
+ normal = normalize normal as point3
|
|
|
+
|
|
|
+ if flipYZ.checked then
|
|
|
+ (
|
|
|
+
|
|
|
+ x = normal.x
|
|
|
+ y = normal.z
|
|
|
+ z = normal.y
|
|
|
+
|
|
|
+ z *= -1
|
|
|
+
|
|
|
+ )
|
|
|
+ else
|
|
|
+ (
|
|
|
+
|
|
|
+ x = normal.x
|
|
|
+ y = normal.y
|
|
|
+ z = normal.z
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ Format vertexNormalFormat x y z to:ostream
|
|
|
+
|
|
|
+ if i < num then Format ", " to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ Format "],\n\n" to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Dump uvs
|
|
|
+
|
|
|
+ function DumpUvs src =
|
|
|
+ (
|
|
|
+
|
|
|
+ Format "'uvs': [" to:ostream
|
|
|
+
|
|
|
+ num = src.count
|
|
|
+
|
|
|
+ if num > 0 and exportUv.checked then
|
|
|
+ (
|
|
|
+
|
|
|
+ for i = 1 to num do
|
|
|
+ (
|
|
|
+
|
|
|
+ uvw = src[i]
|
|
|
+
|
|
|
+ u = uvw.x
|
|
|
+
|
|
|
+ if flipUV.checked then
|
|
|
+ (
|
|
|
+ v = 1 - uvw.y
|
|
|
+ )
|
|
|
+ else
|
|
|
+ (
|
|
|
+ v = uvw.y
|
|
|
+ )
|
|
|
+
|
|
|
+ Format UVFormat u v to:ostream
|
|
|
+
|
|
|
+ if i < num then Format ", " to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ Format "],\n\n" to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Dump face type
|
|
|
+
|
|
|
+ function DumpFaceType label content =
|
|
|
+ (
|
|
|
+ Format "'%': [" label to:ostream
|
|
|
+
|
|
|
+ num = content.count
|
|
|
+
|
|
|
+ if num > 0 then
|
|
|
+ (
|
|
|
+
|
|
|
+ for i = 1 to num do
|
|
|
+ (
|
|
|
+
|
|
|
+ zface = content[i]
|
|
|
+
|
|
|
+ fv = zface[1]
|
|
|
+ fuv = zface[2]
|
|
|
+ m = zface[3] - 1
|
|
|
+
|
|
|
+ needsFlip = zface[4]
|
|
|
+
|
|
|
+ hasUVs = (classof fuv == Point3)
|
|
|
+
|
|
|
+ va = (fv.x - 1) as Integer
|
|
|
+ vb = (fv.y - 1) as Integer
|
|
|
+ vc = (fv.z - 1) as Integer
|
|
|
+
|
|
|
+ if smoothNormal.checked then
|
|
|
+ (
|
|
|
+
|
|
|
+ -- normals have the same indices as vertices
|
|
|
+
|
|
|
+ na = va
|
|
|
+ nb = vb
|
|
|
+ nc = vc
|
|
|
+
|
|
|
+ )
|
|
|
+ else
|
|
|
+ (
|
|
|
+ -- normals have the same indices as faces
|
|
|
+
|
|
|
+ na = i - 1
|
|
|
+ nb = na
|
|
|
+ nc = na
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ if hasUVs then
|
|
|
+ (
|
|
|
+
|
|
|
+ ua = (fuv.x - 1) as Integer
|
|
|
+ ub = (fuv.y - 1) as Integer
|
|
|
+ uc = (fuv.z - 1) as Integer
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ if flipFace.checked or needsFlip then
|
|
|
+ (
|
|
|
+ tmp = vb
|
|
|
+ vb = vc
|
|
|
+ vc = tmp
|
|
|
+
|
|
|
+ tmp = nb
|
|
|
+ nb = nc
|
|
|
+ nc = tmp
|
|
|
+
|
|
|
+ if hasUVs then
|
|
|
+ (
|
|
|
+
|
|
|
+ tmp = ub
|
|
|
+ ub = uc
|
|
|
+ uc = tmp
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ if label == "triangles" then
|
|
|
+ (
|
|
|
+ Format triFormat va vb vc m to:ostream
|
|
|
+ )
|
|
|
+ else if label == "trianglesUvs" then
|
|
|
+ (
|
|
|
+ Format triUVFormat va vb vc m ua ub uc to:ostream
|
|
|
+ )
|
|
|
+ else if label == "trianglesNormals" then
|
|
|
+ (
|
|
|
+ Format triNFormat va vb vc m na nb nc to:ostream
|
|
|
+ )
|
|
|
+ else if label == "trianglesNormalsUvs" then
|
|
|
+ (
|
|
|
+ Format triUVNFormat va vb vc m na nb nc ua ub uc to:ostream
|
|
|
+ )
|
|
|
+
|
|
|
+ if i < num then Format ", " to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ Format "],\n\n" to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Dump faces
|
|
|
+
|
|
|
+ function DumpFaces src =
|
|
|
+ (
|
|
|
+
|
|
|
+ hasUVs = true
|
|
|
+
|
|
|
+ if exportNormal.checked and exportUv.checked and hasUVs then
|
|
|
+
|
|
|
+ triangles = #()
|
|
|
+ trianglesUvs = #()
|
|
|
+ trianglesNormals = #()
|
|
|
+ trianglesNormalsUvs = #()
|
|
|
+
|
|
|
+ quads = #()
|
|
|
+ quadsUvs = #()
|
|
|
+ quadsNormals = #()
|
|
|
+ quadsNormalsUvs = #()
|
|
|
+
|
|
|
+ num = src.count
|
|
|
+
|
|
|
+ if num > 0 then
|
|
|
+ (
|
|
|
+
|
|
|
+ for i = 1 to num do
|
|
|
+ (
|
|
|
+
|
|
|
+ zface = src[i]
|
|
|
+ fuv = zface[2]
|
|
|
+
|
|
|
+ hasUVs = (classof fuv == Point3)
|
|
|
+
|
|
|
+ if hasUVs and exportUv.checked and exportNormal.checked then
|
|
|
+ (
|
|
|
+ append trianglesNormalsUvs zface
|
|
|
+ )
|
|
|
+ else if exportNormal.checked then
|
|
|
+ (
|
|
|
+ append trianglesNormals zface
|
|
|
+ )
|
|
|
+ else if hasUVs and exportUv.checked then
|
|
|
+ (
|
|
|
+ append trianglesUvs zface
|
|
|
+ )
|
|
|
+ else
|
|
|
+ (
|
|
|
+ append triangles zface
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ DumpFaceType "triangles" triangles
|
|
|
+ DumpFaceType "trianglesUvs" trianglesUvs
|
|
|
+ DumpFaceType "trianglesNormals" trianglesNormals
|
|
|
+ DumpFaceType "trianglesNormalsUvs" trianglesNormalsUvs
|
|
|
+
|
|
|
+ DumpFaceType "quads" quads
|
|
|
+ DumpFaceType "quadsUvs" quadsUvs
|
|
|
+ DumpFaceType "quadsNormals" quadsNormals
|
|
|
+ DumpFaceType "quadsNormalsUvs" quadsNormalsUvs
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Dump color
|
|
|
+
|
|
|
+ function DumpColor pcolor label =
|
|
|
+ (
|
|
|
+ r = pcolor.r / 255
|
|
|
+ g = pcolor.g / 255
|
|
|
+ b = pcolor.b / 255
|
|
|
+
|
|
|
+ fr = formattedPrint r format:".4f"
|
|
|
+ fg = formattedPrint g format:".4f"
|
|
|
+ fb = formattedPrint b format:".4f"
|
|
|
+
|
|
|
+ Format "'%' : [%, %, %],\n" label fr fg fb to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Dump map
|
|
|
+
|
|
|
+ function DumpMap pmap label =
|
|
|
+ (
|
|
|
+
|
|
|
+ if classof pmap == BitmapTexture then
|
|
|
+ (
|
|
|
+ bm = pmap.bitmap
|
|
|
+
|
|
|
+ if bm != undefined then
|
|
|
+ (
|
|
|
+
|
|
|
+ fname = filenameFromPath bm.filename
|
|
|
+ Format "'%' : '%',\n" label fname to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Export materials
|
|
|
+
|
|
|
+ function ExportMaterials zmaterials =
|
|
|
+ (
|
|
|
+
|
|
|
+ Format "'materials': [\n" to:ostream
|
|
|
+
|
|
|
+ totalMaterials = zmaterials.count
|
|
|
+
|
|
|
+ for i = 1 to totalMaterials do
|
|
|
+ (
|
|
|
+ mat = zmaterials[i]
|
|
|
+
|
|
|
+ Format "{\n" to:ostream
|
|
|
+
|
|
|
+ -- debug
|
|
|
+
|
|
|
+ Format "'DbgIndex' : %,\n" (i-1) to:ostream
|
|
|
+ Format "'DbgName' : '%',\n" mat.name to:ostream
|
|
|
+
|
|
|
+ -- colors
|
|
|
+
|
|
|
+ DumpColor mat.diffuse "colorDiffuse"
|
|
|
+ DumpColor mat.ambient "colorAmbient"
|
|
|
+ DumpColor mat.specular "colorSpecular"
|
|
|
+
|
|
|
+ t = mat.opacity / 100
|
|
|
+ s = mat.glossiness
|
|
|
+
|
|
|
+ Format "'transparency' : %,\n" t to:ostream
|
|
|
+ Format "'specularCoef' : %,\n" s to:ostream
|
|
|
+
|
|
|
+ -- maps
|
|
|
+
|
|
|
+ DumpMap mat.diffuseMap "mapDiffuse"
|
|
|
+ DumpMap mat.ambientMap "mapAmbient"
|
|
|
+ DumpMap mat.specularMap "mapSpecular"
|
|
|
+ DumpMap mat.bumpMap "mapBump"
|
|
|
+ DumpMap mat.opacityMap "mapAlpha"
|
|
|
+
|
|
|
+ Format "}" to:ostream
|
|
|
+
|
|
|
+ if i < totalMaterials then Format "," to:ostream
|
|
|
+ Format "\n\n" to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ Format "],\n\n" to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Extract vertices from mesh
|
|
|
+
|
|
|
+ function ExtractVertices obj whereto =
|
|
|
+ (
|
|
|
+
|
|
|
+ n = obj.numVerts
|
|
|
+
|
|
|
+ for i = 1 to n do
|
|
|
+ (
|
|
|
+
|
|
|
+ v = GetVert obj i
|
|
|
+ append whereto v
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Extract normals from mesh
|
|
|
+
|
|
|
+ function ExtractNormals obj whereto =
|
|
|
+ (
|
|
|
+ if smoothNormal.checked then
|
|
|
+ (
|
|
|
+
|
|
|
+ num = obj.numVerts
|
|
|
+
|
|
|
+ for i = 1 to num do
|
|
|
+ (
|
|
|
+
|
|
|
+ n = GetNormal obj i
|
|
|
+ append whereto n
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+ else
|
|
|
+ (
|
|
|
+
|
|
|
+ num = obj.numFaces
|
|
|
+
|
|
|
+ for i = 1 to num do
|
|
|
+ (
|
|
|
+
|
|
|
+ n = GetFaceNormal obj i
|
|
|
+ append whereto n
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Extract uvs from mesh
|
|
|
+
|
|
|
+ function ExtractUvs obj whereto =
|
|
|
+ (
|
|
|
+ n = obj.numTVerts
|
|
|
+
|
|
|
+ for i = 1 to n do
|
|
|
+ (
|
|
|
+
|
|
|
+ v = GetTVert obj i
|
|
|
+ append whereto v
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Extract faces from mesh
|
|
|
+
|
|
|
+ function ExtractFaces objMesh objMaterial whereto allMaterials needsFlip offsetVert offsetUv =
|
|
|
+ (
|
|
|
+ n = objMesh.numFaces
|
|
|
+ hasUVs = objMesh.numTVerts > 0
|
|
|
+
|
|
|
+ useMultiMaterial = false
|
|
|
+ materialIDList = #()
|
|
|
+
|
|
|
+ if ( classof objMaterial ) == StandardMaterial then
|
|
|
+ (
|
|
|
+ fm = findItem allMaterials objMaterial
|
|
|
+ )
|
|
|
+ else
|
|
|
+ (
|
|
|
+ useMultiMaterial = true
|
|
|
+
|
|
|
+ for i = 1 to n do
|
|
|
+ (
|
|
|
+ mID = GetFaceMatID objMesh i
|
|
|
+ materialIndex = findItem objMaterial.materialIDList mID
|
|
|
+ subMaterial = objMaterial.materialList[materialIndex]
|
|
|
+
|
|
|
+ mMergedIndex = findItem allMaterials subMaterial
|
|
|
+ if mMergedIndex > 0 then
|
|
|
+ (
|
|
|
+ materialIDList[mID] = mMergedIndex
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ for i = 1 to n do
|
|
|
+ (
|
|
|
+
|
|
|
+ zface = #()
|
|
|
+
|
|
|
+ fv = GetFace objMesh i
|
|
|
+
|
|
|
+ fv.x += offsetVert
|
|
|
+ fv.y += offsetVert
|
|
|
+ fv.z += offsetVert
|
|
|
+
|
|
|
+ if useMultiMaterial then
|
|
|
+ (
|
|
|
+ mID = GetFaceMatID objMesh i
|
|
|
+ fm = materialIDList[mID]
|
|
|
+ )
|
|
|
+
|
|
|
+ if hasUVs then
|
|
|
+ (
|
|
|
+
|
|
|
+ fuv = GetTVFace objMesh i
|
|
|
+
|
|
|
+ fuv.x += offsetUv
|
|
|
+ fuv.y += offsetUv
|
|
|
+ fuv.z += offsetUv
|
|
|
+
|
|
|
+ )
|
|
|
+ else
|
|
|
+ (
|
|
|
+ fuv = false
|
|
|
+ )
|
|
|
+
|
|
|
+ append zface fv
|
|
|
+ append zface fuv
|
|
|
+ append zface fm
|
|
|
+ append zface needsFlip
|
|
|
+
|
|
|
+ append whereto zface
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Extract materials from eventual multimaterial
|
|
|
+
|
|
|
+ function ExtractMaterials objMesh objMaterial whereto =
|
|
|
+ (
|
|
|
+
|
|
|
+ materialClass = classof objMaterial
|
|
|
+
|
|
|
+ if materialClass == StandardMaterial then
|
|
|
+ (
|
|
|
+ if ( findItem whereto objMaterial ) == 0 then
|
|
|
+ (
|
|
|
+ append whereto objMaterial
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+ else if materialClass == MultiMaterial then
|
|
|
+ (
|
|
|
+
|
|
|
+ n = objMesh.numFaces
|
|
|
+
|
|
|
+ for i = 1 to n do
|
|
|
+ (
|
|
|
+
|
|
|
+ mID = getFaceMatId objMesh i
|
|
|
+ materialIndex = findItem objMaterial.materialIDList mID
|
|
|
+ subMaterial = objMaterial.materialList[materialIndex]
|
|
|
+
|
|
|
+ if ( findItem whereto subMaterial ) == 0 then
|
|
|
+ (
|
|
|
+ append whereto subMaterial
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Hack to figure out if normals are messed up
|
|
|
+
|
|
|
+ function NeedsFaceFlip node =
|
|
|
+ (
|
|
|
+ needsFlip = false
|
|
|
+
|
|
|
+ local tmp = Snapshot node
|
|
|
+
|
|
|
+ face_normal = normalize ( getfacenormal tmp 1 )
|
|
|
+
|
|
|
+ face = getface tmp 1
|
|
|
+
|
|
|
+ va = getvert tmp face[1]
|
|
|
+ vb = getvert tmp face[2]
|
|
|
+ vc = getvert tmp face[3]
|
|
|
+
|
|
|
+ computed_normal = normalize ( cross (vc - vb) (va - vb) )
|
|
|
+
|
|
|
+ if distance computed_normal face_normal > 0.1 then needsFlip = true
|
|
|
+
|
|
|
+ delete tmp
|
|
|
+
|
|
|
+ return needsFlip
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Extract only things that either already are or can be converted to meshes
|
|
|
+
|
|
|
+ function ExtractMesh node =
|
|
|
+ (
|
|
|
+
|
|
|
+ if SuperClassOf node == GeometryClass then
|
|
|
+ (
|
|
|
+ return #( SnapshotAsMesh node, node.name, node.material, NeedsFaceFlip node )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -- Not geometry ... could be a camera, light, etc.
|
|
|
+
|
|
|
+ return #( false, node.name, 0 )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Export scene
|
|
|
+
|
|
|
+ function ExportScene =
|
|
|
+ (
|
|
|
+
|
|
|
+ -- Extract meshes
|
|
|
+
|
|
|
+ meshObjects = #()
|
|
|
+
|
|
|
+ mergedVertices = #()
|
|
|
+ mergedNormals = #()
|
|
|
+ mergedUvs = #()
|
|
|
+ mergedFaces = #()
|
|
|
+ mergedMaterials = #()
|
|
|
+
|
|
|
+ for obj in selection do
|
|
|
+ (
|
|
|
+
|
|
|
+ result = ExtractMesh obj
|
|
|
+
|
|
|
+ meshObj = result[1]
|
|
|
+ meshName = result[2]
|
|
|
+ meshMaterial = result[3]
|
|
|
+ needsFlip = result[4]
|
|
|
+
|
|
|
+ if ClassOf meshObj == TriMesh then
|
|
|
+ (
|
|
|
+
|
|
|
+ append meshObjects result
|
|
|
+
|
|
|
+ ExtractMaterials meshObj meshMaterial mergedMaterials
|
|
|
+
|
|
|
+ ExtractVertices meshObj mergedVertices
|
|
|
+ ExtractNormals meshObj mergedNormals
|
|
|
+ ExtractUvs meshObj mergedUvs
|
|
|
+
|
|
|
+ --ExtractFaces meshObj zmaterial mergedFaces mergedVertices.count mergedUvs.count
|
|
|
+ ExtractFaces meshObj meshMaterial mergedFaces mergedMaterials needsFlip 0 0
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ totalVertices = mergedVertices.count
|
|
|
+ totalNormals = mergedNormals.count
|
|
|
+ totalUvs = mergedUvs.count
|
|
|
+ totalFaces = mergedFaces.count
|
|
|
+ totalMaterials = sceneMaterials.count
|
|
|
+
|
|
|
+ -- Dump header
|
|
|
+
|
|
|
+ Format headerFormat maxFileName totalVertices totalNormals totalUvs totalFaces totalMaterials to:ostream
|
|
|
+
|
|
|
+
|
|
|
+ Format "// Source objects:\n\n" to:ostream
|
|
|
+
|
|
|
+ i = 0
|
|
|
+
|
|
|
+ for obj in meshObjects do
|
|
|
+ (
|
|
|
+
|
|
|
+ meshName = obj[2]
|
|
|
+ Format "// %: %\n" i meshName to:ostream
|
|
|
+ i += 1
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+ Format "\n\nvar model = {\n\n" to:ostream
|
|
|
+
|
|
|
+ -- Dump all materials in the scene
|
|
|
+
|
|
|
+ ExportMaterials mergedMaterials
|
|
|
+
|
|
|
+ -- Dump merged data from all selected geometries
|
|
|
+
|
|
|
+ DumpVertices mergedVertices
|
|
|
+ DumpNormals mergedNormals
|
|
|
+ DumpUvs mergedUvs
|
|
|
+ DumpFaces mergedFaces
|
|
|
+
|
|
|
+ -- Dump footer
|
|
|
+
|
|
|
+ Format footerFormat to:ostream
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Open and prepare a file handle for writing
|
|
|
+
|
|
|
+ function GetSaveFileStream =
|
|
|
+ (
|
|
|
+ zname = getFilenameFile maxFileName
|
|
|
+ zname += ".js"
|
|
|
+
|
|
|
+ fname = GetSaveFileName filename:zname types:"JavaScript file (*.js)|*.js|All Files(*.*)|*.*|"
|
|
|
+ if fname == undefined then
|
|
|
+ return undefined
|
|
|
+
|
|
|
+ ostream = CreateFile fname
|
|
|
+ if ostream == undefined then
|
|
|
+ (
|
|
|
+ MessageBox "Couldn't open file for writing !"
|
|
|
+ return undefined
|
|
|
+ )
|
|
|
+
|
|
|
+ return ostream
|
|
|
+ )
|
|
|
+
|
|
|
+ -------------------------------------------------------------------------------------
|
|
|
+ -- Export button click handler
|
|
|
+
|
|
|
+ on btn_export pressed do
|
|
|
+ (
|
|
|
+ ostream = GetSaveFileStream()
|
|
|
+ if ostream != undefined then
|
|
|
+ (
|
|
|
+ ExportScene()
|
|
|
+ close ostream
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+)
|
|
|
+createDialog ThreeJSExporter width:300
|