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)