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

185 lines
4.8 KiB
Plaintext
Executable File

try ( destroyDialog RsGlobalTerrainMapperRollout ) catch ()
filein (RsConfigGetWildWestDir() + "script/3dsmax/_config_files/wildwest_header.ms")
struct RsGlobalTerrainMappingStruct
(
private
-- Round the supplied number to the nearest multiple.
fn roundToNearestMultiple numToRound multiple = (
local result = undefined
-- Negate the multiple if the number to round is a negative.
if numToRound < 0 and multiple > 0 then (
multiple = -multiple
)
-- Do nothing.
if multiple == 0 then (
result = numToRound
) else (
local remainder = mod numToRound multiple
-- Already at the multiple.
if remainder == 0 then (
result = numToRound
-- Round up to the multiple.
) else (
result = numToRound + multiple - remainder
)
)
result as integer
),
-- Return the world=space position of the selected faces.
fn getFaceSelectionPosition obj = (
local center = undefined
if ( getSelectionLevel obj ) == #face then (
local x = #()
local y = #()
if classof obj == Editable_Poly then (
local faces = ( polyop.getFaceSelection obj ) as array
for faceIdx in faces do (
local verts = ( polyop.getVertsUsingFace obj faceIdx ) as array
for vertIdx in verts do (
local vert = polyop.getVert obj vertIdx
append x vert.x
append y vert.y
)
)
) else if classof obj == Editable_Mesh then (
local faces = ( getFaceSelection obj ) as array
for faceIdx in faces do (
local verts = ( meshop.getVertsUsingFace obj faceIdx ) as array
for vertIdx in verts do (
local vert = meshop.getVert obj vertIdx
append x vert.x
append y vert.y
)
)
)
local minX = amin x
local minY = amin y
local maxX = amax x
local maxY = amax y
if minX != undefined then (
local bboxMin = [ minX, minY, 0 ]
local bboxMax = [ maxX, maxY, 0 ]
center = ( bboxMin + bboxMax ) / 2.0
)
)
center
),
public
mapChannel = 1,
mapLength = 200,
mapWidth = 200,
doCollapseStack = true,
fn create objs:( selection as array ) = (
clearSelection()
for obj in objs do (
select obj
local parentPos = obj.pos
-- If any faces are selected, this will return their position in world space.
local faceSelectionPos = getFaceSelectionPosition obj
local uvMod = Uvwmap()
uvMod.mapChannel = mapChannel
uvMod.length = mapLength
uvMod.width = mapWidth
uvMod.height = mapWidth
modPanel.addModToSelection uvMod ui:on
local newGizmoTransform = matrix3 1
local gizmoPos = undefined
-- Faces are currently selected, so use their position.
if faceSelectionPos != undefined then (
gizmoPos = faceSelectionPos
) else (
gizmoPos = parentPos
)
if gizmoPos != undefined then (
local nearestX = roundToNearestMultiple gizmoPos.x mapWidth
local nearestY = roundToNearestMultiple gizmoPos.y mapLength
newGizmoTransform.row4 = [ nearestX - gizmoPos.x, nearestY - gizmoPos.y, 0 ]
uvMod.gizmo.transform = newGizmoTransform
if doCollapseStack then (
collapseStack obj
)
)
)
select objs
)
)
RsGlobalTerrainMapping = RsGlobalTerrainMappingStruct()
rollout RsGlobalTerrainMapperRollout "Global Terrain Mapper" (
--Rockstar Banner
dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:RsGlobalTerrainMapperRollout.width
local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"Global_Terrain_Mapper" filename:(getThisScriptFilename())
spinner spMapChannel "Map Channel:" range:[ 1, 2, 1 ] type:#integer width:96 align:#right
spinner spMapWidth "Map Width:" range:[ -99999, 99999, RsGlobalTerrainMapping.mapWidth ] type:#float width:90 align:#right
spinner spMapHeight "Map Height:" range:[ -99999, 99999, RsGlobalTerrainMapping.mapLength ] type:#float width:92 align:#right
checkbox cbCollapseStack "Collapse Stack" checked:RsGlobalTerrainMapping.doCollapseStack align:#right
button btnCreate "Create" width:200 height:32
on RsGlobalTerrainMapperRollout open do (
banner.setup()
)
on cbCollapseStack changed state do (
RsGlobalTerrainMapping.doCollapseStack = state
)
on spMapWidth changed val do (
RsGlobalTerrainMapping.mapWidth = val
)
on spMapHeight changed val do (
RsGlobalTerrainMapping.mapLength = val
)
on spMapChannel changed val do (
RsGlobalTerrainMapping.mapChannel = val
)
on btnCreate pressed do (
undo "Global Terrain Mapper" on (
RsGlobalTerrainMapping.create()
)
)
)
createDialog RsGlobalTerrainMapperRollout width:220 height:174 style:#( #style_titlebar, #style_toolwindow, #style_sysmenu )