320 lines
8.5 KiB
Plaintext
Executable File
320 lines
8.5 KiB
Plaintext
Executable File
--///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
--------------------------------- DIVIDE
|
|
--///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
rollout RsModelToolDivideRoll "Divide Model"
|
|
(
|
|
local MainFloater
|
|
local sub_name
|
|
|
|
local offset_length = 400
|
|
local bDelete = false
|
|
local bLOD = false
|
|
local bAligned = false
|
|
local columns = 0
|
|
local rows = 0
|
|
|
|
--////////////////////////////////////////////////////////////
|
|
-- interface
|
|
--////////////////////////////////////////////////////////////
|
|
|
|
hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Modelling_Toolkit#Divide_Model"
|
|
offset:[0,-4] align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255)
|
|
|
|
groupBox grpSlicer "Mesh Slicer" pos:[4,20] width:(RsModelToolDivideRoll.width - 8) height:66 across:3
|
|
button btnModelSlicer "Start Slicing" align:#left pos:(grpSlicer.pos + [14, 22]) height:30
|
|
tooltip:"Chops up selected meshes into smaller chunks, along drawn outlines"
|
|
radioButtons btnsSliceObjElem "Slice into:" labels:#("Objects", "Elements") pos:(btnModelSlicer.pos + [90,-10])
|
|
tooltip:"Chop object into objects or elements"
|
|
checkBox chkRandomClr "Random\nColour" width:60 height:30 pos:(btnModelSlicer.pos + [180,0]) checked:true enabled:(btnsSliceObjElem.state == 1)
|
|
tool:"Give new objects random colours, or keep source-object's colour"
|
|
label lblSpacer "" height:9
|
|
|
|
group "Add slice-modifier:"
|
|
(
|
|
button btnSlice90 "Slice 90" width:118 across:2
|
|
button btnSlice180 "Slice 180" width:116
|
|
)
|
|
|
|
group "Chop into blocks:"
|
|
(
|
|
checkbox chkAligned "World Aligned" width:84 height:21 across:2
|
|
spinner spnLength "Size: " tooltip:"Block size in meters" width:136 height:16 range:[0,1e+006,400] type:#integer scale:100 align:#right
|
|
|
|
checkbox chkLod "LOD Object" width:84 height:21 across:2
|
|
editText edtName "Name: " tooltip:"Prefix" width:153 height:18 align:#center align:#right offset:[-12,-4]
|
|
|
|
checkbox chkDelete "Delete Parent" tooltip:"Deletes original object" width:84 height:21 across:3
|
|
button btnGo "Begin" width:103 height:25 offset:[65, 0]
|
|
progressBar progBar orient:#vertical height:25 width:10 align:#right color:green
|
|
)
|
|
|
|
--////////////////////////////////////////////////////////////
|
|
-- methods
|
|
--////////////////////////////////////////////////////////////
|
|
fn worldAlign coord =
|
|
(
|
|
difference = abs(mod coord offset_length)
|
|
adjustment = abs(offset_length - difference)
|
|
coord -= adjustment
|
|
)
|
|
|
|
|
|
fn meshChop obj chopSize:256 namePrefix:"test" =
|
|
(
|
|
if (obj == undefined) then
|
|
(
|
|
return false
|
|
)
|
|
|
|
local meshBits = #()
|
|
|
|
ConvertToPoly obj
|
|
|
|
local chopBitCount = 0
|
|
chopSize = chopSize as Float
|
|
local objBB = nodeGetBoundingBox obj (Matrix3 1)
|
|
local bbWidth = objBB[2].x - objBB[1].x
|
|
local bbHeight = objBB[2].y - objBB[1].y
|
|
|
|
local widthRatio = bbWidth / chopSize
|
|
local heightRatio = bbHeight / chopSize
|
|
|
|
local halfWidthOffset = (bbWidth/2.0)+(chopSize/2.0)
|
|
local halfHeightOffset = (bbHeight/2.0)+(chopSize/2.0)
|
|
|
|
local columns = (ceil widthRatio) as integer
|
|
local rows = (ceil heightRatio) as integer
|
|
|
|
local totalProcessed = 0
|
|
local allToDo = (rows + 1) * (columns + 1)
|
|
|
|
setCommandPanelTaskMode #modify
|
|
modPanel.setCurrentObject obj
|
|
|
|
CopyAttrs obj
|
|
|
|
--setup modifiers on source obj
|
|
local vs = volumeSelect()
|
|
vs.level = 2 --face
|
|
vs.type = 1 --crossing
|
|
vs.method = 0 --replace
|
|
vs.volume = 0 --box
|
|
|
|
addModifier obj vs
|
|
local gizmoScale = [(1.0 / widthRatio), (1.0 / heightRatio), 1]
|
|
vs.Gizmo.scale = gizmoScale
|
|
|
|
--move it for now
|
|
vs.gizmo.pos = [(bbWidth * 2.0), (bbHeight * 2.0), 0]
|
|
|
|
local epMod = Edit_Poly()
|
|
epMod.useStackSelection = on
|
|
addModifier obj epMod
|
|
|
|
local newGizmoPos = [0,0,0]
|
|
|
|
--store previously selected faces to check against
|
|
local faceRegister = #{}
|
|
|
|
-- format "rows: % \n" rows
|
|
-- format "Columns: % \n" columns
|
|
local gridSeq = spiralArraySequence rows columns
|
|
|
|
for visitor in gridSeq do
|
|
(
|
|
row = visitor.x
|
|
col = visitor.y
|
|
|
|
modPanel.setCurrentObject obj
|
|
|
|
--newGizmoPos = [0, 0, 0]
|
|
if bAligned then
|
|
(
|
|
local objTM = obj.transform
|
|
local modTM = getModContextTM obj vs
|
|
|
|
local newX = worldAlign (((col + 1) * chopSize) - halfWidthOffset)
|
|
local newY = worldAlign (((row + 1) * chopSize) - halfHeightOffset)
|
|
|
|
newGizmoPos = [newX, newY, 0] * modTM * (inverse objTM)
|
|
)
|
|
else
|
|
(
|
|
local newX = (col * chopSize) - halfWidthOffset
|
|
local newY = (row * chopSize) - halfHeightOffset
|
|
|
|
newGizmoPos = [newX, newY, 0]
|
|
)
|
|
|
|
vs.gizmo.pos = newGizmoPos
|
|
vs.method = 1
|
|
|
|
modPanel.setCurrentObject obj.modifiers[1]
|
|
local facList = EditPolyMod.GetSelection epMod #Face
|
|
|
|
if (facList.numberSet != 0) and (facList.numberSet != obj.numFaces) then
|
|
(
|
|
local faceClash = faceRegister * facList
|
|
local facesToChop = #{}
|
|
if faceClash.numberSet > 0 then
|
|
(
|
|
facesToChop = facList - faceClash
|
|
)
|
|
else
|
|
(
|
|
facesToChop = facList
|
|
)
|
|
|
|
if (facesToChop.numberSet > 0) and (facesToChop.numberSet != obj.numFaces) then
|
|
(
|
|
local newChop = copy obj
|
|
collapseStack newChop
|
|
|
|
chopBitCount += 1
|
|
newChop.name = namePrefix + "_" + (chopBitCount as string )
|
|
|
|
if bLOD then
|
|
(
|
|
newChop.name += "_LOD"
|
|
)
|
|
|
|
|
|
--apply the orignals Gta Attrs to the chopped pieces
|
|
PasteAttrs newChop
|
|
|
|
polyOp.DeleteFaces newChop -facesToChop
|
|
|
|
centerPivot newChop
|
|
|
|
append meshBits newChop
|
|
|
|
faceRegister += facList
|
|
)
|
|
)
|
|
|
|
totalProcessed += 1
|
|
|
|
progBar.value = (totalProcessed * (100.0 / allToDo))
|
|
|
|
)
|
|
|
|
--clean up
|
|
if bDelete then
|
|
(
|
|
delete obj
|
|
)
|
|
else
|
|
(
|
|
deleteModifier obj 1
|
|
deleteModifier obj 1
|
|
)
|
|
|
|
--return the new pieces
|
|
return meshBits
|
|
)
|
|
|
|
|
|
--////////////////////////////////////////////////////////////
|
|
-- events
|
|
--////////////////////////////////////////////////////////////
|
|
on btnModelSlicer pressed do
|
|
(
|
|
undo "mesh slicer" on
|
|
(
|
|
filein "pipeline/helpers/models/modelSlicer.ms"
|
|
)
|
|
)
|
|
|
|
on btnsSliceObjElem changed val do
|
|
(
|
|
chkRandomClr.enabled = (val == 1)
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Slice
|
|
--------------------------------------------------------------
|
|
on btnSlice90 pressed do (
|
|
if selection.count != 1 then (
|
|
messagebox "Please select one object"
|
|
)
|
|
else (
|
|
modPanel.addModToSelection (SliceModifier ()) ui:on
|
|
$.modifiers[#Slice].slice_plane.rotation =(quat 1 0 1 0)
|
|
)
|
|
)
|
|
|
|
on btnSlice180 pressed do (
|
|
if selection.count != 1 then (
|
|
messagebox "Please select one object"
|
|
)
|
|
else (
|
|
modPanel.addModToSelection (SliceModifier ()) ui:on
|
|
$.modifiers[#Slice].slice_plane.rotation =(quat 1 0 0 1)
|
|
)
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Chop
|
|
--------------------------------------------------------------
|
|
on spnLength changed val do (
|
|
offset_length = spnLength.value
|
|
)
|
|
|
|
on edtName entered text do (
|
|
sub_name = edtName.text
|
|
)
|
|
|
|
on btnGo pressed do
|
|
(
|
|
if (selection.count == 0) then
|
|
(
|
|
messagebox "Nothing Selected" title:"No Selection"
|
|
)
|
|
|
|
if ((getAttrClass selection[1]) != "Gta_Object") and not (isKindOf selection[1] GeometryClass) then
|
|
(
|
|
messagebox "Please pick a mesh object" title:"Bad Selection"
|
|
)
|
|
|
|
meshChop selection[1] chopSize:spnLength.value namePrefix:edtName.text
|
|
|
|
progBar.value = 0
|
|
)
|
|
|
|
on chkAligned changed state do
|
|
(
|
|
if state == true then
|
|
(
|
|
bAligned = true
|
|
)
|
|
else
|
|
(
|
|
bAligned = false
|
|
)
|
|
|
|
)
|
|
|
|
on chkLod changed state do (
|
|
if chkLod.checked == true do
|
|
bLOD = true
|
|
)
|
|
|
|
on chkDelete changed state do (
|
|
if chkDelete.checked == true do
|
|
bDelete = true
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Chop
|
|
--------------------------------------------------------------
|
|
on RsModelToolDivideRoll open do (
|
|
if selection.count == 1 then (
|
|
edtName.text = $.name
|
|
)
|
|
)
|
|
|
|
on RsModelToolDivideRoll rolledUp down do
|
|
(
|
|
RsSettingWrite "RsModelToolDivideRoll" "rollup" (not down)
|
|
)
|
|
) |