mirror of
https://github.com/OpenTrespasser/JurassicParkTrespasser.git
synced 2024-12-19 15:11:57 +00:00
443 lines
16 KiB
Plaintext
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 = ""
|
|
)
|
|
)
|
|
)
|
|
)
|