909 lines
27 KiB
Plaintext
Executable File
909 lines
27 KiB
Plaintext
Executable File
-- /general_tools/
|
|
-- Auth: Kyle Hansen kyle.hansen@rockstarsandiego.com
|
|
-- Auth Date: Oct. 6th 2012
|
|
|
|
|
|
|
|
-- This line loads the custom header
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
|
|
RsCollectToolUsageData (getThisScriptFilename())
|
|
|
|
--================= Skin Transfer from Allan Hayburn
|
|
struct SkinInfo -- struct to store the target data
|
|
(
|
|
theObject = undefined,
|
|
theObjectCenter = undefined,
|
|
theObjectClass = undefined,
|
|
infBones = #(),
|
|
|
|
fn getInfBones = -- finds the bones used in the objects skin modifier
|
|
(
|
|
setCommandPanelTaskMode #modify
|
|
if theObject != undefined then
|
|
(
|
|
select theObject
|
|
theSkin = theObject.modifiers[#skin]
|
|
if theSkin != undefined then
|
|
(
|
|
modPanel.setCurrentObject theObject.modifiers[#Skin]
|
|
numBones = skinOps.GetNumberBones theSkin
|
|
for i in 1 to numBones do
|
|
(
|
|
append infBones (getnodebyname (skinOps.GetBoneName theSkin i 1) )
|
|
)
|
|
)
|
|
)
|
|
),
|
|
|
|
fn getObjectInfo theObj = -- populates the structs data
|
|
(
|
|
theObject = theObj
|
|
theObjectCenter = theObj.center
|
|
theObjectClass = classof theObj
|
|
if theObjectClass == Editable_mesh then theObjectClass = TriMeshGeometry
|
|
getInfBones()
|
|
)
|
|
)
|
|
rsSkinInfo = SkinInfo() -- instance the struct
|
|
|
|
fn ExtractSkin obj =
|
|
(
|
|
rsSkinInfo.getObjectInfo obj
|
|
-- Extract the skindata
|
|
skinUtils.ExtractSkinData obj
|
|
theSkinData = getnodebyname ("SkinData_"+obj.name)
|
|
)
|
|
|
|
fn AddSkin obj =
|
|
(
|
|
theSkinData = getnodebyname ("SkinData_"+obj.name)
|
|
-- Add the skin and bones and import skin data
|
|
modPanel.addModToSelection (Skin ()) ui:on
|
|
theSkin = obj.modifiers[1]
|
|
for i in 1 to rsSkinInfo.infBones.count do
|
|
(
|
|
if i == rsSkinInfo.infBones.count then updateInteger = 1 else updateInteger = 0
|
|
skinOps.addbone theSkin rsSkinInfo.infBones[i] updateInteger
|
|
)
|
|
selectmore theSkinData
|
|
skinUtils.ImportSkinDataNoDialog true false false false false 1.0 0
|
|
delete theSkinData
|
|
)
|
|
--==========
|
|
|
|
|
|
struct modellingCPVUtilsStruct
|
|
(
|
|
fn closestTriangleToPoint giverMesh giverFace recPoint distThreashold=
|
|
(
|
|
escapeEnable = true
|
|
--print ("RECPOINT: " + recPoint as string)
|
|
|
|
local meshTypeGiver = classof giverMesh
|
|
|
|
if meshTypeGiver == Editable_Poly then
|
|
(
|
|
local giverVerts = polyop.getFaceVerts giverMesh giverFace
|
|
|
|
-- get the verts coordinates from the vert list
|
|
local vert0 = (polyop.getvert giverMesh giverVerts[1])
|
|
local vert1 = (polyop.getvert giverMesh giverVerts[2])
|
|
local vert2 = (polyop.getvert giverMesh giverVerts[3])
|
|
)
|
|
else if meshTypeGiver == Editable_Mesh then
|
|
(
|
|
local giverVerts = meshop.getVertsUsingFace giverMesh #(giverFace) as array
|
|
|
|
-- get the verts coordinates from the vert list
|
|
|
|
local vert0 = (meshop.getvert giverMesh giverVerts[1])
|
|
local vert1 = (meshop.getvert giverMesh giverVerts[2])
|
|
local vert2 = (meshop.getvert giverMesh giverVerts[3])
|
|
|
|
)
|
|
|
|
local kickOutTestBool = 0
|
|
local dist1 = ((vert0.x - recPoint.x) + (vert0.y - recPoint.y) + (vert0.z - recPoint.z))
|
|
local dist2 = ((vert0.x - recPoint.x) + (vert0.y - recPoint.y) + (vert0.z - recPoint.z))
|
|
local dist3 = ((vert0.x - recPoint.x) + (vert0.y - recPoint.y) + (vert0.z - recPoint.z))
|
|
|
|
if (abs dist1) > distThreashold then
|
|
(
|
|
if (abs dist2) > distThreashold then
|
|
(
|
|
if (abs dist3) > distThreashold then
|
|
(
|
|
kickOutTestBool = 1
|
|
)
|
|
)
|
|
)
|
|
|
|
|
|
if kickOutTestBool == 0 then
|
|
(
|
|
-- for each vert coordinate (point3) in the giver face, lets create a vector with the receiving point coordinate (point3)
|
|
local vArm0_p = (recPoint - vert0)
|
|
local vArm1_p = (recPoint - vert1)
|
|
local vArm2_p = (recPoint - vert2)
|
|
|
|
-- lets create a vector between each vert on that giver face
|
|
local vArm0_1 = (vert1 - vert0)
|
|
local vArm0_2 = (vert2 - vert0)
|
|
local vArm1_2 = (vert2 - vert1)
|
|
|
|
|
|
-- lets dot our vectors to get new values
|
|
local dot1 = dot vArm0_1 vArm0_p
|
|
local dot2 = dot vArm0_2 vArm0_p
|
|
|
|
local dot3 = dot vArm0_1 vArm1_p
|
|
local dot4 = dot vArm0_2 vArm1_p
|
|
|
|
local dot5 = dot vArm0_1 vArm2_p
|
|
local dot6 = dot vArm0_2 vArm2_p
|
|
|
|
|
|
-- lets create vectors with the new values
|
|
local vector_351 = [dot3, dot5, dot1]
|
|
local vector_624 = [dot6, dot2, dot4]
|
|
local vector_513 = [dot5, dot1, dot3]
|
|
local vector_462 = [dot4, dot6, dot2]
|
|
|
|
-- some math to generate the distance to a point on the given surface
|
|
local subResult = ((vector_351 * vector_624)-(vector_513 * vector_462)) --cross
|
|
|
|
|
|
local sub1_3 = dot1 - dot3
|
|
local sub4_3 = dot4 - dot3
|
|
local sub2_6 = dot2 - dot6
|
|
local sub5_6 = dot5 - dot6
|
|
|
|
|
|
local divU = dot1 / sub1_3 -- U
|
|
local divV = dot2 / sub2_6 -- V
|
|
local divW = sub4_3 / (sub4_3 + sub5_6) -- W
|
|
|
|
--print ("U:" + divU as string + " V:" + divV as string + " W:" + divW as string)
|
|
|
|
local resultDenom = subResult / ( subResult[1] + subResult[2] + subResult[3])
|
|
|
|
-- some logic to decide the end result
|
|
local resultVector = vert0
|
|
if dot1 < 0 and dot2 < 0 then
|
|
(
|
|
|
|
resultVector
|
|
)
|
|
else if dot3 >= dot4 and dot3 >= 0 then
|
|
(
|
|
|
|
resultVector += vArm0_1
|
|
|
|
)
|
|
else if subResult[3] < 0 and dot3 < 0 and dot1 >= 0 then
|
|
(
|
|
|
|
resultVector += (vArm0_1 * divU)
|
|
)
|
|
else if dot6 >= dot5 and dot6 >=0 then
|
|
(
|
|
|
|
resultVector += vArm0_2
|
|
)
|
|
else if subResult[2] < 0 and dot6 < 0 and dot2 >= 0 then
|
|
(
|
|
|
|
resultVector += (vArm0_2 * divV)
|
|
)
|
|
else if subResult[1] < 0 and sub4_3 >=0 and sub5_6 >= 0 then
|
|
(
|
|
|
|
resultVector += (vArm0_1 + (vArm1_2 * divW))
|
|
)
|
|
else
|
|
(
|
|
|
|
resultVector += vArm0_1 * resultDenom[2] + vArm0_2 * resultDenom[3]
|
|
)
|
|
|
|
|
|
resultVector
|
|
)
|
|
else
|
|
(
|
|
resultVector = 10000000
|
|
)
|
|
),
|
|
|
|
fn getClosestFaceToPoint meshToTest pointToTest distThreashold=
|
|
(
|
|
escapeEnable = true
|
|
local meshType = classof meshToTest
|
|
|
|
local closestFaceReturn = #(100000000, undefined, undefined)
|
|
|
|
|
|
|
|
if meshType == Editable_Poly then
|
|
(
|
|
|
|
local meshObjectFaces = polyop.getNumFaces meshToTest
|
|
)
|
|
else if meshType == Editable_Mesh then
|
|
(
|
|
local meshObjectFaces = meshop.getNumFaces meshToTest
|
|
)
|
|
|
|
|
|
|
|
for faceIndex=1 to meshObjectFaces do
|
|
(
|
|
-- Make a call to the closestTriangleToPoint with the mesh object, bbox inst face index, and the point
|
|
|
|
--print (meshToTest as string + " " + faceIndex as string + " " + pointToTest as string + " " + distThreashold as string)
|
|
local returnPoint = modellingCPVUtilsStruct.closestTriangleToPoint meshToTest faceIndex pointToTest distThreashold
|
|
local distanceVector = returnPoint - pointToTest
|
|
local finalDistanceSquared = dot distanceVector distanceVector -- squared distance
|
|
|
|
if finalDistanceSquared < closestFaceReturn[1] then
|
|
(
|
|
closestFaceReturn[1] = finalDistanceSquared
|
|
closestFaceReturn[2] = faceIndex
|
|
closestFaceReturn[3] = returnPoint
|
|
)
|
|
)
|
|
|
|
--end = timeStamp()
|
|
--format "Finding best face took % seconds\n" ((end - start) / 1000.0)
|
|
--print closestFaceReturn
|
|
--point pos:closestFaceReturn[3]
|
|
|
|
closestFaceReturn
|
|
),
|
|
|
|
fn getAreaOfTriangle p1 p2 p3=
|
|
(
|
|
local areaOfTriangle = undefined
|
|
local vAB = (p2 - p1)
|
|
local vAC = (p3 - p1)
|
|
|
|
local areaCross = (cross vAB vAC)
|
|
local areaVector = [areaCross.x, areaCross.y, areaCross.z]
|
|
areaOfTriangle = (sqrt(areaVector.x ^2 + areaVector.y ^2 + areaVector.z ^2) ) * 0.5
|
|
|
|
areaOfTriangle
|
|
|
|
),
|
|
|
|
fn getWeightingFromPointOnFace processPoint p1 p2 p3=
|
|
(
|
|
local start = timeStamp()
|
|
-- make vectors for each point with p1 as the origin
|
|
local ppVector_p1_pp = (processPoint - p1)
|
|
local ppVector_p1_p2 = (p2 - p1)
|
|
local ppVector_p1_p3 = (p3 - p1)
|
|
|
|
-- get the dot prod
|
|
local dotProd_p2 = dot ppVector_p1_p2 ppVector_p1_p2
|
|
local dotProd_p2_p3 = dot ppVector_p1_p2 ppVector_p1_p3
|
|
local dotProd_p3 = dot ppVector_p1_p3 ppVector_p1_p3
|
|
local dotProd_pp_p2 = dot ppVector_p1_pp ppVector_p1_p2
|
|
local dotProd_pp_p3 = dot ppVector_p1_pp ppVector_p1_p3
|
|
|
|
local multi_dotP2_dotP3 = dotProd_p2 * dotProd_p3
|
|
|
|
local denom1 = (multi_dotP2_dotP3 - (dotProd_p2_p3 * dotProd_p2_p3))
|
|
|
|
local weightU = (((dotProd_p3 * dotProd_pp_p2) - (dotProd_p2_p3 * dotProd_pp_p3)) / denom1)
|
|
local weightV = (((dotProd_p2 * dotProd_pp_p3) - (dotProd_p2_p3 * dotProd_pp_p2)) / denom1)
|
|
|
|
local weights = #(1 - (weightU + weightV), weightU, weightV)
|
|
weights
|
|
|
|
),
|
|
|
|
|
|
-- This will take a given tri, and divide it into three tris given a point, then find the weighting per mini-tri, and use that to
|
|
-- find the correct color values per vertex
|
|
fn getVertColorFromPointOnFace giverMesh giverFace recMesh recFaceIndex recVertIndex pointOnFace bakeChannel=
|
|
(
|
|
escapeEnable = true
|
|
local meshTypeGiver = classof giverMesh
|
|
local meshTypeRec = classof recMesh
|
|
|
|
-- get the correct map verts and the verts for the tri
|
|
if meshTypeGiver == Editable_Poly then
|
|
(
|
|
local faceVerts = polyop.getFaceVerts giverMesh giverFace
|
|
local faceMapVerts = polyop.getMapFace giverMesh bakeChannel giverFace
|
|
)
|
|
else if meshTypeGiver == Editable_Mesh then
|
|
(
|
|
local faceVerts = meshop.getVertsUsingFace giverMesh #(giverFace) as array
|
|
local faceMapVerts = meshop.getMapFace giverMesh bakeChannel giverFace
|
|
)
|
|
|
|
|
|
|
|
-- find the correct map verts based on the faces
|
|
local faceVertCoords = #()
|
|
local faceVertColors = #()
|
|
for vertIndex=1 to faceVerts.count do
|
|
(
|
|
if meshTypeGiver == Editable_Poly then
|
|
(
|
|
local tempVertCrd = polyop.getvert giverMesh faceVerts[vertIndex]
|
|
append faceVertCoords tempVertCrd
|
|
|
|
local tempVertClr = polyop.getMapVert giverMesh bakeChannel faceMapVerts[vertIndex]
|
|
|
|
append faceVertColors tempVertClr
|
|
)
|
|
else if meshTypeGiver == Editable_Mesh then
|
|
(
|
|
local tempVertCrd = meshop.getvert giverMesh faceVerts[vertIndex]
|
|
append faceVertCoords tempVertCrd
|
|
|
|
local tempVertClr = meshop.getMapVert giverMesh bakeChannel faceMapVerts[vertIndex]
|
|
|
|
append faceVertColors tempVertClr
|
|
|
|
)
|
|
)
|
|
|
|
local newColorWeights = modellingCPVUtilsStruct.getWeightingFromPointOnFace pointOnFace faceVertCoords[1] faceVertCoords[2] faceVertCoords[3]
|
|
|
|
-- find the weighted color for each point in the tri
|
|
local newColors = #(faceVertColors[1] * newColorWeights[1], faceVertColors[2] * newColorWeights[2], faceVertColors[3] * newColorWeights[3])
|
|
|
|
local giverColor = [0,0,0]
|
|
|
|
-- add all of the colors together to get the final color of that point on the face
|
|
for index=1 to newColors.count do
|
|
(
|
|
giverColor.x += newColors[index].x
|
|
giverColor.y += newColors[index].y
|
|
giverColor.z += newColors[index].z
|
|
)
|
|
|
|
if classof recMesh == Editable_Poly then
|
|
(
|
|
local recMapFace = polyop.getmapface recMesh bakeChannel recFaceIndex
|
|
|
|
--local vertToProcess = polyop.getmapvert recMesh bakeChannel recMapFace[recVertIndex]
|
|
polyop.setMapVert recMesh bakeChannel recMapFace[recVertIndex] giverColor
|
|
)
|
|
|
|
else if classof recMesh == Editable_Mesh then
|
|
(
|
|
local recMapFace = meshOp.getmapface recMesh bakeChannel recFaceIndex
|
|
--local vertToProcess = polyop.getmapvert recMesh bakeChannel recMapFace[recVertIndex]
|
|
meshOp.setMapVert recMesh bakeChannel recMapFace[recVertIndex] giverColor
|
|
)
|
|
),
|
|
|
|
fn scaleVertsInFace pointList scaleFactor=
|
|
(
|
|
local scaledVert = undefined
|
|
local newPoint = pointList[1]
|
|
for opIndex=2 to pointList.count do
|
|
(
|
|
newPoint += ((normalize (pointList[opIndex] - pointList[1])) * scaleFactor)
|
|
|
|
)
|
|
scaledVert = newPoint
|
|
|
|
scaledVert
|
|
),
|
|
|
|
|
|
fn bakeCPVFromMeshToMesh giverMesh recMesh bakeChannel =
|
|
(
|
|
escapeEnable = true
|
|
global g_bakeCPVColorsToMeshesRollout
|
|
local skinData = undefined
|
|
for modifierNode in recMesh.modifiers do
|
|
(
|
|
if ClassOf modifierNode == Skin then
|
|
(
|
|
skinData = ExtractSkin recMesh
|
|
)
|
|
)
|
|
-- auto resetting the map channel, and collapsing
|
|
--channelInfo.ClearChannel recMesh bakeChannel
|
|
--maxOps.CollapseNode recMesh off
|
|
|
|
local meshTypeGiver = classof giverMesh
|
|
local meshTypeRec = classof recMesh
|
|
|
|
|
|
if meshTypeRec == Editable_Poly then
|
|
(
|
|
local numOfVerts = polyop.getnumverts recMesh
|
|
local numOfFaces = polyop.getnumfaces recMesh
|
|
)
|
|
else if meshTypeRec == Editable_Mesh then
|
|
(
|
|
local numOfVerts = meshop.getnumverts recMesh
|
|
local numOfFaces = meshop.getnumfaces recMesh
|
|
)
|
|
|
|
if meshTypeGiver == Editable_Poly then
|
|
(
|
|
for chan in bakeChannel do
|
|
(
|
|
polyop.setMapSupport giverMesh chan True
|
|
)
|
|
)
|
|
else if meshTypeGiver == Editable_Mesh then
|
|
(
|
|
for chan in bakeChannel do
|
|
(
|
|
meshop.setMapSupport giverMesh chan True
|
|
)
|
|
)
|
|
|
|
|
|
-- NEW METHOD BASED ON FACES
|
|
for vertIndex=1 to numOfVerts do
|
|
(
|
|
if meshTypeRec == Editable_Poly then
|
|
(
|
|
local vertFaces = polyop.getFacesUsingVert recMesh vertIndex as array
|
|
--print ("Vert: " + vertIndex as string + " Faces:" + vertFaces as string)
|
|
local vertCoord = polyop.getvert recMesh vertIndex
|
|
local scaledPoint = undefined
|
|
|
|
for faceIndex=1 to vertFaces.count do
|
|
(
|
|
local vertsInFace = polyop.getvertsusingface recMesh vertFaces[faceIndex] as array
|
|
--print ("Face: " + vertFaces[faceIndex] as string + " Vert: " + vertIndex as string)
|
|
local thisVert = findItem vertsInFace vertIndex
|
|
--print ("This vert --> " + thisVert as string)
|
|
--print ("THIS vert --> " + vertIndex as string)
|
|
deleteItem vertsInFace thisVert
|
|
vertsInFace = makeuniquearray vertsInFace
|
|
|
|
local p1 = polyop.getvert recMesh vertsInFace[1]
|
|
local p2 = polyop.getvert recMesh vertsInFace[2]
|
|
local pointList = makeuniquearray #(vertCoord, p1, p2)
|
|
|
|
scaledPoint = modellingCPVUtilsStruct.scaleVertsInFace pointList g_bakeCPVColorsToMeshesRollout.spnTolerance.value
|
|
|
|
|
|
local bestFaceInfo = modellingCPVUtilsStruct.getClosestFaceToPoint giverMesh scaledPoint g_bakeCPVColorsToMeshesRollout.spnDistThreashold.value
|
|
|
|
-- passing in giver mesh, faceindex, receiver mesh, receiver face index, receiver vertex index based on face verts, point on surface, channel
|
|
for chan in bakeChannel do
|
|
(
|
|
modellingCPVUtilsStruct.getVertColorFromPointOnFace giverMesh bestFaceInfo[2] recMesh vertFaces[faceIndex] thisVert bestFaceInfo[3] chan
|
|
)
|
|
|
|
|
|
if g_bakeCPVColorsToMeshesRollout != undefined then
|
|
(
|
|
g_bakeCPVColorsToMeshesRollout.modelProgress.value = 100.*vertIndex/numOfVerts
|
|
)
|
|
)
|
|
|
|
)
|
|
|
|
if meshTypeRec == Editable_Mesh then
|
|
(
|
|
local vertFaces = meshop.getFacesUsingVert recMesh vertIndex as array
|
|
|
|
local vertCoord = meshop.getvert recMesh vertIndex
|
|
local scaledPoint = undefined
|
|
|
|
for faceIndex=1 to vertFaces.count do
|
|
(
|
|
local vertsInFace = meshop.getvertsusingface recMesh vertFaces[faceIndex] as array
|
|
|
|
local thisVert = findItem vertsInFace vertIndex
|
|
|
|
deleteItem vertsInFace thisVert
|
|
vertsInFace = makeuniquearray vertsInFace
|
|
|
|
local p1 = meshop.getvert recMesh vertsInFace[1]
|
|
local p2 = meshop.getvert recMesh vertsInFace[2]
|
|
local pointList = makeuniquearray #(vertCoord, p1, p2)
|
|
|
|
|
|
scaledPoint = modellingCPVUtilsStruct.scaleVertsInFace pointList g_bakeCPVColorsToMeshesRollout.spnTolerance.value
|
|
|
|
|
|
local bestFaceInfo = modellingCPVUtilsStruct.getClosestFaceToPoint giverMesh scaledPoint g_bakeCPVColorsToMeshesRollout.spnDistThreashold.value
|
|
|
|
for chan in bakeChannel do
|
|
(
|
|
-- passing in giver mesh, faceindex, receiver mesh, receiver face index, receiver vertex index based on face verts, point on surface, channel
|
|
modellingCPVUtilsStruct.getVertColorFromPointOnFace giverMesh bestFaceInfo[2] recMesh vertFaces[faceIndex] thisVert bestFaceInfo[3] chan
|
|
)
|
|
|
|
|
|
|
|
if g_bakeCPVColorsToMeshesRollout != undefined then
|
|
(
|
|
g_bakeCPVColorsToMeshesRollout.modelProgress.value = 100.*vertIndex/numOfVerts
|
|
)
|
|
)
|
|
|
|
)
|
|
)
|
|
|
|
if skinData != undefined then
|
|
(
|
|
AddSkin recMesh
|
|
)
|
|
if g_bakeCPVColorsToMeshesRollout != undefined then
|
|
(
|
|
g_bakeCPVColorsToMeshesRollout.modelProgress.value = 0
|
|
)
|
|
),
|
|
|
|
fn bakeCPVFromFaceToFace giverMesh giverFace recMesh recFace bakeChannel=
|
|
(
|
|
if giverMesh != undefined and giverFace != undefined and recMesh != undefined and recFace != undefined then
|
|
(
|
|
local addModBool = 0
|
|
if classof recMesh.baseobject == Editable_Mesh then
|
|
(
|
|
addModBool = 1
|
|
local newMod = Edit_Poly()
|
|
addmodifier recMesh newMod
|
|
|
|
)
|
|
|
|
|
|
local vertsInRecFace = polyop.getFaceVerts recMesh recFace as array
|
|
|
|
for vIndex=1 to vertsInRecFace.count do
|
|
(
|
|
|
|
local vertCoords = polyop.getvert recMesh vertsInRecFace[vIndex]
|
|
|
|
local closestPoint = modellingCPVUtilsStruct.closestTriangleToPoint giverMesh giverFace vertCoords 4000
|
|
|
|
if addModBool == 1 then
|
|
(
|
|
deletemodifier recMesh 1
|
|
)
|
|
|
|
for chan in bakeChannel do
|
|
(
|
|
-- passing in giver mesh, faceindex, receiver mesh, receiver face index, receiver vertex index based on face verts, point on surface, channel
|
|
modellingCPVUtilsStruct.getVertColorFromPointOnFace giverMesh giverFace recMesh recFace vIndex vertCoords chan
|
|
)
|
|
|
|
if classof recMesh.baseobject == Editable_Mesh then
|
|
(
|
|
addModBool = 1
|
|
local newMod = Edit_Poly()
|
|
addmodifier recMesh newMod
|
|
|
|
)
|
|
|
|
)
|
|
if addModBool == 1 then
|
|
(
|
|
deletemodifier recMesh 1
|
|
)
|
|
)
|
|
else
|
|
(
|
|
print "Error: Selections are not valid, please check your giver and receiver!"
|
|
)
|
|
)
|
|
|
|
)
|
|
|
|
fn updateColorDrawOnMesh meshToProcess targetChannel =
|
|
(
|
|
|
|
if( targetChannel == -1 )then
|
|
(
|
|
meshToProcess.vertexColorType = #illum
|
|
)
|
|
|
|
if( targetChannel == 0 )then
|
|
(
|
|
meshToProcess.vertexColorType = #color
|
|
)
|
|
|
|
if( targetChannel >= 1 )then
|
|
(
|
|
meshToProcess.vertexColorType = #map_channel
|
|
meshToProcess.vertexColorMapChannel = targetChannel --Map channel
|
|
)
|
|
|
|
--updateViewport
|
|
local addModBool = 0
|
|
if classof meshToProcess != Editable_Poly then
|
|
(
|
|
local newMod = Edit_Poly()
|
|
addModifier meshToProcess newMod
|
|
addModBool = 0
|
|
)
|
|
try
|
|
(
|
|
polyop.collapsedeadstructs meshToProcess
|
|
)
|
|
catch
|
|
(
|
|
print "Could not update the display, please manually switch CPV sets in the veiwport to see the correct colors."
|
|
)
|
|
|
|
if addModBool == 1 then
|
|
(
|
|
deletemodifier meshToProcess 1
|
|
)
|
|
|
|
)
|
|
|
|
fn treansferCPVFromMeshToMeshesUI=
|
|
(
|
|
escapeEnable = true
|
|
global g_bakeCPVColorsToMeshesRollout
|
|
rollout g_bakeCPVColorsToMeshesRollout "Transfer CPV's "
|
|
(
|
|
local giverObject = undefined
|
|
local receiverObjects = undefined
|
|
local giverFace = #()
|
|
local receiverFace = #()
|
|
|
|
dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:252 -- .NET FORM TO HOLD THE IMAGES
|
|
local banner = makeRsBanner dn_Panel:rsBannerPanel width:290 studio:"sandiego" mail:"kyle.hansen@rockstarsandiego.com" wiki:"Bake CPV From Mesh To Meshes" filename:(getThisScriptFilename())-- INSTANCE THE STRUCT
|
|
group "Mesh To Meshes"
|
|
(
|
|
button btnAddGiver "Select Giver" width:120 tooltip:"Sets the first selected item as the giver." align:#left
|
|
|
|
edittext giverLabel "Giver:" width:225 align:#left readonly:true labelOnTop:true
|
|
spinner spnTolerance "Offset Tol:" range:[0.000,1.000,0.025] type:#float align:#left scale:0.001
|
|
spinner spnDistThreashold "Face Distance Threashold:" range:[0.000,125,25] width:200 type:#float align:#left scale:1 tooltip:"Limits the search to faces whos verts are closer than the value in the field. Increasing this will speed up the process, but makes may hurt accuracy."
|
|
|
|
button btnAddReceivers "Select Receivers" width:120 tooltip:"Sets the selected items as the receivers." align:#left
|
|
|
|
label receiversTextLabel "Receivers:" align:#left
|
|
label receiverLabel "" height:15 width:180 align:#left offset:[50,-18]
|
|
listbox recListBox height: 15
|
|
radiobuttons rdoChannelSelect "Target:" labels:#("Vertex Color", "Vertex Illumination", "Map Channel") columns:2 align:#left offset:[0,5]
|
|
spinner spnChannel "Target Map Channel:" range:[1,99,1] type:#integer align:#left scale:1
|
|
|
|
button btnBakeReceivers "Bake CPVs" width:225 tooltip: "Start the baking for the selected channel from the giver to receivers." offset:[0,5]
|
|
label currentObject "Current Object:" width:255 tooltop: "The current mesh being processed." align:#left offset:[0,15]
|
|
progressbar modelProgress value:0 width:225 height:10 color:green tooltip:"Progress of the current mesh."
|
|
progressbar totalProgress value:0 width:225 height:15 color:green tooltip:"Progress of the baking task."
|
|
)
|
|
|
|
group "Face To Face"
|
|
(
|
|
button btnGiverFace "Select Giver Face" width:225 tooltip: "Select the giver face for processing."
|
|
button btnReceiverFace "Select Receiver Face" width:225 tooltip: "Select the receiver face for processing."
|
|
button btnBakeFaceToFace "Bake CPVs" width:225
|
|
)
|
|
|
|
fn GetTargetChannel =
|
|
(
|
|
--Vertex Color
|
|
if( rdoChannelSelect.state == 1 ) then
|
|
(
|
|
return 0
|
|
)
|
|
--Vertex illumination
|
|
if( rdoChannelSelect.state == 2 ) then
|
|
(
|
|
return -1
|
|
)
|
|
--Map channel
|
|
if( rdoChannelSelect.state == 3 ) then
|
|
(
|
|
return spnChannel.Value
|
|
)
|
|
)
|
|
|
|
--g_RayfireProgressBars = #(modelProgress, totalProgress)
|
|
on g_bakeCPVColorsToMeshesRollout open do
|
|
(
|
|
banner.setup() -- add the banner
|
|
)
|
|
|
|
on btnBakeFaceToFace pressed do
|
|
(
|
|
if giverFace != undefined and receiverFace != undefined then
|
|
(
|
|
if giverFace != receiverFace then
|
|
(
|
|
modellingCPVUtilsStruct.bakeCPVFromFaceToFace giverFace[1] giverFace[2] receiverFace[1] receiverFace[2] #(0, -1)
|
|
)
|
|
else
|
|
(
|
|
"ERROR: Oh no's! The giver and receiver are the same! This will cause the universe to collapse into a singularity."
|
|
)
|
|
targetChannel = GetTargetChannel()
|
|
updateColorDrawOnMesh receiverFace[1] targetChannel
|
|
)
|
|
)
|
|
|
|
on btnGiverFace pressed do
|
|
(
|
|
|
|
local giverMeshObj = pickObject count:1 forceListenerFocus:false
|
|
local addModBool = 0
|
|
|
|
|
|
if classof giverMeshObj.baseobject == Editable_Poly then
|
|
(
|
|
newMeshMod = edit_Mesh()
|
|
addmodifier giverMeshObj newMeshMod
|
|
addModBool = 1
|
|
)
|
|
|
|
local mouseRay = mapScreenToWorldRay mouse.pos
|
|
local intersectCalc = intersectRayEx giverMeshObj mouseray
|
|
|
|
giverFace = #(giverMeshObj, intersectCalc[2])
|
|
|
|
if addModBool == 1 then
|
|
(
|
|
deleteModifier giverMeshObj 1
|
|
)
|
|
if giverFace != undefined then
|
|
(
|
|
btnGiverFace.text = ("Giver: " + giverFace[1].name + " Face[" + giverFace[2] as string + "]")
|
|
)
|
|
else
|
|
(
|
|
btnGiverFace.text = "Select Giver Face"
|
|
)
|
|
|
|
)
|
|
|
|
on btnReceiverFace pressed do
|
|
(
|
|
|
|
local receiverMeshObj = pickObject count:1 forceListenerFocus:false
|
|
if receiverMeshObj != undefined then
|
|
(
|
|
receiverMeshObj = receiverMeshObj
|
|
)
|
|
local addModBool = 0
|
|
|
|
|
|
if classof receiverMeshObj.baseobject == Editable_Poly then
|
|
(
|
|
newMeshMod = edit_Mesh()
|
|
addmodifier receiverMeshObj newMeshMod
|
|
addModBool = 1
|
|
)
|
|
local numModInStack = receiverMeshObj.modifiers.count
|
|
local mouseRay = mapScreenToWorldRay mouse.pos
|
|
local intersectCalc = intersectRayEx receiverMeshObj mouseray
|
|
|
|
receiverFace = #(receiverMeshObj, intersectCalc[2])
|
|
|
|
if addModBool == 1 then
|
|
(
|
|
deleteModifier receiverMeshObj 1
|
|
)
|
|
if receiverFace != undefined then
|
|
(
|
|
btnReceiverFace.text = ("Giver: " + receiverFace[1].name + " Face[" + receiverFace[2] as string + "]")
|
|
)
|
|
else
|
|
(
|
|
btnReceiverFace.text = "Select Giver Face"
|
|
)
|
|
|
|
)
|
|
|
|
on btnAddGiver pressed do
|
|
(
|
|
local sel = (selection as array)
|
|
if sel.count > 0 then
|
|
(
|
|
giverObject = sel[1]
|
|
if classof giverObject == editable_poly then
|
|
(
|
|
subobjectLevel = 1
|
|
meshVerts = polyop.getnumverts giverObject
|
|
polyop.setVertSelection giverObject #{1..meshVerts}
|
|
giverObject.EditablePoly.ConnectVertices ()
|
|
subobjectLevel = 0
|
|
)
|
|
else if classof giverObject == editable_mesh then
|
|
(
|
|
print "triangulate"
|
|
modPanel.addModToSelection (Turn_to_Mesh ()) ui:on
|
|
giverObject.modifiers[#Turn_to_Mesh].useInvisibleEdges = off
|
|
maxOps.CollapseNode giverObject off
|
|
)
|
|
giverLabel.text = (giverObject.name)
|
|
)
|
|
)
|
|
|
|
on btnAddReceivers pressed do
|
|
(
|
|
local sel = (selection as array)
|
|
if sel.count > 0 then
|
|
(
|
|
receiverObjects = sel
|
|
receiverLabel.text = (sel.count as string + " Items selected.")
|
|
local recNames = for obj in receiverObjects where obj.name != undefined collect obj.name
|
|
recListBox.items = recNames
|
|
)
|
|
)
|
|
|
|
on btnBakeReceivers pressed do
|
|
(
|
|
|
|
rayfireCPVUtilInst = modellingCPVUtilsStruct()
|
|
if giverObject != undefined and receiverObjects != undefined then
|
|
(
|
|
local nodeClashes = for obj in receiverObjects where obj == giverObject collect obj
|
|
if nodeClashes.count == 0 then
|
|
(
|
|
print "WE GOT PAST THE PARADOX!!!"
|
|
if getnodebyname giverObject.name != undefined then
|
|
(
|
|
|
|
-- channelIndexMap describes the radio buttons and the channel index for that button
|
|
channelsToBake = #( GetTargetChannel() )
|
|
|
|
for objIndex=1 to receiverObjects.count do
|
|
(
|
|
recListBox.selection = objIndex
|
|
currentObject.text = "Current Object: " + receiverObjects[objIndex].name
|
|
if getnodebyname receiverObjects[objIndex].name != undefined then
|
|
(
|
|
if classof receiverObjects[objIndex] == Editable_Mesh then
|
|
(
|
|
for chan in channelsToBake do
|
|
(
|
|
meshop.setMapSupport receiverObjects[objIndex] chan True
|
|
)
|
|
)
|
|
else if classof receiverObjects[objIndex] == Editable_Poly then
|
|
(
|
|
for chan in channelsToBake do
|
|
(
|
|
polyop.setMapSupport receiverObjects[objIndex] chan True -- channelIndexMap[channelIndex] True
|
|
)
|
|
)
|
|
modellingCPVUtilsStruct.bakeCPVFromMeshToMesh giverObject receiverObjects[objIndex] channelsToBake --channelIndexMap[channelIndex]
|
|
)
|
|
else
|
|
(
|
|
print "Error: Object: " + receiverObjects[objIndex].name + " does not exist, skipping."
|
|
)
|
|
totalProgress.value = 100.*objIndex/receiverObjects.count
|
|
updateColorDrawOnMesh receiverObjects[objIndex] channelsToBake[1] -- updates the veiwport for this object so the colors will show correctly
|
|
)
|
|
|
|
totalProgress.value = 0
|
|
)
|
|
else
|
|
(
|
|
print "Warning: Giver is not in this scene!"
|
|
)
|
|
)
|
|
else
|
|
(
|
|
print "Error: You have the giver as a receiver, this will break the universe! It's like going back in time, and killing your grandfather..."
|
|
)
|
|
)
|
|
else
|
|
(
|
|
print "Warning: Nothing selected for giver or receivers!"
|
|
)
|
|
)
|
|
)
|
|
createDialog g_bakeCPVColorsToMeshesRollout 252 710
|
|
g_bakeCPVColorsToMeshesRollout
|
|
)
|
|
|
|
if newTransferUI != undefined then
|
|
(
|
|
DestroyDialog newTransferUI
|
|
)
|
|
|
|
newTransferUI = treansferCPVFromMeshToMeshesUI() |