Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Ablesons
three.js
提交
c45bddc2
T
three.js
项目概览
Ablesons
/
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,发现更多精彩内容 >>
提交
c45bddc2
编写于
1月 22, 2017
作者:
T
Tristan VALCKE
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Protect AnimationMixer against the closure circular reference bug
上级
251ee408
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
251 addition
and
258 deletion
+251
-258
src/animation/AnimationMixer.js
src/animation/AnimationMixer.js
+251
-258
未找到文件。
src/animation/AnimationMixer.js
浏览文件 @
c45bddc2
...
...
@@ -27,260 +27,10 @@ function AnimationMixer( root ) {
}
AnimationMixer
.
prototype
=
{
Object
.
assign
(
AnimationMixer
.
prototype
,
EventDispatcher
.
prototype
,
{
constructor
:
AnimationMixer
,
// return an action for a clip optionally using a custom root target
// object (this method allocates a lot of dynamic memory in case a
// previously unknown clip/root combination is specified)
clipAction
:
function
(
clip
,
optionalRoot
)
{
var
root
=
optionalRoot
||
this
.
_root
,
rootUuid
=
root
.
uuid
,
clipObject
=
typeof
clip
===
'
string
'
?
AnimationClip
.
findByName
(
root
,
clip
)
:
clip
,
clipUuid
=
clipObject
!==
null
?
clipObject
.
uuid
:
clip
,
actionsForClip
=
this
.
_actionsByClip
[
clipUuid
],
prototypeAction
=
null
;
if
(
actionsForClip
!==
undefined
)
{
var
existingAction
=
actionsForClip
.
actionByRoot
[
rootUuid
];
if
(
existingAction
!==
undefined
)
{
return
existingAction
;
}
// we know the clip, so we don't have to parse all
// the bindings again but can just copy
prototypeAction
=
actionsForClip
.
knownActions
[
0
];
// also, take the clip from the prototype action
if
(
clipObject
===
null
)
clipObject
=
prototypeAction
.
_clip
;
}
// clip must be known when specified via string
if
(
clipObject
===
null
)
return
null
;
// allocate all resources required to run it
var
newAction
=
new
AnimationAction
(
this
,
clipObject
,
optionalRoot
);
this
.
_bindAction
(
newAction
,
prototypeAction
);
// and make the action known to the memory manager
this
.
_addInactiveAction
(
newAction
,
clipUuid
,
rootUuid
);
return
newAction
;
},
// get an existing action
existingAction
:
function
(
clip
,
optionalRoot
)
{
var
root
=
optionalRoot
||
this
.
_root
,
rootUuid
=
root
.
uuid
,
clipObject
=
typeof
clip
===
'
string
'
?
AnimationClip
.
findByName
(
root
,
clip
)
:
clip
,
clipUuid
=
clipObject
?
clipObject
.
uuid
:
clip
,
actionsForClip
=
this
.
_actionsByClip
[
clipUuid
];
if
(
actionsForClip
!==
undefined
)
{
return
actionsForClip
.
actionByRoot
[
rootUuid
]
||
null
;
}
return
null
;
},
// deactivates all previously scheduled actions
stopAllAction
:
function
()
{
var
actions
=
this
.
_actions
,
nActions
=
this
.
_nActiveActions
,
bindings
=
this
.
_bindings
,
nBindings
=
this
.
_nActiveBindings
;
this
.
_nActiveActions
=
0
;
this
.
_nActiveBindings
=
0
;
for
(
var
i
=
0
;
i
!==
nActions
;
++
i
)
{
actions
[
i
].
reset
();
}
for
(
var
i
=
0
;
i
!==
nBindings
;
++
i
)
{
bindings
[
i
].
useCount
=
0
;
}
return
this
;
},
// advance the time and update apply the animation
update
:
function
(
deltaTime
)
{
deltaTime
*=
this
.
timeScale
;
var
actions
=
this
.
_actions
,
nActions
=
this
.
_nActiveActions
,
time
=
this
.
time
+=
deltaTime
,
timeDirection
=
Math
.
sign
(
deltaTime
),
accuIndex
=
this
.
_accuIndex
^=
1
;
// run active actions
for
(
var
i
=
0
;
i
!==
nActions
;
++
i
)
{
var
action
=
actions
[
i
];
if
(
action
.
enabled
)
{
action
.
_update
(
time
,
deltaTime
,
timeDirection
,
accuIndex
);
}
}
// update scene graph
var
bindings
=
this
.
_bindings
,
nBindings
=
this
.
_nActiveBindings
;
for
(
var
i
=
0
;
i
!==
nBindings
;
++
i
)
{
bindings
[
i
].
apply
(
accuIndex
);
}
return
this
;
},
// return this mixer's root target object
getRoot
:
function
()
{
return
this
.
_root
;
},
// free all resources specific to a particular clip
uncacheClip
:
function
(
clip
)
{
var
actions
=
this
.
_actions
,
clipUuid
=
clip
.
uuid
,
actionsByClip
=
this
.
_actionsByClip
,
actionsForClip
=
actionsByClip
[
clipUuid
];
if
(
actionsForClip
!==
undefined
)
{
// note: just calling _removeInactiveAction would mess up the
// iteration state and also require updating the state we can
// just throw away
var
actionsToRemove
=
actionsForClip
.
knownActions
;
for
(
var
i
=
0
,
n
=
actionsToRemove
.
length
;
i
!==
n
;
++
i
)
{
var
action
=
actionsToRemove
[
i
];
this
.
_deactivateAction
(
action
);
var
cacheIndex
=
action
.
_cacheIndex
,
lastInactiveAction
=
actions
[
actions
.
length
-
1
];
action
.
_cacheIndex
=
null
;
action
.
_byClipCacheIndex
=
null
;
lastInactiveAction
.
_cacheIndex
=
cacheIndex
;
actions
[
cacheIndex
]
=
lastInactiveAction
;
actions
.
pop
();
this
.
_removeInactiveBindingsForAction
(
action
);
}
delete
actionsByClip
[
clipUuid
];
}
},
// free all resources specific to a particular root target object
uncacheRoot
:
function
(
root
)
{
var
rootUuid
=
root
.
uuid
,
actionsByClip
=
this
.
_actionsByClip
;
for
(
var
clipUuid
in
actionsByClip
)
{
var
actionByRoot
=
actionsByClip
[
clipUuid
].
actionByRoot
,
action
=
actionByRoot
[
rootUuid
];
if
(
action
!==
undefined
)
{
this
.
_deactivateAction
(
action
);
this
.
_removeInactiveAction
(
action
);
}
}
var
bindingsByRoot
=
this
.
_bindingsByRootAndName
,
bindingByName
=
bindingsByRoot
[
rootUuid
];
if
(
bindingByName
!==
undefined
)
{
for
(
var
trackName
in
bindingByName
)
{
var
binding
=
bindingByName
[
trackName
];
binding
.
restoreOriginalState
();
this
.
_removeInactiveBinding
(
binding
);
}
}
},
// remove a targeted clip from the cache
uncacheAction
:
function
(
clip
,
optionalRoot
)
{
var
action
=
this
.
existingAction
(
clip
,
optionalRoot
);
if
(
action
!==
null
)
{
this
.
_deactivateAction
(
action
);
this
.
_removeInactiveAction
(
action
);
}
}
};
// Implementation details:
Object
.
assign
(
AnimationMixer
.
prototype
,
{
_bindAction
:
function
(
action
,
prototypeAction
)
{
var
root
=
action
.
_localRoot
||
this
.
_root
,
...
...
@@ -332,8 +82,8 @@ Object.assign( AnimationMixer.prototype, {
_propertyBindings
[
i
].
binding
.
parsedPath
;
binding
=
new
PropertyMixer
(
PropertyBinding
.
create
(
root
,
trackName
,
path
),
track
.
ValueTypeName
,
track
.
getValueSize
()
);
PropertyBinding
.
create
(
root
,
trackName
,
path
),
track
.
ValueTypeName
,
track
.
getValueSize
()
);
++
binding
.
referenceCount
;
this
.
_addInactiveBinding
(
binding
,
rootUuid
,
trackName
);
...
...
@@ -362,7 +112,7 @@ Object.assign( AnimationMixer.prototype, {
actionsForClip
=
this
.
_actionsByClip
[
clipUuid
];
this
.
_bindAction
(
action
,
actionsForClip
&&
actionsForClip
.
knownActions
[
0
]
);
actionsForClip
&&
actionsForClip
.
knownActions
[
0
]
);
this
.
_addInactiveAction
(
action
,
clipUuid
,
rootUuid
);
...
...
@@ -710,8 +460,8 @@ Object.assign( AnimationMixer.prototype, {
if
(
interpolant
===
undefined
)
{
interpolant
=
new
LinearInterpolant
(
new
Float32Array
(
2
),
new
Float32Array
(
2
),
1
,
this
.
_controlInterpolantsResultBuffer
);
new
Float32Array
(
2
),
new
Float32Array
(
2
),
1
,
this
.
_controlInterpolantsResultBuffer
);
interpolant
.
__cacheIndex
=
lastActiveIndex
;
interpolants
[
lastActiveIndex
]
=
interpolant
;
...
...
@@ -739,10 +489,253 @@ Object.assign( AnimationMixer.prototype, {
},
_controlInterpolantsResultBuffer
:
new
Float32Array
(
1
)
_controlInterpolantsResultBuffer
:
new
Float32Array
(
1
),
// return an action for a clip optionally using a custom root target
// object (this method allocates a lot of dynamic memory in case a
// previously unknown clip/root combination is specified)
clipAction
:
function
(
clip
,
optionalRoot
)
{
var
root
=
optionalRoot
||
this
.
_root
,
rootUuid
=
root
.
uuid
,
clipObject
=
typeof
clip
===
'
string
'
?
AnimationClip
.
findByName
(
root
,
clip
)
:
clip
,
clipUuid
=
clipObject
!==
null
?
clipObject
.
uuid
:
clip
,
actionsForClip
=
this
.
_actionsByClip
[
clipUuid
],
prototypeAction
=
null
;
if
(
actionsForClip
!==
undefined
)
{
var
existingAction
=
actionsForClip
.
actionByRoot
[
rootUuid
];
if
(
existingAction
!==
undefined
)
{
return
existingAction
;
}
// we know the clip, so we don't have to parse all
// the bindings again but can just copy
prototypeAction
=
actionsForClip
.
knownActions
[
0
];
// also, take the clip from the prototype action
if
(
clipObject
===
null
)
clipObject
=
prototypeAction
.
_clip
;
}
// clip must be known when specified via string
if
(
clipObject
===
null
)
return
null
;
// allocate all resources required to run it
var
newAction
=
new
AnimationAction
(
this
,
clipObject
,
optionalRoot
);
this
.
_bindAction
(
newAction
,
prototypeAction
);
// and make the action known to the memory manager
this
.
_addInactiveAction
(
newAction
,
clipUuid
,
rootUuid
);
return
newAction
;
},
// get an existing action
existingAction
:
function
(
clip
,
optionalRoot
)
{
var
root
=
optionalRoot
||
this
.
_root
,
rootUuid
=
root
.
uuid
,
clipObject
=
typeof
clip
===
'
string
'
?
AnimationClip
.
findByName
(
root
,
clip
)
:
clip
,
clipUuid
=
clipObject
?
clipObject
.
uuid
:
clip
,
actionsForClip
=
this
.
_actionsByClip
[
clipUuid
];
if
(
actionsForClip
!==
undefined
)
{
return
actionsForClip
.
actionByRoot
[
rootUuid
]
||
null
;
}
return
null
;
},
// deactivates all previously scheduled actions
stopAllAction
:
function
()
{
var
actions
=
this
.
_actions
,
nActions
=
this
.
_nActiveActions
,
bindings
=
this
.
_bindings
,
nBindings
=
this
.
_nActiveBindings
;
this
.
_nActiveActions
=
0
;
this
.
_nActiveBindings
=
0
;
for
(
var
i
=
0
;
i
!==
nActions
;
++
i
)
{
actions
[
i
].
reset
();
}
for
(
var
i
=
0
;
i
!==
nBindings
;
++
i
)
{
bindings
[
i
].
useCount
=
0
;
}
return
this
;
},
// advance the time and update apply the animation
update
:
function
(
deltaTime
)
{
deltaTime
*=
this
.
timeScale
;
var
actions
=
this
.
_actions
,
nActions
=
this
.
_nActiveActions
,
time
=
this
.
time
+=
deltaTime
,
timeDirection
=
Math
.
sign
(
deltaTime
),
accuIndex
=
this
.
_accuIndex
^=
1
;
// run active actions
for
(
var
i
=
0
;
i
!==
nActions
;
++
i
)
{
var
action
=
actions
[
i
];
if
(
action
.
enabled
)
{
action
.
_update
(
time
,
deltaTime
,
timeDirection
,
accuIndex
);
}
}
// update scene graph
var
bindings
=
this
.
_bindings
,
nBindings
=
this
.
_nActiveBindings
;
for
(
var
i
=
0
;
i
!==
nBindings
;
++
i
)
{
bindings
[
i
].
apply
(
accuIndex
);
}
return
this
;
},
// return this mixer's root target object
getRoot
:
function
()
{
return
this
.
_root
;
},
// free all resources specific to a particular clip
uncacheClip
:
function
(
clip
)
{
var
actions
=
this
.
_actions
,
clipUuid
=
clip
.
uuid
,
actionsByClip
=
this
.
_actionsByClip
,
actionsForClip
=
actionsByClip
[
clipUuid
];
if
(
actionsForClip
!==
undefined
)
{
// note: just calling _removeInactiveAction would mess up the
// iteration state and also require updating the state we can
// just throw away
var
actionsToRemove
=
actionsForClip
.
knownActions
;
for
(
var
i
=
0
,
n
=
actionsToRemove
.
length
;
i
!==
n
;
++
i
)
{
var
action
=
actionsToRemove
[
i
];
this
.
_deactivateAction
(
action
);
var
cacheIndex
=
action
.
_cacheIndex
,
lastInactiveAction
=
actions
[
actions
.
length
-
1
];
action
.
_cacheIndex
=
null
;
action
.
_byClipCacheIndex
=
null
;
lastInactiveAction
.
_cacheIndex
=
cacheIndex
;
actions
[
cacheIndex
]
=
lastInactiveAction
;
actions
.
pop
();
this
.
_removeInactiveBindingsForAction
(
action
);
}
delete
actionsByClip
[
clipUuid
];
}
},
// free all resources specific to a particular root target object
uncacheRoot
:
function
(
root
)
{
var
rootUuid
=
root
.
uuid
,
actionsByClip
=
this
.
_actionsByClip
;
for
(
var
clipUuid
in
actionsByClip
)
{
var
actionByRoot
=
actionsByClip
[
clipUuid
].
actionByRoot
,
action
=
actionByRoot
[
rootUuid
];
if
(
action
!==
undefined
)
{
this
.
_deactivateAction
(
action
);
this
.
_removeInactiveAction
(
action
);
}
}
var
bindingsByRoot
=
this
.
_bindingsByRootAndName
,
bindingByName
=
bindingsByRoot
[
rootUuid
];
if
(
bindingByName
!==
undefined
)
{
for
(
var
trackName
in
bindingByName
)
{
var
binding
=
bindingByName
[
trackName
];
binding
.
restoreOriginalState
();
this
.
_removeInactiveBinding
(
binding
);
}
}
},
// remove a targeted clip from the cache
uncacheAction
:
function
(
clip
,
optionalRoot
)
{
var
action
=
this
.
existingAction
(
clip
,
optionalRoot
);
if
(
action
!==
null
)
{
this
.
_deactivateAction
(
action
);
this
.
_removeInactiveAction
(
action
);
}
}
}
);
Object
.
assign
(
AnimationMixer
.
prototype
,
EventDispatcher
.
prototype
);
export
{
AnimationMixer
};
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录