1154 lines
34 KiB
Plaintext
Executable File
1154 lines
34 KiB
Plaintext
Executable File
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
|
|
rsta_loadCommonFunction #("FN_RSTA_spline", "FN_RSTA_userSettings", "FN_RSTA_debug", "FN_RSTA_rageMat", "FN_RSTA_UV") -- "FN_RSTA_debug"
|
|
|
|
--if (vDebug == undefined) do vDebug = rsta_debug_visual()
|
|
--vDebug.Dispose()
|
|
|
|
if (gluemaker != undefined) do gluemaker.dispose()
|
|
struct gluemaker
|
|
(
|
|
-- LOCALS ------------------------------------------------
|
|
MainWindow,
|
|
Settings = rsta_userSettings app:"gluemaker",
|
|
settings_array = #("glueTypeIdx", "CornerChamfer", "CornerPush", "CornerSupportAngle", "CornerSupportDistance", \
|
|
"DivideLength", "FlipV", "FlipU", "MiddleLoop", "Offset", "RandomiseScale", "RandomiseStrength", \
|
|
"StraightenVert", "TextureIdx", "ShaderIdx", "VertexAlpha", "Width", "AutoSetRatioWeight", "RatioWeight", "IsRatioWidth"),
|
|
data,
|
|
sweepSpline,
|
|
sweepShape,
|
|
numbSides,
|
|
glue_shader,
|
|
|
|
object_obj,
|
|
ground_obj,
|
|
temp_object,
|
|
temp_ground,
|
|
isLine,
|
|
|
|
maxMoveDistance = 5,
|
|
searchDistance = 100,
|
|
|
|
fnDebugEnabled = false,
|
|
|
|
vectDebug = false,
|
|
|
|
-- FUNCTIONS --------------------------------------------
|
|
fn fnDebug input =
|
|
(
|
|
if (fnDebugEnabled) do format "%\n" input
|
|
),
|
|
-------------------------------------------------------------------
|
|
fn make_sweep_spline =
|
|
(
|
|
fnDebug "make_sweep_spline"
|
|
case data.glueTypeIdx of
|
|
(
|
|
2: -- OBJECT
|
|
(
|
|
local ground_cutter = copy temp_ground
|
|
local object_cutter = copy temp_object
|
|
ProCutter.CreateCutter #(ground_cutter) 1 True False False False False
|
|
ProCutter.AddStocks ground_cutter #(object_cutter) 1 1
|
|
|
|
local pc = selection[1]
|
|
|
|
convertToPoly pc
|
|
|
|
-- TEST TO SEE IF EMPTY
|
|
if not((polyOp.getEdgeSelection pc).isEmpty) then
|
|
(
|
|
pc.EditablePoly.createShape "sweepSpline_temp" false pc
|
|
sweepSpline = getnodebyname "sweepSpline_temp"
|
|
sweepSpline.name = (object_obj.name + "_glue_")
|
|
)
|
|
delete pc
|
|
)
|
|
|
|
Default: -- EDGE
|
|
(
|
|
temp_object.EditablePoly.createShape "sweepSpline_temp" false temp_object
|
|
sweepSpline = getnodebyname "sweepSpline_temp"
|
|
sweepSpline.name = (temp_object.name + "_glue_")
|
|
)
|
|
)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn make_sweep_shape banking:false =
|
|
(
|
|
fnDebug "make_sweep_shape"
|
|
local width = Data.Width
|
|
local height = width
|
|
numbSides = 3
|
|
|
|
-- SET THE WIDTH AND HEIGHT
|
|
if (data.glueTypeIdx == 0 OR data.glueTypeIdx == 1) do
|
|
(
|
|
if (data.RatioWeight != 100) do
|
|
(
|
|
if (data.IsRatioWidth) then height = width * (data.RatioWeight/100)
|
|
else width = width * (data.RatioWeight/100)
|
|
)
|
|
)
|
|
|
|
case data.glueTypeIdx of
|
|
(
|
|
1: -- FLAT
|
|
(
|
|
-- MAKE 2 SIDED SHAPE
|
|
if (data.CornerChamfer == 0) then
|
|
(
|
|
numbSides = 2
|
|
knots = #([-width,0,0],[0,0,0],[height,0,0])
|
|
)
|
|
-- MAKE 3 SIDED SHAPE
|
|
else
|
|
(
|
|
local chamfer = (Data.Width/100.0)*data.CornerChamfer
|
|
if (data.MiddleLoop) then
|
|
(
|
|
numbSides += 1
|
|
knots = #([-width,0,0],[chamfer,0,0],[0,0,0],[chamfer,0,0],[height,0,0])
|
|
)
|
|
else knots = #([-width,0,0],[-chamfer,0,0],[chamfer,0,0],[height,0,0])
|
|
)
|
|
)
|
|
|
|
Default : -- EDGE
|
|
(
|
|
if (data.CornerChamfer > 0) do numbSides = 4
|
|
local cp = (Data.Width/100.0)*((data.CornerChamfer /2) + ((100-data.CornerChamfer )/100)*Data.CornerPush)
|
|
-- MAKE 2 SIDED SHAPE
|
|
if numbSides == 3 then knots = #([0,0,0],[0,width,0],[cp,cp,0],[height,0,0])
|
|
-- MAKE 3 SIDED SHAPE
|
|
else
|
|
(
|
|
local chamfer = (Data.Width/100.0)*data.CornerChamfer
|
|
chamfer = sqrt((chamfer*chamfer)*2)
|
|
|
|
local cpMin = cp - (cos 45)*(chamfer/2)
|
|
local cpPlus = cp + (cos 45)*(chamfer/2)
|
|
|
|
if (data.MiddleLoop) then
|
|
(
|
|
numbSides += 1
|
|
knots = #([0,0,0],[0,width,0],[cpMin,cpPlus,0], [(cpMin+cpPlus)/2,(cpMin+cpPlus)/2,0] , [cpPlus, cpMin,0], [height,0,0])
|
|
)
|
|
else
|
|
(
|
|
knots = #([0,0,0],[0,width,0],[cpMin,cpPlus,0], [cpPlus, cpMin,0], [height,0,0])
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
local ss = SplineShape pos:[0,0,0] name:"sweepShape"
|
|
addNewSpline ss
|
|
for k in knots do addKnot ss 1 #corner #line k
|
|
updateShape ss
|
|
sweepShape = ss
|
|
),
|
|
-------------------------------------------------------------------------
|
|
fn do_setSmoothingGroups =
|
|
(
|
|
fnDebug "do_setSmoothingGroups"
|
|
polyop.setFaceSmoothGroup sweepSpline #{1..(polyOp.getNumFaces sweepSpline)} 1
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn do_sweep angle:0 banking:false pAlign:2 =
|
|
(
|
|
fnDebug "do_sweep"
|
|
mod_sweep = sweep()
|
|
mod_normal = Normalmodifier()
|
|
|
|
mod_sweep.shapes[1] = sweepShape
|
|
mod_sweep.CustomShape = 1
|
|
mod_sweep.Banking = banking
|
|
mod_sweep.GenerateMappingCoords = true
|
|
mod_sweep.RealWorldMapSize = true
|
|
mod_sweep.XOffset = 0
|
|
mod_sweep.YOffset = 0
|
|
|
|
|
|
if (data.glueTypeIdx < 2 ) do
|
|
(
|
|
mod_sweep.MirrorXYPlane = data.MirrorY
|
|
mod_sweep.MirrorXZPlane = data.MirrorX
|
|
|
|
if (data.MirrorX) do pAlign += 6
|
|
if (data.MirrorY) do pAlign -= 2
|
|
)
|
|
|
|
mod_sweep.PivotAlignment = pAlign
|
|
|
|
mod_sweep.angle = angle
|
|
|
|
mod_normal.flip = true
|
|
|
|
addModifier sweepSpline mod_sweep
|
|
addModifier sweepSpline mod_normal
|
|
|
|
converttopoly sweepSpline
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn do_push =
|
|
(
|
|
fnDebug "do_push"
|
|
mod_push = push()
|
|
mod_push.Push_Value = data.Offset
|
|
addModifier sweepSpline mod_push
|
|
converttopoly sweepSpline
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn test_for_brace idx knot type =
|
|
(
|
|
fnDebug "test_for_brace"
|
|
local min_angle = data.CornerSupportAngle
|
|
local knot_angle = rsta_spline.getAngleOfKnot sweepSpline idx (knot+1)
|
|
if (type == #last) do knot_angle = rsta_spline.getAngleOfKnot sweepSpline idx (knot)
|
|
|
|
local doBrace = false
|
|
if knot_angle > (180 + (min_angle)) OR knot_angle < (180-(min_angle)) do doBrace = true
|
|
|
|
if not(isClosed sweepSpline idx) do
|
|
(
|
|
if (type == #last) AND knot == 1 do return true
|
|
if (type == #first) AND knot == (numSegments sweepSpline idx) do return true
|
|
)
|
|
|
|
return doBrace
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn add_cornerSupport =
|
|
(
|
|
fnDebug "add_cornerSupport"
|
|
if (data.CornerSupportDistance > 0) do
|
|
(
|
|
for idx = 1 to numSplines sweepSpline do
|
|
(
|
|
local edgeOffset = data.CornerSupportDistance
|
|
local segLength = (getSegLengths sweepSpline idx)
|
|
local segOffset = (segLength.count-1)/2
|
|
|
|
for knot = segOffset to 1 by -1 do
|
|
(
|
|
local length = segLength[knot+segOffset]
|
|
local min_angle = 45
|
|
if (length/2 > edgeOffset) do
|
|
(
|
|
local fraction = (1.0/length)*edgeOffset
|
|
if (test_for_brace idx knot #first) do refineSegment sweepSpline idx knot (1.0-fraction)
|
|
-- OTHER SIDE
|
|
if (test_for_brace idx knot #last) do refineSegment sweepSpline idx knot fraction
|
|
)
|
|
)
|
|
)
|
|
updateShape sweepSpline
|
|
)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn add_divisions =
|
|
(
|
|
fnDebug "add_divisions"
|
|
for idx = 1 to (numSplines sweepSpline) do
|
|
(
|
|
local segLength = (getSegLengths sweepSpline idx)
|
|
local segOffset = (segLength.count-1)/2
|
|
|
|
for segment = segOffset to 1 by -1 do
|
|
(
|
|
subdivideSegment sweepSpline idx segment (floor (segLength[segment+segOffset]/data.DivideLength))
|
|
)
|
|
)
|
|
updateShape sweepSpline
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn get_vert_new_pos pA pB m norm: =
|
|
(
|
|
fnDebug "get_vert_new_pos"
|
|
local vectorAB = pB-pA
|
|
if (norm != unsupplied) do vectorAB = normalize vectorAB
|
|
local multi = [m,m,m]
|
|
---------------------------------------------------------
|
|
return (vectorAB*multi)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn add_noise_mod strength =
|
|
(
|
|
fnDebug "add_noise_mod"
|
|
local mod_noise = Noisemodifier()
|
|
|
|
max modify mode
|
|
select sweepSpline
|
|
subobjectLevel = 1
|
|
|
|
modPanel.addModToSelection mod_noise
|
|
|
|
mod_noise.scale = data.RandomiseScale
|
|
mod_noise.fractal = on
|
|
mod_noise.strength = strength
|
|
|
|
converttopoly sweepSpline
|
|
|
|
max create mode
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn do_randomise =
|
|
(
|
|
fnDebug "do_randomise"
|
|
if (data.RandomiseStrength != 0) do
|
|
(
|
|
case data.glueTypeIdx of
|
|
(
|
|
0: -- EDGE
|
|
(
|
|
local topVerts = #()
|
|
local bottomVerts = #()
|
|
|
|
for i = 1 to (polyOp.getNumVerts sweepSpline) by (numbSides + 1) do
|
|
(
|
|
append topVerts i
|
|
append bottomVerts (i + numbSides)
|
|
)
|
|
|
|
-- TOP
|
|
polyOp.SetVertSelection sweepSpline topVerts
|
|
add_noise_mod [0,0,data.RandomiseStrength]
|
|
|
|
-- BOTTOM
|
|
polyOp.SetVertSelection sweepSpline bottomVerts
|
|
add_noise_mod [data.RandomiseStrength,data.RandomiseStrength,0]
|
|
)
|
|
|
|
1: -- GROUND
|
|
(
|
|
local topVerts = #()
|
|
|
|
for i = 1 to (polyOp.getNumVerts sweepSpline) by (numbSides + 1) do
|
|
(
|
|
append topVerts i
|
|
append topVerts (i + numbSides)
|
|
)
|
|
|
|
polyOp.SetVertSelection sweepSpline topVerts
|
|
add_noise_mod [data.RandomiseStrength,data.RandomiseStrength,0]
|
|
)
|
|
)
|
|
)
|
|
),
|
|
--------------------------------------------------------------------------
|
|
fn do_ray startPos vect testMesh debug:false =
|
|
(
|
|
fnDebug "do_ray"
|
|
local theRay = ray startPos vect
|
|
local hitdata = intersectRayEx testMesh theRay
|
|
|
|
-- DEBUG
|
|
if (debug) do
|
|
(
|
|
if (hitdata != undefined) then vDebug.add_ray theRay h:hitdata[1]
|
|
else vDebug.add_ray theRay h:undefined
|
|
)
|
|
|
|
return hitdata
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn get_vPoints idx count =
|
|
(
|
|
fnDebug "get_vPoints"
|
|
local vPoints = #()
|
|
for i = 0 to count-1 do append vPoints (polyOp.getVert sweepSpline (idx+i))
|
|
return vPoints
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn remove_extraFaces =
|
|
(
|
|
fnDebug "remove_extraFaces"
|
|
local faceIdxs = #()
|
|
for f = 1 to (polyop.getNumFaces sweepSpline) by numbSides do append faceIdxs f
|
|
polyop.deleteFaces sweepSpline faceIdxs
|
|
numbSides -= 1
|
|
),
|
|
----------------------------------------------------------------------------
|
|
fn get_RunUp startPos vect runup:1 =
|
|
(
|
|
fnDebug "get_RunUp"
|
|
return (startPos + (vect * [-runup,-runup,-runup]))
|
|
),
|
|
----------------------------------------------------------------------------
|
|
fn do_ray_moveBackStart vect startPos vtx obj runup:1 debug:vectDebug =
|
|
(
|
|
fnDebug "do_ray_moveBackStart"
|
|
local hitData = do_ray (get_RunUp startPos vect runup:runup) vect obj debug:debug
|
|
if (hitdata != undefined) AND ((distance hitdata[1].pos startPos) < maxMoveDistance) do
|
|
(
|
|
polyOp.setVert sweepSpline vtx hitdata[1].pos
|
|
)
|
|
return (polyOp.getVert sweepSpline vtx)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn do_projectEdgeToSurface =
|
|
(
|
|
fnDebug "do_projectEdgeToSurface"
|
|
for idx=1 to (numSplines sweepSpline) do
|
|
(
|
|
for knot = 1 to (numKnots sweepSpline idx) do
|
|
(
|
|
local knotPos = getKnotPoint sweepSpline idx knot
|
|
local vect = [0,0,-1]
|
|
local hitData = do_ray (get_RunUp knotPos vect runup:searchDistance) vect temp_ground
|
|
|
|
if (hitdata != undefined) do setKnotPoint sweepSpline idx knot hitdata[1].pos
|
|
setKnotType sweepSpline idx knot #corner
|
|
)
|
|
)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn do_projectToSurface =
|
|
(
|
|
fnDebug "do_projectToSurface"
|
|
case (data.glueTypeIdx) of
|
|
(
|
|
0: -- BUILDING
|
|
(
|
|
local numbEdges = (numbSides + 1)
|
|
|
|
for idx=1 to (polyOp.getNumVerts sweepSpline) by numbEdges do
|
|
(
|
|
local vPt = get_vPoints idx numbEdges
|
|
|
|
-- VECTOR BETWEEN LOOP
|
|
local vLoop = normalize (vPt[numbEdges] - vPt[1])
|
|
local vEdge = normalize (vPt[numbEdges-1] - vPt[numbEdges])
|
|
local vInward = cross (cross vLoop vEdge) vLoop
|
|
|
|
do_ray_moveBackStart vInward vPt[numbEdges] (idx+numbSides) temp_ground runup:(data.Width * data.SearchSecondary)
|
|
)
|
|
)
|
|
1: -- GROUND
|
|
(
|
|
convertToMesh temp_object
|
|
-- PROJECT TO SELF temp_object
|
|
if not(isLine) do for idx=1 to (polyOp.getNumVerts sweepSpline) do
|
|
(
|
|
local vertPos = polyOp.getVert sweepSpline (idx)
|
|
do_ray_moveBackStart [0,0,-1] vertPos idx temp_object runup:(data.Width * data.SearchPrimary)
|
|
)
|
|
|
|
-- PROJECT TO GROUND temp_object
|
|
if (temp_ground != undefined) do
|
|
(
|
|
for idx=1 to (polyOp.getNumVerts sweepSpline) do
|
|
(
|
|
local vertPos = polyOp.getVert sweepSpline (idx)
|
|
do_ray_moveBackStart [0,0,-1] vertPos idx temp_ground runup:(data.Width * data.SearchSecondary)
|
|
)
|
|
)
|
|
)
|
|
2: -- OBJECT INTERSECT
|
|
(
|
|
convertToMesh temp_object
|
|
local numbEdges = (numbSides + 1)
|
|
|
|
for idx=1 to (polyOp.getNumVerts sweepSpline) by numbEdges do
|
|
(
|
|
local vPt = get_vPoints idx numbEdges
|
|
local w = data.Width
|
|
|
|
-- VECTOR BETWEEN LOOP
|
|
local vLoop = normalize (vPt[2] - vPt[numbEdges])
|
|
|
|
-- MIDDLE OF LOOP
|
|
local midPoint = ((vPt[2] - vPt[numbEdges]) * [0.5,0.5,0.5]) + vPt[numbEdges]
|
|
local vAim = vPt[1] - midPoint
|
|
|
|
-- SET TO GROUND
|
|
local hitData = do_ray_moveBackStart (vLoop*-1) (midPoint) (idx+numbSides) temp_ground runup:(data.Width * data.SearchSecondary)
|
|
|
|
-- NEW FLOAING MID POINT
|
|
midPoint = hitData + (vLoop * [w,w,w])
|
|
|
|
-- GET OFFSET FROM GROUND TO CENTER
|
|
local vMidHit = normalize (hitData - midPoint)
|
|
local vMidCenter = normalize (vPt[1] - midPoint)
|
|
local vDouble = vMidCenter + (vMidCenter - vMidHit)
|
|
|
|
-- SET TO OBJ
|
|
if not(isLine) do do_ray_moveBackStart vDouble midPoint (idx+1) temp_object runup:(data.Width * data.SearchPrimary)
|
|
|
|
-- DO CHAMFER
|
|
if (numbEdges > 3) do
|
|
(
|
|
vPt = get_vPoints idx numbEdges
|
|
local vOA = vPt[2] - vPt[1]
|
|
local vOC = vPt[numbEdges] - vPt[1]
|
|
local chamferOffset = w * (100/data.CornerChamfer)
|
|
|
|
polyOp.setVert sweepSpline (idx + 2) (vPt[1] + (vOA * 1/(100/data.CornerChamfer)))
|
|
polyOp.setVert sweepSpline (idx + numbEdges-2) (vPt[1] + (vOC * 1/(100/data.CornerChamfer)))
|
|
|
|
if (data.MiddleLoop) do
|
|
(
|
|
vPt = get_vPoints idx numbEdges
|
|
local vChamf = (vPt[4] - vPt[3]) * [0.5,0.5,0.5]
|
|
polyOp.setVert sweepSpline (idx + 3) (vPt[3] + vChamf)
|
|
)
|
|
)
|
|
)
|
|
|
|
remove_extraFaces()
|
|
)
|
|
)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn do_straighten =
|
|
(
|
|
fnDebug "do_straighten"
|
|
if (data.StraightenVert) do
|
|
(
|
|
vCount = polyOp.getNumVerts sweepSpline
|
|
|
|
for vtx = 1 to vCount by (numbSides + 1) do
|
|
(
|
|
pA = polyOp.getVert sweepSpline (vtx+1)
|
|
pB = polyOp.getVert sweepSpline (vtx)
|
|
polyOp.moveVert sweepSpline #{vtx+1} [pB.x-pA.x, pB.y-pA.y, 0]
|
|
)
|
|
)
|
|
|
|
remove_extraFaces()
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn make_shader =
|
|
(
|
|
fnDebug "make_shader"
|
|
local TextureSet = data.TextureList.Item[data.TextureIdx]
|
|
|
|
if (TextureSet != undefined) do
|
|
(
|
|
glue_shader = MultiMaterial()
|
|
glue_shader.materiallist.count = 1
|
|
|
|
local newRage = Rage_Shader()
|
|
local SelectedShader = data.ShaderList.Item[data.ShaderIdx]
|
|
if (RsShaderExists SelectedShader) do RstSetShaderName newRage (SelectedShader + ".sps")
|
|
|
|
glue_shader.materiallist[1] = newRage
|
|
|
|
|
|
-- DIFFUSE
|
|
if (TextureSet.Diffuse != undefined) do
|
|
(
|
|
rsta_rageMat.setVarByName newRage "Diffuse Texture" (RsConfigGetTextureSourceDir() + TextureSet.Diffuse)
|
|
rsta_rageMat.setVarByName newRage "Diffuse 1" (RsConfigGetTextureSourceDir() + TextureSet.Diffuse)
|
|
)
|
|
|
|
-- DIFFUSE 2
|
|
if (TextureSet.Diffuse2 != undefined) do
|
|
(
|
|
rsta_rageMat.setVarByName newRage "Diffuse 2" (RsConfigGetTextureSourceDir() + TextureSet.Diffuse2)
|
|
)
|
|
|
|
-- DIFFUSE ALPHA
|
|
if (TextureSet.Diffuse_alpha != undefined) do
|
|
(
|
|
rsta_rageMat.SetAlphaByName newRage "Diffuse Texture" (RsConfigGetTextureSourceDir() + TextureSet.Diffuse_alpha)
|
|
rsta_rageMat.SetAlphaByName newRage "Diffuse 1" (RsConfigGetTextureSourceDir() + TextureSet.Diffuse_alpha)
|
|
)
|
|
|
|
-- DIFFUSE 2 ALPHA
|
|
if (TextureSet.Diffuse2_alpha != undefined) do
|
|
(
|
|
rsta_rageMat.SetAlphaByName newRage "Diffuse 2" (RsConfigGetTextureSourceDir() + TextureSet.Diffuse2_alpha)
|
|
)
|
|
|
|
-- NORMAL
|
|
if (TextureSet.Normal != undefined) do
|
|
(
|
|
rsta_rageMat.setVarByName newRage "Bump Texture" (RsConfigGetTextureSourceDir() + TextureSet.Normal)
|
|
rsta_rageMat.setVarByName newRage "Bump 1" (RsConfigGetTextureSourceDir() + TextureSet.Normal)
|
|
)
|
|
|
|
-- NORMAL
|
|
if (TextureSet.Normal2 != undefined) do
|
|
(
|
|
rsta_rageMat.setVarByName newRage "Bump 2" (RsConfigGetTextureSourceDir() + TextureSet.Normal2)
|
|
)
|
|
|
|
|
|
-- SPECULAR
|
|
if (TextureSet.Specular != undefined) do
|
|
(
|
|
rsta_rageMat.setVarByName newRage "Specular Texture" (RsConfigGetTextureSourceDir() + TextureSet.Specular)
|
|
)
|
|
|
|
-- HEIGHT
|
|
if (TextureSet.Height != undefined) do
|
|
(
|
|
rsta_rageMat.setVarByName newRage "Height Texture" (RsConfigGetTextureSourceDir() + TextureSet.Height)
|
|
)
|
|
)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn getValidUvVerts mod_uv obj =
|
|
(
|
|
fnDebug "getValidUvVerts"
|
|
-- THIS GETS RID OF ANY NON-UVS
|
|
local validVerts = #()
|
|
local maxValue = 10000
|
|
local minValue = -10000
|
|
|
|
mod_uv.unwrap2.setTVSubObjectMode 1
|
|
mod_uv.selectVertices #{1..(mod_uv.numberVerticesByNode obj)}
|
|
local verts = mod_uv.unwrap6.getSelectedVerticesByNode obj
|
|
|
|
for i=1 to verts.count do
|
|
(
|
|
local pt = mod_uv.unwrap6.GetVertexPositionByNode 1 i obj
|
|
local isValid = true
|
|
if (pt.x > maxValue OR pt.x < minValue) do isValid = false
|
|
if (pt.y > maxValue OR pt.y < minValue) do isValid = false
|
|
|
|
if (isValid) do append validVerts i
|
|
)
|
|
|
|
return validVerts
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn FlipUV arg =
|
|
(
|
|
if ((getCurrentSelection()).count != 0) do
|
|
(
|
|
for obj in (getCurrentSelection()) where (superClassOf obj == GeometryClass) do
|
|
(
|
|
local mod_uv = unwrap_uvw()
|
|
addModifier obj mod_uv
|
|
-- SELECT VERTS
|
|
mod_uv.selectVertices ((getValidUvVerts mod_uv obj) as bitarray)
|
|
|
|
case arg of
|
|
(
|
|
#U: mod_uv.mirrorH()
|
|
#V: mod_uv.mirrorV()
|
|
)
|
|
|
|
collapseStack obj
|
|
)
|
|
)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn do_uvs obj =
|
|
(
|
|
fnDebug "do_uvs"
|
|
local TextureSet = data.TextureList.Item[data.TextureIdx]
|
|
if (TextureSet != undefined) do
|
|
(
|
|
-- GET RING COUNT
|
|
local tempPoly = copy obj
|
|
convertToPoly tempPoly
|
|
|
|
polyop.setEdgeSelection tempPoly #{1}
|
|
tempPoly.SelectEdgeRing()
|
|
local ringCount = (polyop.getEdgeSelection tempPoly).numberSet
|
|
|
|
delete tempPoly
|
|
|
|
-- IS VERTICAL
|
|
|
|
local isVertical = if (TextureSet.vMax - TextureSet.vMin) > (TextureSet.uMax - TextureSet.uMin) then true else false
|
|
|
|
-- UVS DON'T WORK UNLESS SELECTED IN THE MOD PANAL
|
|
max modify mode
|
|
select obj
|
|
local mod_uv = unwrap_uvw()
|
|
addModifier obj mod_uv
|
|
|
|
-- SELECT VERTS
|
|
mod_uv.selectVertices ((getValidUvVerts mod_uv obj) as bitarray)
|
|
|
|
-- TEXTURE STRETCH
|
|
mod_uv.scaleSelectedCenter data.TextureList.Item[data.TextureIdx].Ratio 2
|
|
|
|
local bbox = rsta_uv.get_selBoundingBox mod_uv
|
|
local w = (bbox[2] - bbox[1]) as Float
|
|
local h = (bbox[4] - bbox[3]) as Float
|
|
|
|
-- ROTATE IF VERTICAL TEXTURE
|
|
if isVertical AND h < w do mod_uv.rotateSelectedVerticesCenter (pi/2)
|
|
if not(isVertical) AND h > w do mod_uv.rotateSelectedVerticesCenter (pi/2)
|
|
|
|
bbox = rsta_uv.get_selBoundingBox mod_uv
|
|
w = (bbox[2] - bbox[1]) as Float
|
|
h = (bbox[4] - bbox[3]) as Float
|
|
|
|
--format "(1/w) : % TextureSet.uMax : % TextureSet.uMin : % \n" (1/w) TextureSet.uMax TextureSet.uMin
|
|
|
|
local s = if isVertical then (1/w)*(TextureSet.uMax - TextureSet.uMin) else (1/h)*(TextureSet.vMax - TextureSet.vMin)
|
|
|
|
mod_uv.scaleSelectedCenter s 0
|
|
|
|
bbox = rsta_uv.get_selBoundingBox mod_uv
|
|
|
|
mod_uv.unwrap2.snapPivot 2 -- BOTTOM LEFT
|
|
mod_uv.unwrap2.moveSelected [TextureSet.uMin-bbox[1],TextureSet.vMax-bbox[4],0]
|
|
|
|
--FLIP
|
|
mod_uv.mirrorV()
|
|
|
|
-- GET MIDDLE VERTS
|
|
bbox = rsta_uv.get_selBoundingBox mod_uv
|
|
|
|
local middleVerts = #()
|
|
for i = 1 to (mod_uv.numberVerticesByNode obj) by ringCount do
|
|
(
|
|
for j = 1 to (ringCount-2) do append middleVerts (i + j)
|
|
)
|
|
|
|
-- MOVE THE MIDDLE TO TARGET
|
|
mod_uv.selectVertices (middleVerts as bitarray)
|
|
min_bbox = rsta_uv.get_selBoundingBox mod_uv
|
|
|
|
local midtargetValue = 50
|
|
if (data.RatioWeight != 100) do
|
|
(
|
|
if (data.IsRatioWidth) then midtargetValue = (data.RatioWeight/2.0)
|
|
else midtargetValue = 100 - (data.RatioWeight/2.0)
|
|
)
|
|
|
|
if (isVertical) then
|
|
(
|
|
minPoint = min_bbox[1] + ((min_bbox[2] - min_bbox[1])/2)
|
|
targetMid = ((bbox[2]-bbox[1]) * (midtargetValue/100.0)) + bbox[1]
|
|
offset = [(targetMid - minPoint),0,0]
|
|
)
|
|
else
|
|
(
|
|
minPoint = min_bbox[3] + ((min_bbox[4] - min_bbox[3])/2)
|
|
targetMid = ((bbox[4]-bbox[3]) * (midtargetValue/100.0)) + bbox[3]
|
|
offset = [0,(targetMid - minPoint),0]
|
|
)
|
|
|
|
mod_uv.unwrap2.snapPivot 1
|
|
mod_uv.unwrap2.moveSelected offset
|
|
|
|
converttopoly obj
|
|
)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn UV_Fix arg =
|
|
(
|
|
if (arg == 1) do
|
|
(
|
|
local obj = (getCurrentSelection())[1]
|
|
if not ((polyop.getFaceSelection obj).isempty) do
|
|
(
|
|
local uvMod = Unwrap_UVW()
|
|
modPanel.addModToSelection uvMod
|
|
|
|
uvMod.faceToVertSelect()
|
|
local start_bb = rsta_uv.get_selBoundingBox uvMod
|
|
data.UV_boundingBox.minX = start_bb[1]
|
|
data.UV_boundingBox.maxX = start_bb[2]
|
|
data.UV_boundingBox.minY = start_bb[3]
|
|
data.UV_boundingBox.maxY = start_bb[4]
|
|
|
|
uvMod.mappingMode 1
|
|
uvMod.mappingMode 0
|
|
|
|
uvMod.relaxByFaceAngle 1000 0 1 false
|
|
|
|
subobjectLevel = 2
|
|
uvMod.selectEdges #{}
|
|
)
|
|
)
|
|
|
|
if (arg == 2) do
|
|
(
|
|
local obj = (getCurrentSelection())[1]
|
|
local uvMod = obj.modifiers[#unwrap_uvw]
|
|
|
|
if not ((uvMod.getSelectedEdges()).isEmpty) do
|
|
(
|
|
local alignEdge = uvMod.getSelectedEdges()
|
|
|
|
rsta_uv.snapRotateShellToEdge uvMod
|
|
|
|
uvMod.uvRing 0
|
|
local edges = uvMod.getSelectedEdges()
|
|
|
|
for e in edges do
|
|
(
|
|
uvMod.selectEdges #{e}
|
|
uvMod.uvLoop 0
|
|
uvMod.align true
|
|
)
|
|
|
|
subobjectLevel = 3
|
|
|
|
local targetBB = #(data.UV_boundingBox.minX,data.UV_boundingBox.maxX,data.UV_boundingBox.minY,data.UV_boundingBox.maxY)
|
|
rsta_uv.uniformScaleToTarget uvMod (targetBB[4]-targetBB[3]) 2
|
|
rsta_uv.set_selBoundingBox uvMod targetBB dir:2
|
|
|
|
convertToPoly obj
|
|
subobjectLevel = 4
|
|
)
|
|
)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn do_vertex_alpha =
|
|
(
|
|
fnDebug "do_vertex_alpha"
|
|
if (data.VertexAlpha) do
|
|
(
|
|
local vCount = polyOp.getNumVerts sweepSpline
|
|
local outSide_verts = #()
|
|
|
|
for vtx = 1 to vCount by (numbSides + 1) do
|
|
(
|
|
append outSide_verts vtx
|
|
append outSide_verts (vtx + numbSides)
|
|
)
|
|
|
|
-- SET INSIDE
|
|
local alphaValue = 255
|
|
polyop.setVertColor sweepSpline -2 #{1..vCount} [alphaValue,alphaValue,alphaValue]
|
|
-- SET OUTSIDE
|
|
alphaValue = 0
|
|
polyop.setVertColor sweepSpline -2 outSide_verts [alphaValue,alphaValue,alphaValue]
|
|
|
|
sweepSpline.vertexColorType = 2
|
|
sweepSpline.showVertexColors = on
|
|
)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn delete_old =
|
|
(
|
|
fnDebug "delete_old"
|
|
for child in object_obj.children where (MatchPattern child.name pattern:"*_glue_") do delete child
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn do_optimize =
|
|
(
|
|
fnDebug "do_optimize"
|
|
-- BY LENGTH
|
|
for idx = 1 to numSplines sweepSpline do
|
|
(
|
|
local minsize = 0.005
|
|
local segLength = (getSegLengths sweepSpline idx)
|
|
local segOffset = (segLength.count-1)/2
|
|
|
|
local knots_to_delete = #()
|
|
|
|
for knot = 1 to segOffset do if (segLength[knot] < minsize) do append knots_to_delete knot
|
|
for k = knots_to_delete.count to 1 by -1 do deleteKnot sweepSpline idx knots_to_delete[k]
|
|
)
|
|
|
|
-- BY ANGLE
|
|
for idx=1 to (numSplines sweepSpline) do
|
|
(
|
|
local knots_to_delete = #()
|
|
|
|
for knot = 1 to (numKnots sweepSpline idx) do
|
|
(
|
|
local kAngle = rsta_spline.getAngleOfKnot sweepSpline idx knot
|
|
if kAngle > 175 AND kAngle < 185 do append knots_to_delete knot
|
|
)
|
|
|
|
for k = knots_to_delete.count to 1 by -1 do deleteKnot sweepSpline idx knots_to_delete[k]
|
|
)
|
|
updateshape sweepSpline
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn do_shader =
|
|
(
|
|
fnDebug "do_shader"
|
|
local objs = for i in selection where (classof_array #(Editable_Poly, Editable_mesh) i) collect i
|
|
if (objs.count != 0) then
|
|
(
|
|
undo on
|
|
(
|
|
make_shader()
|
|
for obj in objs do
|
|
(
|
|
if (glue_shader != undefined) do obj.mat = glue_shader
|
|
do_uvs obj
|
|
RsScaleTexturesOnSelectedObjs 1.0 #(obj) quiet:true
|
|
)
|
|
)
|
|
)
|
|
else messageBox "Nothing Selected!" title:"GlueMaker Error!"
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn make_temp =
|
|
(
|
|
fnDebug "make_temp"
|
|
temp_object = copy object_obj
|
|
convertToPoly temp_object
|
|
if (ground_obj != undefined) do
|
|
(
|
|
temp_ground = copy ground_obj
|
|
convertToMesh temp_ground
|
|
)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn do_cleanup =
|
|
(
|
|
fnDebug "do_cleanup"
|
|
if (temp_object != undefined) do
|
|
(
|
|
delete temp_object
|
|
temp_object = undefined
|
|
)
|
|
if (temp_ground != undefined) do
|
|
(
|
|
delete temp_ground
|
|
temp_ground = undefined
|
|
)
|
|
delete sweepShape
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn make_glue =
|
|
(
|
|
fnDebug "make_glue"
|
|
if (object_obj != undefined) then
|
|
(
|
|
undo on
|
|
(
|
|
isLine = if (classof_array #(line, SplineShape) object_obj) then true else false
|
|
max create mode
|
|
case data.glueTypeIdx of
|
|
(
|
|
0 : -- EDGE SELECTION MODE
|
|
(
|
|
delete_old()
|
|
make_temp()
|
|
if (temp_object.getSelection #edge).isEmpty then
|
|
(
|
|
make_sweep_shape()
|
|
|
|
if (isLine) then
|
|
(
|
|
sweepSpline = copy object_obj
|
|
sweepSpline.name = (object_obj.name + "_glue_")
|
|
)
|
|
else make_sweep_spline()
|
|
|
|
add_cornerSupport()
|
|
add_divisions()
|
|
if (temp_ground != undefined) do do_projectEdgeToSurface()
|
|
do_sweep()
|
|
do_straighten()
|
|
do_randomise()
|
|
if (temp_ground != undefined) do do_projectToSurface()
|
|
do_push()
|
|
do_vertex_alpha()
|
|
do_setSmoothingGroups()
|
|
max create mode
|
|
CenterPivot sweepSpline
|
|
sweepSpline.parent = object_obj
|
|
do_cleanup()
|
|
-------------------------------------------------
|
|
make_shader()
|
|
sweepSpline.mat = glue_shader
|
|
do_uvs sweepSpline
|
|
RsScaleTexturesOnSelectedObjs 1.0 #(sweepSpline) quiet:true
|
|
)
|
|
else messageBox "No Edges Are Selected"
|
|
)
|
|
1: -- GROUND MODE
|
|
(
|
|
delete_old()
|
|
make_temp()
|
|
if (temp_object.getSelection #edge).isEmpty then
|
|
(
|
|
make_sweep_shape()
|
|
|
|
if (isLine) then
|
|
(
|
|
sweepSpline = copy object_obj
|
|
sweepSpline.name = (object_obj.name + "_glue_")
|
|
)
|
|
else make_sweep_spline()
|
|
|
|
add_cornerSupport()
|
|
add_divisions()
|
|
do_sweep angle:0 pAlign:-1
|
|
do_randomise()
|
|
do_projectToSurface()
|
|
do_push()
|
|
do_vertex_alpha()
|
|
do_setSmoothingGroups()
|
|
max create mode
|
|
CenterPivot sweepSpline
|
|
sweepSpline.parent = object_obj
|
|
do_cleanup()
|
|
-------------------------------------------------
|
|
make_shader()
|
|
sweepSpline.mat = glue_shader
|
|
do_uvs sweepSpline
|
|
RsScaleTexturesOnSelectedObjs 1.0 #(sweepSpline) quiet:true
|
|
)
|
|
else messageBox "No Edges Are Selected"
|
|
)
|
|
2 : -- ROCK MODE
|
|
(
|
|
if (ground_obj != undefined) then
|
|
(
|
|
delete_old()
|
|
make_temp()
|
|
make_sweep_shape()
|
|
|
|
if (isLine) then
|
|
(
|
|
sweepSpline = copy object_obj
|
|
sweepSpline.name = (object_obj.name + "_glue_")
|
|
)
|
|
else make_sweep_spline()
|
|
|
|
if (sweepSpline != undefined) then
|
|
(
|
|
--do_optimize()
|
|
add_cornerSupport()
|
|
add_divisions()
|
|
do_sweep angle:-45 pAlign:1 banking:true
|
|
do_projectToSurface()
|
|
do_push()
|
|
do_vertex_alpha()
|
|
do_setSmoothingGroups()
|
|
max create mode
|
|
CenterPivot sweepSpline
|
|
sweepSpline.parent = object_obj
|
|
)
|
|
else messageBox "Something went wrong, maybe your ground mesh is to complex please make a copy and cut this back to just the polys that intersect with the rock." title:"GlueMaker"
|
|
|
|
do_cleanup()
|
|
-------------------------------------------------
|
|
make_shader()
|
|
sweepSpline.mat = glue_shader
|
|
do_uvs sweepSpline
|
|
RsScaleTexturesOnSelectedObjs 1.0 #(sweepSpline) quiet:true
|
|
)
|
|
else messageBox "No ground mesh found, please set one."
|
|
)
|
|
)
|
|
subobjectLevel = 0
|
|
)
|
|
)
|
|
),
|
|
---------------------------------------------------------------------
|
|
fn check_commit=
|
|
(
|
|
fnDebug "check_commit"
|
|
if (object_obj != undefined) AND not(isDeleted object_obj)do
|
|
(
|
|
local checkCommit = false
|
|
for child in object_obj.children where (MatchPattern child.name pattern:"*_glue_") do checkCommit = true
|
|
if (checkCommit) do
|
|
(
|
|
if (queryBox "There are still preview glue meshes on the last object, did you want to commit them to mesh?") do
|
|
(
|
|
this.Commit()
|
|
)
|
|
)
|
|
)
|
|
),
|
|
---------------------------------------------------------------------
|
|
fn Commit =
|
|
(
|
|
fnDebug "Commit"
|
|
for child in object_obj.children where (MatchPattern child.name pattern:"*_glue_") do child.parent = undefined
|
|
),
|
|
---------------------------------------------------------------------
|
|
fn set_obj type =
|
|
(
|
|
fnDebug "set_obj"
|
|
if (selection.count != 0) then
|
|
(
|
|
if (classof_array #(Editable_Poly,Editable_Mesh, RSrefObject, line, SplineShape) selection[1]) then
|
|
(
|
|
if (type == #glue) then
|
|
(
|
|
if (selection[1] != object_obj) do check_commit()
|
|
object_obj = selection[1]
|
|
data.ObjectName = object_obj.name
|
|
)
|
|
else
|
|
(
|
|
ground_obj = selection[1]
|
|
data.GroundName = ground_obj.name
|
|
)
|
|
)
|
|
else messageBox "Selected object isn't mesh/poly/rsRef." title:"GlueMaker Error!"
|
|
)
|
|
else
|
|
(
|
|
if (type == #glue) then
|
|
(
|
|
object_obj = undefined
|
|
data.ObjectName = ""
|
|
)
|
|
else
|
|
(
|
|
ground_obj = undefined
|
|
data.GroundName = ""
|
|
)
|
|
)
|
|
),
|
|
---------------------------------------------------------------------
|
|
fn dispose =
|
|
(
|
|
fnDebug "dispose"
|
|
if (MainWindow != undefined) do
|
|
(
|
|
-- SETTINGS
|
|
for attr in settings_array do settings.getDnProp attr data attr
|
|
|
|
-- WINDOW POS
|
|
settings.wpf_windowPos mainWindow #set
|
|
|
|
MainWindow.Close()
|
|
MainWindow = undefined
|
|
)
|
|
execute ("gluemaker = undefined")
|
|
),
|
|
-------------------------------------------------------------------
|
|
fn init =
|
|
(
|
|
fnDebug "init"
|
|
-- LOAD ASSEMBLY
|
|
local assembly = (RsConfigGetToolsDir() + @"techart\dcc\3dsMax\RSG.TechArt.GlueMaker.dll")
|
|
if (RSConfigGetProjectName() == "gta5_liberty") do assembly = (RsConfigGetToolsDir() + @"techart\dcc\3dsMax\RSG.TechArt.GlueMaker_Liberty.dll")
|
|
dotnet.loadAssembly assembly
|
|
--dotnet.loadAssembly (@"X:\wildwest\src\Library\RSG.TechArt\RSG.TechArt.GlueMaker\GlueMaker\bin\Release\RSG.TechArt.GlueMaker.dll")
|
|
|
|
MainWindow = dotNetObject "RSG.TechArt.GlueMaker.MainWindow"
|
|
dn_window.setup MainWindow
|
|
MainWindow.Tag = dotnetmxsvalue this
|
|
|
|
-- LOAD SHADER DATA
|
|
MainWindow.set_shaderXML (RSConfigGetProjectName()) (RsConfigGetWildWestDir()) @"etc\config\maps\glueMakerGlobal.xml"
|
|
|
|
MainWindow.ChangeOwner (DotNetObject "System.IntPtr" (Windows.GetMAXHWND()))
|
|
MainWindow.Title = "Gluemaker - v2.4"
|
|
|
|
data = MainWindow.dataContext
|
|
|
|
data.setDefaults()
|
|
|
|
-- SETTINGS
|
|
for attr in settings_array do settings.setDnProp attr data attr
|
|
|
|
-- WINDOW POS
|
|
settings.wpf_windowPos mainWindow #get
|
|
|
|
MainWindow.show()
|
|
MainWindow.set_visablity()
|
|
),
|
|
-- EVENTS -----------------------------------------------------
|
|
on create do init()
|
|
)
|
|
gluemaker = gluemaker()
|
|
|
|
|
|
|
|
|