1 Star 0 Fork 1

Alex / maxscript

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
ShareTools.ms 55.30 KB
一键复制 编辑 原始数据 按行查看 历史
Alex 提交于 2023-10-13 23:18 . 升级检查重叠缩放点功能
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600
rollout Common_SelectFaceByUVWTool "依据UnwrapUVW选面"
(
button btnOpenPanel "打开依据UVW选面工具" toolTip:"打开依据UVW选面工具" align:#center
on btnOpenPanel pressed do
(
if Common_SelectFaceByUVW != undefined then
(
DestroyDialog Common_SelectFaceByUVW
)
createDialog Common_SelectFaceByUVW width:220
)
)
rollout Common_VertexPaintToSelectedFaceTool "给选中面刷顶点色"
(
button btnOpenPanel "打开给选中面刷顶点色工具" toolTip:"打开给选中面刷顶点色工具" align:#center
on btnOpenPanel pressed do
(
if Common_VertexPaintToSelectedFace != undefined then
(
DestroyDialog Common_VertexPaintToSelectedFace
)
createDialog Common_VertexPaintToSelectedFace width:220
)
)
rollout Common_NormalMappingTool "Normal映射"
(
button btnOpenPanel "打开Normal映射工具" toolTip:"打开Normal映射工具" align:#center
on btnOpenPanel pressed do
(
if Common_NoorsNormalThief != undefined then
(
DestroyDialog Common_NoorsNormalThief
)
createDialog Common_NoorsNormalThief width:220
)
)
rollout Common_RolloutSolveExportGimbalLock "FBX GimbalLock修复"
(
/*
逻辑:
填入报错骨骼
填入相关mesh
对报错骨骼 assume skin pose
-- 根据报错骨骼找mesh
for mesh
mesh 缩放为 100
extract skin data to mesh 新产生的mesh为 SkinData_原mesh名
记录skin modifier上的boneList
对skin modifier 做 collapse to
新加skin modifier,加boneList
传权重
删掉 SkinData_原mesh名
*/
-- string1 = "-zhuozi"
-- string2 = replace string1 1 1 "$"
-- namesArray = for s in selection collect s.name
fn getSkinBones obj =
(
max modify mode
select obj
if obj.modifiers[#Skin] != undefined do
(
skinBones = #()
skinModifiers = getclassinstances Skin target:obj
for s = 1 to skinModifiers.count where skinModifiers.count > 0 do
(
boneCount = skinOps.getnumberbones skinModifiers[s]
for x = 1 to boneCount do
(
myBone = (skinOps.getBoneName skinModifiers[s] x 0)
append skinBones (getNodeByName myBone)
)
)
print skinBones
)
return skinBones
)
-- Not considering multi skin modifiers condition
fn reSkins objName =
(
obj = getNodeByName objName
print obj
obj.scale = [1,1,1]
-- refresh mesh size
sliderTime = 1f
sliderTime = 0f
skinUtils.ExtractSkinData obj
max modify mode
select obj
if obj.modifiers[#Skin] != undefined do
(
skinBones = #()
skinModifiers = getclassinstances Skin target:obj
if skinModifiers.count > 1 then
(
print skinModifiers.count
print "Warning! Too many Skin modifiers!"
return 0
)
else
(
if skinModifiers.count == 1 do
(
boneCount = skinOps.getnumberbones skinModifiers[1]
for i = 1 to boneCount do
(
myBone = (skinOps.getBoneName skinModifiers[1] i 0)
append skinBones (getNodeByName myBone)
)
)
print skinBones
)
/*
for modifierIndex = 1 to obj.modifiers.count do
(
if obj.modifiers[modifierIndex] == skinModifiers[1] then
(
skinModifiers[1].mirrorEnabled = off
-- deleteModifier obj skinModifiers[1]
maxOps.CollapseNodeTo obj modifierIndex off
)
)
*/
-- modPanel.setCurrentObject skinModifiers[1]
modifierIndex = modPanel.getModifierIndex obj skinModifiers[1]
maxOps.CollapseNodeTo obj modifierIndex off
addModifier obj (Skin())
newSkin = obj.modifiers[#Skin]
skinDataObjName = "SkinData_" + objName
skinDataObj = getNodeByName skinDataObjName
for skinBoneIndex=1 to skinBones.count do
(
skinBone = skinBones[skinBoneIndex]
modPanel.setCurrentObject newSkin
skinOps.addBone newSkin skinBone skinBoneIndex
print skinBone
)
select #(obj, skinDataObj)
skinUtils.ImportSkinDataNoDialog true false false false false 1.0 0
-- newSkin.always_deform = false
-- newSkin.enabled=true
-- newSkin.always_deform = true
delete skinDataObj
clearSelection()
)
)
fn batching boneArray meshArray=
(
-- boneArray = #("huatong", "shanzi", "muban", "Bone001", "Bone003", "Bone005", "zhuozi")
-- meshArray = #("SM_af32mrr_csdesk_01", "SK_af32mrr_default_CG")
sliderTime = 0f
for boneName in boneArray do
(
myBone = getNodeByName boneName
myBone.assumeSkinPose()
skinModifiers = getclassinstances Skin target:myBone
for index = 1 to skinModifiers.count do deleteModifier myBone skinModifiers[index]
)
for meshName in meshArray do
(
reSkins meshName
)
)
group ""
(
edittext boneList "骨骼/控制器:" height:100 labelOnTop:true
listbox meshList "模型:" height:7 items:#() readOnly:false
button addMeshButton "添加模型" toolTip:"将选择的模型添加到上面的列表中" align:#center across:2 offset:[0,2]
button deleteMeshButton "删除模型" toolTip:"删除上面的列表中选择的模型" align:#center offset:[0,2]
)
button batchingButton "开始批处理" toolTip:"1.让骨骼/控制器回到初始Pose(Assume Skin Pose)\n2.模型还原缩放到100\n3.重做Skin,还原权重"
on addMeshButton pressed do
(
tempArray = meshList.items
for obj in selection do
(
objName = obj.name
if (findItem tempArray objName) != 0 or (classOf obj as string) != "PolyMeshObject" do continue
meshList.items = append meshList.items objName
)
)
on deleteMeshButton pressed do
(
if meshList.items.count > 0 and meshList.selection > 0 do
(
meshList.items = deleteItem meshList.items meshList.selection
)
)
on batchingButton pressed do
(
boneArray = FilterString boneList.text "- \r\n"
meshArray = meshList.items
batching boneArray meshArray
)
)
rollout Common_AssembleTool "动画组装工具"
(
button btnOpenDialogPanel "动画组装工具" toolTip:"打开动画组装工具面板" align:#center width:100
on btnOpenDialogPanel pressed do
(
if assembleAnimDialog != undefined then
(
DestroyDialog assembleAnimDialog
)
createDialog assembleAnimDialog modal:false
)
)
-- FBX可以用FBX - Merge操作合并回Max
rollout MocapBipedToolsRollout "动捕相关工具" width:250 height:244
(
group "添加Root/*Origin点"
(
label lblAddRoot "请选中骨架的质心点(如:Bip01)" align:#left width:190 across:2
button btnAddRoot "添加" align:#right width:40
)
group "生成TPose Fbx"
(
editText textFBXSuffix "Fbx文件后缀" width:160 text:"_TPose" align:#left
checkbox chkBipedOnly "只输出CS骨骼" default:false align:#Left
label lblTPoseExport "输出Tpose Fbx到Max文件目录" width:180 align:#left across:2
button btnTPoseExport "输出" width:40 align:#right
)
group "动捕数据应用到Max文件"
(
label lbl1 "1 打开需要应用动捕fbx的Max文件" align:#left
label lbl2 "2" across:3 align:#left width:10 offset:[0,8]
edittext MocapFbxPath "" width:160 offset:[-65,6] text:"请选择动捕fbx源文件目录"
button btnSelectMocapFbxPath "选择" width:40 offset:[0,6] height:18 align:#right
label lbl3 "3" across:2 align:#left width:10 offset:[0,6]
button btnatchExecute "批处理转换" offset:[-100,0] width:100 align:#left toolTip:"根据所有动捕动作fbx,依次生成对应max文件(帧速率60FPS)"
)
fn TraversalChildNode parentNode selectionArray =
(
if parentNode == undefined then
(
return false
)
for childnode in parentNode.children do
(
if childnode.children.count > 0 then
(
if not (TraversalChildNode childnode selectionArray) then
return false
)
else
(
append selectionArray childnode
)
)
append selectionArray parentNode
return true
)
fn SelectSkeletonAll =
(
local selectionArray = #()
local ret = TraversalChildNode $Root selectionArray
if ret then
(
selectMore selectionArray
)
return ret
)
fn GetAllBipedObjects =
(
local bipedObjects = #()
for geo in geometry where (isKindOf geo Biped_Object) do
(
append bipedObjects geo
)
return bipedObjects
)
fn getFilesRecursive root pattern =
(
local dir_array = GetDirectories (root+"/*")
for d in dir_array do
join dir_array (GetDirectories (d+"/*"))
local my_files = getFiles (root+"/*")
for f in dir_array do
join my_files (getFiles (f + pattern))
return my_files
)
on btnAddRoot pressed do
(
if $ != undefined then
(
if getnodebyname "Root" == undefined then
Dummy pos:[0,0,0] name:"Root" boxSize:[20,20,20]
if getnodebyname "*origin" == undefined then
Dummy pos:[0,0,0] name:"*origin" boxSize:[10,10,10]
$.parent = $Root
messageBox("添加Root和*Origin点成功! ")
)
else
(
messageBox("请选中骨架的质心点! ")
)
)
on btnTPoseExport pressed do
(
setquietmode true
max hold
max unhide all #noPrompt
local filename = maxfilepath + maxfilename
if filename == "" then
(
setquietmode false
messagebox("操作失败 Max文件异常! ")
return false
)
fbxExporterSetParam "Animation" false
sliderTime = 0
local rootBone = $Root
if undefined == rootBone then
(
setquietmode false
messagebox("操作失败 骨架上没有Root点! ")
return false
)
local BipedBones = GetAllBipedObjects()
local L_Clavicle = undefined
local L_UpperArm = undefined
local L_Forearm = undefined
local L_Hand = undefined
local R_Clavicle = undefined
local R_UpperArm = undefined
local R_Forearm = undefined
local R_Hand = undefined
local L_Finger0Arr = #()
local L_Finger1Arr = #()
local L_Finger2Arr = #()
local L_Finger3Arr = #()
local L_Finger4Arr = #()
local R_Finger0Arr = #()
local R_Finger1Arr = #()
local R_Finger2Arr = #()
local R_Finger3Arr = #()
local R_Finger4Arr = #()
for BoneNode in BipedBones do
(
if (findString BoneNode.name "L Clavicle" != undefined) then
L_Clavicle = BoneNode
if (findString BoneNode.name "L UpperArm" != undefined) then
L_UpperArm = BoneNode
if (findString BoneNode.name "L Forearm" != undefined) then
L_Forearm = BoneNode
if (findString BoneNode.name "L Hand" != undefined) then
L_Hand = BoneNode
if (findString BoneNode.name "L Finger0" != undefined) then
append L_Finger0Arr BoneNode
if (findString BoneNode.name "L Finger1" != undefined) then
append L_Finger1Arr BoneNode
if (findString BoneNode.name "L Finger2" != undefined) then
append L_Finger2Arr BoneNode
if (findString BoneNode.name "L Finger3" != undefined) then
append L_Finger3Arr BoneNode
if (findString BoneNode.name "L Finger4" != undefined) then
append L_Finger4Arr BoneNode
if (findString BoneNode.name "R Clavicle" != undefined) then
R_Clavicle = BoneNode
if (findString BoneNode.name "R UpperArm" != undefined) then
R_UpperArm = BoneNode
if (findString BoneNode.name "R Forearm" != undefined) then
R_Forearm = BoneNode
if (findString BoneNode.name "R Hand" != undefined) then
R_Hand = BoneNode
if (findString BoneNode.name "R Finger0" != undefined) then
append R_Finger0Arr BoneNode
if (findString BoneNode.name "R Finger1" != undefined) then
append R_Finger1Arr BoneNode
if (findString BoneNode.name "R Finger2" != undefined) then
append R_Finger2Arr BoneNode
if (findString BoneNode.name "R Finger3" != undefined) then
append R_Finger3Arr BoneNode
if (findString BoneNode.name "R Finger4" != undefined) then
append R_Finger4Arr BoneNode
)
if L_Clavicle != undefined then
biped.settransform L_Clavicle #rotation ((eulerAngles 0 0 0) as quat) false
if L_UpperArm != undefined then
biped.settransform L_UpperArm #rotation ((eulerAngles 0 0 0) as quat) false
if L_Forearm != undefined then
biped.settransform L_Forearm #rotation ((eulerAngles 0 0 0) as quat) false
if L_Hand != undefined then
biped.settransform L_Hand #rotation ((eulerAngles -90 0 0) as quat) false
for _bone in L_Finger0Arr do
biped.settransform _bone #rotation ((eulerAngles -90 0 0) as quat) false
for _bone in L_Finger1Arr do
biped.settransform _bone #rotation ((eulerAngles -90 0 0) as quat) false
for _bone in L_Finger2Arr do
biped.settransform _bone #rotation ((eulerAngles -90 0 0) as quat) false
for _bone in L_Finger3Arr do
biped.settransform _bone #rotation ((eulerAngles -90 0 0) as quat) false
for _bone in L_Finger4Arr do
biped.settransform _bone #rotation ((eulerAngles -90 0 0) as quat) false
if R_Clavicle != undefined then
biped.settransform R_Clavicle #rotation ((eulerAngles 0 180 0) as quat) false
if R_UpperArm != undefined then
biped.settransform R_UpperArm #rotation ((eulerAngles 0 180 0) as quat) false
if R_Forearm != undefined then
biped.settransform R_Forearm #rotation ((eulerAngles 0 180 0) as quat) false
if R_Hand != undefined then
biped.settransform R_Hand #rotation ((eulerAngles 90 180 0) as quat) false
for _bone in R_Finger0Arr do
biped.settransform _bone #rotation ((eulerAngles 90 180 0) as quat) false
for _bone in R_Finger1Arr do
biped.settransform _bone #rotation ((eulerAngles 90 180 0) as quat) false
for _bone in R_Finger2Arr do
biped.settransform _bone #rotation ((eulerAngles 90 180 0) as quat) false
for _bone in R_Finger3Arr do
biped.settransform _bone #rotation ((eulerAngles 90 180 0) as quat) false
for _bone in R_Finger4Arr do
biped.settransform _bone #rotation ((eulerAngles 90 180 0) as quat) false
clearSelection()
if chkBipedOnly.checked then
(
local allBiped = GetAllBipedObjects()
selectmore allBiped
)
else
(
SelectSkeletonAll()
)
filename = substring filename 1 (filename.count-4)
filename = filename + textFBXSuffix.text + ".fbx"
local dir = getFilenamePath filename
if not isDirectoryWriteable dir then makeDir dir all:true
exportFile filename #noPrompt selectedOnly:true using:FBXEXP
max fetch
setquietmode false
messagebox("成功导出Tpose FBX骨架! ")
return true
)
on btnatchExecute pressed do
(
try
(
--maxfilepath --当前打开的文件的文件路径
--maxfilename --当前打开的文件名
RigFilePath = maxfilepath + maxfilename --获取当前打开文件的绝对路径
local fbxfilearray = getFilesRecursive MocapFbxPath.text "*.fbx" --获取文件夹内所有fbx
local filecount = fbxfilearray.count --统计fbx数量
pluginManager.loadClass FbxImporter
for i = 1 to filecount do
(
local exportFilePath = substituteString fbxfilearray[i] ".fbx" ".max"
FBXImporterSetParam "Mode" #merge
FBXImporterSetParam "Animation" true
FBXImporterSetParam "FillTimeline" true
FBXImporterSetParam "BakeAnimationLayers" true
FBXImporterSetParam "PointCache" true
loadMaxFile RigFilePath useFileUnits:true quiet:true #noPrompt --打开rig文件
frameRate = 30
importFile fbxfilearray[i] #noPrompt
frameRate = 60
saveMaxFile exportFilePath
resetMaxFile #noprompt --重置maxfile
)
messagebox("全部转换完成! ")
)
catch();
)
--获取motion data 目录
on btnSelectMocapFbxPath pressed do
(
global tp_MaxfileArray=#()
tp_Batch = getSavePath caption:"请选择动捕数据源文件目录"
if tp_Batch == undefined then
(
return false
)
MocapFbxPath.text = tp_Batch
tp_MaxfileArray = getfiles (tp_Batch+"\*.fbx" as string)
tp_Direcories = getDirectories (tp_Batch+"\*" as string)
for i in tp_Direcories do
(
tp_MaxfileArrayFoo = getfiles (i+"*.fbx" as string)
for a in tp_MaxfileArrayFoo do append tp_MaxfileArray a
)
)
)
rollout Common_MocapBipedTool "动捕相关工具"
(
button btnOpenDialogPanel1 "动捕相关工具" toolTip:"打开动捕相关工具面板" align:#center width:100
on btnOpenDialogPanel1 pressed do
(
if MocapBipedToolsRollout != undefined then
(
DestroyDialog MocapBipedToolsRollout
)
createDialog MocapBipedToolsRollout modal:false
)
)
rollout Common_BatchImportExportAnim "动画批量导入导出"
(
label lblSrcText "源文件夹路径 (如D:\\AnimOld)"
editText textSrcPath "" align:#left width:140 tooltip:"填写源文件夹路径名,例如D:\\AnimOld"
label lblDstText "输出文件夹路径 (如D:\\AnimNew)"
editText textDstPath "" align:#left width:140 tooltip:"填写导出文件夹路径名,例如D:\\AnimNew"
label lblRefText1 "输出文件夹下 蒙皮max文件名"
label lblRefText2 "(如NewSkin.max)"
editText textRefPath "" align:#left width:140 tooltip:"填写导出文件夹下的max文件名,例如NewSkin.max"
checkbox chkOutputBone "导出Bone" align:#left checked:true across:2
checkbox chkMultiBiped "多套CS" align:#right checked:false enabled:false tooltip:"多套CS骨骼,按照Root点匹配名字,分别导出.bip文件并导入"
button btnGenerate "批量执行"
button btnBatchLoadCustomBoneData "批量自定义数据"
button btnSingleLoadCustomBoneData "单个自定义数据"
local srcPath = ""
local dstPath = ""
local refPath = ""
local refMaxFilePath = ""
local exportBone = true
local multiBiped = false
on textSrcPath entered text do
(
srcPath = textSrcPath.text
)
on textDstPath entered text do
(
dstPath = textDstPath.text
)
on textRefPath entered text do
(
refPath = textRefPath.text
)
on chkOutputBone changed theState do
(
exportBone = theState
)
on chkMultiBiped changed theState do
(
multiBiped = theState
)
fn getAllBipedObjects =
(
local bipedObjects = #()
for geo in geometry where (isKindOf geo Biped_Object) do
(
append bipedObjects geo
)
return bipedObjects
)
fn getAllBoneGeometry =
(
local boneObjects = #()
for geo in geometry where (isKindOf geo BoneGeometry) do
(
append boneObjects geo
)
return boneObjects
)
fn getAllHelpers =
(
local helperArray = #()
for _node in helpers where (classOf _node != Particle_View) do
(
append helperArray _node
)
return helperArray
)
fn getAllShapes =
(
return shapes
)
fn exportAnimTxtFile fileName =
(
local rangeOutFile = createfile (fileName + "_range.txt")
local bipedOutFile = createfile (fileName + "_biped.txt")
local boneOutFile = createfile (fileName + "_bone.txt")
local boneLinkedOutFile = createfile (fileName + "_bone_linked.txt")
local bipedObjs = getAllBipedObjects()
local boneObjs = #()
local boneObjects = getAllBoneGeometry()
local helperObjects = getAllHelpers()
local shapeObjects = getAllShapes()
join boneObjs boneObjects
join boneObjs helperObjects
join boneObjs shapeObjects
local animLayerBones = #()
format "%\n" animationRange.start to:rangeOutFile
format "%\n" animationRange.end to:rangeOutFile
close rangeOutFile
-- bipedKeyPerFrame
local bipedKeyPerFrameObjects = #()
-- filter biped per frame objects (by checking the node property "ik space" is set to "object")
for obj in bipedObjs do
(
for i = 1 to obj.controller.keys.count do
(
if (biped.getKey obj.controller i).type == #body and (biped.getKey obj.controller i).ikSpace == 1 then
(
append bipedKeyPerFrameObjects obj
exit
)
)
)
for i = animationRange.start to animationRange.end do
(
format "#%\n" i to:bipedOutFile
at time i
(
for obj in bipedKeyPerFrameObjects do
(
local _nodeName = obj.name
local _position = Biped.getTransform obj #pos
local _rotation = Biped.getTransform obj #rotation
local _scale = Biped.getTransform obj #scale
local str = "@" + _nodeName + "@" + (_position as string) + "@" + (_rotation as string) + "@" + (_scale as string) + "\n"
format "%" str to:bipedOutFile
)
)
)
close bipedOutFile
if exportBone then
(
/*
-- Gather all nodes that have anim layers
for obj in boneObjs do
(
if (classOf (obj.controller) == prs) then
(
if classOf(obj.position.controller) == Position_Layer or classOf(obj.rotation.controller) == Rotation_Layer or classOf(obj.scale.controller) == Scale_Layer then
(
append animLayerBones obj
)
)
)
-- Collapse all bone nodes that have anim layers
local animLayerIndexArray = AnimLayerManager.getNodesLayers animLayerBones
sort animLayerIndexArray
if animLayerIndexArray.count > 0 then
(
for i = animLayerIndexArray.count to 1 by -1 do
(
local _layerIndex = animLayerIndexArray[i]
if not (_layerIndex == 1 or AnimLayerManager.getLayerName _layerIndex == "Base Layer" or AnimLayerManager.getLayerName _layerIndex == "基础层") then
(
AnimLayerManager.collapseLayerNodes _layerIndex animLayerBones
)
)
)
-- Disable the base anim layer
for _curAnimLayerBone in animLayerBones do
(
AnimLayerManager.disableLayerNodes _curAnimLayerBone
)
*/
-- All Bone Data
for obj in boneObjs do
(
-- Max.chm Link_Constraint - superclass: Matrix3Controller
if (classOf (obj.controller) == Link_Constraint) then
(
local str = "#" + obj.name + "\n"
format "%" str to:boneLinkedOutFile
local numLinkTargets = obj.controller.getNumTargets()
for i = 1 to numLinkTargets do
(
local _linkto = obj.controller.getNode i
local _linkname = "#LinkToWorld#"
if _linkto != undefined then
(
_linkname = _linkto.name
)
local _keymode = obj.controller.key_mode
local _linkframe = obj.controller.getFrameNo i
local _position = (obj.controller.Link_Params.position)
local _rotation = (obj.controller.Link_Params.rotation)
local _scale = (obj.controller.Link_Params.scale)
local str = "@" + "Link_Constraint" + "@" + (_keymode as string) + "@" + (_linkname as string) + "@" + (_linkframe as string) + "@" + (_position as string) + "@" + (_rotation as string) + "@" + (_scale as string) + "\n"
format "%" str to:boneLinkedOutFile
)
local scaleKeys = obj.transform.controller.link_params.position.controller.keys
local rotKeys = obj.transform.controller.link_params.position.controller.keys
local posKeys = obj.transform.controller.link_params.position.controller.keys
-- Link_Constraint_Scale
if scaleKeys.count > 0 then
(
for k in scaleKeys do
(
at time k.time
(
local str = "@" + "Link_Constraint_Scale" + "@" + (k.time as string) + "@" + (obj.transform.controller.link_params.scale as string) + "\n"
format "%" str to:boneLinkedOutFile
)
)
)
else
(
at time animationRange.start
(
local str = "@" + "Link_Constraint_Scale" + "@" + (animationRange.start as string) + "@" + (obj.transform.controller.link_params.scale as string) + "\n"
format "%" str to:boneLinkedOutFile
)
)
-- Link_Constraint_Rotation
if rotKeys.count > 0 then
(
for k in rotKeys do
(
at time k.time
(
local str = "@" + "Link_Constraint_Rotation" + "@" + (k.time as string) + "@" + (obj.transform.controller.link_params.rotation as string) + "\n"
format "%" str to:boneLinkedOutFile
)
)
)
else
(
at time animationRange.start
(
local str = "@" + "Link_Constraint_Rotation" + "@" + (animationRange.start as string) + "@" + (obj.transform.controller.link_params.rotation as string) + "\n"
format "%" str to:boneLinkedOutFile
)
)
-- Link_Constraint_Translation
if posKeys.count > 0 then
(
for k in posKeys do
(
at time k.time
(
local str = "@" + "Link_Constraint_Translation" + "@" + (k.time as string) + "@" + (obj.transform.controller.link_params.position as string) + "\n"
format "%" str to:boneLinkedOutFile
)
)
)
else
(
at time animationRange.start
(
local str = "@" + "Link_Constraint_Translation" + "@" + (animationRange.start as string) + "@" + (obj.transform.controller.link_params.position as string) + "\n"
format "%" str to:boneLinkedOutFile
)
)
)
else if (classOf (obj.controller) == prs) then
(
local str = "#" + obj.name + "\n"
-- 在上面塌陷+屏蔽动画层之后不应该再有AnimLayer
local haveAnimLayer = false
if classOf(obj.position.controller) == Position_Layer or classOf(obj.rotation.controller) == Rotation_Layer or classOf(obj.scale.controller) == Scale_Layer then
(
haveAnimLayer = true
print("### Node Have AnimLayer:" + obj.name)
)
if haveAnimLayer then
(
for _frametime = animationRange.start to animationRange.end do
(
at time _frametime
(
local selfMat = obj.transform
local _position = selfMat.translationpart
local _rotation = selfMat.rotationpart
local _scale = selfMat.scalepart
str = str + "@" + "prs" + "@" + (_frametime as string) + "@" + (_position as string) + "@" + (_rotation as string) + "@" + (_scale as string) + "\n"
)
)
)
else
(
local keyPosition = obj.position.controller.keys
local keyRotation = obj.rotation.controller.keys
local keyScale = obj.scale.controller.keys
local keys = #()
for k in keyPosition do
(
appendIfUnique keys k.time
)
for k in keyRotation do
(
appendIfUnique keys k.time
)
for k in keyScale do
(
appendIfUnique keys k.time
)
if keys.count > 0 then
(
for key in keys do
(
local _frametime = key
at time _frametime
(
local selfMat = obj.transform
local _position = selfMat.translationpart
local _rotation = selfMat.rotationpart
local _scale = selfMat.scalepart
str = str + "@" + "prs" + "@" + (_frametime as string) + "@" + (_position as string) + "@" + (_rotation as string) + "@" + (_scale as string) + "\n"
)
)
)
else
(
local _frametime = animationRange.start
at time _frametime
(
local selfMat = obj.transform
local _position = selfMat.translationpart
local _rotation = selfMat.rotationpart
local _scale = selfMat.scalepart
str = str + "@" + "prs" + "@" + (_frametime as string) + "@" + (_position as string) + "@" + (_rotation as string) + "@" + (_scale as string) + "\n"
)
)
)
format "%" str to:boneOutFile
)
)
)
)
fn importAnimTxtFile fileName =
(
local rangeOutFileName = (fileName + "_range.txt")
local bipedPerFrameOutFileName = (fileName + "_biped.txt")
local boneOutFileName = (fileName + "_bone.txt")
local boneLinkedOutFileName = (fileName + "_bone_linked.txt")
local rangeOutTextArray = #()
local bipedOutFileArray = #()
local boneOutFileArray = #()
local boneLinkedOutFileArray = #()
local rangeOutFile = (openFile rangeOutFileName mode:"r")
if rangeOutFile != undefined then
(
while not eof rangeOutFile do
(
append rangeOutTextArray (readline rangeOutFile)
)
close rangeOutFile
animationRange = interval (execute rangeOutTextArray[1]) (execute rangeOutTextArray[2])
slidertime = animationRange.start
)
local bipedOutFile = (openFile bipedPerFrameOutFileName mode:"r")
if bipedOutFile != undefined then
(
while not eof bipedOutFile do
(
append bipedOutFileArray (readline bipedOutFile)
)
close bipedOutFile
)
local boneOutFile = (openFile boneOutFileName mode:"r")
if boneOutFile != undefined then
(
while not eof boneOutFile do
(
append boneOutFileArray (readline boneOutFile)
)
close boneOutFile
)
local boneLinkedOutFile = (openFile boneLinkedOutFileName mode:"r")
if boneLinkedOutFile != undefined then
(
while not eof boneLinkedOutFile do
(
append boneLinkedOutFileArray (readline boneLinkedOutFile)
)
close boneLinkedOutFile
)
with animate on
(
local curNode = undefined
local curNodeKeyTimes = #()
local curFrameTime = undefined
for txt in bipedOutFileArray do
(
if txt[1] == "#" then
(
local _frametime = execute (substring txt 2 txt.count)
curFrameTime = _frametime
)
else if txt[1] == "@" then
(
local transformDataInfo = filterString txt "@"
if transformDataInfo.count == 4 then
(
local _nodeName = transformDataInfo[1]
local _position = execute transformDataInfo[2]
local _rotation = execute transformDataInfo[3]
local _scale = execute transformDataInfo[4]
curNode = getNodeByName _nodeName
if curNode != undefined then
(
at time curFrameTime
(
Biped.setTransform curNode #pos _position true
Biped.setTransform curNode #rotation _rotation true
Biped.setTransform curNode #scale _scale true
)
)
)
)
)
if exportBone then
(
for txt in boneLinkedOutFileArray do
(
-- 新的Node
if txt[1] == "#" then
(
local nodeName = substring txt 2 txt.count
curNode = getNodeByName nodeName
if (isKindOf curNode Biped_Object) then
(
curNode = undefined
)
)
-- 更新Node每个关键帧时间
else if txt[1] == "@" then
(
local Info = filterString txt "@"
if (Info[1] == "Link_Constraint") then
(
local _keyMode = execute Info[2]
local _linktoName = Info[3]
local _linkframe = execute Info[4]
local _position = execute Info[5]
local _rotation = execute Info[6]
local _scale = execute Info[7]
print("### Link_Constraint" + curNode.name + " keymode" + (_keyMode as string))
if not (classOf (curNode.controller) == Link_Constraint) then
(
curNode.Controller = Link_Constraint()
)
curNode.controller.key_mode = _keyMode
if _linktoName == "#LinkToWorld#" then
(
curNode.controller.addWorld frameNo:_linkframe
)
else
(
local _linktoObj = getNodeByName _linktoName
if _linktoObj != undefined then
(
curNode.controller.addTarget _linktoObj _linkframe
)
)
-- print(_linktoName)
-- print(_linkframe)
-- print(_position)
-- print(_rotation)
-- print(_scale)
at time _linkframe
(
curNode.controller.Link_Params.Scale = _scale
curNode.controller.Link_Params.Rotation = _rotation
curNode.controller.Link_Params.Position = _position
)
)
else
(
if Info[1] == "Link_Constraint_Scale" then
(
local _frametime = execute Info[2]
local _scale = execute Info[3]
at time _frametime
(
curNode.transform.controller.link_params.scale = _scale
addNewKey curNode.transform.controller.link_params.scale.controller _frametime
)
)
else if Info[1] == "Link_Constraint_Rotation" then
(
local _frametime = execute Info[2]
local _rotation = execute Info[3]
at time _frametime
(
curNode.transform.controller.link_params.rotation = (inverse _rotation)
addNewKey curNode.transform.controller.link_params.rotation.controller _frametime
)
)
else if Info[1] == "Link_Constraint_Translation" then
(
local _frametime = execute Info[2]
local _position = execute Info[3]
at time _frametime
(
curNode.transform.controller.link_params.position = _position
addNewKey curNode.transform.controller.link_params.position.controller _frametime
)
)
)
)
)
/*
for txt in boneOutFileArray do
(
-- 新的Node
if txt[1] == "#" then
(
local nodeName = substring txt 2 txt.count
curNode = getNodeByName nodeName
if (isKindOf curNode Biped_Object) then
(
curNode = undefined
)
)
-- 更新Node每个关键帧时间
else if txt[1] == "@" then
(
if curNode != undefined then
(
local Info = filterString txt "@"
if Info[1] == "PRS_Scale" then
(
local _frametime = execute Info[2]
local _scale = execute Info[3]
at time _frametime
(
-- (in coordsys world curNode.scale = _scale)
curNode.scale = _scale
addNewKey curNode.scale.controller _frametime
)
)
else if Info[1] == "PRS_Rotation" then
(
local _frametime = execute Info[2]
local _rotation = execute Info[3]
at time _frametime
(
-- (in coordsys world curNode.rotation = inverse _rotation)
curNode.rotation = inverse _rotation
addNewKey curNode.rotation.controller _frametime
)
)
else if Info[1] == "PRS_Translation" then
(
local _frametime = execute Info[2]
local _position = execute Info[3]
at time _frametime
(
-- (in coordsys world curNode.position = _position)
curNode.position = _position
addNewKey curNode.position.controller _frametime
)
)
)
)
)
*/
for txt in boneOutFileArray do
(
-- 新的Node
if txt[1] == "#" then
(
local nodeName = substring txt 2 txt.count
curNode = getNodeByName nodeName
if (isKindOf curNode Biped_Object) then
(
curNode = undefined
)
)
-- 更新Node每个关键帧时间
else if txt[1] == "@" then
(
if curNode != undefined then
(
local Info = filterString txt "@"
if (Info[1] == "prs" and Info.count == 5) then
(
if not (classOf (curNode.controller) == prs) then
(
curNode.Controller = prs()
)
local _frametime = execute Info[2]
local _position = execute Info[3]
local _rotation = execute Info[4]
local _scale = execute Info[5]
at time _frametime
(
(in coordsys world curNode.scale = _scale)
(in coordsys world curNode.rotation = inverse _rotation)
(in coordsys world curNode.position = _position)
)
)
)
)
)
)
)
)
fn exportBip =
(
/*
local dir_array = GetDirectories (srcPath+"*")
for d in dir_array do
exportBip d
*/
local ExportFailedMaxFileNames = ""
for f in getfiles (srcPath + "\\*.max") do
(
print f
loadMaxFile f usefileunits:true
local fileName = getFilenameFile maxFileName
-- 隐藏所有非bone的Geometry
hideByCategory.none()
hideByCategory.geometry = true
max unhide all #noPrompt
for i = 1 to GetNumberDisplayFilters() do
SetDisplayFilter i false
max select all
local allBipObjects = getAllBipedObjects()
local bipRoots = #()
-- [Vertical_Horizontal_Turn] : Matrix3Controller
-- This class represents the transform controller for the root object within the biped system.
for obj in allBipObjects do
(
if classof(obj.controller) == Vertical_Horizontal_Turn then
append bipRoots obj
)
if multiBiped == false and bipRoots.count > 1 then
(
messagebox ("导出失败!有多套CS骨骼,且未勾选【多套CS】选项")
print ("导出失败!有多套CS骨骼,且未勾选【多套CS】选项 " + maxFileName)
continue
)
if bipRoots.count > 0 then
(
if multiBiped == false then
(
local bipFilePath = dstPath + "\\AnimFiles\\" + fileName + ".bip"
local controller = bipRoots[1].controller
biped.saveBipFileSegment controller bipFilePath animationRange.start animationRange.end
)
else
(
for obj in bipRoots do
(
local bipFilePath = dstPath + "\\AnimFiles\\" + fileName + obj.name + ".bip"
local controller = obj.controller
biped.saveBipFileSegment controller bipFilePath animationRange.start animationRange.end
)
)
)
if exportBone and bipRoots.count > 0 then
(
local xafFilePath = dstPath + "\\AnimFiles\\" + fileName + ".xaf"
clearSelection()
local boneObjects = getAllBoneGeometry()
local helperObjects = getAllHelpers()
local shapeObjects = getAllShapes()
selectmore boneObjects
selectmore helperObjects
selectmore shapeObjects
local success = LoadSaveAnimation.saveAnimation xafFilePath $ #() #()
if success == false then
(
print("Save Animation Failed For File " + maxFileName)
ExportFailedMaxFileNames = ExportFailedMaxFileNames + (maxFileName + "\n")
)
)
-- Export Custom Data
local txtFilePath = dstPath + "\\AnimFiles\\" + fileName
exportAnimTxtFile txtFilePath
-- copy maxfile to dstPath
refMaxFilePath = dstPath + "\\" + refPath
generatedMaxFilePath = dstPath + "\\" + fileName + ".max"
copyFile refMaxFilePath generatedMaxFilePath
)
if ExportFailedMaxFileNames == "" then
(
messageBox("动画导出成功")
)
else
(
messageBox("以下Bone动画导出失败: \n" + ExportFailedMaxFileNames)
)
)
fn importBip =
(
for f in getfiles (dstPath + "\\*.max") where f != refMaxFilePath do
(
print("******************** Import Anim " + f)
loadMaxFile f usefileunits:true
local fileName = getFilenameFile maxFileName
--删除所有关键帧 TODO
max select all
macros.run "Animation Tools" "DeleteSelectedAnimation"
clearSelection()
--隐藏所有非bone的Geometry
hideByCategory.none()
hideByCategory.geometry = true
setquietmode true
max unhide all #noPrompt
for i = 1 to GetNumberDisplayFilters() do
SetDisplayFilter i false
local allBipObjects = getAllBipedObjects()
local bipRoots = #()
if multiBiped == false and bipRoots.count > 1 then
(
messagebox ("导出失败!有多套CS骨骼,请勾选【多套CS】选项")
return false
)
-- [Vertical_Horizontal_Turn] : Matrix3Controller
-- This class represents the transform controller for the root object within the biped system.
local bipPosList_WorldSpace = #()
local bipRotList_WorldSpace = #()
for o in allBipObjects do
(
if classof(o.controller) == Vertical_Horizontal_Turn then
append bipRoots o
)
if bipRoots.count > 0 then
(
if multiBiped == false then
(
local obj = bipRoots[1]
local bipFilePath = dstPath + "\\AnimFiles\\" + fileName + ".bip"
local controller = obj.controller
biped.loadBipFile controller bipFilePath
)
else
(
for obj in bipRoots do
(
local bipFilePath = dstPath + "\\AnimFiles\\" + fileName + obj.name + ".bip"
local controller = obj.controller
biped.loadBipFile controller bipFilePath
)
)
)
if exportBone and bipRoots.count > 0 then
(
local xafFilePath = dstPath + "\\AnimFiles\\" + fileName + ".xaf"
-- 防止有些bone选不中
local boneObjects = getAllBoneGeometry()
local helperObjects = getAllHelpers()
local shapeObjects = getAllShapes()
clearSelection()
selectmore boneObjects
selectmore helperObjects
selectmore shapeObjects
local success = LoadSaveAnimation.loadAnimation xafFilePath $ relative:false insert:false
if success == false then
(
print("Load Animation Failed For File " + maxFileName)
)
)
saveMaxFile f
)
)
fn importCustomData =
(
for f in getfiles (dstPath + "\\*.max") where f != refMaxFilePath do
(
print("******************** Import Custom Anim " + f)
loadMaxFile f usefileunits:true
local fileName = getFilenameFile maxFileName
local txtFilePath = dstPath + "\\AnimFiles\\" + fileName
importAnimTxtFile txtFilePath
saveMaxFile f
)
)
on btnGenerate pressed do
(
if srcPath == "" then
messagebox("原始路径未设置")
else if dstPath == "" then
messagebox("目标路径未设置")
else if refPath == "" then
messagebox("参考文件未设置")
else if not isDirectoryWriteable dstPath then
messagebox("导出路径不存在")
else (
local refFile = dstPath + "\\" + refPath
if (not (doesFileExist refFile)) then
(
messagebox("参考文件不存在")
return 0
)
setquietmode true
-- disableRefMsgs()
tmpPath = dstPath + "\\AnimFiles"
makeDir tmpPath
exportBip()
importBip()
importCustomData()
setquietmode false
-- enableRefMsgs()
)
)
on btnBatchLoadCustomBoneData pressed do
(
importCustomData()
)
on btnSingleLoadCustomBoneData pressed do
(
local fileName = getFilenameFile maxFileName
local txtFilePath = dstPath + "\\AnimFiles\\" + fileName
importAnimTxtFile txtFilePath
)
)
rollout Common_DebugTool "Debug工具"
(
button btnSelectMoreBiped "加选CS骨骼"
button btnSelectMoreBone "加选Bone骨骼"
button btnSelectMoreMesh "加选模型"
button btnPrintAllSelectedTransform "print选中骨骼Transform"
button btnPrintAllBoneTransform "print所有骨骼Transform"
button btnPrintSelectedTransformKeys "print选中骨骼Transform的Keys"
button btnTest1 "Debug 1"
button btnTest2 "Debug 2"
button btnTest3 "Debug 3"
button btnTest4 "Debug 4"
button btnTest5 "Debug 5"
on btnSelectMoreBiped pressed do
(
local a = A2UFn_GetAllBipedObject()
selectmore a
)
on btnSelectMoreBone pressed do
(
local a = A2UFn_GetAllBoneObject()
local b = A2UFn_GetAllShape()
local c = A2UFn_GetAllHelper()
selectmore a
selectmore b
selectmore c
)
on btnSelectMoreMesh pressed do
(
local a = A2UFn_GetAllMesh()
selectmore a
)
on btnPrintAllSelectedTransform pressed do
(
local selectedNodes = getCurrentSelection()
local _start = animationrange.start
local _end = animationrange.end
for t = _start to _end do
(
A2UFn_PrintNodesTransformAtFrame selectedNodes t
)
)
on btnPrintAllBoneTransform pressed do
(
local _start = animationrange.start
local _end = animationrange.end
)
on btnPrintSelectedTransformKeys pressed do
(
local selectedNodes = getCurrentSelection()
local obj = selectedNodes[1]
if obj == undefined then
(
messageBox("当前没有选中任何Node")
return false
)
else if selectedNodes.count > 1 then
(
messageBox("请不要选择超过1个Node")
return false
)
local _start = animationrange.start
local _end = animationrange.end
local keys = #()
local str = ""
for k in obj.position.controller.keys do
(
appendIfUnique keys k.time
)
for k in obj.rotation.controller.keys do
(
appendIfUnique keys k.time
)
for k in obj.scale.controller.keys do
(
appendIfUnique keys k.time
)
print "***************** Position Keys *****************"
print obj.position.controller.keys
print "***************** Rotation Keys *****************"
print obj.rotation.controller.keys
print "***************** Scale Keys *****************"
print obj.scale.controller.keys
print "***************** All Transform Keys *****************"
sort keys
if keys.count > 0 then
(
for key in keys do
(
local _frametime = key
at time _frametime
(
local selfMat = obj.transform
local _position = selfMat.translationpart
local _rotation = selfMat.rotationpart
local _scale = selfMat.scalepart
str = str + "Frame:" + (_frametime as string) + " Pos:" + (_position as string) + " Rotation:" + (_rotation as string) + " Scale:" + (_scale as string) + "\n"
)
)
)
else
(
local _frametime = animationRange.start
at time _frametime
(
local selfMat = obj.transform
local _position = selfMat.translationpart
local _rotation = selfMat.rotationpart
local _scale = selfMat.scalepart
str = str + "Frame:" + (_frametime as string) + " Pos:" + (_position as string) + " Rotation:" + (_rotation as string) + " Scale:" + (_scale as string) + "\n"
)
)
print str
)
on btnTest1 pressed do
(
A2UFn_SelectAllSkeleton($)
)
on btnTest2 pressed do
(
)
on btnTest3 pressed do
(
)
on btnTest4 pressed do
(
)
on btnTest5 pressed do
(
)
)
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/AlexMercerX/maxscript.git
git@gitee.com:AlexMercerX/maxscript.git
AlexMercerX
maxscript
maxscript
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891