bobbysoon
March 6th, 2008, 12:46 AM
Someone asked me to make a non-icy ground texture for Icefields, and I said sure, simple enough. Later that day, I found myself making a maxscript to import scenario positions of vehicle, item, and player spawns, and scenery positions. Something I was thinking of doing for a while anyway. I rendered layers, and used those layers in photoshop to define roads and blend in with the bases of cliffs and tree trunks. I thought it looked pretty nice, and maybe I should share how I did it. Or, maybe there's a better way and someone else would like to share. Maybe both. Anyways, script and pics:
Script: Copy, paste into notepad, save to max\scripts\importGuerillaScenExport.ms
scen = undefined
fn loadPosition =
( skipToString scen "position real point 3d "
[(readValue scen),(readValue scen),(readValue scen)]
)
fn loadEuler =
( skipToString scen "euler angles 3d "
eulerToQuat (eulerangles -(readValue scen) -(readValue scen) -(readValue scen))
)
fn loadFacing =
( skipToString scen "angle "
eulerToQuat (eulerangles 0 0 (readValue scen))
)
fn loadTagRef =
( skipToString scen "tag reference "
readLine scen
)
fn loadShortInt =
( skipToString scen "short integer "
readValue scen
)
fn loadType =
(
skipToString scen "type short block index "
readLine scen
)
fn loadScenery =
(
gs = #()
skipToString scen "scenery block "
n = readValue scen
for i = 1 to n do
(
type = filterString (loadType()) "\t"
in coordsys world gs[i] = GeoSphere pos:((loadPosition() as Point3)*100) prefix:type[type.count-1]
in coordsys world gs[i].rotation = loadEuler()
gs[i].baseType = 2
gs[i].segs = 1
gs[i].hemisphere=true
gs[i].radius = 100
gs[i].wirecolor = color 128 128 255
)
)
fn loadVehicles =
(
gs = #()
skipToString scen "vehicles block "
n = readValue scen
for i = 1 to n do
(
type = filterString (loadType()) "\t"
in coordsys world gs[i] = GeoSphere pos:((loadPosition() as Point3)*100) prefix:type[type.count-1]
in coordsys world gs[i].rotation = loadEuler()
gs[i].baseType = 2
gs[i].segs = 1
gs[i].hemisphere=true
gs[i].radius = 100
gs[i].wirecolor = color 128 128 255
)
)
fn loadStartingLocations =
(
gs = #()
skipToString scen "player starting locations block "
n = readValue scen
for i = 1 to n do
(
gs[i] = GeoSphere pos:((loadPosition() as Point3)*100) prefix:"spawn"
gs[i].rotation = loadFacing()
gs[i].baseType = 1
gs[i].segs = 1
gs[i].hemisphere=true
gs[i].radius = 50
gs[i].wirecolor = color 32 255 32
)
)
fn loadNetgameEquipment =
(
gs = #()
skipToString scen "netgame equipment block "
n = readValue scen
for i = 1 to n do
(
gs[i] = GeoSphere pos:((loadPosition() as Point3)*100)
gs[i].rotation = loadFacing()
tag = filterString (loadTagRef()) "\\\t"
gs[i].name=tag[tag.count]+" "+tag[tag.count-1]
gs[i].baseType = 0
gs[i].segs = 1
gs[i].hemisphere=true
gs[i].radius = 25
gs[i].wirecolor = color 192 192 192
)
)
fn loadScenario fileName =
(
scen = openFile (fileName) mode:"r"
if scen != undefined then
(
sWords = filterString (readLine scen) "\t"
print (sWords[1] as string) to:listener
if sWords[1] == "scenario" then
(
loadScenery()
loadVehicles()
loadStartingLocations()
loadNetgameEquipment()
)
)
else
(
messageBox "the scenario couldn't be opened" title:"For some reason,"
)
)
clearListener()
loadScenario(getOpenFileName \
types:"Guerilla Exported Scenery(*.txt)|*.txt|" \
filename:"C:\\Program Files\\Microsoft Games\\Halo Custom Edition\\tags\\levels\\test\\*.txt")
viewport.setType #view_top
max tool zoomextentsfn loadEuler and fn loadFacing don't work. Oh well, no biggie
After using the gbxModel importer to import, a tree for example, and naming it "_tree", you could type "instanceReplace $tree_pine_small* $_tree" in the mini listener in the lower left corner of max, and all the nodes having "tree_pine_small" in their names would become instances of _tree
Pics: http://static3.filefront.com/images/personal/b/bobbysoon/86476/eneieunqpp.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/tqpchjxjbt.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/ixmwhypfce.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/ojhgwovitg.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/lijifoystu.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/vdbnnxnbev.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/yblaxuhapj.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/fkzyoxlkog.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/yneitzddof.jpgThe pics are inconsistent, they're from my learning process, but they should give you the basic idea of what it's about. The green fuzzies of the tree leaves should have been the brown of the trunks, as often is the ground beneath a tree, by assigning the trunk material to the leaves. It'd blend well if the leaf's alpha was applied to the leaf material's opacity
The rocks are only used for reference when erasing away from the grass layer to define roads. Obviously the player and vehicle spawn points are also only for reference. I never got around to rendering items, but the script will import those positions too
If anyone wants to read it, I'll elaborate on the rendering and photoshop work. Gmax users, unless you got some uber hires desktop space for a screenshot, this would be more difficult, requiring the use of Yafray (http://www.yayap.com/rendertut.html) to render, something I haven't gotten into yet. But it could be done, if you're OC enough :cool:
Thoughts?
Script: Copy, paste into notepad, save to max\scripts\importGuerillaScenExport.ms
scen = undefined
fn loadPosition =
( skipToString scen "position real point 3d "
[(readValue scen),(readValue scen),(readValue scen)]
)
fn loadEuler =
( skipToString scen "euler angles 3d "
eulerToQuat (eulerangles -(readValue scen) -(readValue scen) -(readValue scen))
)
fn loadFacing =
( skipToString scen "angle "
eulerToQuat (eulerangles 0 0 (readValue scen))
)
fn loadTagRef =
( skipToString scen "tag reference "
readLine scen
)
fn loadShortInt =
( skipToString scen "short integer "
readValue scen
)
fn loadType =
(
skipToString scen "type short block index "
readLine scen
)
fn loadScenery =
(
gs = #()
skipToString scen "scenery block "
n = readValue scen
for i = 1 to n do
(
type = filterString (loadType()) "\t"
in coordsys world gs[i] = GeoSphere pos:((loadPosition() as Point3)*100) prefix:type[type.count-1]
in coordsys world gs[i].rotation = loadEuler()
gs[i].baseType = 2
gs[i].segs = 1
gs[i].hemisphere=true
gs[i].radius = 100
gs[i].wirecolor = color 128 128 255
)
)
fn loadVehicles =
(
gs = #()
skipToString scen "vehicles block "
n = readValue scen
for i = 1 to n do
(
type = filterString (loadType()) "\t"
in coordsys world gs[i] = GeoSphere pos:((loadPosition() as Point3)*100) prefix:type[type.count-1]
in coordsys world gs[i].rotation = loadEuler()
gs[i].baseType = 2
gs[i].segs = 1
gs[i].hemisphere=true
gs[i].radius = 100
gs[i].wirecolor = color 128 128 255
)
)
fn loadStartingLocations =
(
gs = #()
skipToString scen "player starting locations block "
n = readValue scen
for i = 1 to n do
(
gs[i] = GeoSphere pos:((loadPosition() as Point3)*100) prefix:"spawn"
gs[i].rotation = loadFacing()
gs[i].baseType = 1
gs[i].segs = 1
gs[i].hemisphere=true
gs[i].radius = 50
gs[i].wirecolor = color 32 255 32
)
)
fn loadNetgameEquipment =
(
gs = #()
skipToString scen "netgame equipment block "
n = readValue scen
for i = 1 to n do
(
gs[i] = GeoSphere pos:((loadPosition() as Point3)*100)
gs[i].rotation = loadFacing()
tag = filterString (loadTagRef()) "\\\t"
gs[i].name=tag[tag.count]+" "+tag[tag.count-1]
gs[i].baseType = 0
gs[i].segs = 1
gs[i].hemisphere=true
gs[i].radius = 25
gs[i].wirecolor = color 192 192 192
)
)
fn loadScenario fileName =
(
scen = openFile (fileName) mode:"r"
if scen != undefined then
(
sWords = filterString (readLine scen) "\t"
print (sWords[1] as string) to:listener
if sWords[1] == "scenario" then
(
loadScenery()
loadVehicles()
loadStartingLocations()
loadNetgameEquipment()
)
)
else
(
messageBox "the scenario couldn't be opened" title:"For some reason,"
)
)
clearListener()
loadScenario(getOpenFileName \
types:"Guerilla Exported Scenery(*.txt)|*.txt|" \
filename:"C:\\Program Files\\Microsoft Games\\Halo Custom Edition\\tags\\levels\\test\\*.txt")
viewport.setType #view_top
max tool zoomextentsfn loadEuler and fn loadFacing don't work. Oh well, no biggie
After using the gbxModel importer to import, a tree for example, and naming it "_tree", you could type "instanceReplace $tree_pine_small* $_tree" in the mini listener in the lower left corner of max, and all the nodes having "tree_pine_small" in their names would become instances of _tree
Pics: http://static3.filefront.com/images/personal/b/bobbysoon/86476/eneieunqpp.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/tqpchjxjbt.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/ixmwhypfce.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/ojhgwovitg.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/lijifoystu.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/vdbnnxnbev.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/yblaxuhapj.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/fkzyoxlkog.jpg
http://static3.filefront.com/images/personal/b/bobbysoon/86476/yneitzddof.jpgThe pics are inconsistent, they're from my learning process, but they should give you the basic idea of what it's about. The green fuzzies of the tree leaves should have been the brown of the trunks, as often is the ground beneath a tree, by assigning the trunk material to the leaves. It'd blend well if the leaf's alpha was applied to the leaf material's opacity
The rocks are only used for reference when erasing away from the grass layer to define roads. Obviously the player and vehicle spawn points are also only for reference. I never got around to rendering items, but the script will import those positions too
If anyone wants to read it, I'll elaborate on the rendering and photoshop work. Gmax users, unless you got some uber hires desktop space for a screenshot, this would be more difficult, requiring the use of Yafray (http://www.yayap.com/rendertut.html) to render, something I haven't gotten into yet. But it could be done, if you're OC enough :cool:
Thoughts?