home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Unreal Tools
/
UnrealTools.iso
/
ASEExport4Unreal.zip
/
ASEExport4Unreal.lua
Wrap
Text File
|
2007-11-15
|
26KB
|
599 lines
-- lua
---------------------------------------
-- UnrealASE Exporter for Modo v1.04 -
---------------------------------------
-- AUTHOR: Zoltan Erdokovy (zoltan.erdokovy@gmail.com)
--
--
-- This script saves the selected layer and its child layers into an ASE file.
-- IMPORTANT: This exporter exports ONLY the Unreal relevant parts of the ASE format!
-- So you probably can't use it to transfer objects to application other than UnrealEd.
-- Although DeepExploration shows the objects properly.
--
-- USAGE:
-- The objects will be exported to the "objectdir" directory, located in the "content directory".
-- The "objectdir" variable can be changed bellow, the content dir can be set in the preferences window.
-- The name of the exported file will be the name of the selected layer.
-- It exports the first selected layer and any kids it has. (Child layers don't have to be selected.)
-- The children layers should contain the collision primitives, with the proper name. (MCDSP/MCDCX for UT2k4 and UCX/USP for U3)
-- The exporter exports the following vertex maps:
-- UV called "UV1"
-- UV called "UV2"
-- UV called "UV3"
-- RGB map called "Color"
-- If no vertexmap found with these names, then it assigns 0,0,0 automatically.
-- Set all your materials to a 89 degrees smoothing and use the separated polygon technique to achieve
-- proper shading. Unreal disregards smoothinggroup ID >32, so this exporter reuses the 0-32 range. Sometimes
-- this results in smoothing together otherwise independent, neighbouring poly islands. To fix this just cut and
-- paste one of them to change the order of the polygons.
-- Sometimes smoothing groups are not exported properly. A re-export after restarting modo will fix it.
--
-- You can set what unit in modo you want to be 1 unit in unreal. Check out the "UnitSystem" variable bellow.
-- I recommend using gameunits, but you can use a few other units, the object will be scaled properly.
--
-- Known issues:
-- You have to edit the parameters in the script. It would need too many arguments to define all aspects
-- of the export, I think. But if you want this changed, just drop me a mail.
--
-- If you find a bug or have a feature requests don't hesitate to contact me. :)
--
--
-- Changes in v1.04:
--
-- - Fixed smoothing group numbering.
-- - Fixed errors when something was selected.
-- - Fixed default value for content dir.
--
--
-- Changes in v1.03:
--
-- - Fixed precision when scaling from game units.
-- - Fixed export when no partname is assigned to polys.
-- - Fixed smoothing group generation.
-- - 3 UV support.
--
--
-- Changes in v1.02:
--
-- - Fixed quad/ngon handling, fixed discontinuos UVs.
--
--
-- Changes in v1.01:
--
-- - Fixed object rotation.
-- - Added scale factors when using different unit systems.
version = "v1.04"
contentdir = "c:"
objectdir = "/!Export" -- The proper directory to store exported objects.
UnitSystem = "METER" -- Set what you want to be 1 unreal unit:
-- "GAMEUNIT", "METER", "MILLIMETER", "FEET", "INCH".
TempFileName = "temp.lxo" -- The temp file's name.
bSaveTempFile = false -- If true it saves the temporary scene to a file, next to the exported files.
-----------------------------
UV1Name = "UV1"
UV2Name = "UV2"
UV3Name = "UV3"
VColName = "Color"
-- --
-- FORMATNUM --
-- --
function FormatNum (Num)
return (string.format("%.4f", Num))
end
-- --
-- ASSIGNSGROUPS --
-- --
function AssignSGroups ()
SGroup = 0 -- The actual smoothing group.
--lx("select.drop polygon")
for i = 0, FaceNum-1 do
SelectLayer(1)
if FaceSGroups[i] == nil then -- If we have no stored smg...
lx("select.element [1] polygon add ["..i.."]") -- Select face #i on the first layer.
lx("select.connect") -- Select connected faces.
--lxq("query layerservice layer.name ? 1")
ActSel = lxq("query layerservice polys ? selected") -- We get back the array of indexes of selected polys.
ActSelSize = table.getn(ActSel) -- Get the number of selected polys.
for j = 1, ActSelSize do -- Go through all selected polys.
if FaceSGroups[tonumber(ActSel[j])] == nil then -- If we have no stored data there...
FaceSGroups[tonumber(ActSel[j])] = SGroup -- We set the smg.
end
--lxout("tonumber(ActSel[j]) == "..tonumber(ActSel[j]))
end
--lx("select.drop polygon") -- Deselect everything.
SGroup = SGroup+1 -- Increase the smg number.
if SGroup == 33 then SGroup = 0 end -- If we have reached the 32 SMG limit then we start over.
else
end
end
end
-- --
-- GETFACEPOINTS --
-- --
function GetFacePoints (FaceIndex)
p = lxq("query layerservice poly.vertList ? "..FaceIndex)
return ({p[1],p[2],p[3]})
end
-- --
-- GETPOINTPOSITION --
-- --
function GetPointPosition (PointIndex)
p = lxq("query layerservice vert.pos ? "..PointIndex) -- Getting original coordinates.
-- Rotating the object so it will be in the proper position in UEd. --
p = {p[1], p[3], -p[2]} -- X,Z,-Y = 90 around Unreal X
p = {-p[1], p[2], -p[3]} -- -X,Y,-Z = 180 around Unreal Y
p = {-p[2], p[1], p[3]} -- -Y,X,Z = 90 around Unreal Z
p = {p[1]*UnitScale, p[2]*UnitScale, p[3]*UnitScale} -- Scale properly.
return ({FormatNum(p[1]),FormatNum(p[2]),FormatNum(p[3])})
end
-- --
-- UVSETEXISTS --
-- --
function UVSetExists (TargetUVName)
lxq("query layerservice vmap_groups ? all")
VmapNum = lxq("query layerservice vmap.n ? all")[1]
for i = 0, VmapNum-1 do
ActVmapType = lxq("query layerservice vmap.type ? "..i)[1]
ActVmapName = lxq("query layerservice vmap.name ? "..i)[1]
if ( ActVmapType == "texture") and ( ActVmapName == TargetUVName) then
return(true)
end
end
return(false)
end
-- --
-- GETPOINTUV --
-- --
function GetPointUV (PointIndex, TargetUVName)
lxq("query layerservice vmap_groups ? all")
VmapNum = lxq("query layerservice vmap.n ? all")[1]
for i = 0, VmapNum-1 do
ActVmapType = lxq("query layerservice vmap.type ? "..i)[1]
ActVmapName = lxq("query layerservice vmap.name ? "..i)[1]
if ( ActVmapType == "texture") and ( ActVmapName == TargetUVName) then
p = lxq("query layerservice vert.vmapValue ? "..PointIndex)
--if p == ("query layerservice vert.vmapValue ? "..PointIndex) then -- !!! WORKAROUND !!!
-- p = nil -- If the point has no value on a vmap
--end -- then the query should give back nil,
-- but now it gives back the query itself.
-- If the bug gets squashed, this 3 lines
-- can be removed.
if p == nil then p = {"0.0000","0.0000"} end -- Failsafe if a vertex doesn't have a UV value.
end
end
return ({FormatNum(p[1]),FormatNum(p[2])})
end
-- --
-- GETPOINTCOLOR --
-- --
function GetPointColor (PointIndex)
p = {"0.0000","0.0000","0.0000"}
lxq("query layerservice vmap_groups ? all")
for i = 0, (lxq("query layerservice vmap.n ? all")[1])-1 do
ActVmapType = lxq("query layerservice vmap.type ? "..i)[1]
ActVmapName = lxq("query layerservice vmap.name ? "..i)[1]
if ( ActVmapType == "rgb") and ( ActVmapName == VColName) then
p = lxq("query layerservice vert.vmapValue ? "..PointIndex)
--if p == ("query layerservice vert.vmapValue ? "..PointIndex) then -- !!! WORKAROUND !!!
-- p = nil -- If the point has no value on a vmap
--end -- then the query should give back nil,
-- but now it gives back the query itself.
-- If the bug gets squashed, this 3 lines
-- can be removed.
if p == nil then p = {"1.0000","1.0000","1.0000"} end -- Failsafe if a vertex doesn't have a color value.
end
end
return ({FormatNum(p[1]),FormatNum(p[2]),FormatNum(p[3])})
end
-- --
-- GETFACENORMAL --
-- --
function GetFaceNormal (FaceIndex)
p = lxq("query layerservice poly.normal ? "..FaceIndex)
return ({FormatNum(p[1]),FormatNum(p[2]),FormatNum(p[3])})
end
-- --
-- GETPOINTNORMAL --
-- --
function GetPointNormal (PointIndex)
p = lxq("query layerservice vert.normal ? "..PointIndex)
return ({FormatNum(p[1]),FormatNum(p[2]),FormatNum(p[3])})
end
-- --
-- GETFACEMATERIALID --
-- --
function GetFaceMaterialID (FaceIndex)
m = lxq("query layerservice poly.material ? "..FaceIndex)[1] -- It gives back a material name, but we need an index.
for i = 0, (MaterialNum-1) do -- Iterating through the materials.
if MaterialNames[i+1] == m then
MaterialID = i
end
end
return (MaterialID) -- And return with the proper material index.
end
-- --
-- SELECTLAYER --
-- --
function SelectLayer (LayerIndex)
lx("select.layer "..LayerIndex.." set") -- Let's make absolutely damn sure...
lxq("query layerservice layer.name ? "..LayerIndex) -- ...that we have the given layer selected...
lxq("query layerservice layer.index ? fg") -- ... in every possible way.
end
-- --
-- MAIN --
-- --
lxout("------- ASE conversion started. -------")
lxout("("..version..")")
StartTime = os.time()
MainLayer = 0 -- The index of the main layer.
MainLayerName = "" -- The name of the main layer.
ActLayer = 8 -- The index of the layer we are working on.
ChildrenNum = 0 -- The number of children.
ChildrenLayers = {} -- Array for indices of child layers.
ChildrenNames = {} -- Array for names of child layers.
Layers = {} -- The indices of all relevant layers: main layer + any children.
LayerNames = {} -- The names of all relevant layers: main layer + any children.
LayerNum = 0 -- The number of all relevant layers.
MaterialNum = 0 -- The number of materials.
MaterialNames = {} -- Array for material names.
FacePoints = {} -- Array for the point indices of a face.
FaceSGroups = {} -- Array of numbers, one for each face, representing smoothing groups.
Pos = {} -- Array for point positions in both 3D and UV space.
ProcFaceNum = 0 -- The total number of processed faces.
-- Determining scale factor for different unit systems --
if UnitSystem == "GAMEUNIT" then UnitScale = 53.3333
elseif UnitSystem == "METER" then UnitScale = 1
elseif UnitSystem == "MILLIMETER" then UnitScale = 1000
elseif UnitSystem == "FEET" then UnitScale = 3.2808398950131
elseif UnitSystem == "INCH" then UnitScale = 39.3700787
else UnitScale = 1 end
-- Dropping every selection --
--lx("select.drop vertex")
--lx("select.drop edge")
--lx("select.drop polygon")
--lx("select.vertexMap \"\" txuv replace")
--lx("select.invert")
-- Setting up directories --
contentdir = lxq("pref.value lwio.lwoContentDir ?")
lxout("> Content dir: "..contentdir[1])
if (contentdir == nil) then error("Please set the content directory.") end
contentdir = contentdir[1]
string.gsub(contentdir,"\\","/") -- Replacing all "\" to "/".
savedir = contentdir..objectdir -- Adding the proper object dir to the final path.
-- Collecting layer data --
MainLayer = lxq("query layerservice layer.index ? fg")[1] -- We need only the first selected layer.
MainLayerName = lxq("query layerservice layer.name ? fg")[1] -- We use the name of the first fg layer as export name.
lxout("> MainLayerIndex: "..MainLayer)
ChildrenNum = lxq("query layerservice layer.childCount ? "..MainLayer)[1] -- Get child count.
lxout("> ChildrenNum: "..ChildrenNum)
if ChildrenNum ~= 0 then -- If there are children, then get info about them.
ChildrenLayers = lxq("query layerservice layer.children ? "..MainLayer)
for i=1, ChildrenNum do
-- !!!WORKAROUND!!! -- We add +1 to the recieved layer indices to fix a bug in the layer.children query.
ChildrenLayers[i] = ChildrenLayers[i]+1
lxout("> Child "..i.." index: "..ChildrenLayers[i])
-- Collecting children data --
ChildrenNames[i] = lxq("query layerservice layer.name ? "..ChildrenLayers[i])[1]
lxout("> Child "..i.." name: "..ChildrenNames[i])
end
-- Making arrays for all relevant layer data --
Layers = ChildrenLayers
table.insert(Layers,1,MainLayer) -- Collect the indices of all relevant layers.
LayerNames = ChildrenNames
table.insert(LayerNames,1,MainLayerName) -- Collect the names of all relevant layers.
LayerNum = ChildrenNum+1 -- Compute the number of the relevant layers.
else -- If no children, then we set layer data of the mainlayer.
Layers = {MainLayer}
LayerNames = {MainLayerName}
LayerNum = 1
end
-- Copying data to a new scene --
lxout("- Copying data to a new scene. -")
OriginalScene = lxq("query sceneservice scene.index ? current")[1] -- Store the index of the source scene.
lx("scene.new")
NewScene = lxq("query sceneservice scene.index ? current")[1] -- Store the index of the new scene.
for i = 1, LayerNum do -- Iterating through the layers.
lx("scene.set "..OriginalScene) -- Go back from the new scene to the original.
SelectLayer(Layers[i]) -- Select the proper layer.
lx("select.copy") -- Copy layer contents.
lx("scene.set "..NewScene) -- Go to the new scene.
SelectLayer(i) -- Select the next empty layer.
lx("select.paste") -- Paste stuff.
lx("item.name "..LayerNames[i].." mesh") -- Set proper name.
if (i < LayerNum) then -- If there are children, and we are not working with the last of them...
lx("layer.newItem mesh") -- ... then we make a new empty layer for the next one.
end
end
-- Preparing files --
fileOutName = savedir.."/"..MainLayerName..".ase"
TempFileName = savedir.."/"..TempFileName
fileOut = io.open(fileOutName, "w+")
if (fileOut == nil) then error("Can't open "..fileOutName.."!") end
-- Writing data to file --
-- Header --
fileOut:write("*3DSMAX_ASCIIEXPORT 200\n")
fileOut:write("*COMMENT \"Generated by ASEExport4Unreal v1.0\" \n")
-- Scene --
fileOut:write("*SCENE {\n")
fileOut:write("\t*SCENE_FILENAME \""..LayerNames[1].."\"\n")
fileOut:write("\t*SCENE_FIRSTFRAME 0\n")
fileOut:write("\t*SCENE_LASTFRAME 100\n")
fileOut:write("\t*SCENE_FRAMESPEED 30\n")
fileOut:write("\t*SCENE_TICKSPERFRAME 160\n")
fileOut:write("\t*SCENE_BACKGROUND_STATIC 0.0000\t0.0000\t0.0000\n")
fileOut:write("\t*SCENE_AMBIENT_STATIC 0.0000\t0.0000\t0.0000\n")
fileOut:write("}\n")
---------------------------
-- Proccessing materials --
---------------------------
lxout("- Proccessing materials -")
SelectLayer(1) -- Select te first layer, where we actually care about materials.
-- This is the render object, all other layers are for collision.
MaterialNum = lxq("query layerservice material.n ? all")[1]
--lxout("> Material number: "..MaterialNum)
for j = 1, MaterialNum do
MaterialNames[j] = lxq("query layerservice material.name ? "..j-1)[1]
end
fileOut:write("*MATERIAL_LIST {\n")
fileOut:write("\t*MATERIAL_COUNT 1 \n")
fileOut:write("\t*MATERIAL 0 {\n")
fileOut:write("\t\t*MATERIAL_NAME \""..MaterialNames[1].."\"\n")
fileOut:write("\t\t*MATERIAL_CLASS \"Multi/Sub-Object\" \n")
fileOut:write("\t\t*NUMSUBMTLS "..MaterialNum.."\n")
for i = 1, MaterialNum do -- Iterating through the materials which become submaterials.
fileOut:write("\t\t*SUBMATERIAL "..(i-1).." { \n")
fileOut:write("\t\t\t*MATERIAL_NAME \""..MaterialNames[i].."\"\n")
fileOut:write("\t\t\t*MATERIAL_CLASS \"Standard\" \n")
fileOut:write("\t\t\t*MAP_DIFFUSE {\n")
fileOut:write("\t\t\t\t*MAP_NAME \""..MaterialNames[i].."\"\n")
fileOut:write("\t\t\t\t*BITMAP \"c:\\"..MaterialNames[i]..".tga\"\n")
fileOut:write("\t\t\t\t*UVW_U_TILING 1.0000 \n")
fileOut:write("\t\t\t\t*UVW_V_TILING 1.0000 \n")
fileOut:write("\t\t\t}\n")
fileOut:write("\t\t}\n")
end
fileOut:write("\t}\n")
fileOut:write("}\n")
--------------------------
-- Proccessing geometry --
--------------------------
lxout("- Proccessing geometry -")
for ActLayer = 1, LayerNum do -- Iterating through the layers.
SelectLayer(ActLayer)
lx("select.type polygon")
lx("poly.triple")
Faces = lxq("query layerservice polys ? all") -- Getting the list of faces.
FaceNum = table.getn(Faces)
ProcFaceNum = ProcFaceNum + FaceNum
if ActLayer == 1 then -- We only bother with smoothing groups in the case of layer #1.
AssignSGroups() -- Assigning the smoothing groups before the unweld destroys poly islands.
end
lx("select.type polygon")
lx("vert.split") -- Unweld, so every vertex has it's own UV coordinates.
SelectLayer(ActLayer) -- Reselect layer to make sure internal data is updated.
Vertices = lxq("query layerservice verts ? all") -- Getting the list of vertices.
VertexNum = table.getn(Vertices)
fileOut:write("*GEOMOBJECT {\n")
fileOut:write("\t*NODE_NAME \""..LayerNames[ActLayer].."\"\n")
-- Geometry - Node --
fileOut:write("\t*NODE_TM {\n")
fileOut:write("\t\t*NODE_NAME \""..LayerNames[ActLayer].."\"\n")
fileOut:write("\t}\n")
-- Geometry - Mesh --
fileOut:write("\t*MESH {\n" )
fileOut:write("\t\t*MESH_NUMVERTEX "..VertexNum.."\n")
fileOut:write("\t\t*MESH_NUMFACES "..FaceNum.."\n")
-- Geometry - Mesh - Vertex list --
fileOut:write("\t\t*MESH_VERTEX_LIST {\n")
for j = 0, (VertexNum-1) do -- Iterating through the vertices.
Pos = GetPointPosition(j)
fileOut:write("\t\t\t*MESH_VERTEX\t"..j.."\t"..Pos[1].."\t"..Pos[2].."\t"..Pos[3].."\n")
end
fileOut:write("\t\t}\n")
-- Geometry - Mesh - Face list --
fileOut:write("\t\t*MESH_FACE_LIST {\n")
for j = 0, (FaceNum-1) do -- Iterating through the faces.
FacePoints = GetFacePoints(j)
fileOut:write("\t\t\t*MESH_FACE\t"..j..":\tA:\t"..FacePoints[1].." B:\t"..FacePoints[2].." C:\t"..FacePoints[3])
if ActLayer == 1 then
-- If the actual layer is #1 then we assign the proper material ID.
fileOut:write(" AB:\t1 BC:\t1 CA:\t0\t*MESH_SMOOTHING "..FaceSGroups[j].."\t*MESH_MTLID "..GetFaceMaterialID(j).."\n")
else
-- If the actual layer is not #1 then it's for collision info, so we force material #1, and prevent storing
-- unused material references in the object.
fileOut:write(" AB:\t1 BC:\t1 CA:\t0\t*MESH_SMOOTHING 0\t*MESH_MTLID 1 \n")
end
end
fileOut:write("\t\t}\n")
---------------------
-- Proccessing UVs --
---------------------
-- Texture - Vertex list - UV1 --
fileOut:write("\t\t*MESH_NUMTVERTEX "..VertexNum.."\n")
fileOut:write("\t\t*MESH_TVERTLIST {\n")
for j = 0, (VertexNum-1) do -- Iterating through the vertices.
UVPos = GetPointUV(j,UV1Name)
fileOut:write("\t\t\t*MESH_TVERT "..j.."\t"..UVPos[1].."\t"..UVPos[2].."\t0.0000\n")
end
fileOut:write("\t\t}\n") -- Closing MESH_TVERTLIST
-- Texture - Face list --
fileOut:write("\t\t*MESH_NUMTVFACES "..FaceNum.."\n")
fileOut:write("\t\t*MESH_TFACELIST {\n")
for j = 0, (FaceNum-1) do -- Iterating through the faces.
FacePoints = GetFacePoints(j)
fileOut:write("\t\t\t*MESH_TFACE\t"..j.."\t"..FacePoints[1].."\t"..FacePoints[2].."\t"..FacePoints[3].."\n")
end
fileOut:write("\t\t}\n") -- Closing MESH_TFACELIST
fileOut:write("\t\t*MESH_MAPPINGCHANNEL 2 {\n")
-- Texture - Vertex list - UV2 --
fileOut:write("\t\t\t*MESH_NUMTVERTEX "..VertexNum.."\n")
fileOut:write("\t\t\t*MESH_TVERTLIST {\n")
for j = 0, (VertexNum-1) do -- Iterating through the vertices.
UVPos = GetPointUV(j,UV2Name)
fileOut:write("\t\t\t\t*MESH_TVERT\t"..j.."\t"..UVPos[1].."\t"..UVPos[2].."\t0.0000\n")
end
fileOut:write("\t\t\t}\n") -- Closing MESH_TVERTLIST
-- Texture - Face list --
fileOut:write("\t\t\t*MESH_NUMTVFACES "..FaceNum.."\n")
fileOut:write("\t\t\t*MESH_TFACELIST {\n")
for j = 0, (FaceNum-1) do -- Iterating through the faces.
FacePoints = GetFacePoints(j)
fileOut:write("\t\t\t\t*MESH_TFACE\t"..j.."\t"..FacePoints[1].."\t"..FacePoints[2].."\t"..FacePoints[3].."\n")
end
fileOut:write("\t\t\t}\n" ) -- Closing MESH_TFACELIST
fileOut:write("\t\t}\n") -- Closing MESH_MAPPINGCHANNEL 2
if UVSetExists(UV3Name) then -- If UV3 exists then we bother with writing it to the file.
fileOut:write("\t\t*MESH_MAPPINGCHANNEL 3 {\n")
-- Texture - Vertex list - UV3 --
fileOut:write("\t\t\t*MESH_NUMTVERTEX "..VertexNum.."\n")
fileOut:write("\t\t\t*MESH_TVERTLIST {\n")
for j = 0, (VertexNum-1) do -- Iterating through the vertices.
UVPos = GetPointUV(j,UV3Name)
fileOut:write("\t\t\t\t*MESH_TVERT\t"..j.."\t"..UVPos[1].."\t"..UVPos[2].."\t0.0000\n")
end
fileOut:write("\t\t\t}\n") -- Closing MESH_TVERTLIST
-- Texture - Face list --
fileOut:write("\t\t\t*MESH_NUMTVFACES "..FaceNum.."\n")
fileOut:write("\t\t\t*MESH_TFACELIST {\n")
for j = 0, (FaceNum-1) do -- Iterating through the faces.
FacePoints = GetFacePoints(j)
fileOut:write("\t\t\t\t*MESH_TFACE\t"..j.."\t"..FacePoints[1].."\t"..FacePoints[2].."\t"..FacePoints[3].."\n")
end
fileOut:write("\t\t\t}\n" ) -- Closing MESH_TFACELIST
fileOut:write("\t\t}\n") -- Closing MESH_MAPPINGCHANNEL 3
end
------------------------------
-- Proccessing vertex color --
------------------------------
-- VertexColor - Vertex list --
fileOut:write("\t\t*MESH_NUMCVERTEX "..VertexNum.."\n")
fileOut:write("\t\t*MESH_CVERTLIST {\n")
for j = 0, (VertexNum-1) do -- Iterating through the vertices.
Col = GetPointColor(j)
fileOut:write("\t\t\t*MESH_VERTCOL\t"..j.."\t"..Col[1].."\t"..Col[2].."\t"..Col[3].."\n")
end
fileOut:write("\t\t}\n" )
-- VertexColor - Face list --
fileOut:write("\t\t*MESH_NUMCVFACES "..FaceNum.."\n")
fileOut:write("\t\t*MESH_CFACELIST {\n")
for j = 0, (FaceNum-1) do -- Iterating through the faces.
FacePoints = GetFacePoints(j)
fileOut:write("\t\t\t*MESH_CFACE\t"..j.."\t"..FacePoints[1].."\t"..FacePoints[2].."\t"..FacePoints[3].."\n")
end
fileOut:write("\t\t}\n")
-------------------------
-- Proccessing normals --
-------------------------
fileOut:write("\t\t*MESH_NORMALS {\n")
for j = 0, (FaceNum-1) do -- Iterating through the faces.
Normal = GetFaceNormal(j)
fileOut:write("\t\t\t*MESH_FACENORMAL\t"..j.."\t"..Normal[1].."\t"..Normal[2].."\t"..Normal[3].."\n")
FacePoints = GetFacePoints(j)
for k = 1, 3 do -- Iterating through the points of the actual face.
Normal = GetPointNormal(FacePoints[k])
fileOut:write("\t\t\t\t*MESH_VERTEXNORMAL\t"..FacePoints[k].."\t"..Normal[1].."\t"..Normal[2].."\t"..Normal[3].."\n")
end
end
fileOut:write("\t\t}\n" )
fileOut:write("\t}\n" )
fileOut:write("\t*MATERIAL_REF 0\n" )
fileOut:write("}\n" )
end
-----------------
-- Cleaning up --
-----------------
if bSaveTempFile then lx("!scene.saveAs filename:\""..TempFileName.."\"") end
lx("!scene.close") -- Closing scene with suppressed dialog.
fileOut:close()
SelectLayer(MainLayer) -- Going back to the original layer.
EndTime = os.time()
ExportTime = os.difftime(EndTime, StartTime)
lxout("Export took "..ExportTime.." seconds.")
lxout("Total number of processed polygons: "..ProcFaceNum)
lxout("Speed: "..(ProcFaceNum / ExportTime).." polygons/sec.")
lxout("------- Object exported. -------")