feat(All):Initial

This commit is contained in:
2025-10-04 23:36:07 +08:00
commit 2b4e5d2668
1321 changed files with 415958 additions and 0 deletions
+130
View File
@@ -0,0 +1,130 @@
import {MathUtils, OrthographicCamera, PerspectiveCamera, Scene, WebGLRenderer,Object3D} from "three";
import Viewer from "@/core/viewer/Viewer";
interface IMiniMapOptions {
mapSize: number, // 决定了摄像机看到的内容大小, mapSize * mapSize 大小内容
mapRenderSize: number, // 决定了小地图2D平面的大小
followTarget:Object3D, // 小地图画面主要跟随对象
isShow: boolean // 是否显示小地图
}
class MiniMap {
_miniMapCamera: OrthographicCamera | PerspectiveCamera | null = null;
_miniMapRenderer: WebGLRenderer | null = null;
_followTarget: Object3D;
private scene: Scene;
private sceneHelpers: Scene;
private mapRenderSize: number;
// @ts-ignore
public dom: HTMLDivElement;
isShow: boolean = false;
constructor(viewer:Viewer, options:IMiniMapOptions) {
this.scene = viewer.scene;
this.sceneHelpers = viewer.sceneHelpers;
this.mapRenderSize = options.mapRenderSize;
this._followTarget = options.followTarget;
this.isShow = options.isShow;
if (!this.scene) {
throw new Error("scene不能为空");
}
if (!this._followTarget) {
throw new Error("target不能为空,表示小地图画面主要跟随对象");
}
this.dom = this.createDomElement();
viewer.container.appendChild(this.dom);
// 初始化小地图相机
this._miniMapCamera = new OrthographicCamera(
-options.mapSize / 2,
options.mapSize / 2,
options.mapSize / 2,
-options.mapSize / 2,
1, 100 * 1000
);
// 更新地图相机位置和朝向
this.updateCamera();
}
createDomElement() {
// 初始化小地图渲染器
const mapRenderer = new WebGLRenderer({alpha: true});
mapRenderer.setSize(this.mapRenderSize, this.mapRenderSize);
// mapRenderer.setClearColor(0x7d684f);
mapRenderer.shadowMap.enabled = false;
mapRenderer.autoClear = false;
this._miniMapRenderer = mapRenderer;
const pDiv = document.createElement("div");
pDiv.id = "es-3d-mini-map";
pDiv.style.position = "absolute";
pDiv.style.right = "10px";
pDiv.style.top = "10px";
pDiv.style.zIndex = "1001";
pDiv.style.border = "1px solid #FFF";
pDiv.style.background = "rgba(0, 0, 0, 0.40)";
pDiv.style.width = this.mapRenderSize - 100 + "px";
pDiv.style.height = this.mapRenderSize - 100 + "px";
pDiv.style.overflow = "hidden";
pDiv.style.display = this.isShow ? "block" : "none";
mapRenderer.domElement.style.transform = `rotateZ(0deg)`;
mapRenderer.domElement.style.width = this.mapRenderSize + "px";
mapRenderer.domElement.style.height = this.mapRenderSize + "px";
mapRenderer.domElement.style.position = "absolute";
mapRenderer.domElement.style.left = "-50px";
mapRenderer.domElement.style.top = "-50px";
pDiv.appendChild(mapRenderer.domElement);
return pDiv;
}
open(){
this.dom.style.display = "block";
this.isShow = true;
}
close(){
this.dom.style.display = "none";
this.isShow = false;
}
updateCamera() {
// 更新小地图css旋转角度,与玩家同步
let targetRotateY = MathUtils.radToDeg(this._followTarget.rotation.y - Math.PI);
(this._miniMapRenderer as WebGLRenderer).domElement.style.transform = `rotateZ(${targetRotateY}deg)`;
// 更新地图相机位置和朝向
let targetPos = this._followTarget.position;
(this._miniMapCamera as OrthographicCamera).position.set(
targetPos.x,
targetPos.y + 10,
targetPos.z
);
(this._miniMapCamera as OrthographicCamera).lookAt(targetPos.x, 2, targetPos.z);
}
update() {
// 更新地图相机位置和朝向
this.updateCamera();
const renderer = this._miniMapRenderer as WebGLRenderer;
renderer.autoClear = false;
// 渲染小地图
renderer.render(this.scene, this._miniMapCamera as OrthographicCamera);
renderer.render(this.sceneHelpers, this._miniMapCamera as OrthographicCamera);
renderer.autoClear = true;
}
}
export {MiniMap}