@kimap/indoor-positioning-sdk-vue2 5.8.7 → 5.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/KimapSDK.js +19 -90
- package/src/core/SceneCore.js +49 -21
package/package.json
CHANGED
package/src/core/KimapSDK.js
CHANGED
|
@@ -10,10 +10,6 @@ var SceneCore = require('./SceneCore.js');
|
|
|
10
10
|
// THREE.js 将在运行时加载
|
|
11
11
|
var THREE = null;
|
|
12
12
|
var loadThree = loaders.loadThree;
|
|
13
|
-
|
|
14
|
-
function easeInOutCubic(t) {
|
|
15
|
-
return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
|
|
16
|
-
}
|
|
17
13
|
var loadOBJLoader = loaders.loadOBJLoader;
|
|
18
14
|
var loadFBXLoader = loaders.loadFBXLoader;
|
|
19
15
|
var loadGLTFLoader = loaders.loadGLTFLoader;
|
|
@@ -88,9 +84,10 @@ KimapSDK.prototype.init = function() {
|
|
|
88
84
|
self.startRenderLoop();
|
|
89
85
|
self._extractWallsFromModel();
|
|
90
86
|
|
|
91
|
-
//
|
|
87
|
+
// 多楼层默认显示第一个楼层,并设 -60° 俯角相机
|
|
92
88
|
if (self.isMultiFloor && self.floorGroups && self.floorGroups.length > 0) {
|
|
93
89
|
self.showSingleFloor(0);
|
|
90
|
+
self.core.adjustCameraToSingleFloorView(0);
|
|
94
91
|
}
|
|
95
92
|
|
|
96
93
|
// 渲染内置楼层选择器 UI
|
|
@@ -628,66 +625,38 @@ KimapSDK.prototype.showSingleFloor = function(floorIndex) {
|
|
|
628
625
|
// 判断方向:目标层是从上方滑下(低→高)还是从下方滑上(高→低)
|
|
629
626
|
var targetFromAbove = floorIndex > currentFloorIndex;
|
|
630
627
|
|
|
631
|
-
//
|
|
628
|
+
// 滑入起始偏移(减小幅度,约原值的50%)
|
|
632
629
|
var slideOffset = 4;
|
|
633
630
|
|
|
634
631
|
var steps = [];
|
|
635
|
-
var fromAll = (currentFloorIndex === -1); // 是否从 ALL 模式切来
|
|
636
|
-
|
|
637
632
|
this.floorGroups.forEach(function(group, idx) {
|
|
638
633
|
if (idx === floorIndex) {
|
|
639
|
-
//
|
|
640
|
-
if (fromAll) {
|
|
641
|
-
var origY = self.core.floorOriginalY[idx] || 0;
|
|
642
|
-
group.position.y = origY;
|
|
643
|
-
} else {
|
|
644
|
-
group.position.y = targetFromAbove ? slideOffset : -slideOffset;
|
|
645
|
-
}
|
|
634
|
+
// 目标层:从偏移位滑入到 y=0
|
|
646
635
|
group.visible = true;
|
|
636
|
+
group.position.y = targetFromAbove ? slideOffset : -slideOffset;
|
|
647
637
|
steps.push({
|
|
648
638
|
group: group,
|
|
649
|
-
fromY:
|
|
639
|
+
fromY: targetFromAbove ? slideOffset : -slideOffset,
|
|
650
640
|
toY: 0,
|
|
651
641
|
toVisible: true
|
|
652
642
|
});
|
|
653
643
|
} else {
|
|
654
|
-
//
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
var et = 1 - Math.pow(1 - t, 3);
|
|
659
|
-
for (var i = 0; i < cur.steps.length; i++) {
|
|
660
|
-
var cs = cur.steps[i];
|
|
661
|
-
if (cs.group === group) {
|
|
662
|
-
group.position.y = cs.fromY + (cs.toY - cs.fromY) * et;
|
|
663
|
-
break;
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
var origY2 = self.core.floorOriginalY[idx] || 0;
|
|
668
|
-
// 从 ALL 来:滑出动画到原始位置;普通切换:立即隐藏
|
|
669
|
-
if (fromAll) {
|
|
670
|
-
steps.push({
|
|
671
|
-
group: group,
|
|
672
|
-
fromY: group.position.y,
|
|
673
|
-
toY: origY2,
|
|
674
|
-
toVisible: true
|
|
675
|
-
});
|
|
676
|
-
} else {
|
|
677
|
-
group.visible = false;
|
|
678
|
-
group.position.y = -origY2 - 1;
|
|
679
|
-
}
|
|
644
|
+
// 离场层:立即消失(移到下方,不做动画)
|
|
645
|
+
group.visible = false;
|
|
646
|
+
var origY = self.core.floorOriginalY[idx] || 0;
|
|
647
|
+
group.position.y = -origY - 1;
|
|
680
648
|
}
|
|
681
649
|
});
|
|
682
650
|
|
|
683
|
-
//
|
|
651
|
+
// 合并/覆盖已有动画:先停止当前帧再以新起止值启动
|
|
684
652
|
if (self.core.floorAnim && self.core.floorAnim.running) {
|
|
685
653
|
var cur = self.core.floorAnim;
|
|
686
654
|
var t = Math.min((Date.now() - cur.startTime) / cur.duration, 1);
|
|
687
|
-
var et = 1 - Math.pow(1 - t, 3);
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
655
|
+
var et = 1 - Math.pow(1 - t, 3); // easeOutCubic reverse
|
|
656
|
+
// 把每个 group 瞬移到当前动画帧的位置
|
|
657
|
+
for (var i = 0; i < cur.steps.length; i++) {
|
|
658
|
+
var cs = cur.steps[i];
|
|
659
|
+
cs.group.position.y = cs.fromY + (cs.toY - cs.fromY) * et;
|
|
691
660
|
}
|
|
692
661
|
}
|
|
693
662
|
|
|
@@ -699,50 +668,10 @@ KimapSDK.prototype.showSingleFloor = function(floorIndex) {
|
|
|
699
668
|
};
|
|
700
669
|
|
|
701
670
|
this._currentShowingFloorIndex = floorIndex;
|
|
702
|
-
|
|
703
|
-
// 退出 ALL
|
|
671
|
+
self.core._lastSingleFloorIndex = floorIndex;
|
|
672
|
+
// 退出 ALL 时:相机动画恢复到单楼层视角(保持当前位置,不重置)
|
|
704
673
|
if (self.core.cameraPitchState === 1) {
|
|
705
|
-
|
|
706
|
-
if (self.core.cameraPitchAnim && self.core.cameraPitchAnim.running) {
|
|
707
|
-
var cpa = self.core.cameraPitchAnim;
|
|
708
|
-
var tc = Math.min((Date.now() - cpa.startTime) / cpa.duration, 1);
|
|
709
|
-
var etc = easeInOutCubic(tc);
|
|
710
|
-
self.core.camera.position.lerpVectors(cpa.fromPos, cpa.toPos, etc);
|
|
711
|
-
self.core.camera.lookAt(
|
|
712
|
-
cpa.fromTarget.x + (cpa.toTarget.x - cpa.fromTarget.x) * etc,
|
|
713
|
-
cpa.fromTarget.y + (cpa.toTarget.y - cpa.fromTarget.y) * etc,
|
|
714
|
-
cpa.fromTarget.z + (cpa.toTarget.z - cpa.fromTarget.z) * etc
|
|
715
|
-
);
|
|
716
|
-
if (self.core.controls) self.core.controls.update();
|
|
717
|
-
self.core.cameraPitchAnim = null;
|
|
718
|
-
}
|
|
719
|
-
// 目标相机位置:单楼层 -60° 俯角,lookAt 稍偏高处
|
|
720
|
-
var floorMeshes = [];
|
|
721
|
-
self.floorGroups[floorIndex].traverse(function(child) {
|
|
722
|
-
if (child.isMesh) floorMeshes.push(child);
|
|
723
|
-
});
|
|
724
|
-
var box2 = new THREE.Box3();
|
|
725
|
-
floorMeshes.forEach(function(m) { box2.expandByObject(m); });
|
|
726
|
-
var ctr = new THREE.Vector3();
|
|
727
|
-
var sz = new THREE.Vector3();
|
|
728
|
-
box2.getCenter(ctr);
|
|
729
|
-
box2.getSize(sz);
|
|
730
|
-
var ms = Math.max(sz.x, sz.z);
|
|
731
|
-
var d = ms * 1.8;
|
|
732
|
-
var lookAtH = new THREE.Vector3(ctr.x, ctr.y + ms * 0.15, ctr.z);
|
|
733
|
-
var toPos = new THREE.Vector3(lookAtH.x, lookAtH.y - d * 0.866, lookAtH.z + d * 0.5);
|
|
734
|
-
var fromCP = self.core.camera.position.clone();
|
|
735
|
-
var fromTgt = self.core.lookAtTarget ? self.core.lookAtTarget.clone() : lookAtH.clone();
|
|
736
|
-
self.core.cameraPitchAnim = {
|
|
737
|
-
running: true,
|
|
738
|
-
startTime: Date.now(),
|
|
739
|
-
duration: 600,
|
|
740
|
-
fromPos: fromCP,
|
|
741
|
-
toPos: toPos,
|
|
742
|
-
fromTarget: fromTgt,
|
|
743
|
-
toTarget: lookAtH
|
|
744
|
-
};
|
|
745
|
-
self.core.cameraPitchState = 0;
|
|
674
|
+
self.core.animateCameraToFloorView(600);
|
|
746
675
|
}
|
|
747
676
|
};
|
|
748
677
|
|
package/src/core/SceneCore.js
CHANGED
|
@@ -532,23 +532,16 @@ SceneCore.prototype.adjustCameraToFloor = function(floorIndex) {
|
|
|
532
532
|
box.getCenter(center);
|
|
533
533
|
box.getSize(size);
|
|
534
534
|
var maxSize = Math.max(size.x, size.z);
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
// camera.z - lookAt.z = dist * cos(-60°) = dist * 0.5
|
|
541
|
-
this.camera.position.set(
|
|
542
|
-
lookAtTgt.x,
|
|
543
|
-
lookAtTgt.y - dist * 0.866,
|
|
544
|
-
lookAtTgt.z + dist * 0.5
|
|
545
|
-
);
|
|
535
|
+
var distance = maxSize * 1.5;
|
|
536
|
+
|
|
537
|
+
// -60° 俯角(与 ALL -45° 区分,单楼层更俯视)
|
|
538
|
+
this.camera.position.set(center.x, center.y - distance * 1.732, center.z + distance);
|
|
539
|
+
var lookAtTgt = new THREE.Vector3(center.x, center.y, center.z);
|
|
546
540
|
this.camera.lookAt(lookAtTgt);
|
|
547
541
|
if (this.controls) {
|
|
548
542
|
this.controls.target.copy(lookAtTgt);
|
|
549
543
|
this.controls.update();
|
|
550
544
|
}
|
|
551
|
-
// 记录当前 lookAt 目标(ALL 退场恢复用)
|
|
552
545
|
this.camera.lookAtTarget = lookAtTgt;
|
|
553
546
|
this.coordinateSystem.maxX = size.x;
|
|
554
547
|
this.coordinateSystem.maxY = size.z;
|
|
@@ -557,6 +550,14 @@ SceneCore.prototype.adjustCameraToFloor = function(floorIndex) {
|
|
|
557
550
|
}
|
|
558
551
|
};
|
|
559
552
|
|
|
553
|
+
/**
|
|
554
|
+
* 首次加载 / ALL 退出时:单楼层 -60° 俯角相机定位(独立方法,不改变现有 adjustCameraToFloor)
|
|
555
|
+
* @param {number} floorIndex
|
|
556
|
+
*/
|
|
557
|
+
SceneCore.prototype.adjustCameraToSingleFloorView = function(floorIndex) {
|
|
558
|
+
this.adjustCameraToFloor(floorIndex);
|
|
559
|
+
};
|
|
560
|
+
|
|
560
561
|
/**
|
|
561
562
|
* 加载 Kimap 加密文件(内部方法)
|
|
562
563
|
* @private
|
|
@@ -1349,12 +1350,12 @@ SceneCore.prototype.animateCameraToAllView = function(duration) {
|
|
|
1349
1350
|
this.cameraPrePitchPos = this.camera.position.clone();
|
|
1350
1351
|
this.cameraPrePitchTarget = this.controls ? this.controls.target.clone() : center.clone();
|
|
1351
1352
|
|
|
1352
|
-
//
|
|
1353
|
-
// camera.z - center.z = distance × cos(-
|
|
1354
|
-
var dist = maxSize * 1.8;
|
|
1353
|
+
// 较低俯角 -45°(-60°太极端):camera.y - center.y = distance × sin(-45°) ≈ -distance × 0.707
|
|
1354
|
+
// camera.z - center.z = distance × cos(-45°) ≈ distance × 0.707
|
|
1355
|
+
var dist = maxSize * 1.8; // 适度拉近,视野更舒适
|
|
1355
1356
|
var fromPos = this.camera.position.clone();
|
|
1356
1357
|
var fromTarget = this.controls ? this.controls.target.clone() : center.clone();
|
|
1357
|
-
var toPos = new THREE.Vector3(center.x, center.y - dist * 0.
|
|
1358
|
+
var toPos = new THREE.Vector3(center.x, center.y - dist * 0.707, center.z + dist * 0.707);
|
|
1358
1359
|
var toTarget = new THREE.Vector3(center.x, center.y, center.z);
|
|
1359
1360
|
|
|
1360
1361
|
this.cameraPitchAnim = {
|
|
@@ -1392,22 +1393,49 @@ SceneCore.prototype.animateCameraToFloorView = function(duration) {
|
|
|
1392
1393
|
this.cameraPitchAnim = null;
|
|
1393
1394
|
}
|
|
1394
1395
|
|
|
1395
|
-
//
|
|
1396
|
-
var
|
|
1397
|
-
var
|
|
1396
|
+
// 计算当前单楼层中心(-60° 单楼层俯角,不压低)
|
|
1397
|
+
var floorIdx = this._lastSingleFloorIndex !== undefined ? this._lastSingleFloorIndex : 0;
|
|
1398
|
+
var floorGroup = this.floorGroups[floorIdx];
|
|
1399
|
+
var toTarget, toPos, dist, maxSize;
|
|
1400
|
+
|
|
1401
|
+
if (floorGroup) {
|
|
1402
|
+
var meshes = [];
|
|
1403
|
+
floorGroup.traverse(function(child) { if (child.isMesh) meshes.push(child); });
|
|
1404
|
+
if (meshes.length > 0) {
|
|
1405
|
+
var box = new THREE.Box3();
|
|
1406
|
+
meshes.forEach(function(mesh) { box.expandByObject(mesh); });
|
|
1407
|
+
toTarget = new THREE.Vector3();
|
|
1408
|
+
var size = new THREE.Vector3();
|
|
1409
|
+
box.getCenter(toTarget);
|
|
1410
|
+
box.getSize(size);
|
|
1411
|
+
maxSize = Math.max(size.x, size.z);
|
|
1412
|
+
dist = maxSize * 1.5;
|
|
1413
|
+
// -60° 俯角,与 ALL -45° 区分
|
|
1414
|
+
toPos = new THREE.Vector3(toTarget.x, toTarget.y - dist * 1.732, toTarget.z + dist);
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
if (!toPos) {
|
|
1419
|
+
toTarget = this.camera.lookAtTarget || this.camera.position.clone();
|
|
1420
|
+
toPos = this.camera.position.clone();
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
var fromPos = this.camera.position.clone();
|
|
1424
|
+
var fromTarget = this.camera.lookAtTarget ? this.camera.lookAtTarget.clone() : toTarget.clone();
|
|
1398
1425
|
|
|
1399
1426
|
this.cameraPitchAnim = {
|
|
1400
1427
|
running: true,
|
|
1401
1428
|
startTime: Date.now(),
|
|
1402
1429
|
duration: duration,
|
|
1403
|
-
fromPos:
|
|
1430
|
+
fromPos: fromPos,
|
|
1404
1431
|
toPos: toPos,
|
|
1405
|
-
fromTarget:
|
|
1432
|
+
fromTarget: fromTarget,
|
|
1406
1433
|
toTarget: toTarget
|
|
1407
1434
|
};
|
|
1408
1435
|
this.cameraPitchState = 0;
|
|
1409
1436
|
this.cameraPrePitchPos = null;
|
|
1410
1437
|
this.cameraPrePitchTarget = null;
|
|
1438
|
+
this.camera.lookAtTarget = toTarget.clone();
|
|
1411
1439
|
};
|
|
1412
1440
|
|
|
1413
1441
|
module.exports = SceneCore;
|