--/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// --------------------------------- 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) ) )