右键环视:左右=纬度方向倾倒,上下=经度方向倾倒,强制北朝上
This commit is contained in:
+29
-14
@@ -372,6 +372,7 @@ export class CesiumGlobe {
|
|||||||
offset: new Cesium.Cartesian3(),
|
offset: new Cesium.Cartesian3(),
|
||||||
upAxis: new Cesium.Cartesian3(),
|
upAxis: new Cesium.Cartesian3(),
|
||||||
eastAxis: new Cesium.Cartesian3(),
|
eastAxis: new Cesium.Cartesian3(),
|
||||||
|
northAxis: new Cesium.Cartesian3(),
|
||||||
qAz: new Cesium.Quaternion(),
|
qAz: new Cesium.Quaternion(),
|
||||||
qEl: new Cesium.Quaternion(),
|
qEl: new Cesium.Quaternion(),
|
||||||
q: new Cesium.Quaternion(),
|
q: new Cesium.Quaternion(),
|
||||||
@@ -379,7 +380,7 @@ export class CesiumGlobe {
|
|||||||
newOffset: new Cesium.Cartesian3(),
|
newOffset: new Cesium.Cartesian3(),
|
||||||
newPos: new Cesium.Cartesian3(),
|
newPos: new Cesium.Cartesian3(),
|
||||||
dir: new Cesium.Cartesian3(),
|
dir: new Cesium.Cartesian3(),
|
||||||
upRot: new Cesium.Cartesian3(),
|
upProj: new Cesium.Cartesian3(),
|
||||||
};
|
};
|
||||||
|
|
||||||
handler.setInputAction((movement) => {
|
handler.setInputAction((movement) => {
|
||||||
@@ -394,8 +395,8 @@ export class CesiumGlobe {
|
|||||||
if (!Cesium.defined(pivot)) return;
|
if (!Cesium.defined(pivot)) return;
|
||||||
const sc = this._orbitScratch;
|
const sc = this._orbitScratch;
|
||||||
const offset = Cesium.Cartesian3.subtract(camera.position, pivot, sc.offset);
|
const offset = Cesium.Cartesian3.subtract(camera.position, pivot, sc.offset);
|
||||||
const upAxis = Cesium.Cartesian3.normalize(pivot, sc.upAxis); // 绕它转 = 左右旋转
|
const upAxis = Cesium.Cartesian3.normalize(pivot, sc.upAxis);
|
||||||
const eastAxis = Cesium.Cartesian3.cross(Cesium.Cartesian3.UNIT_Z, pivot, sc.eastAxis); // 绕它转 = 上下倾角
|
const eastAxis = Cesium.Cartesian3.cross(Cesium.Cartesian3.UNIT_Z, pivot, sc.eastAxis); // 绕它转 = 左右拖动(纬度方向倾倒)
|
||||||
if (Cesium.Cartesian3.magnitudeSquared(eastAxis) < 1e-12) {
|
if (Cesium.Cartesian3.magnitudeSquared(eastAxis) < 1e-12) {
|
||||||
eastAxis.x = 1;
|
eastAxis.x = 1;
|
||||||
eastAxis.y = 0;
|
eastAxis.y = 0;
|
||||||
@@ -403,11 +404,15 @@ export class CesiumGlobe {
|
|||||||
} else {
|
} else {
|
||||||
Cesium.Cartesian3.normalize(eastAxis, eastAxis);
|
Cesium.Cartesian3.normalize(eastAxis, eastAxis);
|
||||||
}
|
}
|
||||||
|
const northAxis = Cesium.Cartesian3.normalize(
|
||||||
|
Cesium.Cartesian3.cross(upAxis, eastAxis, sc.northAxis), // 绕它转 = 上下拖动(经度方向倾倒)
|
||||||
|
sc.northAxis,
|
||||||
|
);
|
||||||
this._lookState = {
|
this._lookState = {
|
||||||
pivot: Cesium.Cartesian3.clone(pivot),
|
pivot: Cesium.Cartesian3.clone(pivot),
|
||||||
startOffset: Cesium.Cartesian3.clone(offset),
|
startOffset: Cesium.Cartesian3.clone(offset),
|
||||||
upAxis: Cesium.Cartesian3.clone(upAxis),
|
|
||||||
eastAxis: Cesium.Cartesian3.clone(eastAxis),
|
eastAxis: Cesium.Cartesian3.clone(eastAxis),
|
||||||
|
northAxis: Cesium.Cartesian3.clone(northAxis),
|
||||||
position: Cesium.Cartesian3.clone(camera.position),
|
position: Cesium.Cartesian3.clone(camera.position),
|
||||||
direction: Cesium.Cartesian3.clone(camera.direction),
|
direction: Cesium.Cartesian3.clone(camera.direction),
|
||||||
up: Cesium.Cartesian3.clone(camera.up),
|
up: Cesium.Cartesian3.clone(camera.up),
|
||||||
@@ -443,26 +448,36 @@ export class CesiumGlobe {
|
|||||||
this._lookHandler = handler;
|
this._lookHandler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按累计角度(已限制)把相机绕点击点旋转;位置、朝向、up 一起做刚体旋转
|
// 按累计角度(已限制)把相机绕点击点倾倒:左右 = 纬度方向(绕东西轴),
|
||||||
|
// 上下 = 经度方向(绕南北轴);up 始终强制北朝上。
|
||||||
_orbitCamera(s) {
|
_orbitCamera(s) {
|
||||||
const camera = this.viewer.camera;
|
const camera = this.viewer.camera;
|
||||||
const sc = this._orbitScratch;
|
const sc = this._orbitScratch;
|
||||||
Cesium.Quaternion.fromAxisAngle(s.upAxis, s.azimuth, sc.qAz);
|
Cesium.Quaternion.fromAxisAngle(s.eastAxis, s.azimuth, sc.qAz);
|
||||||
Cesium.Quaternion.fromAxisAngle(s.eastAxis, s.elevation, sc.qEl);
|
Cesium.Quaternion.fromAxisAngle(s.northAxis, s.elevation, sc.qEl);
|
||||||
Cesium.Quaternion.multiply(sc.qEl, sc.qAz, sc.q);
|
Cesium.Quaternion.multiply(sc.qEl, sc.qAz, sc.q);
|
||||||
Cesium.Matrix3.fromQuaternion(sc.q, sc.rotMat);
|
Cesium.Matrix3.fromQuaternion(sc.q, sc.rotMat);
|
||||||
Cesium.Matrix3.multiplyByVector(sc.rotMat, s.startOffset, sc.newOffset);
|
Cesium.Matrix3.multiplyByVector(sc.rotMat, s.startOffset, sc.newOffset);
|
||||||
Cesium.Cartesian3.add(s.pivot, sc.newOffset, sc.newPos);
|
Cesium.Cartesian3.add(s.pivot, sc.newOffset, sc.newPos);
|
||||||
// up 不强制北朝上,与方向一起旋转(否则左右拽缺少 roll 分量,表现异常)
|
const dir = Cesium.Cartesian3.normalize(
|
||||||
Cesium.Matrix3.multiplyByVector(sc.rotMat, s.direction, sc.dir);
|
Cesium.Cartesian3.subtract(s.pivot, sc.newPos, sc.dir),
|
||||||
Cesium.Cartesian3.normalize(sc.dir, sc.dir);
|
sc.dir,
|
||||||
Cesium.Matrix3.multiplyByVector(sc.rotMat, s.up, sc.upRot);
|
);
|
||||||
Cesium.Cartesian3.normalize(sc.upRot, sc.upRot);
|
// 强制北朝上:up = 世界 Z 投影到垂直于视线的方向
|
||||||
|
const z = dir.z;
|
||||||
|
sc.upProj.x = -dir.x * z;
|
||||||
|
sc.upProj.y = -dir.y * z;
|
||||||
|
sc.upProj.z = 1 - z * z;
|
||||||
|
if (Cesium.Cartesian3.magnitudeSquared(sc.upProj) < 1e-12) {
|
||||||
|
Cesium.Cartesian3.clone(s.up, sc.upProj); // 垂直俯视时北朝上无定义,回退起始 up
|
||||||
|
} else {
|
||||||
|
Cesium.Cartesian3.normalize(sc.upProj, sc.upProj);
|
||||||
|
}
|
||||||
camera.setView({
|
camera.setView({
|
||||||
destination: Cesium.Cartesian3.clone(sc.newPos),
|
destination: Cesium.Cartesian3.clone(sc.newPos),
|
||||||
orientation: {
|
orientation: {
|
||||||
direction: Cesium.Cartesian3.clone(sc.dir),
|
direction: Cesium.Cartesian3.clone(dir),
|
||||||
up: Cesium.Cartesian3.clone(sc.upRot),
|
up: Cesium.Cartesian3.clone(sc.upProj),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user