|
@@ -24872,7 +24872,7 @@
|
|
|
};
|
|
|
var maintainCenter = e => {
|
|
|
//MergeEditor.maintainBoundXY(model)
|
|
|
- e.by2d || MergeEditor.maintainBoundCenter(model);
|
|
|
+ e.by2d || model.atPath || MergeEditor.maintainBoundCenter(model);
|
|
|
_updateBound();
|
|
|
model.dispatchEvent({
|
|
|
type: 'transformChanged',
|
|
@@ -82457,91 +82457,6 @@
|
|
|
var oldDisToCam = ((_this$camFollowObject = this.camFollowObject) === null || _this$camFollowObject === void 0 ? void 0 : _this$camFollowObject.length) == 1 && this.keepDistance && this.camFollowObject[0].boundCenter.distanceTo(viewer.mainViewport.view.position);
|
|
|
var transitionRatio = 0.05 * delta * 60; //渐变系数,越小缓动程度越高,越平滑 //假设标准帧率为60fps,当帧率低时(delta大时) 降低缓动。速度快时缓动太高会偏移路径
|
|
|
var transitionRatio2 = 0.8 * delta * 60;
|
|
|
-
|
|
|
- /* for(let [model, keys] of this.pathKeys){//路径。开头结尾和别的衔接过渡
|
|
|
- let atPath //是否在path中 至多只有一个
|
|
|
- let fadeToPath//是否在过渡到path中
|
|
|
- let fadeFromPath //是否从path中过渡到下一pose
|
|
|
- //以上三个权重越来越小,但都比pose大
|
|
|
- keys.find(key=>{
|
|
|
- if(key.path.points.length < 2) return
|
|
|
- let startToFade = key.time - maxClipFadeTime/2
|
|
|
- let endFade = key.time + key.dur + maxClipFadeTime/2
|
|
|
- atPath = time >= key.time && time <= key.time + key.dur
|
|
|
- if(atPath){
|
|
|
- atPath = key //找到一个就退出
|
|
|
- return true
|
|
|
- }else if(delta!=void 0){ //有delta代表是播放时,要缓动,如果是点击时间轴到这一帧,就不缓动
|
|
|
- if(time > startToFade && time < key.time){
|
|
|
- fadeToPath = key
|
|
|
- }else if(!fadeToPath && time > key.time + key.dur && time < endFade){
|
|
|
- fadeFromPath = key
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- pathStates.set(model,{atPath,fadeToPath,fadeFromPath})
|
|
|
-
|
|
|
-
|
|
|
- if(atPath){//沿着curve行走,目视curve前方 (参照CameraAnimationCurve,搜quaFromCurveTan)
|
|
|
- let percent = THREE.Math.clamp((time - atPath.time) / atPath.dur, 0, 1)
|
|
|
- let {position , quaternion} = this.getPoseAtPathKey(atPath, percent) //模型文件先保证其center在脚底,如果要我手动将bound底部对齐路径高度再说
|
|
|
- model.position.copy(position);
|
|
|
- quaternion && model.quaternion.copy(quaternion)
|
|
|
- }else if(fadeToPath){
|
|
|
- let {position , quaternion} = this.getPoseAtPathKey(fadeToPath, 0)
|
|
|
- quaternion && lerp.quaternion(model.quaternion, quaternion)(transitionRatio) //每次只改变一点点
|
|
|
- lerp.vector(model.position, position)(transitionRatio)
|
|
|
- }
|
|
|
-
|
|
|
- if(atPath || fadeToPath){
|
|
|
- model.dispatchEvent('position_changed') //暂时都这么写,以后再判断是否真的改变了
|
|
|
- model.dispatchEvent('rotation_changed')
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- for(let [model, keys] of this.poseKeys){
|
|
|
- if(keys.length == 0) continue
|
|
|
- let {atPath, fadeFromPath, fadeToPath} = pathStates.get(model) || {}
|
|
|
-
|
|
|
- tweens.scale = new Tween(keys.map(e=>e.time), keys.map(e=>e.scale))
|
|
|
- model.scale.copy(tweens.scale.lerp(time))
|
|
|
-
|
|
|
- if(!atPath && !fadeToPath){
|
|
|
- tweens.pos = new Tween(keys.map(e=>e.time), keys.map(e=>e.pos))
|
|
|
- tweens.qua = new Tween(keys.map(e=>e.time), keys.map(e=>e.qua))
|
|
|
-
|
|
|
- let time_ = time
|
|
|
- if(fadeFromPath){ //但如果开始播放时模型已经在fadeFromPath这个区间里,也是直接过渡过去
|
|
|
- time_ = fadeFromPath.time + fadeFromPath.dur + maxClipFadeTime/2 //fadeTimeEnd
|
|
|
- }
|
|
|
- let position = tweens.pos.lerp(time_)
|
|
|
- let quaternion = tweens.qua.lerp(time_)
|
|
|
- if(k){
|
|
|
- lerp.quaternion(model.quaternion, quaternion)(transitionRatio) //每次只改变一点点
|
|
|
- lerp.vector(model.position, position)(transitionRatio)
|
|
|
- }else{
|
|
|
- if(this.poseTransition && delta!=void 0){
|
|
|
- lerp.quaternion(model.quaternion, quaternion)(transitionRatio2) //每次只改变一点点
|
|
|
- lerp.vector(model.position, position)(transitionRatio2)
|
|
|
- }else{
|
|
|
- model.position.copy(position)
|
|
|
- model.quaternion.copy(quaternion)
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- model.dispatchEvent('position_changed')
|
|
|
- model.dispatchEvent('rotation_changed')
|
|
|
-
|
|
|
- } */
|
|
|
-
|
|
|
var posePathModels = [];
|
|
|
[this.poseKeys, this.pathKeys /* , this.clipKeys */].forEach(map => {
|
|
|
map.keys().forEach(model => {
|
|
@@ -82549,13 +82464,12 @@
|
|
|
});
|
|
|
});
|
|
|
posePathModels.forEach(model => {
|
|
|
- var _poseKeys;
|
|
|
- var pathKeys = this.pathKeys.get(model);
|
|
|
- var poseKeys = this.poseKeys.get(model);
|
|
|
+ var pathKeys = this.pathKeys.get(model) || [];
|
|
|
+ var poseKeys = this.poseKeys.get(model) || [];
|
|
|
var atPath; //是否在path中 至多只有一个
|
|
|
var lastPath;
|
|
|
var nextPath;
|
|
|
- if (pathKeys !== null && pathKeys !== void 0 && pathKeys.length) {
|
|
|
+ if (pathKeys.length) {
|
|
|
pathKeys.find(key => {
|
|
|
if (key.path.points.length < 2) return;
|
|
|
var startToFade = key.time - maxClipFadeTime / 2;
|
|
@@ -82567,26 +82481,30 @@
|
|
|
}
|
|
|
if (key.time + key.dur < time) lastPath = key;else if (key.time > time && !nextPath) nextPath = key;
|
|
|
});
|
|
|
- if (atPath) {
|
|
|
- //沿着curve行走,目视curve前方 (参照CameraAnimationCurve,搜quaFromCurveTan)
|
|
|
- var percent = MathUtils.clamp((time - atPath.time) / atPath.dur, 0, 1);
|
|
|
- var {
|
|
|
- position,
|
|
|
- quaternion
|
|
|
- } = this.getPoseAtPathKey(atPath, percent, model); //模型文件先保证其center在脚底,如果要我手动将bound底部对齐路径高度再说
|
|
|
- model.position.copy(position);
|
|
|
- model.quaternion.copy(quaternion);
|
|
|
- model.dispatchEvent('position_changed'); //暂时都这么写,以后再判断是否真的改变了
|
|
|
- model.dispatchEvent('rotation_changed');
|
|
|
- } //pose关键帧加到路径上是无效的(scale除外)!
|
|
|
- }
|
|
|
- if ((_poseKeys = poseKeys) !== null && _poseKeys !== void 0 && _poseKeys.length) {
|
|
|
+ }
|
|
|
+ if (poseKeys.length) {
|
|
|
tweens.scale = new Tween$1(poseKeys.map(e => e.time), poseKeys.map(e => e.scale));
|
|
|
model.scale.copy(tweens.scale.lerp(time));
|
|
|
+ tweens.qua = new Tween$1(poseKeys.map(e => e.time), poseKeys.map(e => e.qua));
|
|
|
+ model.quaternion.copy(tweens.qua.lerp(time));
|
|
|
} else {
|
|
|
- poseKeys = [];
|
|
|
+ if (pathKeys.length) {
|
|
|
+ var _model$defaultAniPose;
|
|
|
+ model.quaternion.copy(((_model$defaultAniPose = model.defaultAniPose) === null || _model$defaultAniPose === void 0 ? void 0 : _model$defaultAniPose.quaternion) || new Quaternion()); //设置路径朝向前要先还原
|
|
|
+ }
|
|
|
}
|
|
|
- if (!atPath) {
|
|
|
+ if (atPath) {
|
|
|
+ //沿着curve行走,目视curve前方 (参照CameraAnimationCurve,搜quaFromCurveTan)
|
|
|
+ var percent = MathUtils.clamp((time - atPath.time) / atPath.dur, 0, 1);
|
|
|
+ var {
|
|
|
+ position,
|
|
|
+ quaternion
|
|
|
+ } = this.getPoseAtPathKey(atPath, percent, model); //模型文件先保证其center在脚底,如果要我手动将bound底部对齐路径高度再说
|
|
|
+ model.position.copy(position);
|
|
|
+ model.quaternion.copy(quaternion);
|
|
|
+ model.atPath = atPath;
|
|
|
+ } else {
|
|
|
+ model.atPath = null;
|
|
|
poseKeys = poseKeys.slice();
|
|
|
var addPathToPoseKey = (pathKey, percent) => {
|
|
|
//把当前前后的path姿态加入帧
|
|
@@ -82610,15 +82528,18 @@
|
|
|
nextPath && addPathToPoseKey(nextPath, 0);
|
|
|
if (poseKeys.length) {
|
|
|
tweens.pos = new Tween$1(poseKeys.map(e => e.time), poseKeys.map(e => e.pos));
|
|
|
- tweens.qua = new Tween$1(poseKeys.map(e => e.time), poseKeys.map(e => e.qua));
|
|
|
- var _position = tweens.pos.lerp(time);
|
|
|
- var _quaternion = tweens.qua.lerp(time);
|
|
|
- model.position.copy(_position);
|
|
|
- model.quaternion.copy(_quaternion);
|
|
|
- model.dispatchEvent('position_changed');
|
|
|
- model.dispatchEvent('rotation_changed');
|
|
|
+ model.position.copy(tweens.pos.lerp(time));
|
|
|
+ var poseKeys2 = poseKeys.filter(e => e.isPath);
|
|
|
+ if (poseKeys2.length) {
|
|
|
+ tweens.qua = new Tween$1(poseKeys2.map(e => e.time), poseKeys2.map(e => e.qua));
|
|
|
+ model.quaternion.copy(tweens.qua.lerp(time));
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ if (poseKeys.length || pathKeys.length) {
|
|
|
+ model.dispatchEvent('position_changed');
|
|
|
+ model.dispatchEvent('rotation_changed');
|
|
|
+ }
|
|
|
});
|
|
|
var _loop = function _loop(keys) {
|
|
|
if (keys.length == 0) return 1; // continue
|
|
@@ -82733,17 +82654,26 @@
|
|
|
var curve = key.path.curve.clone();
|
|
|
if (key.reverse) curve.points.reverse();
|
|
|
var position = curve.getPointAt(percent);
|
|
|
- var quaternion;
|
|
|
+ var pathQua, quaternion;
|
|
|
if (percent2 <= 1) {
|
|
|
var position2 = curve.getPointAt(percent2);
|
|
|
- quaternion = math.getQuaFromPosAim(position2, position);
|
|
|
+ pathQua = math.getQuaFromPosAim(position2, position);
|
|
|
} else {
|
|
|
percent2 = percent - delta;
|
|
|
- var _position2 = curve.getPointAt(percent2);
|
|
|
- quaternion = math.getQuaFromPosAim(position, _position2);
|
|
|
+ var _position = curve.getPointAt(percent2);
|
|
|
+ pathQua = math.getQuaFromPosAim(position, _position);
|
|
|
+ }
|
|
|
+ pathQua.multiplyQuaternions(pathQua, rot90Qua); //这是当模型导进来就旋转正确时的quaternion
|
|
|
+ key.curQua_ = pathQua.clone(); //记录下
|
|
|
+ if (model.quaAtPath) {
|
|
|
+ //quaternion = pathQua.premultiply(model.quaAtPath)
|
|
|
+ quaternion = new Quaternion().multiplyQuaternions(pathQua, model.quaAtPath);
|
|
|
+ } else {
|
|
|
+ quaternion = pathQua.clone();
|
|
|
}
|
|
|
- quaternion.multiplyQuaternions(quaternion, rot90Qua);
|
|
|
+ //quaternion.multiplyQuaternions( quaternion, rot90Qua );
|
|
|
|
|
|
+ //model && quaternion.multiplyQuaternions( quaternion, model.quaternion ); //应用当前已有的quaternion
|
|
|
//如果要将模型底部中心对准路径,需要先修改好模型scale ,然后boundingBox中心应用scale和qua, 加到position里
|
|
|
//目前两个人物模型刚好模型pivot在脚底,如果是其他物体甚至直接用curve的朝向不太对,没有明确朝向。除非所有模型都保持上路径前的朝向
|
|
|
//或者pos的z还用之前的
|
|
@@ -82752,6 +82682,17 @@
|
|
|
quaternion
|
|
|
};
|
|
|
}
|
|
|
+ getModelQuaAtPath(model) {
|
|
|
+ //获取当前时间
|
|
|
+ if (!model.atPath) return;
|
|
|
+ //let qua = new THREE.Quaternion().multiplyQuaternions(model.quaternion, model.atPath.curQua_.clone().invert())
|
|
|
+ var qua = new Quaternion().multiplyQuaternions(model.atPath.curQua_.clone().invert(), model.quaternion);
|
|
|
+ //qua = new THREE.Quaternion().multiplyQuaternions(qua, rot90Qua.clone().invert())
|
|
|
+
|
|
|
+ console.log('getModelQuaAtPath', qua);
|
|
|
+ model.quaAtPath = qua; //相对旋转
|
|
|
+ return qua;
|
|
|
+ }
|
|
|
play() {
|
|
|
var {
|
|
|
time = -maxClipFadeTime / 2
|