Files
2025-09-29 00:52:08 +02:00

513 lines
16 KiB
Plaintext
Executable File

--tool for pre skin data transfer setup to bring in a template mesh
--we will bring in the template mesh
--rename the receiver meshes joints to match a predefined template name
--load skinning for template mesh via load enevelopes
--rename joints back to origninal names
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
filein "rockstar/export/settings.ms" -- This is fast
-- Figure out the project
global theProjectRoot = RsConfigGetProjRootDir()
global theProject = RSConfigGetProjectName()
global theWildWest = RsConfigGetWildWestDir()
global theProjectConfig = RsConfigGetProjBinConfigDir()
global toolsRoot = RsConfigGetToolsRootDir()
global boneList = #()
global mjrTarget = undefined
global handVerts = #() --used for storing which verts comprise the hands for if we want to preserve hand skinning
global skinDataFileName = "c:/skins/skinDataTransferHands.skn"
-- filein (theProjectRoot + "tools/wildwest/script/3dsMax/Characters/Rigging/usefulScripts/Skinning_Tools.ms")
filein (toolsRoot + "/wildwest/script/3dsMax/_common_functions/FN_Rigging.ms")
global RsPreserveHandSkin = true
global skinXFerComplete = undefined
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
fn LSW_EnvelopeCallbackFunction =
(
WindowHandle = DialogMonitorOPS.GetWindowHandle()
theDialogName = UIAccessor.GetWindowText WindowHandle
if theDialogName != undefined and matchpattern theDialogName pattern:"*Load Envelopes*" do
UIAccessor.PressButtonByName WindowHandle "Match by Name"
if theDialogName != undefined and matchpattern theDialogName pattern:"*Load Envelopes*" do
UIAccessor.PressButtonByName WindowHandle "OK"
true
)
fn inputHandSkinData recMesh =
(
-- loadedSkinData = ST_input_skin_data recMesh skinDataFileName
format ("Loading "+skinDataFileName+" onto "+(recMesh as string)+"\n")
ST_apply_skin_weights recMesh skinDataFileName
)
fn outPutHandSkinData recMesh =
(
--this will use a vol select to select verts that make the hands and save out their skinning data for later loading
--we will do this by doing a vol select around each middle finger 20 joint
local skinMod = recMesh.modifiers[#Skin]
-- Abort if model has no Skin modifier:
if (skinMod == undefined) do
(
RsPreserveHandSkin = false
return False
)
--now we'll make a selectionVolume
volSphere = Sphere radius:0.2 smooth:on segs:32 chop:0 slice:off sliceFrom:0 sliceTo:0 mapcoords:on recenter:off pos:[0,0,0] isSelected:on name:"VolSphere" color:green
SetCommandPanelTaskMode #Modify
--first we'll gather the right hand verts
volSphere.transform = $SKEL_R_Finger20.transform
modPanel.setCurrentObject recMesh.baseObject
local volSelMod = Vol__Select()
modPanel.addModToSelection volSelMod ui:on
volSelMod.level = 1
volSelMod.volume = 3
volSelMod.node = VolSphere
selectedVerts = recMesh.mesh.selectedVerts as bitarray
for vert in selectedVerts do
(
append handVerts vert
)
--now do the other hand
volSphere.transform = $SKEL_L_Finger20.transform
selectedVerts = recMesh.mesh.selectedVerts as bitarray
for vert in selectedVerts do
(
append handVerts vert
)
if handVerts.count < 1 do
(
format ("Warning! "+recMesh.name+" mesh doesnt appear to HAVE any hands!")
RsPreserveHandSkin = false
)
--now we can delete the volSelect modifier etc
delete volSphere
for modi = recMesh.modifiers.count to 1 by -1 do
(
if recMesh.modifiers[modi].name == "Vol. Select" do
(
deleteModifier recMesh modi
)
)
--now we're ready to save the data out
modPanel.setCurrentObject skinMod
skinOps.SelectVertices skinMod handVerts
skinnedVertListData = ST_get_skin_weights recMesh --first of all query the skin weights
ST_output_skin_data theMeshObject skinnedVertListData skinDataFileName
)
fn inputBones input_name =
(
--*************************************************************************************
-- NEED TO ADD A DISABLE UI HERE OTHERWISE IT TAKES AGES!
--*************************************************************************************
Geo = selection
if Geo.count == 1 then
(
g = $
if g.modifiers[#Skin] == undefined then
(
messageBox "Please pick an object with a skin modifier." title:"gta5_boneinput"
)
else
(
skinMod = $.modifiers[#Skin]
if input_name == undefined do
(
input_name = getOpenFileName caption:"Bone input file" types:"BoneData (*.bon)|*.bon|All Files (*.*)|*.*|"
)
if input_name != undefined then
(
f = openfile input_name
inputData = #() -- define as array
while not eof f do
(
append inputData (filterstring (readLine f) ",")
)
close f
for i in inputData do
(
currBonename = (i as string)
currBoneLength = currBonename.count
-- currBone = ("$"+(substring currBonename 4 (currBonelength - 5)))
currBone = (substring currBonename 4 (currBonelength - 5))
-- executeStr = ("if "+currBone+" != undefined do ("+"select "+currBone+")")
-- currentBone = execute executeStr
-- currentBone = execute currBone
currentBone = getNodeByName currBone
-- if currentBone != undefined do
if currentBone != undefined then
(
appendIfUnique boneList currentBone
)
else
(
print ("Couldn't find "+currBone+" in this scene.")
)
)
-- print ("BoneList = " +(boneList as String))
select g
SetCommandPanelTaskMode mode:#modify
for i = 1 to boneList.count do
(
boneToAdd = getNodeByName bonelist[i].name
boneUpdateInt = undefined
if i != bonelist.count then
(
boneUpdateInt = 1
)
else
(
boneUpdateInt = 0
)
if boneToAdd != undefined do
(
skinOps.addbone g.modifiers[#Skin] boneList[i] boneUpdateInt
)
)
)
)
)
else
(
messageBox "Please run with only 1 object selected." title:"gta5_boneinput"
)
)
fn importTemplateMesh recMesh templateString =
(
--this will merge in a predefined head which has skinning onto a rig with joints with a TEMPLATE suffix instead of a name.
--we merge in the head then rename the joints suffix of the existing recMesh to have a TEMPLATE suffix instead of their number
--we then load the skinning form a predefined bone and weight file for the template mesh
--then rename the joints back to the number of the recMesh
--turn off the gta callbacks
callbacks.removeScripts id:#RsGlobalCallbacks
--Facial Rig template
-- templateMeshFile = (theProjectRoot + "art/peds/AmbientHead/templateHead.max")
-- templateSkinFile = (theProjectRoot + "art/peds/AmbientHead/templateMesh.env")
-- templateBoneFile = (theProjectRoot + "art/peds/AmbientHead/templateMesh.bon")#
tPr = "x:/gta5/"
templateMeshFile = (tPr + "art/peds/AmbientHead/templateHead.max")
templateSkinFile = (tPr + "art/peds/AmbientHead/templateMesh.env")
templateBoneFile = (tPr + "art/peds/AmbientHead/templateMesh.bon")
if( templateString == "B-Rig [Ortega]" ) then
(
--Facial B-Rig template [Ortega]
print "Ortega"
-- templateMeshFile = (theProjectRoot + "art/peds/AmbientHead/B_Rigs/templateHead_Ortega.max")
-- templateSkinFile = (theProjectRoot + "art/peds/AmbientHead/B_Rigs/templateMesh_Ortega.env")
-- templateBoneFile = (theProjectRoot + "art/peds/AmbientHead/B_Rigs/templateMesh_Brig.bon")
templateMeshFile = (tPr + "art/peds/AmbientHead/B_Rigs/templateHead_Ortega.max")
templateSkinFile = (tPr + "art/peds/AmbientHead/B_Rigs/templateMesh_Ortega.env")
templateBoneFile = (tPr + "art/peds/AmbientHead/B_Rigs/templateMesh_Brig.bon")
)
if( templateString == "B-Rig [ProlSec]" ) then
(
--Facial B-Rig template [ProlSec]
print "ProlSec"
-- templateMeshFile = (theProjectRoot + "art/peds/AmbientHead/B_Rigs/templateHead_B_ProlSec.max")
-- templateSkinFile = (theProjectRoot + "art/peds/AmbientHead/B_Rigs/templateMesh_B_ProlSec.env")
-- templateBoneFile = (theProjectRoot + "art/peds/AmbientHead/B_Rigs/templateMesh_Brig.bon")
templateMeshFile = (tPr + "art/peds/AmbientHead/B_Rigs/templateHead_B_ProlSec.max")
templateSkinFile = (tPr + "art/peds/AmbientHead/B_Rigs/templateMesh_B_ProlSec.env")
templateBoneFile = (tPr + "art/peds/AmbientHead/B_Rigs/templateMesh_Brig.bon")
)
foundData = 0 --used to track if files exist
if doesFileExist templateMeshFile != true then
(
print ("Syncing "+templateMeshFile)
-- sync templateMeshFile
gRsPerforce.sync templateMeshFile silent:true force:true
if doesFileExist templateMeshFile != true then
(
format ("WARNING FAILED Syncing "+templateMeshFile+"\n")
messagebox ("WARNING FAILED Syncing "+templateMeshFile+"\n")
)
)
if doesFileExist templateBoneFile != true then
(
print ("Syncing "+templateBoneFile)
-- sync templateBoneFile
gRsPerforce.sync templateBoneFile silent:true force:true
if doesFileExist templateBoneFile != true then
(
format ("WARNING FAILED Syncing "+templateBoneFile+"\n")
messagebox ("WARNING FAILED Syncing "+templateBoneFile+"\n")
)
)
if doesFileExist templateSkinFile != true then
(
print ("Syncing "+templateSkinFile)
-- sync templateSkinFile
gRsPerforce.sync templateSkinFile silent:true force:true
if doesFileExist templateSkinFile != true then
(
format ("WARNING FAILED Syncing "+templateSkinFile+"\n")
messagebox ("WARNING FAILED Syncing "+templateSkinFile+"\n")
)
)
if doesFileExist templateMeshFile == true then
(
if doesFileExist templateBoneFile == true then
(
if doesFileExist templateSkinFile == true then
(
mergeMaxFile templateMeshFile #deleteOldDups #useSceneMtlDups #alwaysReparent quiet:true
tempMesh = getNodeByName "templateMesh"
boneList = #()
currsel = selection as array
select tempMesh
--now we need to do the bone renaming bit.
meshName = recMesh.name
tempMesh.pivot = recMesh.pivot
-- meshLength = meshName.count
-- meshNo = (substring meshName (meshLength - 3) 3)
meshNo = filterString meshName "_"
meshNo = meshNo[2]
for o in objects do
(
if (classof o as string) == "BoneGeometry" do
(
oName = o.name
if (substring o.name (oName.count - 2) 3) == meshNo do
(
format ("renaming "+o.name+"\n")
o.name = ((substring o.name 1 (oName.count - 3))+"TEMPLATE")
)
)
)
modPanel.addModToSelection (Skin ()) ui:on
tempMesh.modifiers[#Skin].bone_Limit = 4
inputBones templateBoneFile
DialogMonitorOPS.RegisterNotification LSW_EnvelopeCallbackFunction ID:#ANoon_Envelopes
DialogMonitorOPS.Enabled = true
completeRedraw()
skinOps.loadEnvelope tempMesh.modifiers[#Skin] templateSkinFile
completeRedraw()
DialogMonitorOPS.Enabled = false
DialogMonitorOPS.UnRegisterNotification ID:#ANoon_Envelopes
--need to toggle always defmore on the template mesh
tempMesh.modifiers[#Skin].always_Deform = false
tempMesh.modifiers[#Skin].always_Deform = true
--NOW RENAME THE JOINTS BACK
for o in objects do
(
if (classof o as string) == "BoneGeometry" do
(
oName = o.name
--print ("obj: "+oName)
-- if (substring o.name (oName.count - 7) 8) == "TEMPLATE" do
isTemplate = findString o.name "TEMPLATE"
if isTemplate != undefined do
(
format ("renaming "+o.name+"\n")
o.name = ((substring o.name 1 (oName.count - 8))+meshNo)
)
)
)
completeRedraw()
--turn back on the gta callbacks
-- filein (theProjectRoot+ "tools/dcc/current/max2012/scripts/pipeline/util/global_callbacks.ms")
filein (toolsRoot+ "/dcc/current/max2012/scripts/pipeline/util/global_callbacks.ms")
for o in objects do
(
if o != recMesh do
(
if o != tempMesh do
(
hide o
)
)
)
)
else
(
format ("Quiting out due to missing "+templateSkinFile+"\n")
)
)
else
(
format ("Quiting out due to missing "+templateBoneFile+"\n")
)
)
else
(
format ("Quiting out due to missing "+templateMeshFile+"\n")
)
)
-- recMesh = $Head_001_R
-- importTemplateMesh recMesh
try (destroyDialog RStransferSkinDataUI) catch ()
rollout RStransferSkinDataUI "Transfer Skin Data" width:170
(
dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:RStransferSkinDataUI.width
local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"SkinDataXFer_Prep" filename:(getThisScriptFilename())
fn sourceFilter obj = (isKindOf obj.baseObject Editable_Poly) and (obj.modifiers[#skin] != undefined)
fn targetFilter obj = (isKindOf obj.baseObject Editable_Poly)
-- pickbutton getSourceObjBtn "[pick Source]" filter:targetFilter autoDisplay:true width:130 across:2
dropdownlist templateCombo width:145 items:#("B-Rig [Ortega]", "B-Rig [ProlSec]", "Standard Rig")
pickbutton getTargetObjBtn "[pick Target]" filter:targetFilter autoDisplay:true width:145 color:green
checkBox keepHandsChk "Preserve Hand Skinning" default:false
local objBtns = #(getTargetObjBtn)
button skinXferBtn "Launch Skin Transfer" width:145
on RStransferSkinDataUI open do
(
banner.setup()
skinXferBtn.enabled = false
RsPreserveHandSkin = keepHandsChk.state
--check we're not set nitrous
dispDrv = gw.getDriverString()
if dispDrv == undefined do
(
messageBox ("WARNING! Viewport rendering not set to Direct3D. Tool will be unstable/unusable.") beep:true Title:"Display settings Error"
)
)
on keepHandsChk changed theState do
(
if keepHandsChk.state == true then
(
RsPreserveHandSkin = true
print "Twooo"
)
else
(
RsPreserveHandSkin = false
print "Fud"
)
)
on getTargetObjBtn picked obj do
(
mjrTarget = obj
select mjrTarget
max hide inv --hide unselected
skinXferBtn.enabled = true
)
on skinXferBtn pressed do
(
--first save out hand skinning data if we are preserving
if RsPreserveHandSkin == true do
(
outPutHandSkinData mjrTarget
)
print ("mjrTarget: "+(mjrTarget as string))
--nned to collapse the mjrTarget object.
collapseStack mjrTarget
-- addModifier mjrTarget (Skin())
importTemplateMesh mjrTarget templateCombo.selected
destroyDialog RStransferSkinDataUI
--now we're ready to do the skin data transfer
filein (::RsConfigGetWildwestDir() + "script/3dsmax/characters/rigging/skindatatransfer_UI.ms")
-- while skinXFerComplete == true do
-- (
-- if RsPreserveHandSkin == true do
-- (
-- inputHandSkinData targetObj
-- )
-- )
)
)
createDialog RStransferSkinDataUI