Files
2025-09-29 00:52:08 +02:00

354 lines
10 KiB
Plaintext
Executable File

FileIn (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
rsta_loadCommonFunction #("FN_RSTA_userSettings")
try (destroyDialog embedRoadRoll) catch()
rollout embedRoadRoll "Embed Road Tool" width:200
(
-------------------------------------------------
-- LOCALS
-------------------------------------------------
local ground
local road
local roadSections
local Settings = rsta_userSettings app:"embedRoad"
local isDebugMode = false
-------------------------------------------------
-- CONTROLS
-------------------------------------------------
dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:embedRoadRoll.Width
local banner = makeRsBanner dn_Panel:rsBannerPanel versionNum:1.02 versionName:"" wiki:"EmbedRoadTool" filename:(getThisScriptFilename())
button btn_pickGround ">> Set Ground Tile <<" width:190
button btn_pickRoad ">> Set Road Sections <<" width:190
group "Options"
(
spinner spn_GrowShrink "Grow/Shrink Sel :" fieldwidth:50 align:#right type:#integer range:[-10,10,0]
spinner spn_Offset "Offset Downwards :" fieldwidth:50 align:#right range:[-10,10,0.1]
)
group "Soft Selection"
(
spinner spn_falloff "Falloff :" fieldwidth:50 align:#right
spinner spn_pinch "Pinch :" fieldwidth:50 align:#right range:[-5,5,0]
spinner spn_bubble "Bubble :" fieldwidth:50 align:#right range:[-5,5,0]
)
button btn_applyToGround "Apply To Ground" width:190
progressbar pb_bar width:190 color:(color 246 186 0) offset:[-8,0] height:10
-------------------------------------------------
-- FUNCITONS
-------------------------------------------------
fn pick_road =
(
if (selection.count != 0) do
(
roadSections = #()
for i in (getCurrentSelection()) do
(
if (classof_array #(editable_poly, editable_mesh) i AND i != ground) do append roadSections i
)
btn_pickRoad.text = "Road : " + roadSections.count as string + " Sections"
)
)
-------------------------------------------------
fn pick_ground =
(
if (selection.count != 0) do
(
if (classof_array #(editable_poly, editable_mesh) selection[1]) AND selection[1] != road do
(
ground = selection[1]
btn_pickGround.text = "Ground: " + ground.name
)
)
)
-------------------------------------------------
fn addPercent value percent =
(
value + ((value/100) * percent)
)
-------------------------------------------------
fn chopRoad =
(
road = undefined
for i in roadSections do
(
local temp = copy i
convertToPoly temp
if road == undefined then road = temp
else polyop.attach road temp
)
local groundBB = ground.max - ground.min
local volBox = Box lengthsegs:1 widthsegs:1 heightsegs:1 length:(addPercent groundBB.y 5) width:(addPercent groundBB.x 5) height:10000 pos:[ground.center.x,ground.center.y,ground.min.z-5000]
local vol_mod = Vol__Select level:2 type:1 invert:true method:0 volume:3
addModifier road vol_mod
vol_mod.node = volBox
addModifier road (DeleteMesh())
convertToMesh road
road.pivot = road.center
if not (isDebugMode) do delete volBox
-- RESET XFORMS
ResetXForm road
convertToMesh road
)
-------------------------------------------------
fn getWorldPos obj rm closest:true =
(
local closetsFace = if (closest) then rm.getClosestHit() else rm.getFarthestHit()
local face = rm.getHitFace closetsFace
local bary = rm.getHitBary closetsFace
local faceVerts = getFace obj face
return (((getVert obj faceVerts[1]) * bary.x) + ((getVert obj faceVerts[2]) * bary.y) + ((getVert obj faceVerts[3]) * bary.z))
)
-------------------------------------------------
fn applyToGround =
(
if (ground != undefined AND roadSections.count != 0) then
(
undo "Embed Road" on
(
chopRoad()
max modify mode
roadIsPoly = if (classof road == Editable_Poly) then true else false
groundIsPoly = if (classof ground == Editable_Poly) then true else false
convertToMesh ground
convertToMesh road
local divisions = 40
local proxy = plane pos:ground.center width:(addPercent (ground.max - ground.min).x 10) length:(addPercent (ground.max - ground.min).y 10) lengthsegs:divisions widthsegs:divisions
-- FLATTEN
local flatRoad = copy road
convertToPoly flatRoad
flatRoad.EditablePoly.MakePlanarIn #Z
local moveAmount = proxy.max.z - flatRoad.max.z
flatRoad.pos.z += moveAmount
pb_bar.value = 5
-- ADD SKIN WRAP
local skin_wrap_mod = Skin_Wrap()
addModifier proxy skin_wrap_mod
skin_wrap_mod.Blend = false
skin_wrap_mod.weightAllVerts = true
skin_wrap_mod.engine = 0
skin_wrap_mod.falloff = 0.001
skin_wrap_mod.meshList = #(flatRoad)
pb_bar.value = 10
-- ADD MORPH TO FLAT ROAD
local road_morph_mod = Morpher()
addModifier flatRoad road_morph_mod
WM3_MC_BuildFromNode road_morph_mod 1 road
road_morph_mod.Autoload_of_targets = 1
redrawViews()
WM3_MC_SetValue road_morph_mod 1 100.0
flatRoad.pos.z -= moveAmount
pb_bar.value = 15
-- CLEAN UP
local road_turboSmooth_mod = TurboSmooth()
addModifier proxy road_turboSmooth_mod
convertToPoly proxy
delete flatRoad
pb_bar.value = 20
-- GET VERT SELECTION
local selectionArray = #{}
local testMesh = snapShot road
local rm = RayMeshGridIntersect ()
rm.Initialize 10
rm.addNode testMesh
rm.buildGrid ()
local vPos
local groundVertCount = ground.numverts
local currentPercent = 20
local step = 30.0/groundVertCount
for v = 1 to ground.numverts do
(
vPos = getVert ground v
if ((rm.intersectRay (vPos + [0,0,10000]) [0,0,-1] true ) > 0) do selectionArray += #{v}
currentPercent += step
if (mod v 30 == 0) do pb_bar.value = currentPercent
)
delete testMesh
convertToMesh proxy
select ground
subobjectLevel = 1
setVertSelection ground selectionArray
pb_bar.value = 50
-- GROW SHRINK
local gs_v = embedRoadRoll.spn_GrowShrink.value
if (gs_v != 0) do
(
convertToPoly ground
if (gs_v > 0) do for i=1 to gs_v do ground.GrowSelection selLevel:#vertex
if (gs_v < 0) do for i=1 to (abs gs_v) do ground.shrinkSelection selLevel:#vertex
convertToMesh ground
select ground
subobjectLevel = 1
)
meshop.setSoftSel ground true
meshop.setFalloff ground (embedRoadRoll.spn_falloff.value)
meshop.setBubble ground (embedRoadRoll.spn_bubble.value)
meshop.setPinch ground (embedRoadRoll.spn_pinch.value)
-- PROJECT BACK DOWN
local underRoad_BitArray = #{}
local softSel_BitArray = #{}
local softSel
for i=1 to groundVertCount do
(
softSel = pointSelection ground i
if (softSel != 0.0) do
(
if (softSel == 1.0) then underRoad_BitArray += #{i}
else softSel_BitArray += #{i}
)
)
-- DO SOFTSELECTION -----------------------------------------------------------------
rm = RayMeshGridIntersect ()
rm.Initialize 10
rm.addNode proxy
rm.buildGrid ()
local vPos
local closetsFace
local face
local bary
local faceVerts
local worldPos
local all_bitArray = softSel_BitArray + underRoad_BitArray
currentPercent = 50
step = 25.0/all_bitArray.numberSet
for i in all_bitArray do
(
vPos = getVert ground i
if ((rm.intersectRay (vPos + [0,0,10000]) [0,0,-1] true) > 0) do
(
setVert ground i (vPos - ((vPos - (getWorldPos proxy rm) + [0,0,embedRoadRoll.spn_Offset.value]) * (pointSelection ground i)))
)
currentPercent += step
if (mod i 30 == 0) do pb_bar.value = currentPercent
)
-- DO UNDER ROAD -----------------------------------------------------------------
rm = RayMeshGridIntersect ()
rm.Initialize 10
rm.addNode road
rm.buildGrid ()
currentPercent = 75
step = 25.0/underRoad_BitArray.numberSet
for i in underRoad_BitArray do
(
vPos = getVert ground i
if ((rm.intersectRay (vPos + [0,0,10000]) [0,0,-1] true) > 0) do
(
worldpos = ((getWorldPos road rm closest:false) - [0,0,embedRoadRoll.spn_Offset.value])
if (worldpos.z < vPos.z) do setVert ground i worldpos
)
currentPercent += step
if (mod i 30 == 0) do pb_bar.value = currentPercent
)
-- CLEAN UP
if not(isDebugMode) do delete proxy
if not(isDebugMode) do delete road
pb_bar.value = 100
subobjectLevel = 0
-- RESMOOTH
addModifier ground (smooth autosmooth:true Threshold:90)
convertToMesh ground
-- SET BACK TO POLY IF IT WAS BEFORE
if (groundIsPoly) do convertToPoly ground
if (roadIsPoly) do convertToPoly road
)
)
else messagebox "Please set a ground and road mesh first." Title:"Embed Road Warning!"
)
------------------------------------------------
fn setControl control attr =
(
if ((settings.getValue attr) != undefined) do control.value = (settings.getValue attr)
)
-------------------------------------------------
-- EVENTS
-------------------------------------------------
on embedRoadRoll open do
(
settings.dialog_windowPos embedRoadRoll #get
banner.setup()
setControl spn_GrowShrink "GrowShrink"
setControl spn_GrowShrink "GrowShrink"
setControl spn_Offset "Offset"
setControl spn_falloff "Falloff"
setControl spn_pinch "Pinch"
setControl spn_bubble "Bubble"
)
on embedRoadRoll close do
(
settings.dialog_windowPos embedRoadRoll #set
settings.setValue "GrowShrink" spn_GrowShrink.value
settings.setValue "Offset" spn_Offset.value
settings.setValue "Falloff" spn_falloff.value
settings.setValue "Pinch" spn_pinch.value
settings.setValue "Bubble" spn_bubble.value
)
on btn_pickRoad pressed do pick_road()
on btn_pickGround pressed do pick_ground()
on btn_applyToGround pressed do applyToGround()
)
createDialog embedRoadRoll style:#(#style_titlebar, #style_border, #style_sysmenu,#style_toolwindow)