TT_HEAD

Tuesday, April 12, 2011

1 to 1 3dsMax to Game. Level Exporter

So this is a script I've been working on for a while and I thought it was about time to post it. It's a Maxscript for 3DSMAX that turn 3dsMax itself into a level editor for our game. It acts like a WYSIWYG for us and is fast and easy which makes for quick iteration.

Without Further adieu here is the video.
pardon my stutter.



If you wanna see the Code for this, click on the spoiler box.


CODE FOUND HERE:



---------------------------------------------------------------------
--Level Export Script V2.0
--created by: Joshua Jones
-- last updated: April, 7 , 2011
---------------------------------------------------------------------

-------------------------------------------
--GLOBAL VARIABLES
-------------------------------------------

aLights = #()
aObjects = #()
fsSaved = openfile "AudysseyExporterSavedData.txt"
sWhere = readline fsSaved
sName = readline fsSaved
fsDirectory = (sWhere+ "\\" + sName + ".txt") as string

-------------------------------------------
--UI MAPPING
-------------------------------------------

-- Creates the Interface Window.
utility uiExporter "Audyssey Level Exporter"
(
--DIRECTORY
groupbox gbBrowser "DIRECTORY" width:175 height:160 pos:[10,5]
label lbName1 "1.) Select a place to save and" pos:[15,20]
label lbName2 "name for the environment script." pos:[15,32]
edittext etWhere "File Location:" fieldWidth:160 labelOnTop:true pos:[15,55] Text: sWhere
edittext etName "Name:" fieldWidth:160 labelOnTop:true pos:[15,95] Text: sName
button btnSave "Save" width:160 height:24 align:#center pos:[15,135]

--GENERATE
groupbox gpObjectArrays "GENERATE" width:175 height:110 pos:[10,165]
label lbName3 "2.) Select all Objects you want" pos:[15,180]
label lbName4 " exported including lights." pos:[15,192]
button btnCreateArrays "Generate Arrays" width:160 height:24 align:#center pos:[15,215]
button btnRemoveTargets "Remove Light Targets" width:160 height:24 align:#center pos:[15,240]

--EXPORT
groupbox gpExport "EXPORT" width:175 height:65 pos:[10,275]
label lbName5 "3.) Export Arrays to Game" pos:[15,290]
button btnExport "EXPORT" width:160 height:24 align:#center pos:[15,310]

--EXTRA
groupbox gpExtra "EXTRA" width:175 height:95 pos:[10,340]
button btnReset "RESET" width:160 height:24 align:#center pos:[15,355]
button btnUndock "UNDOCK" width:80 height:24 align:#center pos:[15,380]
button btnDock "DOCK" width:80 height:24 align:#center pos:[95,380]
button btnManual "MANUAL" width:160 height:24 align:#center pos:[15,405]


-------------------------------------------
--BUTTON SCRIPTS
-------------------------------------------

on btnSave pressed do
(
fsSaved2 = createfile "AudysseyExporterSavedData.txt"
format (etWhere.text + "\n") to: fsSaved2
format etName.text to: fsSaved2
close fsSaved2
messagebox "Information Saved"
)

on btnCreateArrays pressed do
(
CreateArrays $
)

on btnRemoveTargets pressed do
(
RemoveTargets()
)

on btnExport pressed do
(
fsDirectory = createfile (etWhere.text + "\\" + etName.text + ".txt")
PrintObjects()
PrintLights()
close fsDirectory
messagebox "Level Exported"
resetData()

)

on btnUndock pressed do
(
cui.unregisterDialogbar uiExporter
)

on btnDock pressed do
(
cui.RegisterDialogBar uiExporter
--style:#(#cui_handles,#cui_floatable,#cui_dock_all )
cui.DockDialogBar uiExporter #cui_dock_left
)

on btnReset pressed do
(
resetData()
)

on btnManual pressed do
(
fsManual = openfile "AudysseyExporterV2Manual.txt"
wManual = newscript()
for x=1 to 1000 do
(
sValue = readline fsManual
format (sValue + "\n") to: wManual
if eof fsManual == true do exit
)
close fsManual
)

)

-------------------------------------------
--UI FUNCTIONS
-------------------------------------------

fn resetData =
(
if (aLights.count != 0 or aObjects.count != 0) then
(
aLights = #()
aObjects = #()
fsSaved = openfile "AudysseyExporterSavedData.txt"
sWhere = readline fsSaved
sName = readline fsSaved
--close fsSaved
fsDirectory = (sWhere + "\\" + sName + ".txt") as string
)
else
(
messagebox "Data already reset"
)
)

-- Moves Selection Objects into the correct coresponding array
fn CreateArrays selection =
(
if (aObjects.count == 0 and aLights.count == 0)then
(
aSelection = getcurrentselection()
if (aSelection.count > 1) then
(
For i=1 to aSelection.count do
(
sTempName = aSelection[i].name as string
If sTempName[1] == "L" do append aLights aSelection[i]
If sTempName[1] == "P" do append aObjects aSelection[i]
)
SelectionInformation $
)
else
(
messagebox "Selection is too small"
)
)
Else
(
messagebox "You Already Added to the arrays"
)
)

