SplineGenerator = {} SplineGenerator.defaultFence = { placeOnTerrain = false, fenceGenerationParentId = 0, onlyScaleLastPanel = false, panels = {{ id = 0, size = 2, weight = 1 }}, poles = {{ id = 0, weight = 1 }}, specialObjects = {{ id = 0, size = 4, offset = 0.5 }} } function SplineGenerator.loadFenceFromSpline(spline) local maxAmountOfItems = 10 local fence = { placeOnTerrain = getUserAttribute(spline,"fenceGenerationPlaceOnTerrain") or false, fenceGenerationParentId = getUserAttribute(spline,"fenceGenerationParentId") or 0, onlyScaleLastPanel = getUserAttribute(spline,"fenceGenerationOnlyScaleLastPanel") or false } fence.panels = {} fence.poles = {} fence.specialObjects = {} for i=1,maxAmountOfItems do local id = getUserAttribute(spline,"fenceGenerationPanelObjectId" .. i) local size = getUserAttribute(spline,"fenceGenerationPanelObjectSize" .. i) local weight = getUserAttribute(spline,"fenceGenerationPanelObjectWeight" .. i) if id ~= nil then print("Found panel " .. id .. " with size " .. size) table.insert(fence.panels, { id = id, size = size, weight = weight }) end end for i=1,maxAmountOfItems do local id = getUserAttribute(spline,"fenceGenerationPoleObjectId" .. i) local weight = getUserAttribute(spline,"fenceGenerationPoleObjectWeight" .. i) if id ~= nil then print("Found pole " .. id) table.insert(fence.poles, { id = id, weight = weight }) end end for i=1,maxAmountOfItems do local id = getUserAttribute(spline,"fenceGenerationSpecialObjectId" .. i) local size = getUserAttribute(spline,"fenceGenerationSpecialObjectSize" .. i) local offset = getUserAttribute(spline,"fenceGenerationSpecialObjectOffset" .. i) if id ~= nil then print("Found special object " .. id .. " with size " .. size) table.insert(fence.specialObjects, { id = id, size = size, offset = offset }) end end return fence end function SplineGenerator.saveFenceToSpline(spline, fence) setUserAttribute(spline,"fenceGenerationPlaceOnTerrain",0,fence.placeOnTerrain or false) setUserAttribute(spline,"fenceGenerationParentId",5, fence.fenceGenerationParentId or 0) setUserAttribute(spline,"fenceGenerationOnlyScaleLastPanel",0,fence.onlyScaleLastPanel or false) for i=1,#fence.panels do if fence.panels[i] ~= nil then setUserAttribute(spline,"fenceGenerationPanelObjectId" .. i, 5, fence.panels[i].id or 0) setUserAttribute(spline,"fenceGenerationPanelObjectSize" .. i, 1, fence.panels[i].size or 2) setUserAttribute(spline,"fenceGenerationPanelObjectWeight" .. i, 1, fence.panels[i].weight or 1) end end for i=1,#fence.poles do if fence.poles[i] ~= nil then setUserAttribute(spline,"fenceGenerationPoleObjectId" .. i, 5, fence.poles[i].id or 0) setUserAttribute(spline,"fenceGenerationPoleObjectWeight" .. i, 5, fence.poles[i].weight or 1) end end for i=1,#fence.specialObjects do if fence.specialObjects[i] ~= nil then setUserAttribute(spline,"fenceGenerationSpecialObjectId" .. i, 5, fence.specialObjects[i].id or 0) setUserAttribute(spline,"fenceGenerationSpecialObjectSize" .. i, 1, fence.specialObjects[i].size or 4) setUserAttribute(spline,"fenceGenerationSpecialObjectOffset" .. i, 2, fence.specialObjects[i].offset or 0.5) end end end function SplineGenerator.connectPoints(template, startX, startY, startZ, endX, endY, endZ) local splinePoints = {endX, endY, endZ,startX, endY, startZ} local newSpline = createSplineFromEditPoints(getRootNode(),splinePoints,true,false) local rX, rY, rZ = getSplineOrientation(newSpline,0,0,-1,0) delete(newSpline) local newFence = clone(template,false) link(getRootNode(),newFence) setWorldRotation(newFence, rX, rY, rZ) setWorldTranslation(newFence, startX,startY,startZ) return newFence end function SplineGenerator.buildFence(spline, fence) local spawnedObject = {} local fenceLength = fence.panels[1].size -- Max amount of panels/poles places local amount = 200 local panelTemplate = fence.panels[1].id local poleTemplate = fence.poles[1].id local offsetMultiplier = 2 local mSplineLength = getSplineLength(spline) print("Spline length: " .. mSplineLength) local fenceLengthTime = 1 / (mSplineLength / fenceLength) print("Fence length: " .. fenceLengthTime) local splinePos = 0.0 -- Spawn all Objects for i=0,amount do if splinePos <= 1.0 and ((splinePos + fenceLengthTime) <= 1.0) then local x, y, z = getSplinePosition(spline,splinePos) local endX, endY, endZ = getSplinePosition(spline,(splinePos + fenceLengthTime)) if (panelTemplate ~= nil and panelTemplate ~= 0) then local panel = SplineGenerator.connectPoints(panelTemplate, x, y, z, endX, endY, endZ) if (offsetMultiplier ~= nil and offsetMultiplier ~= 0) then local heightDifference = (endY - y) * offsetMultiplier local shaderParameterName = "yOffset" local xOffset, yOffset, zOffset, wOffset = 0, 0, 0, 0 xOffset = math.atan(heightDifference/fenceLength) setShaderParameterRecursive(panel, shaderParameterName, xOffset, yOffset, zOffset, wOffset, false) end table.insert(spawnedObject, panel) end if (poleTemplate ~= nil and poleTemplate ~= 0) then local pole = SplineGenerator.connectPoints(poleTemplate, x, y, z, endX, endY, endZ) table.insert(spawnedObject, pole) if (splinePos + fenceLengthTime) >= 1 then local endPole = SplineGenerator.connectPoints(pole, endX, endY, endZ, x,y,z) table.insert(spawnedObject, endPole) i = amount + 1 end end splinePos = splinePos + fenceLengthTime end end -- Move Objects to parent Group local parentGroup = createTransformGroup("fence") link(getRootNode(),parentGroup) setWorldTranslation(parentGroup, getSplinePosition(spline,0)) for i=1,#spawnedObject do local x, y, z = getWorldTranslation(spawnedObject[i]) link(parentGroup, spawnedObject[i]) setWorldTranslation(spawnedObject[i], x, y, z) end end -- SideNote, this script loads and saves all fenceGeneration settings. -- But doesn't use most of them yet. ex. SpecialObjects aren't implemented just yet. local node = getSelection(0) -- 1. Save default settings to selected Spline SplineGenerator.saveFenceToSpline(node, SplineGenerator.defaultFence) -- 1. Manually Select the spline, go to user attributes and update these settings -- fenceGenerationPanelObjectId1 -- fenceGenerationPanelObjectSize1 -- fenceGenerationPoleObjectId1 -- 2. Load settings from selected spline and generate fence -- local fence = SplineGenerator.loadFenceFromSpline(node) -- SplineGenerator.buildFence(node, fence)