1211 lines
32 KiB
Plaintext
Executable File
1211 lines
32 KiB
Plaintext
Executable File
-- scatterer.ms
|
|
-- by Stuart Macdonald
|
|
|
|
global scatterFloat
|
|
global refObjects = #()
|
|
global objCount
|
|
global baseMeshObj
|
|
global ScatterObjRoll
|
|
--global ScatterFuncRoll
|
|
|
|
global theMousePos
|
|
global plantedObjects = #()
|
|
global numOfObjects
|
|
global startPlant
|
|
global lastObjPos
|
|
global plantThis
|
|
|
|
|
|
----------------------------------------------------------------------------------------------
|
|
-- Structs
|
|
----------------------------------------------------------------------------------------------
|
|
|
|
|
|
struct objStruct ( pObject, zAlign, zOffset, sXY, sZ, zRotVal,oDistVal )
|
|
|
|
----------------------------------------------------------------------------------------------
|
|
-- Functions
|
|
----------------------------------------------------------------------------------------------
|
|
|
|
fn findRandomPlant =
|
|
(
|
|
local totalWeight = 0
|
|
local weightInc
|
|
local randPick = random 1 99
|
|
local weightRange
|
|
|
|
--Find total weighting
|
|
for n = 1 to objCount do
|
|
(
|
|
|
|
totalWeight = totalWeight + refObjects[n].oDistVal
|
|
|
|
)
|
|
|
|
--find increment of weight
|
|
weightInc = 100/totalWeight
|
|
|
|
--find what object weighting the random number falls into and return that object index
|
|
weightRange = 0
|
|
val = 1
|
|
foundObject = false
|
|
for n = 1 to objCount while foundObject == false do
|
|
(
|
|
weightRange = weightRange + ( refObjects[n].oDistVal * weightInc )
|
|
|
|
if randPick < weightRange then
|
|
(
|
|
val = n
|
|
foundObject = true
|
|
)
|
|
)
|
|
val
|
|
)
|
|
|
|
---------------------------------------------------------------------------------
|
|
|
|
fn LoadObjectParameters objNum =
|
|
(
|
|
--get new weightings first
|
|
refObjects[1].oDistVal = ScatterObjRoll.distObj1.value
|
|
if objCount >1 then
|
|
(
|
|
refObjects[2].oDistVal = ScatterObjRoll.distObj2.value
|
|
if objCount >2 then
|
|
(
|
|
refObjects[3].oDistVal = ScatterObjRoll.distObj3.value
|
|
if objCount >3 then
|
|
(
|
|
refObjects[4].oDistVal = ScatterObjRoll.distObj4.value
|
|
if objCount >4 then
|
|
(
|
|
refObjects[5].oDistVal = ScatterObjRoll.distObj5.value
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
case objNum of
|
|
(
|
|
|
|
1:( refObjects[1].zAlign = ScatterObjRoll.zAlign1.state
|
|
refObjects[1].zOffset = ScatterObjRoll.zOff1.value
|
|
refObjects[1].sXY = ScatterObjRoll.sXY1.value
|
|
refObjects[1].sZ = ScatterObjRoll.sZ1.value
|
|
refObjects[1].zRotVal = ScatterObjRoll.zRot1.selection
|
|
)
|
|
|
|
2: (refObjects[2].zAlign = ScatterObjRoll.zAlign2.state
|
|
refObjects[2].zOffset = ScatterObjRoll.zOff2.value
|
|
refObjects[2].sXY = ScatterObjRoll.sXY2.value
|
|
refObjects[2].sZ = ScatterObjRoll.sZ2.value
|
|
refObjects[2].zRotVal = ScatterObjRoll.zRot2.selection
|
|
)
|
|
|
|
3: (refObjects[3].zAlign = ScatterObjRoll.zAlign3.state
|
|
refObjects[3].zOffset = ScatterObjRoll.zOff3.value
|
|
refObjects[3].sXY = ScatterObjRoll.sXY3.value
|
|
refObjects[3].sZ = ScatterObjRoll.sZ3.value
|
|
refObjects[3].zRotVal = ScatterObjRoll.zRot3.selection
|
|
)
|
|
|
|
4: (refObjects[4].zAlign = ScatterObjRoll.zAlign4.state
|
|
refObjects[4].zOffset = ScatterObjRoll.zOff4.value
|
|
refObjects[4].sXY = ScatterObjRoll.sXY4.value
|
|
refObjects[4].sZ = ScatterObjRoll.sZ4.value
|
|
refObjects[4].zRotVal = ScatterObjRoll.zRot4.selection
|
|
)
|
|
|
|
5:(refObjects[5].zAlign = ScatterObjRoll.zAlign5.state
|
|
refObjects[5].zOffset = ScatterObjRoll.zOff5.value
|
|
refObjects[5].sXY = ScatterObjRoll.sXY5.value
|
|
refObjects[5].sZ = ScatterObjRoll.sZ5.value
|
|
refObjects[5].zRotVal = ScatterObjRoll.zRot5.selection
|
|
)
|
|
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
---------------------------------------------------------------------------------
|
|
|
|
fn getViewDirectionRay =
|
|
(
|
|
local coordSysTM = Inverse(getViewTM())
|
|
local viewDir = -coordSysTM.row3
|
|
local viewPt = coordSysTM.row4
|
|
return ray viewPt viewDir
|
|
)
|
|
|
|
---------------------------------------------------------------------------------
|
|
fn drawLineQuick pointA pointB =
|
|
|
|
(
|
|
|
|
ss = SplineShape pos:pointA
|
|
|
|
addNewSpline ss
|
|
|
|
addKnot ss 1 #corner #line PointA
|
|
|
|
addKnot ss 1 #corner #line PointB
|
|
|
|
updateShape ss
|
|
|
|
ss
|
|
|
|
)
|
|
|
|
---------------------------------------------------------------------------------
|
|
|
|
fn findSurfacePos obj mousePos =
|
|
(
|
|
|
|
local ray deathray = mapScreenToWorldRay mousePos
|
|
|
|
local px = ((deathray.dir.x * 2000)+deathray.pos.x)
|
|
local py = ((deathray.dir.y * 2000)+deathray.pos.y)
|
|
local pz = ((deathray.dir.z * 2000)+deathray.pos.z)
|
|
|
|
-- line debugger
|
|
--drawLineQuick deathray.pos [px,py,pz]
|
|
|
|
--local ray dahitray = IntersectRay Ebase_object deathray
|
|
local surfHitRay2 = IntersectRayEx obj deathray
|
|
|
|
--if surfHitRay2 != undefined then return surfHitRay2
|
|
return surfHitRay2
|
|
)
|
|
|
|
---------------------------------------------------------------------------------
|
|
|
|
fn plantObject theObject facAlign zOffset xyScale zScale zaxis_rot =
|
|
(
|
|
|
|
-- cast ray from mouse point
|
|
local CheckHitRay2 = findSurfacePos baseMeshObj theMousePos
|
|
print " HITRAY2 "
|
|
print CheckHitRay2
|
|
|
|
-- if ray hits base object then it will have defnintion
|
|
if CheckHitRay2 != undefined then
|
|
(
|
|
|
|
-- create new object and find face to plant to
|
|
newobj = copy theObject
|
|
newobj.pos = CheckHitRay2[1].pos
|
|
newobj.wirecolor = red
|
|
|
|
faceID = CheckHitRay2[2]
|
|
faceNormal = in coordsys world (getFaceNormal baseMeshObj faceID )
|
|
|
|
-- Align to face if checked
|
|
if facAlign then newobj.dir = faceNormal
|
|
|
|
-- Offset object if float height set
|
|
if zOffset != 0 then
|
|
(
|
|
objdiffx =(zOffset * faceNormal.x)
|
|
objdiffy = (zOffset * faceNormal.y)
|
|
objdiffz = (zOffset * faceNormal.z)
|
|
|
|
move newobj [objdiffx,objdiffy, objdiffz]
|
|
)
|
|
|
|
----------------------
|
|
-- z-rotation stuff
|
|
----------------------
|
|
|
|
if zaxis_rot == 0 then
|
|
(
|
|
--no rotation on z
|
|
)
|
|
else
|
|
(
|
|
if zaxis_rot == 2 then
|
|
(
|
|
--random rotation
|
|
rndZrot = eulerangles 0 0 (random 0 360)
|
|
in coordsys newobj rotate newobj rndZrot
|
|
)
|
|
else if zaxis_rot == 3 then
|
|
(
|
|
--rotation of 0 degrees
|
|
|
|
)
|
|
else if zaxis_rot == 4 then
|
|
(
|
|
--rotation of 90 degrees
|
|
rndZrot = eulerangles 0 0 90
|
|
in coordsys world rotate newobj rndZrot
|
|
|
|
)
|
|
else if zaxis_rot == 5 then
|
|
(
|
|
--rotation of 180 degrees
|
|
rndZrot = eulerangles 0 0 180
|
|
in coordsys world rotate newobj rndZrot
|
|
|
|
)
|
|
else if zaxis_rot == 5 then
|
|
(
|
|
--rotation of 270 degrees
|
|
rndZrot = eulerangles 0 0 270
|
|
in coordsys world rotate newobj rndZrot
|
|
|
|
)
|
|
)
|
|
|
|
-----------------------
|
|
-- scale stuff
|
|
-----------------------
|
|
|
|
scaleOff = ( random 0.0 xyScale )/100
|
|
|
|
if xyScale != 0 then
|
|
(
|
|
--scaleOff = ( random 0.0 xyScale )/100
|
|
newXYscale = 1.0 + scaleOff
|
|
newobj.scale = [newXYscale, newXYscale, 1]
|
|
|
|
)
|
|
|
|
if zScale != 0 then
|
|
(
|
|
--scaleOff = ( random 0.0 zScale )/100
|
|
newZscale = 1.0 + scaleOff
|
|
newobj.scale = [1, 1, newZscale]
|
|
|
|
)
|
|
|
|
-- update last plant location
|
|
lastObjPos = CheckHitRay2[1].pos
|
|
-- add to array of planted objects ( for undo )
|
|
append plantedObjects newobj
|
|
|
|
|
|
|
|
) else numofObjects = numofObjects - 1
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
----------------------------------------------------------------------------------------------
|
|
-- Rollouts
|
|
----------------------------------------------------------------------------------------------
|
|
|
|
--scattering options
|
|
rollout PlantFuncRoll "menu" width:480 height:256
|
|
(
|
|
|
|
--UI--
|
|
|
|
--groupBox scatterGrp "Scatter" pos:[8,8] width:464 height:208
|
|
hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Scatterer" align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255)
|
|
pickButton pickBaseMesh "Pick Base Mesh" pos:[144,32] width:192 height:24
|
|
|
|
button loadObjects "Load Selected Objects" pos:[144,64] width:192 height:24
|
|
checkbutton goRPlant "Plant Random" pos:[188,120] width:100 height:36
|
|
|
|
|
|
|
|
|
|
fn ResetScatterObjRoll =
|
|
(
|
|
|
|
--resets values in Object list for planting
|
|
ScatterObjRoll.selObj1.caption = "-----"
|
|
ScatterObjRoll.selObj2.caption = "-----"
|
|
ScatterObjRoll.selObj3.caption = "-----"
|
|
ScatterObjRoll.selObj4.caption = "-----"
|
|
ScatterObjRoll.selObj5.caption = "-----"
|
|
|
|
ScatterObjRoll.sXY1.value = 0
|
|
ScatterObjRoll.sZ1.value = 0
|
|
ScatterObjRoll.sXY1.enabled = true
|
|
ScatterObjRoll.sZ1.enabled = true
|
|
|
|
ScatterObjRoll.sXY2.value = 0
|
|
ScatterObjRoll.sZ2.value = 0
|
|
ScatterObjRoll.sXY2.enabled = true
|
|
ScatterObjRoll.sZ2.enabled = true
|
|
|
|
ScatterObjRoll.sXY3.value = 0
|
|
ScatterObjRoll.sZ3.value = 0
|
|
ScatterObjRoll.sXY3.enabled = true
|
|
ScatterObjRoll.sZ3.enabled = true
|
|
|
|
ScatterObjRoll.sXY4.value = 0
|
|
ScatterObjRoll.sZ4.value = 0
|
|
ScatterObjRoll.sXY4.enabled = true
|
|
ScatterObjRoll.sZ4.enabled = true
|
|
|
|
ScatterObjRoll.sXY5.value = 0
|
|
ScatterObjRoll.sZ5.value = 0
|
|
ScatterObjRoll.sXY5.enabled = true
|
|
ScatterObjRoll.sZ5.enabled = true
|
|
|
|
ScatterObjRoll.distObj1.value = 0
|
|
ScatterObjRoll.distObj2.value = 0
|
|
ScatterObjRoll.distObj3.value = 0
|
|
ScatterObjRoll.distObj4.value = 0
|
|
ScatterObjRoll.distObj5.value = 0
|
|
|
|
ScatterObjRoll.zRot1.selection = 1
|
|
ScatterObjRoll.zRot2.selection = 1
|
|
ScatterObjRoll.zRot3.selection = 1
|
|
ScatterObjRoll.zRot4.selection = 1
|
|
ScatterObjRoll.zRot5.selection = 1
|
|
|
|
ScatterObjRoll.zAlign1.checked = false
|
|
ScatterObjRoll.zAlign2.checked = false
|
|
ScatterObjRoll.zAlign3.checked = false
|
|
ScatterObjRoll.zAlign4.checked = false
|
|
ScatterObjRoll.zAlign5.checked = false
|
|
|
|
)
|
|
----------------------------------------------------------------------------------
|
|
--EVENTS
|
|
----------------------------------------------------------------------------------
|
|
-------------------------------------------------------------------------------
|
|
--Mousetool for planting
|
|
-------------------------------------------------------------------------------
|
|
|
|
tool clickyplanter
|
|
(
|
|
on mousePoint clickno do
|
|
(
|
|
if startPlant do
|
|
(
|
|
--plant object, test objects defined
|
|
if objCount > 0 then
|
|
(
|
|
if baseMeshObj != undefined then
|
|
(
|
|
if ctrlKey == false then
|
|
(
|
|
|
|
|
|
theMousePos = viewPoint
|
|
numofObjects = numofObjects + 1
|
|
if numofObjects > 1 then
|
|
(
|
|
plantcheck = plantedObjects.count
|
|
|
|
if goRPlant.state == true then
|
|
(
|
|
|
|
plantThis = findRandomPlant()
|
|
|
|
)
|
|
|
|
-- call plantobject align z-offset xyScale zScale Zaxis_rotation
|
|
print " PLANTING "
|
|
print plantThis
|
|
|
|
loadObjectParameters plantThis
|
|
try(
|
|
plantObject refObjects[plantThis].pObject refObjects[plantThis].zAlign refObjects[plantThis].zOffset refObjects[plantThis].sXY refObjects[plantThis].sZ refObjects[plantThis].zRotVal
|
|
) catch ()
|
|
|
|
)
|
|
else
|
|
(
|
|
|
|
dahitray = findSurfacePos baseMeshObj theMousePos
|
|
if dahitray != undefined then
|
|
(
|
|
lastObjPos = dahitray[1].pos
|
|
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
else
|
|
(
|
|
|
|
-- delete last plant
|
|
objCount = plantedObjects.count
|
|
if objCount > 1 then
|
|
(
|
|
select plantedObjects[objCount]
|
|
delete plantedObjects[objCount]
|
|
deleteItem plantedObjects objCount
|
|
|
|
lastObjPos = plantedObjects[objCount-1].pos
|
|
|
|
|
|
|
|
)
|
|
)
|
|
|
|
)
|
|
)
|
|
)
|
|
|
|
|
|
|
|
)
|
|
|
|
on stop do
|
|
(
|
|
startPlant = false
|
|
--turn off UI buttons
|
|
goRPlant.state = false
|
|
ScatterObjRoll.plantObj1.state = false
|
|
ScatterObjRoll.plantObj2.state = false
|
|
ScatterObjRoll.plantObj3.state = false
|
|
ScatterObjRoll.plantObj4.state = false
|
|
ScatterObjRoll.plantObj5.state = false
|
|
)
|
|
|
|
)
|
|
|
|
on loadObjects pressed do
|
|
(
|
|
|
|
|
|
selset = getcurrentSelection()
|
|
|
|
|
|
if selset.count > 0 then
|
|
(
|
|
|
|
ScatterObjRoll.open = true
|
|
|
|
ResetScatterObjRoll()
|
|
|
|
if selset.count > 5 then objCount = 5 else objCount = selset.count
|
|
|
|
--load structure for handling decal objects
|
|
-- would love to do in loop, but unique ui names in decal object ui prevents this
|
|
refObjects[1] = objStruct()
|
|
refObjects[1].pObject = selset[1]
|
|
refObjects[1].zAlign = ScatterObjRoll.zAlign1.state
|
|
refObjects[1].zOffset = ScatterObjRoll.zOff1.value
|
|
refObjects[1].sXY = ScatterObjRoll.sXY1.value
|
|
refObjects[1].sZ = ScatterObjRoll.sZ1.value
|
|
refObjects[1].zRotVal = ScatterObjRoll.zRot1.selection
|
|
-- distribution set as equal
|
|
refObjects[1].oDistVal = ScatterObjRoll.distObj1.value = (6-objcount)
|
|
|
|
--ScatterObjRoll.selObj1.object = selset[1]
|
|
ScatterObjRoll.selObj1.caption = selset[1].name
|
|
|
|
|
|
--xref check ( disable scale )
|
|
ScatterObjRoll.sXY1.enabled = true
|
|
ScatterObjRoll.sZ1.enabled = true
|
|
if isRefObj selset[1] do
|
|
(
|
|
ScatterObjRoll.sXY1.enabled = false
|
|
ScatterObjRoll.sZ1.enabled = false
|
|
)
|
|
|
|
if objCount > 1 then
|
|
(
|
|
refObjects[2] = objStruct()
|
|
refObjects[2].pObject = selset[2]
|
|
refObjects[2].zAlign = ScatterObjRoll.zAlign2.state
|
|
refObjects[2].zOffset = ScatterObjRoll.zOff2.value
|
|
refObjects[2].sXY = ScatterObjRoll.sXY2.value
|
|
refObjects[2].sZ = ScatterObjRoll.sZ2.value
|
|
refObjects[2].zRotVal = ScatterObjRoll.zRot2.selection
|
|
-- distribution set as equal
|
|
refObjects[2].oDistVal = ScatterObjRoll.distObj2.value = (6-objcount)
|
|
|
|
--ScatterObjRoll.selObj2.object = selset[2]
|
|
ScatterObjRoll.selObj2.caption = selset[2].name
|
|
|
|
--xref check ( disable scale )
|
|
ScatterObjRoll.sXY2.enabled = true
|
|
ScatterObjRoll.sZ2.enabled = true
|
|
if isRefObj selset[2] do
|
|
(
|
|
ScatterObjRoll.sXY2.enabled = false
|
|
ScatterObjRoll.sZ2.enabled = false
|
|
)
|
|
|
|
if objCount > 2 then
|
|
(
|
|
refObjects[3] = objStruct()
|
|
refObjects[3].pObject = selset[3]
|
|
refObjects[3].zAlign = ScatterObjRoll.zAlign3.state
|
|
refObjects[3].zOffset = ScatterObjRoll.zOff3.value
|
|
refObjects[3].sXY = ScatterObjRoll.sXY3.value
|
|
refObjects[3].sZ = ScatterObjRoll.sZ3.value
|
|
refObjects[3].zRotVal = ScatterObjRoll.zRot3.selection
|
|
-- distribution set as equal
|
|
refObjects[3].oDistVal = ScatterObjRoll.distObj3.value = (6-objcount)
|
|
|
|
--ScatterObjRoll.selObj3.object = selset[3]
|
|
ScatterObjRoll.selObj3.caption = selset[3].name
|
|
|
|
--xref check ( disable scale )
|
|
ScatterObjRoll.sXY3.enabled = true
|
|
ScatterObjRoll.sZ3.enabled = true
|
|
if isRefObj selset[3] do
|
|
(
|
|
ScatterObjRoll.sXY3.enabled = false
|
|
ScatterObjRoll.sZ3.enabled = false
|
|
)
|
|
|
|
|
|
if objCount >3 then
|
|
(
|
|
|
|
|
|
refObjects[4] = objStruct()
|
|
refObjects[4].pObject = selset[4]
|
|
refObjects[4].zAlign = ScatterObjRoll.zAlign4.state
|
|
refObjects[4].zOffset = ScatterObjRoll.zOff4.value
|
|
refObjects[4].sXY = ScatterObjRoll.sXY4.value
|
|
refObjects[4].sZ = ScatterObjRoll.sZ4.value
|
|
refObjects[4].zRotVal = ScatterObjRoll.zRot4.selection
|
|
-- distribution set as equal
|
|
refObjects[4].oDistVal = ScatterObjRoll.distObj4.value = (6-objcount)
|
|
|
|
--ScatterObjRoll.selObj4.object = selset[4]
|
|
ScatterObjRoll.selObj4.caption = selset[4].name
|
|
|
|
--xref check ( disable scale )
|
|
ScatterObjRoll.sXY4.enabled = true
|
|
ScatterObjRoll.sZ4.enabled = true
|
|
if isRefObj selset[4] do
|
|
(
|
|
ScatterObjRoll.sXY4.enabled = false
|
|
ScatterObjRoll.sZ4.enabled = false
|
|
)
|
|
|
|
|
|
if objCount > 4 then
|
|
(
|
|
|
|
refObjects[5] = objStruct()
|
|
refObjects[5].pObject = selset[5]
|
|
refObjects[5].zAlign = ScatterObjRoll.zAlign5.state
|
|
refObjects[5].zOffset = ScatterObjRoll.zOff5.value
|
|
refObjects[5].sXY = ScatterObjRoll.sXY5.value
|
|
refObjects[5].sZ = ScatterObjRoll.sZ5.value
|
|
refObjects[5].zRotVal = ScatterObjRoll.zRot5.selection
|
|
-- distribution set as equal
|
|
refObjects[5].oDistVal = ScatterObjRoll.distObj5.value = (6-objcount)
|
|
|
|
--ScatterObjRoll.selObj5.object = selset[5]
|
|
ScatterObjRoll.selObj5.caption = selset[5].name
|
|
|
|
--xref check ( disable scale )
|
|
ScatterObjRoll.sXY5.enabled = true
|
|
ScatterObjRoll.sZ5.enabled = true
|
|
if isRefObj selset[5] do
|
|
(
|
|
ScatterObjRoll.sXY5.enabled = false
|
|
ScatterObjRoll.sZ5.enabled = false
|
|
)
|
|
|
|
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
-----------------------------
|
|
-- Base mesh to plant on picked
|
|
-----------------------------
|
|
on pickBaseMesh picked obj do
|
|
(
|
|
|
|
if classof obj == editable_mesh then
|
|
(
|
|
|
|
baseMeshObj = obj
|
|
pickBaseMesh.text = baseMeshObj.name
|
|
|
|
|
|
|
|
)
|
|
else
|
|
(
|
|
messagebox "Base has to be Editable Mesh"
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
-----------------------------
|
|
-- Start random planting
|
|
-----------------------------
|
|
on goRPlant changed state do
|
|
(
|
|
if goRPlant.state == true then
|
|
(
|
|
if objCount != undefined then
|
|
(
|
|
if baseMeshObj != undefined then
|
|
(
|
|
startPlant = true
|
|
numOfObjects = 0
|
|
plantedObjects = #()
|
|
|
|
startTool clickyplanter
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
goRPlant.state = false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
goRPlant.state = false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
goRPlant.state = false
|
|
)
|
|
)
|
|
|
|
|
|
|
|
)
|
|
|
|
--scatterer rollout
|
|
rollout ScatterFuncRoll "Scatter" rolledup:true width:480 height:190
|
|
(
|
|
local useBBox
|
|
local useSFaces
|
|
local scObjCount = 20
|
|
local scatteredObjects = #()
|
|
|
|
hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Scatterer" align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255)
|
|
spinner plantCountNum "" pos:[248,8] width:48 height:16 range:[0,50000,20] scale:1 type:#integer
|
|
label plantCountLab "Plant Count" pos:[160,8] width:64 height:16
|
|
|
|
--spinner spacingDist "" pos:[248,32] width:72 height:16 range:[0,100,1] scale:1
|
|
--label spacingLab "Spacing" pos:[160,32] width:64 height:16
|
|
checkbox useBoundBox "" pos:[165,24] width:24 height:32
|
|
label usesbbox "Avoid overlap" pos:[196,32] width:152 height:32
|
|
|
|
checkbox useBaseFaces "" pos:[165,48] width:24 height:32
|
|
label usebflab "Use Selected Faces" pos:[196,57] width:152 height:32
|
|
|
|
checkbox delPrevScatter "" pos:[165,72] width:24 height:32 checked:true
|
|
label delScatlab "Re-Generate Scatter" pos:[196,81] width:152 height:32
|
|
|
|
button goGenerate "Generate" pos:[185,108] width:100 height:36
|
|
|
|
--Functions
|
|
fn scatterColCheck scatObject =
|
|
(
|
|
-- if colcheck not checked the ignore
|
|
if useBoundBox.checked == false then return false
|
|
|
|
for n = 1 to scatteredObjects.count do
|
|
(
|
|
|
|
ctest = intersects scatObject scatteredObjects[n]
|
|
|
|
if ctest == true then
|
|
(
|
|
|
|
return true
|
|
|
|
)
|
|
|
|
)
|
|
|
|
return false
|
|
|
|
)
|
|
|
|
fn plantScatterObject NuPos faceID theObject facAlign zOffset xyScale zScale zaxis_rot =
|
|
(
|
|
|
|
|
|
-- create new object and find face to plant to
|
|
newobj = copy theObject
|
|
newobj.pos = NuPos
|
|
newobj.wirecolor = red
|
|
|
|
colCheck = scatterColCheck newobj
|
|
|
|
|
|
if colCheck == false then
|
|
(
|
|
|
|
|
|
|
|
faceNormal = in coordsys world (getFaceNormal baseMeshObj faceID )
|
|
|
|
-- Align to face if checked
|
|
if facAlign then newobj.dir = faceNormal
|
|
|
|
-- Offset object if float height set
|
|
if zOffset != 0 then
|
|
(
|
|
objdiffx =(zOffset * faceNormal.x)
|
|
objdiffy = (zOffset * faceNormal.y)
|
|
objdiffz = (zOffset * faceNormal.z)
|
|
|
|
move newobj [objdiffx,objdiffy, objdiffz]
|
|
)
|
|
|
|
----------------------
|
|
-- z-rotation stuff
|
|
----------------------
|
|
|
|
if zaxis_rot == 0 then
|
|
(
|
|
--no rotation on z
|
|
)
|
|
else
|
|
(
|
|
if zaxis_rot == 2 then
|
|
(
|
|
--random rotation
|
|
rndZrot = eulerangles 0 0 (random 0 360)
|
|
in coordsys newobj rotate newobj rndZrot
|
|
)
|
|
else if zaxis_rot == 3 then
|
|
(
|
|
--rotation of 0 degrees
|
|
|
|
)
|
|
else if zaxis_rot == 4 then
|
|
(
|
|
--rotation of 90 degrees
|
|
rndZrot = eulerangles 0 0 90
|
|
in coordsys world rotate newobj rndZrot
|
|
|
|
)
|
|
else if zaxis_rot == 5 then
|
|
(
|
|
--rotation of 180 degrees
|
|
rndZrot = eulerangles 0 0 180
|
|
in coordsys world rotate newobj rndZrot
|
|
|
|
)
|
|
else if zaxis_rot == 5 then
|
|
(
|
|
--rotation of 270 degrees
|
|
rndZrot = eulerangles 0 0 270
|
|
in coordsys world rotate newobj rndZrot
|
|
|
|
)
|
|
)
|
|
|
|
-----------------------
|
|
-- scale stuff
|
|
-----------------------
|
|
scaleOff = ( random 0.0 xyScale )/100
|
|
|
|
if xyScale != 0 then
|
|
(
|
|
--scaleOff = ( random 0.0 xyScale )/100
|
|
newXYscale = 1.0 + scaleOff
|
|
newobj.scale = [newXYscale, newXYscale, 1]
|
|
|
|
)
|
|
|
|
if zScale != 0 then
|
|
(
|
|
--scaleOff = ( random 0.0 zScale )/100
|
|
newZscale = 1.0 + scaleOff
|
|
newobj.scale = [1, 1, newZscale]
|
|
|
|
)
|
|
|
|
-- update last plant location
|
|
lastObjPos = nuPos
|
|
-- add to array of planted objects ( for undo )
|
|
append scatteredObjects newobj
|
|
|
|
) else delete newobj
|
|
|
|
)
|
|
|
|
fn scatterObject =
|
|
(
|
|
--pick random face
|
|
numFaces = getNumFaces baseMeshObj
|
|
baseFaceList = baseMeshObj.faces
|
|
|
|
if useBaseFaces.checked == true then
|
|
(
|
|
|
|
baseFaceList = baseMeshObj.selectedFaces
|
|
numFaces = baseFaceList.count
|
|
|
|
)
|
|
|
|
randFace = random 1 numFaces
|
|
pFace = baseFaceList[randFace].index
|
|
|
|
|
|
--generate random barycentric position
|
|
px = random 0.0 1.0
|
|
nr = 1.0 - px
|
|
py = random 0.0 nr
|
|
pz = 1 - (px + py)
|
|
|
|
pOrder = random 1 3
|
|
|
|
if pOrder == 1 then
|
|
(
|
|
newVect = [px,py,pz]
|
|
) else if pOrder == 2 then
|
|
(
|
|
newVect = [py,pz,px]
|
|
) else newVect = [pz,px,py]
|
|
|
|
facVerts = (meshop.getVertsUsingFace baseMeshObj pFace) as array
|
|
|
|
pPos = [0,0,0]
|
|
|
|
v1= getVert baseMeshObj facVerts[1]
|
|
v2= getVert baseMeshObj facVerts[2]
|
|
v3= getVert baseMeshObj facVerts[3]
|
|
|
|
pPos.x= (newVect.x * v1.x) + (newVect.y * v2.x) + (newVect.z * v3.x)
|
|
pPos.y= (newVect.x * v1.y) + (newVect.y * v2.y) + (newVect.z * v3.y)
|
|
pPos.z= (newVect.x * v1.z) + (newVect.y * v2.z) + (newVect.z * v3.z)
|
|
|
|
--Pick random object to scatter
|
|
plantThis = findRandomPlant()
|
|
|
|
--plant scatter object call
|
|
loadObjectParameters plantThis
|
|
try(
|
|
plantScatterObject pPos pFace refObjects[plantThis].pObject refObjects[plantThis].zAlign refObjects[plantThis].zOffset refObjects[plantThis].sXY refObjects[plantThis].sZ refObjects[plantThis].zRotVal
|
|
) catch ()
|
|
)
|
|
|
|
|
|
|
|
|
|
--Events
|
|
on plantCountNum changed pcount do
|
|
(
|
|
|
|
scObjCount = pcount
|
|
|
|
)
|
|
|
|
on goGenerate pressed do
|
|
(
|
|
|
|
--delete old set of scatters if there and option checked
|
|
if delPrevScatter.state == true then
|
|
(
|
|
if scatteredObjects != undefined then
|
|
(
|
|
try(
|
|
select scatteredObjects
|
|
delete scatteredObjects
|
|
) catch ()
|
|
|
|
)
|
|
)
|
|
|
|
if objCount != undefined then
|
|
(
|
|
if baseMeshObj != undefined then
|
|
(
|
|
numOfObjects = 0
|
|
scatteredObjects = #()
|
|
for n = 1 to scObjCount do
|
|
(
|
|
scatterObject()
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
--rollout for planting objects
|
|
rollout ScatterObjRoll "Decal Objects" rolledup:true width:480 height:240
|
|
(
|
|
--ui
|
|
groupBox grp1 "Object Control" pos:[8,8] width:464 height:208
|
|
label lbl7 "Object Name" pos:[16,32] width:80 height:16
|
|
label lbl8 "Align" pos:[128,32] width:32 height:16
|
|
label lbl9 "Weight" pos:[372,32] width:80 height:16
|
|
hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Scatterer" align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255) pos:[440,25]
|
|
label lblzrot "Z-Rot" pos:[324,32] width:32 height:16
|
|
label lbl17 "Z offset" pos:[176,32] width:48 height:16
|
|
label lbl12 "xy%" pos:[236,41] width:24 height:16
|
|
label lbl13 "z%" pos:[278,41] width:24 height:16
|
|
label lbl14 "Scale offset" pos:[236,25] width:64 height:16
|
|
|
|
label selObj1 "-----" pos:[16,60] width:112 height:16
|
|
spinner distObj1 "" pos:[372,59] width:36 height:16 range:[0,5,0] type:#integer
|
|
checkbox zAlign1 "" pos:[136,60] width:16 height:16
|
|
spinner zOff1 "" pos:[168,59] width:53 height:16 range:[-100,100,0]
|
|
spinner sXY1 "" pos:[236,58] width:37 height:16 range:[0,999,0] type:#integer
|
|
spinner sZ1 "" pos:[276,57] width:37 height:16 range:[0,999,0] type:#integer
|
|
dropdownlist zRot1 "" pos:[320,56] width:50 height:7 items:#( "none", "rand", "0", "90", "180", "270" )
|
|
checkbutton plantObj1 "Plant" pos:[424,56] width:40 height:24
|
|
|
|
label selObj2 "-----" pos:[16,92] width:112 height:16
|
|
spinner distObj2 "" pos:[372,92] width:36 height:16 range:[0,5,0] type:#integer
|
|
checkbox zAlign2 "" pos:[136,92] width:16 height:16
|
|
spinner zOff2 "" pos:[168,92] width:53 height:16 range:[-100,100,0]
|
|
spinner sXY2 "" pos:[236,92] width:37 height:16 range:[0,999,0] type:#integer
|
|
spinner sZ2 "" pos:[276,92] width:37 height:16 range:[0,999,0] type:#integer
|
|
dropdownlist zRot2 "" pos:[320,90] width:50 height:7 items:#( "none", "rand", "0", "90", "180", "270" )
|
|
checkbutton plantObj2 "Plant" pos:[424,90] width:40 height:24
|
|
|
|
label selObj3 "-----" pos:[16,124] width:112 height:16
|
|
spinner distObj3 "" pos:[372,124] width:36 height:16 range:[0,5,0] type:#integer
|
|
checkbox zAlign3 "" pos:[136,124] width:16 height:16
|
|
spinner zOff3 "" pos:[168,124] width:53 height:16 range:[-100,100,0]
|
|
spinner sXY3 "" pos:[236,124] width:37 height:16 range:[0,999,0] type:#integer
|
|
spinner sZ3 "" pos:[276,124] width:37 height:16 range:[0,999,0] type:#integer
|
|
dropdownlist zRot3 "" pos:[320,122] width:50 height:7 items:#( "none", "rand", "0", "90", "180", "270" )
|
|
checkbutton plantObj3 "Plant" pos:[424,120] width:40 height:24
|
|
|
|
label selObj4 "-----" pos:[16,156] width:112 height:16
|
|
spinner distObj4 "" pos:[372,156] width:36 height:16 range:[0,5,0] type:#integer
|
|
checkbox zAlign4 "" pos:[136,156] width:16 height:16
|
|
spinner zOff4 "" pos:[168,156] width:53 height:16 range:[-100,100,0]
|
|
spinner sXY4 "" pos:[236,156] width:37 height:16 range:[0,999,0] type:#integer
|
|
spinner sZ4 "" pos:[276,156] width:37 height:16 range:[0,999,0] type:#integer
|
|
dropdownlist zRot4 "" pos:[320,154] width:50 height:7 items:#( "none", "rand", "0", "90", "180", "270" )
|
|
checkbutton plantObj4 "Plant" pos:[424,152] width:40 height:24
|
|
|
|
label selObj5 "-----" pos:[16,188] width:112 height:16
|
|
spinner distObj5 "" pos:[372,188] width:36 height:16 range:[0,5,0] type:#integer
|
|
checkbox zAlign5 "" pos:[136,188] width:16 height:16
|
|
spinner zOff5 "" pos:[168,188] width:53 height:16 range:[-100,100,0]
|
|
spinner sXY5 "" pos:[236,188] width:37 height:16 range:[0,999,0] type:#integer
|
|
spinner sZ5 "" pos:[276,188] width:37 height:16 range:[0,999,0] type:#integer
|
|
dropdownlist zRot5 "" pos:[320,186] width:50 height:7 items:#( "none", "rand", "0", "90", "180", "270" )
|
|
checkbutton plantObj5 "Plant" pos:[424,184] width:40 height:24
|
|
|
|
|
|
-----------------------------
|
|
-- Start planting object 1
|
|
-----------------------------
|
|
on plantObj1 changed state do
|
|
(
|
|
if plantObj1.state == true then
|
|
(
|
|
if objCount != undefined then
|
|
(
|
|
if baseMeshObj != undefined then
|
|
(
|
|
startPlant = true
|
|
plantThis = 1
|
|
numOfObjects = 0
|
|
plantedObjects = #()
|
|
|
|
startTool PlantFuncRoll.clickyplanter
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj1.state = false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj1.state = false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj1.state = false
|
|
)
|
|
)
|
|
|
|
-----------------------------
|
|
-- Start planting object 2
|
|
-----------------------------
|
|
on plantObj2 changed state do
|
|
(
|
|
if plantObj2.state == true then
|
|
(
|
|
if objCount > 1 then
|
|
(
|
|
if baseMeshObj != undefined then
|
|
(
|
|
startPlant = true
|
|
plantThis = 2
|
|
numOfObjects = 0
|
|
plantedObjects = #()
|
|
|
|
startTool PlantFuncRoll.clickyplanter
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj2.state = false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj2.state = false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj2.state = false
|
|
)
|
|
)
|
|
|
|
-----------------------------
|
|
-- Start planting object 3
|
|
-----------------------------
|
|
on plantObj3 changed state do
|
|
(
|
|
if plantObj3.state == true then
|
|
(
|
|
if objCount > 2 then
|
|
(
|
|
if baseMeshObj != undefined then
|
|
(
|
|
startPlant = true
|
|
plantThis = 3
|
|
numOfObjects = 0
|
|
plantedObjects = #()
|
|
|
|
startTool PlantFuncRoll.clickyplanter
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj3.state = false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj3.state = false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj3.state = false
|
|
)
|
|
)
|
|
|
|
|
|
|
|
-----------------------------
|
|
-- Start planting object 4
|
|
-----------------------------
|
|
on plantObj4 changed state do
|
|
(
|
|
if plantObj4.state == true then
|
|
(
|
|
if objCount > 3 then
|
|
(
|
|
if baseMeshObj != undefined then
|
|
(
|
|
startPlant = true
|
|
plantThis = 4
|
|
numOfObjects = 0
|
|
plantedObjects = #()
|
|
|
|
startTool PlantFuncRoll.clickyplanter
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj4.state = false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj4.state = false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj4.state = false
|
|
)
|
|
)
|
|
|
|
-----------------------------
|
|
-- Start planting object 5
|
|
-----------------------------
|
|
on plantObj5 changed state do
|
|
(
|
|
if plantObj5.state == true then
|
|
(
|
|
if objCount == 5 then
|
|
(
|
|
if baseMeshObj != undefined then
|
|
(
|
|
startPlant = true
|
|
plantThis = 5
|
|
numOfObjects = 0
|
|
plantedObjects = #()
|
|
|
|
startTool PlantFuncRoll.clickyplanter
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj5.state = false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj5.state = false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
startPlant = false
|
|
plantObj5.state = false
|
|
)
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- rollout and floater generation
|
|
if scatterFloat != undefined then closerolloutfloater scatterFloat
|
|
scatterFloat = newrolloutfloater "Scatterer" 500 400 100 100
|
|
addrollout PlantFuncRoll scatterFloat
|
|
addrollout ScatterFuncRoll scatterFloat
|
|
addrollout ScatterObjRoll scatterFloat
|