部件挂点插槽工具
# NDTools_RootTransformZero.ms 归原点功能说明文档
# 文件概述
scripts\NDTools\NDTools_RootTransformZero.ms是一个3ds Max脚本文件,主要提供了骨骼和对象归原点相关的功能。
该文件定义了一个名为TransformZeroStruct的结构体,包含多个用于处理3ds Max场景骨骼 归原点和还原位置的函数。这些功能对于游戏角色的装备部件导出前预处理非常有用。
# 结构体定义
struct TransformZeroStruct
(
-- 结构体成员函数...
)
-- 创建全局实例
global TransformZeroinit
TransformZeroinit = TransformZeroStruct()
2
3
4
5
6
7
8
# 数据存储说明
该脚本使用3ds Max的appData系统存储临时数据,主要使用以下索引:
| 索引 | 用途 | 数据类型 |
|---|---|---|
| 101 | 存储父对象名称和原始变换 | 字符串 ("父对象名称 |
| 102 | 存储父对象的ID代码 | GUID字符串 |
| 103 | 标记对象是否与父对象对齐 | 字符串 ("0"或"1") |
| 104 | 存储子对象的配对ID代码 | GUID字符串 |
| 105 | 存储对象与父对象的偏移信息 | 字符串 ("父对象名称 |
# 全局实例
脚本在最后创建了一个全局实例TransformZeroinit,其他脚本可以通过这个实例调用TransformZeroStruct结构体中的所有函数:
global TransformZeroinit
TransformZeroinit = TransformZeroStruct()
2
# 使用示例
# 标记根骨骼
-- 选择一个或多个对象,然后执行以下代码
TransformZeroinit.fn_set_scoket()
2
# 执行变换归零
-- 选择一个已标记的对象,然后执行以下代码
TransformZeroinit.__TransformZero__ $ true
2
# 恢复原始变换
-- 选择一个已归零的对象,然后执行以下代码
TransformZeroinit.__resetTramform__ $
2
# 清除变换信息
-- 选择一个或多个对象,然后执行以下代码
TransformZeroinit.clearInfo()
2
# 注意事项
- 该脚本主要用于3ds Max中的骨骼和对象变换处理,特别适用于游戏资源制作流程。
- 对于名称以"v_"开头的对象(通常是挂点),
__resetTramform__函数不会执行恢复操作。 - 脚本使用GUID作为对象间的唯一标识符,确保在复杂场景中能够正确识别配对对象。
- 在批量处理大量对象时,建议先在小范围内测试功能,确保符合预期效果。
# 函数详细说明
# 1. find_parent_for_id
点击查看代码
fn find_parent_for_id child_obj id_code =
(
local find_parent = undefined
for i in objects do
(
local temp_id = getAppData i 102
if temp_id != undefined do (
if temp_id == id_code and i != child_obj do
(
find_parent = i ;exit
)
)
)
find_parent
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
功能:根据ID代码查找指定子对象的父对象。
参数:
child_obj:子对象,需要查找其父对象的对象id_code:父对象的ID代码,通常是通过getAppData存储的值
返回值:
- 找到的父对象,如果未找到则返回
undefined
使用场景:在对象变换归零后需要恢复父子关系时使用,通过预存的ID代码重新建立对象间的连接。
# 2. align_anim
点击查看代码
fn align_anim for_obj to_obj =
(
offset_ParentName = filterString (getAppData to_obj 105) "|")
local Offset_str = execute offset_ParentName[2]
animate false (to_obj.transform = Offset_str * for_obj.transform)
)
2
3
4
5
6
功能:根据预存的偏移量,将一个对象的变换与另一个对象对齐。
参数:
for_obj:源对象,作为对齐的参考to_obj:目标对象,需要被对齐的对象
返回值:无
使用场景:在重置变换时,将子对象重新对齐到父对象,同时保持之前存储的偏移关系。
# 3. align_anim_offset
点击查看代码
fn align_anim_offset for_obj to_obj =
(
local OffsetTm = to_obj.transform * inverse for_Obj.transform
return OffsetTm
)
2
3
4
5
功能:计算两个对象之间的变换偏移量。
参数:
for_obj:源对象to_obj:目标对象
返回值:
- 变换矩阵,代表从源对象到目标对象的偏移
使用场景:在执行变换归零前,预先计算并保存对象与其父对象之间的偏移关系,以便后续恢复。
# 4. TransformZero
点击查看代码
fn __TransformZero__ o oring_true=
(
local pin_id = genguid()
if o.parent != undefined then
(
oParent = o.parent.name
local old_id = getAppData o.parent 102
--检查父级是否有分配ID
if old_id == undefined then (
--如果没有,生成新的
setAppData o.parent 102 pin_id
)
else(
--如果有,将继续使用该ID
pin_id = old_id
)
if o.transform.pos == o.parent.transform.pos and o.transform.rotation == o.parent.transform.rotation then
(
setAppData o 103 "1" --如果是和挂点对齐的,设为 1
)else(
setAppData o 103 "0" --如果和挂点有偏移,设为 0
local temp_offset = this.align_anim_offset o.parent o
setAppData o 105 (oParent+"|"+(temp_offset as string))
--保存和父级的偏移量
)
)else (oParent = "undefined")
setAppData o 104 pin_id --在子骨骼上保存配对ID
setAppData o 101 (oParent+"|"+(o.transform as string))
if oring_true do (
if classof o == Biped_Object then
(
animate false
(
o.transform = (matrix3 [1,0,0] [0,1,0] [0,0,1] [0,0,0])
rotate o (angleaxis -90 [0,0,1])
)
)
else(
animate false (o.transform = (matrix3 [1,0,0] [0,1,0] [0,0,1] [0,0,0]))
)
o.parent = undefined
)
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
功能:将对象的变换归零,同时保存其原始变换和父子关系信息以便后续恢复。
参数:
o:要处理的对象oring_true:布尔值,决定是否实际执行变换归零操作
返回值:无
使用场景:
- 在导出模型前将骨骼归零,便于游戏引擎正确处理
- 在调整对象层级关系时临时断开父子连接
- 需要重置对象变换但希望保留原始位置信息时
关键处理:
- 为对象及其父对象分配和保存配对ID
- 保存对象的原始变换矩阵和父对象信息
- 根据对象类型(普通对象或Biped骨骼)执行不同的归零操作
- 对于与父对象有偏移的情况,保存偏移信息
# 5. resetTramform
点击查看代码
fn __resetTramform__ o =
(
if matchPattern o.name pattern:"v_*" do
(
--format "根骨骼不能 是挂点的命名 -> % 这个就是这样\n" o.name
return false
)
sliderTime = animationRange.start
local child_pin_id = getAppData o 104 --获取子级配对ID
oParentName = filterString (getAppData o 101) "|"
if oParentName[1] != "undefined" do
(
oParent = getNodeByName oParentName[1]
if oParent != undefined do (
local parent_pin_id = getAppData oParent 102
if child_pin_id == parent_pin_id then (o.parent = oParent)
else(o.parent = this.find_parent_for_id o child_pin_id)
)
)
if classof o == Biped_Object then
(
if (getAppData o 103) == "1" and o.parent != undefined then (
animate false (o.transform = o.parent.transform)
)else(
if (getAppData o 105) != undefined then (
if o.parent != undefined then(this.align_anim o.parent o)
else(animate false(o.transform = execute oParentName[2]))
)else(
animate false(o.transform = execute oParentName[2])
)
)
)
else
(
if (getAppData o 103) == "1" and o.parent != undefined then (
animate false (o.transform = o.parent.transform)
)else(
if (getAppData o 105) != undefined then (
if isValidNode o.parent then (this.align_anim o.parent o)
else(animate false (o.transform = execute oParentName[2]))
)else(
animate false (o.transform = execute oParentName[2])
)
)
)
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
功能:将先前通过__TransformZero__函数处理过的对象恢复到原始变换状态和父子关系。
参数:
o:要恢复的对象
返回值:
- 如果对象名称以"v_"开头(被识别为挂点),则返回
false - 其他情况无明确返回值
使用场景:在完成导出或其他操作后,需要将对象恢复到原始位置和层级关系时使用。
关键处理:
- 检查对象是否为挂点(名称以"v_"开头),如果是则不处理
- 恢复对象与父对象的连接关系
- 根据预存的信息,恢复对象的原始变换
- 对于Biped骨骼和普通对象采用不同的恢复策略
# 6. fn_set_scoket
点击查看代码
fn fn_set_scoket =
(
for i in selection do
(
this.__TransformZero__ i false
)
)
2
3
4
5
6
7
功能:为当前选择集中的所有对象标记为根骨骼,但不执行实际的变换归零操作。
参数:无
返回值:无
使用场景:批量将选择的对象标记为根骨骼,通常在准备导出或组织骨架结构时使用。
# 7. clearInfo
点击查看代码
fn clearInfo =
(
try
(
for i in selection do
(
deleteAppData i 101
deleteAppData i 102
deleteAppData i 103
deleteAppData i 104
deleteAppData i 105
)
)
catch()
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
功能:清除当前选择集中所有对象的变换归零相关数据。
参数:无
返回值:无
使用场景:当不再需要对象上存储的变换归零信息时,清除这些数据以释放内存或避免冲突。
# 8. get_rootbone_from_object
点击查看代码
fn get_rootbone_from_object _objects =
(
index = 0
if (classof _objects) != Array do (return false)
root_bone = #()
for o in _objects do
(
pin_id = getAppData o 104
if pin_id != undefined and pin_id.count == 38 do
(
append root_bone o
index += 1
)
)
if index > 1 do
(
format "选择内有 % 挂点,请手动处理\n" index
)
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
功能:从给定的对象数组中找出已标记为根骨骼的对象。
参数:
_objects:对象数组,要从中查找根骨骼的对象集合
返回值:
- 如果输入不是数组,返回
false - 否则在控制台输出找到的根骨骼数量,并将找到的根骨骼存储在局部变量
root_bone中(但函数没有显式返回这个变量)
使用场景:在处理多个对象时,快速识别出哪些对象已经被标记为根骨骼。
