Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
车家大少爷
three.js
提交
30da0beb
T
three.js
项目概览
车家大少爷
/
three.js
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
three.js
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
30da0beb
编写于
3月 27, 2017
作者:
M
Mr.doob
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
FBXLoader2: Refactored parseAnimations.
上级
8b04814c
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
309 addition
and
307 deletion
+309
-307
examples/js/loaders/FBXLoader2.js
examples/js/loaders/FBXLoader2.js
+309
-307
未找到文件。
examples/js/loaders/FBXLoader2.js
浏览文件 @
30da0beb
...
...
@@ -1467,7 +1467,6 @@
var
rawCurves
=
FBXTree
.
Objects
.
subNodes
.
AnimationCurve
;
var
rawLayers
=
FBXTree
.
Objects
.
subNodes
.
AnimationLayer
;
var
rawStacks
=
FBXTree
.
Objects
.
subNodes
.
AnimationStack
;
var
rawModels
=
FBXTree
.
Objects
.
subNodes
.
Model
;
/**
* @type {{
...
...
@@ -2136,6 +2135,7 @@
*/
var
layer
=
[];
var
children
=
connections
.
get
(
parseInt
(
nodeID
)
).
children
;
for
(
var
childIndex
=
0
;
childIndex
<
children
.
length
;
childIndex
++
)
{
// Skip lockInfluenceWeights
...
...
@@ -2167,8 +2167,8 @@
var
layers
=
[];
var
children
=
connections
.
get
(
parseInt
(
nodeID
)
).
children
;
var
maxTimeStamp
=
0
;
var
minTimeStamp
=
Number
.
MAX_VALUE
;
var
timestamps
=
{
max
:
0
,
min
:
Number
.
MAX_VALUE
}
;
for
(
var
childIndex
=
0
;
childIndex
<
children
.
length
;
++
childIndex
)
{
var
currentLayer
=
returnObject
.
layers
[
children
[
childIndex
].
ID
];
...
...
@@ -2183,7 +2183,170 @@
if
(
layer
)
{
getCurveNodeMaxMinTimeStamps
(
layer
);
getCurveNodeMaxMinTimeStamps
(
layer
,
timestamps
);
}
}
}
}
// Do we have an animation clip with actual length?
if
(
timestamps
.
max
>
timestamps
.
min
)
{
returnObject
.
stacks
[
nodeID
]
=
{
name
:
rawStacks
[
nodeID
].
attrName
,
layers
:
layers
,
length
:
timestamps
.
max
-
timestamps
.
min
,
frames
:
(
timestamps
.
max
-
timestamps
.
min
)
*
30
};
}
}
return
returnObject
;
}
/**
* @param {Object} FBXTree
* @param {{id: number, attrName: string, properties: Object<string, any>}} animationCurveNode
* @param {Map<number, {parents: {ID: number, relationship: string}[], children: {ID: number, relationship: string}[]}>} connections
* @param {{skeleton: {bones: {FBX_ID: number}[]}}} sceneGraph
*/
function
parseAnimationNode
(
FBXTree
,
animationCurveNode
,
connections
,
sceneGraph
)
{
var
rawModels
=
FBXTree
.
Objects
.
subNodes
.
Model
;
var
returnObject
=
{
/**
* @type {number}
*/
id
:
animationCurveNode
.
id
,
/**
* @type {string}
*/
attr
:
animationCurveNode
.
attrName
,
/**
* @type {number}
*/
internalID
:
animationCurveNode
.
id
,
/**
* @type {boolean}
*/
attrX
:
false
,
/**
* @type {boolean}
*/
attrY
:
false
,
/**
* @type {boolean}
*/
attrZ
:
false
,
/**
* @type {number}
*/
containerBoneID
:
-
1
,
/**
* @type {number}
*/
containerID
:
-
1
,
curves
:
{
x
:
null
,
y
:
null
,
z
:
null
},
/**
* @type {number[]}
*/
preRotations
:
null
};
if
(
returnObject
.
attr
.
match
(
/S|R|T/
)
)
{
for
(
var
attributeKey
in
animationCurveNode
.
properties
)
{
if
(
attributeKey
.
match
(
/X/
)
)
{
returnObject
.
attrX
=
true
;
}
if
(
attributeKey
.
match
(
/Y/
)
)
{
returnObject
.
attrY
=
true
;
}
if
(
attributeKey
.
match
(
/Z/
)
)
{
returnObject
.
attrZ
=
true
;
}
}
}
else
{
return
null
;
}
var
conns
=
connections
.
get
(
returnObject
.
id
);
var
containerIndices
=
conns
.
parents
;
for
(
var
containerIndicesIndex
=
containerIndices
.
length
-
1
;
containerIndicesIndex
>=
0
;
--
containerIndicesIndex
)
{
var
boneID
=
findIndex
(
sceneGraph
.
skeleton
.
bones
,
function
(
bone
)
{
return
bone
.
FBX_ID
===
containerIndices
[
containerIndicesIndex
].
ID
;
}
);
if
(
boneID
>
-
1
)
{
returnObject
.
containerBoneID
=
boneID
;
returnObject
.
containerID
=
containerIndices
[
containerIndicesIndex
].
ID
;
var
model
=
rawModels
[
returnObject
.
containerID
.
toString
()
];
if
(
'
PreRotation
'
in
model
.
properties
)
{
returnObject
.
preRotations
=
parseVector3
(
model
.
properties
.
PreRotation
).
multiplyScalar
(
Math
.
PI
/
180
);
}
break
;
}
}
return
returnObject
;
}
/**
* @param {{id: number, subNodes: {KeyTime: {properties: {a: string}}, KeyValueFloat: {properties: {a: string}}, KeyAttrFlags: {properties: {a: string}}, KeyAttrDataFloat: {properties: {a: string}}}}} animationCurve
*/
function
parseAnimationCurve
(
animationCurve
)
{
return
{
version
:
null
,
id
:
animationCurve
.
id
,
internalID
:
animationCurve
.
id
,
times
:
parseFloatArray
(
animationCurve
.
subNodes
.
KeyTime
.
properties
.
a
).
map
(
convertFBXTimeToSeconds
),
values
:
parseFloatArray
(
animationCurve
.
subNodes
.
KeyValueFloat
.
properties
.
a
),
attrFlag
:
parseIntArray
(
animationCurve
.
subNodes
.
KeyAttrFlags
.
properties
.
a
),
attrData
:
parseFloatArray
(
animationCurve
.
subNodes
.
KeyAttrDataFloat
.
properties
.
a
)
};
}
...
...
@@ -2310,7 +2473,25 @@
},
}} layer
*/
function
getCurveNodeMaxMinTimeStamps
(
layer
)
{
function
getCurveNodeMaxMinTimeStamps
(
layer
,
timestamps
)
{
if
(
layer
.
R
)
{
getCurveMaxMinTimeStamp
(
layer
.
R
.
curves
,
timestamps
);
}
if
(
layer
.
S
)
{
getCurveMaxMinTimeStamp
(
layer
.
S
.
curves
,
timestamps
);
}
if
(
layer
.
T
)
{
getCurveMaxMinTimeStamp
(
layer
.
T
.
curves
,
timestamps
);
}
}
/**
* Sets the maxTimeStamp and minTimeStamp if one of the curve's time stamps
...
...
@@ -2345,213 +2526,34 @@
}
}} curve
*/
function
getCurveMaxMinTimeStamp
(
curve
)
{
/**
* Sets the maxTimeStamp and minTimeStamp if one of its timestamps exceeds the maximum or minimum.
* @param {{times: number[]}} axis
*/
function
getCurveAxisMaxMinTimeStamps
(
axis
)
{
maxTimeStamp
=
axis
.
times
[
axis
.
times
.
length
-
1
]
>
maxTimeStamp
?
axis
.
times
[
axis
.
times
.
length
-
1
]
:
maxTimeStamp
;
minTimeStamp
=
axis
.
times
[
0
]
<
minTimeStamp
?
axis
.
times
[
0
]
:
minTimeStamp
;
}
function
getCurveMaxMinTimeStamp
(
curve
,
timestamps
)
{
if
(
curve
.
x
)
{
getCurveAxisMaxMinTimeStamps
(
curve
.
x
);
getCurveAxisMaxMinTimeStamps
(
curve
.
x
,
timestamps
);
}
if
(
curve
.
y
)
{
getCurveAxisMaxMinTimeStamps
(
curve
.
y
);
getCurveAxisMaxMinTimeStamps
(
curve
.
y
,
timestamps
);
}
if
(
curve
.
z
)
{
getCurveAxisMaxMinTimeStamps
(
curve
.
z
);
}
}
if
(
layer
.
R
)
{
getCurveMaxMinTimeStamp
(
layer
.
R
.
curves
);
}
if
(
layer
.
S
)
{
getCurveMaxMinTimeStamp
(
layer
.
S
.
curves
);
}
if
(
layer
.
T
)
{
getCurveMaxMinTimeStamp
(
layer
.
T
.
curves
);
getCurveAxisMaxMinTimeStamps
(
curve
.
z
,
timestamps
);
}
}
}
}
}
// Do we have an animation clip with actual length?
if
(
maxTimeStamp
>
minTimeStamp
)
{
returnObject
.
stacks
[
nodeID
]
=
{
name
:
rawStacks
[
nodeID
].
attrName
,
layers
:
layers
,
length
:
maxTimeStamp
-
minTimeStamp
,
frames
:
(
maxTimeStamp
-
minTimeStamp
)
*
30
};
}
}
return
returnObject
;
/**
* @param {Object} FBXTree
* @param {{id: number, attrName: string, properties: Object<string, any>}} animationCurveNode
* @param {Map<number, {parents: {ID: number, relationship: string}[], children: {ID: number, relationship: string}[]}>} connections
* @param {{skeleton: {bones: {FBX_ID: number}[]}}} sceneGraph
*/
function
parseAnimationNode
(
FBXTree
,
animationCurveNode
,
connections
,
sceneGraph
)
{
var
returnObject
=
{
/**
* @type {number}
*/
id
:
animationCurveNode
.
id
,
/**
* @type {string}
*/
attr
:
animationCurveNode
.
attrName
,
/**
* @type {number}
*/
internalID
:
animationCurveNode
.
id
,
/**
* @type {boolean}
*/
attrX
:
false
,
/**
* @type {boolean}
*/
attrY
:
false
,
/**
* @type {boolean}
*/
attrZ
:
false
,
/**
* @type {number}
*/
containerBoneID
:
-
1
,
/**
* @type {number}
*/
containerID
:
-
1
,
curves
:
{
x
:
null
,
y
:
null
,
z
:
null
},
/**
* @type {number[]}
*/
preRotations
:
null
};
if
(
returnObject
.
attr
.
match
(
/S|R|T/
)
)
{
for
(
var
attributeKey
in
animationCurveNode
.
properties
)
{
if
(
attributeKey
.
match
(
/X/
)
)
{
returnObject
.
attrX
=
true
;
}
if
(
attributeKey
.
match
(
/Y/
)
)
{
returnObject
.
attrY
=
true
;
}
if
(
attributeKey
.
match
(
/Z/
)
)
{
returnObject
.
attrZ
=
true
;
}
}
}
else
{
return
null
;
}
var
conns
=
connections
.
get
(
returnObject
.
id
);
var
containerIndices
=
conns
.
parents
;
for
(
var
containerIndicesIndex
=
containerIndices
.
length
-
1
;
containerIndicesIndex
>=
0
;
--
containerIndicesIndex
)
{
var
boneID
=
findIndex
(
sceneGraph
.
skeleton
.
bones
,
function
(
bone
)
{
return
bone
.
FBX_ID
===
containerIndices
[
containerIndicesIndex
].
ID
;
}
);
if
(
boneID
>
-
1
)
{
returnObject
.
containerBoneID
=
boneID
;
returnObject
.
containerID
=
containerIndices
[
containerIndicesIndex
].
ID
;
var
model
=
rawModels
[
returnObject
.
containerID
.
toString
()
];
if
(
'
PreRotation
'
in
model
.
properties
)
{
returnObject
.
preRotations
=
parseVector3
(
model
.
properties
.
PreRotation
).
multiplyScalar
(
Math
.
PI
/
180
);
}
break
;
}
}
return
returnObject
;
}
/**
* @param {{id: number, subNodes: {KeyTime: {properties: {a: string}}, KeyValueFloat: {properties: {a: string}}, KeyAttrFlags: {properties: {a: string}}, KeyAttrDataFloat: {properties: {a: string}}}}} animationCurve
* Sets the maxTimeStamp and minTimeStamp if one of its timestamps exceeds the maximum or minimum.
* @param {{times: number[]}} axis
*/
function
parseAnimationCurve
(
animationCurve
)
{
return
{
version
:
null
,
id
:
animationCurve
.
id
,
internalID
:
animationCurve
.
id
,
times
:
parseFloatArray
(
animationCurve
.
subNodes
.
KeyTime
.
properties
.
a
).
map
(
convertFBXTimeToSeconds
),
values
:
parseFloatArray
(
animationCurve
.
subNodes
.
KeyValueFloat
.
properties
.
a
),
function
getCurveAxisMaxMinTimeStamps
(
axis
,
timestamps
)
{
attrFlag
:
parseIntArray
(
animationCurve
.
subNodes
.
KeyAttrFlags
.
properties
.
a
),
attrData
:
parseFloatArray
(
animationCurve
.
subNodes
.
KeyAttrDataFloat
.
properties
.
a
)
};
}
timestamps
.
max
=
axis
.
times
[
axis
.
times
.
length
-
1
]
>
timestamps
.
max
?
axis
.
times
[
axis
.
times
.
length
-
1
]
:
timestamps
.
max
;
timestamps
.
min
=
axis
.
times
[
0
]
<
timestamps
.
min
?
axis
.
times
[
0
]
:
timestamps
.
min
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录