--Displays A message box of the selection information and Arrays
fn SelectionInformation selection =
(
aSelection = selection as array
sSelLength = aSelection.count as String
sLitLength = aLights.count as String
sObjLength = aObjects.count as String
sTotal = (aLights.count + aObjects.count) as String
messagebox ("Total Selection: " + sSelLength + "\nNumber Sent to Object Array: " + sObjLength + "\nNumber Sent to Light Array: " + sLitLength + "\n Total: " + sTotal +" / " +sSelLength )
)

--removes targets from aLights
fn RemoveTargets =
(
sStartTotal = aLights.count as string
sRemoved = 0;
atemp = #()
for i=1 to aLights.count do
(
sName = aLights[i].name
if ( matchPattern sName pattern:"*.Target" == True) then
(
sRemoved = sRemoved + 1
)
else
(
append aTemp aLights[i]
)
)
aLights = atemp
print atemp
sFinalTotal = aLights.count as string
messagebox ("Starting Total Lights in Array: " + sStartTotal + "\nTargets removed: " + (sRemoved as string) + "\nNew Total in Array: " + sFinalTotal)
)

-------------------------------------------
--CORE EXPORT FUNCTIONS
-------------------------------------------

-- Corrects 3dsMax and Rounds to Zero. (removes "E"s from the export script)
fn zeroRound theInt =
(
if theInt > -0.001 and theInt < 0.001 do theInt = 0
return theInt
)

--- Prints Grid to Outfile.
fn PrintObjects =
(
--Print position / rotation / scale to environment script
for i=1 to aObjects.count do
(
oObject = aObjects[i]

-- Corects name (removes instance numbers)
sName = oObject.name
sName = trimright sName "1234567890"

-- rounds Values (positions)
mPos = oObject.position
mPos.x = zeroRound mPos.x
mPos.y = zeroRound mPos.y
mPos.z = zeroRound mPos.z

-- rounds Values (rotation) (Spits out the Quaternion)
mRot = oObject.rotation
mRot.x = zeroRound mRot.x
mRot.y = zeroRound mRot.y
mRot.z = zeroRound mRot.z

--** scale Parameters (Spits out the scale parameter)
mScale = oObject.scale

-- Prints values to File
print sName to: fsDirectory
print mPos to: fsDirectory
print mRot to: fsDirectory
Print mScale to: fsDirectory
print "" to: fsDirectory
)
print "End of Grid" to: fsDirectory
print "" to: fsDirectory
)

fn PrintLights =
(
for i=1 to aLights.count do (
if aLights[i] != "null" do -- "null" refers to a instanced light, skip if hit.
(
-- Sets Default Values
Lit1 = aLights[i]
sName = Lit1.name
mPos = Lit1.pos
iMultiplier = Lit1.multiplier
mColor = Lit1.rgb
mAtten = [0,0] -- baseline attenuation value
mAtten.x = Lit1.farattenstart
mAtten.y = Lit1.farAttenEnd
mAngle = [0,0] -- baseline Angle Value
sType = Lit1.type

-- Make placement variables if not a spot light.
if sType == #targetSpot then
(
mAngle.x = Lit1.hotspot
mAngle.y = Lit1.falloff
mTarget = Lit1.target.pos
)

-- These are defaults for an Omni Light
else
(
mAngle = [0,0]
mTarget = [0,0,0]
)

--Print Master Values to Outfile
Print sName to: fsDirectory
Print sType to: fsDirectory
Print iMultiplier to: fsDirectory
Print mColor to: fsDirectory
Print mAtten to: fsDirectory
Print mAngle to: fsDirectory

-- INSTANCES--

--Finds and prints positions instances then sets them as null
-- Sets position for self and instances here
for k=1 to aLights.count do
(
Lit2 = aLights[k]
if (Lit2 != "null" ) and (areNodesInstances Lit1 Lit2 == true) do --checks against self and nulls
(
-- Corrects Position.
mPos = Lit2.position
mPos.x = zeroRound mPos.x
mPos.y = zeroRound mPos.y
mPos.z = zeroRound mPos.z

Print "" to: fsDirectory
Print Lit2.pos to: fsDirectory

if Lit2.type == #targetSpot then
(

-- Corrects Target Position
mTarget = Lit2.target.pos
mTarget.x = zeroRound mTarget.x
mTarget.y = zeroRound mTarget.y
mTarget.z = zeroRound mTarget.z

)
else
(
mTarget = [0,0,0]
)

print mTarget to: fsDirectory
--print "" to: outfile
aLights[k] = "null"
)
)
Print "End_Light" to: fsDirectory
)
)
Print "End Of Lights" to: fsDirectory
print "" to: fsDirectory
print "End Of Environment" to: fsDirectory
)

---------------------------------
--RUN CODE
---------------------------------

--Displays the Interface Window.
createDialog uiExporter 200 500
--cui.RegisterDialogBar uiExporter
--cui.DockDialogBar uiExporter #cui_dock_left




No comments:

Post a Comment