JurassicParkTrespasser/jp2_pc/Tools/MAXScript/TreeDebrisPlacer.ms
2018-01-01 23:07:24 +01:00

443 lines
16 KiB
Plaintext

-- **********************************************************************************************
-- *
-- * Copyright © DreamWorks Interactive, 1997
-- *
-- * Contents:
-- * Implementation of TreePlacement.ms
-- *
-- * Bugs:
-- *
-- * To do:
-- *
-- * Notes:
-- *
-- **********************************************************************************************
fn TerrainObjectFlt obj = findstring obj.name "!Terrain" == 1
fn LowestVert obj =
(
-- returns the index of the vertex with the lowest pos.z value
local LowVertPos = obj.max.z
local LowestVert = 1
nv = obj.numverts
for i = 1 to nv do
(
local Cvert = getvert obj i
if Cvert.z < LowVertPos do
(
LowVertPos = Cvert.z
LowestVert = i
)
)
return LowestVert
)
fn LowestVerts obj thresh =
(
-- returns the index of the vertex with the lowest pos.z value
local LowVertPos = obj.max.z
local LowestVert = 1
nv = obj.numverts
for i = 1 to nv do
(
local Cvert = getvert obj i
if Cvert.z < LowVertPos do
(
LowVertPos = Cvert.z
LowestVert = i
)
)
LowVertThreshold = LowVertPos + thresh
LowVerts = #()
for i = 1 to nv do
(
local Cvert = getvert obj i
if Cvert.z < LowVertThreshold do
append LowVerts i
)
return LowVerts
)
-- **********************************************************************************************
-- Start Utility
-- **********************************************************************************************
Utility Tree_Debris_Placer "Tree Placer"
(
local Terrain_surface, Tapeobj, tree, taperay, ir, ParentObject, Debris1Obj, Debris2Obj,
Debris3Obj, Debris4Obj, InitialDebrisPos, NewDebris, ParentObject, PlacedObjCount,
TotalPolyCount, SubPolyCount1, SubPolyCount2, SubPolyCount3, SubPolyCount4, NumSelected,DebrisOptions1,
DebrisOptions2, DebrisOptions3, DebrisOptions4, DebrisOptions5, DebrisOptions6, CWireColor
local debug = false
group "Distribution Options"
(
label chooseTerrainLabel "Terrain:" align:#left offset:[-5,0]
pickbutton Pick_Terrain width:100 align:#right offset:[5,-20] filter:TerrainObjectFlt
label chooseSurfLabel "Surface:" align:#left offset:[-5,0]
pickbutton Pick_PlaceSurface width:100 align:#right offset:[5,-20]
checkbox RotSel "Random Z Rotation" checked:false
spinner ZrotHi "Hi:" range:[0,180,30] enabled:false fieldwidth:45 offset:[-5,0] align:#left
spinner ZrotLo "Lo:" range:[-180,0,-30] enabled:false fieldwidth:45 offset:[5,-21]
checkbox RndTilt "Random Tilt" enabled:false
spinner tilt "Tilt up to:" range:[0,30,0] type:#float enabled:false fieldwidth:40 align:#left
label tiltlabel "degrees" align:#right offset:[0,-20]
checkbox RndScale "Random Scale"
spinner rndScaleLo "Low %:" range:[.001,1000,75] type:#float enabled:false
spinner rndScaleHi "High %:" range:[.001,1000,150] type:#float enabled:false
spinner HeightOffset "Height Offset: " range:[-10,10,0] type: #float
)
group "Placement Method"
(
radiobuttons PlacementMethod labels:#("Box", "Vert","Normal","Boulder", "Planted") columns:2
spinner VertexThreshold "Vert Threshold:" range:[0,10,.25] enabled:false fieldwidth:45
)
group "Conforming Options"
(
checkbox conformSelected "Conform Selected Verts"
checkbox ApplyRenaming "Apply Renaming" checked:true offset:[15,0]
checkbox ConformOnly "ConformOnly" checked:false offset:[15,0]
)
group "Direction Options"
(
checkbox OverrideDirection "Override Direction"
spinner DirX "X:" range:[-1,1,0] enabled:false
spinner DirY "Y:" range:[-1,1,0] enabled:false
spinner DirZ "Z:" range:[-1,1,-1] enabled:false
label blank0
button PresetX "X" width:25 offset:[-45,-80] enabled:false
button PresetY "Y" width:25 offset:[-45,0] enabled:false
button PresetZ "Z" widht:25 offset:[-45,0] enabled:false
checkbox negative "(-)" offset:[10,0] enabled:false
label blank1
label ObjDir "Picked Dir:" align:#left offset:[-5,0] enabled:false
pickbutton PickObjDir width:80 align:#right offset:[5,-20] enabled:false
)
button place_many "Place Selection" width:145
checkbox SmartMode "Smart Mode"
label results " " align: #left
on OverrideDirection changed state do
(
if state then
(
DirX.enabled = DirY.enabled = DirZ.enabled = PresetX.enabled = PresetY.enabled = PresetZ.enabled = negative.enabled = ObjDir.enabled = PickObjDir.enabled = true
PlacementMethod.state = 1
) else (
DirX.enabled = DirY.enabled = DirZ.enabled = PresetX.enabled = PresetY.enabled = PresetZ.enabled = negative.enabled = ObjDir.enabled = PickObjDir.enabled = false
)
)
on PickObjDir picked obj do
(
cDir = -(obj.dir)
DirX.value = cDir.x
DirY.value = cDir.y
DirZ.value = cDir.z
PickObjDir.text = obj.name
)
on PresetX pressed do
(
if negative.checked then
DirX.value = -1
else
DirX.value = 1
DirY.value = DirZ.value = 0
)
on PresetY pressed do
(
if negative.checked then
DirY.value = -1
else
DirY.value = 1
DirX.value = DirZ.value = 0
)
on PresetZ pressed do
(
if negative.checked then
DirZ.value = -1
else
DirZ.value = 1
DirX.value = DirY.value = 0
)
on PlacementMethod changed state do
if state != 5 then
VertexThreshold.enabled = false
else
VertexThreshold.enabled = true
on RotSel changed state do
if RotSel.checked then
ZrotHi.enabled = ZrotLo.enabled = true
else
ZrotHi.enabled = ZrotLo.enabled = false
on RndTilt changed state do
if state then tilt.enabled = true else tilt.enabled = false
on RndScale changed state do
if state then (rndScaleLo.enabled = rndScaleHi.enabled = true) else (rndScaleLo.enabled = rndScaleHi.enabled = false)
on rndScaleLo changed state do
if rndScaleLo.value > rndScaleHi.value do rndScaleHi.value = rndScaleLo.value
on rndScaleHi changed state do
if rndScaleHi.value < rndScaleLo.value do rndScaleLo.value = rndScaleHi.value
on Pick_Terrain picked obj do
(
Terrain_surface = obj
Pick_Terrain.text = Terrain_surface.name
Pick_PlaceSurface.text = ""
)
on Pick_PlaceSurface picked obj do
(
Terrain_surface = obj
Pick_PlaceSurface.text = Terrain_surface.name
Pick_Terrain.text = ""
)
-- ********************************************************************************
-- * Place Many
-- ********************************************************************************
on place_many pressed do
(
undo on
(
-- Make sure the terrain object hasn't been deleted
terrain_surface = undefined
for o in geometry do if (o.name == Pick_Terrain.text) or (o.name == Pick_PlaceSurface.text) do terrain_surface = o
if terrain_surface != undefined then
(
VertThresh = VertexThreshold.value
taperay = ray [0,0,0] (normalize [DirX.value, DirY.value, DirZ.value])
TapeHeight = ((terrain_surface.max).z + 1.0)
Current_Obj_count = 0
Sel_obj_count = 0
SelObjects = #()
ProgressStart "Distributing Trees"
if SmartMode.checked then
for b in selection do
if (substring b.name (b.name.count - 2) 3) != "-00" do
append SelObjects b
else
SelObjects = selection as array
Sel_obj_count = SelObjects.count
for i = 1 to Sel_obj_count do
(
b = SelObjects[i]
if debug do format "%\n" b.name
if b.parent == undefined do
(
Current_Obj_count = (Current_Obj_count + 1);
ProgressValue = (((Current_Obj_Count as float) / (Sel_obj_count as float)) * 100);
ProgressUpdate (ProgressValue);
-- random scale
if PlacementMethod.state != 3 do
if RndScale.checked == true do
(
ScaleFactor = ((random RndScaleLo.value RndScaleHi.value) * 0.01)
b.scale = [ScaleFactor, ScaleFactor, ScaleFactor]
)
-- random tilt
if RndTilt.checked == true do
(
rotate b (random tilt.value (tilt.value * -1)) x_axis
rotate b (random tilt.value (tilt.value * -1)) y_axis
)
-- random Z rotation
if PlacementMethod.state != 3 do
if RotSel.checked == true do
(
Hi = ZRotHi.value
Lo = ZRotLo.value
bpos = b.pos
-- rotate b (random Lo Hi) z_axis
b.rotation = (quat 0.0 0.0 1.0 (random Lo Hi))
b.pos = bpos
)
-- position object
if OverrideDirection.checked then
Taperay.pos = b.pos
else
Taperay.pos = [(b.pos).x, (b.pos).y, TapeHeight]
if (ir = intersectray terrain_surface taperay) != undefined do
(
if classof b == Editable_Mesh do
(
-- conform selected verts
if conformSelected.checked then
(
ObjHeightOffset = ((b.pivot).z - (b.min).z)
if ConformOnly.checked == false do
b.pos = [(ir.pos).x, (ir.pos).y, ((ir.pos).z + HeightOffset.value + ObjHeightOffset)]
CVertSel = getvertselection b
if CVertSel.count != 0 do
(
for j = 1 to CVertSel.count do
(
CVertPos = getvert b CVertSel[j]
Taperay.pos = [CVertPos.x, CVertPos.y, CVertPos.z + 100]
if (ir = intersectray terrain_surface taperay) != undefined do
setvert b CVertSel[j] ir.pos
if ApplyRenaming.checked do
if (substring b.name (b.name.count - 2) 3) != "-00" do
b.name = "rename me"
)
update b
)
) else (
if PlacementMethod.state == 1 do
(
ObjHeightOffset = ((b.pivot).z - (b.min).z)
b.pos = [(ir.pos).x, (ir.pos).y, ((ir.pos).z + HeightOffset.value + ObjHeightOffset)]
)
-- VertexPlacement method
if PlacementMethod.state == 2 do
(
LowVertPos = (getvert b (LowestVert b))
LowVertOffset = (LowVertPos - b.pivot)
Taperay.pos = [LowVertPos.x, LowVertPos.y, TapeHeight]
ir = intersectray terrain_surface taperay
ObjHeightOffset =((b.pivot).z - LowVertPos.z)
b.pos = [(ir.pos).x - LowVertOffset.x, (ir.pos).y - LowVertOffset.y, ((ir.pos).z + HeightOffset.value + ObjHeightOffset)]
)
-- Normal Placement method
if PlacementMethod.state == 3 do
(
Taperay.pos = [b.pos.x, b.pos.y, (terrain_surface.max.z + 100)]
ir = intersectray terrain_surface taperay
if ir != undefined do
(
bscale = b.scale
b.dir = [0,0,1]
ObjHeightOffset = ((b.pivot).z - (b.min).z)
bPos = [(ir.pos).x, (ir.pos).y, ((ir.pos).z + HeightOffset.value + ObjHeightOffset)]
b.dir = ir.dir
b.pos = bPos
-- set the scale back to original
b.scale = bscale
if RotSel.checked == true do
(
Hi = ZRotHi.value
Lo = ZRotLo.value
in coordsys local rotate b (random Lo Hi) z_axis
)
)
)
-- Boulder placement method
if PlacementMethod.state == 4 do
(
Taperay.pos = [b.pos.x, b.pos.y, (terrain_surface.max.z + 100)]
ir = intersectray terrain_surface taperay
if ir != undefined do
(
-- grab the scale
bscale = b.scale
b.dir = [0,0,1]
ObjHeightOffset = ((b.pivot).z - (b.min).z)
bPos = [(ir.pos).x, (ir.pos).y, ((ir.pos).z + HeightOffset.value + ObjHeightOffset)]
b.dir = ir.dir
-- set the scale back to original
b.scale = bscale
if RotSel.checked == true do
(
Hi = ZRotHi.value
Lo = ZRotLo.value
in coordsys local rotate b (random Lo Hi) z_axis
)
-- place based on lowest vertex....
LowVertPos = (getvert b (LowestVert b))
LowVertOffset = (LowVertPos - b.pivot)
Taperay.pos = [LowVertPos.x, LowVertPos.y, TapeHeight]
ir = intersectray terrain_surface taperay
ObjHeightOffset =((b.pivot).z - LowVertPos.z)
b.pos = [(ir.pos).x - LowVertOffset.x, (ir.pos).y - LowVertOffset.y, ((ir.pos).z + HeightOffset.value + ObjHeightOffset)]
)
)
-- Planted placement method
if PlacementMethod.state == 5 do
(
b.pos.z += 1000.0
Taperay.pos = [b.pos.x, b.pos.y, (terrain_surface.max.z + 100)]
ir = intersectray terrain_surface taperay
if ir != undefined do
(
ObjHeightOffset = ((b.pivot).z - (b.min).z)
-- place based on lowest vertex that is highest off terrain
LowVertArray = LowestVerts b VertThresh
smDistance = 0
LowVertPos = [0,0,0]
Cir = ray [0,0,0] [0,0,0]
continue = false
for j = 1 to LowVertArray.count do
(
CIndex = LowVertArray[j]
CVert = getVert b CIndex
tapeRay.pos = [CVert.x, CVert.y, TapeHeight]
if (ir = intersectray terrain_surface taperay) != undefined do
(
irPos = ir.pos
if (CDist = (CVert.z - irPos.z)) > smDistance do
(
continue = true
smDistance = CDist
LowVertPos = CVert
Cir = ir
)
)
)
if continue do
(
LowVertOffset = (LowVertPos - b.pivot)
Taperay.pos = [LowVertPos.x, LowVertPos.y, TapeHeight]
ObjHeightOffset =((b.pivot).z - LowVertPos.z)
b.pos = [(Cir.pos).x - LowVertOffset.x, (Cir.pos).y - LowVertOffset.y, ((Cir.pos).z + HeightOffset.value + ObjHeightOffset)]
)
)
)
)
)
-- Selected is a group
if classof b == Dummy do
(
ObjHeightOffset = (b.pivot.z - b.min.z)
b.pos = [(ir.pos).x, (ir.pos).y, ((ir.pos).z + HeightOffset.value + ObjHeightOffset)]
)
if classof b == targetcamera do (b.pos = [(ir.pos).x, (ir.pos).y, ((ir.pos).z + HeightOffset.value)])
if classof b == freecamera do (b.pos = [(ir.pos).x, (ir.pos).y, ((ir.pos).z + HeightOffset.value)])
)
if getProgressCancel == true then exit;
)
)
ProgressEnd();
results.text = (Sel_obj_count as string + " objects placed!")
) else (
messageBox "The terrain object is either undefined or has been deleted."
Pick_Terrain.text = ""
)
)
)
)