2025-07-03 17:39:09 +08:00
|
|
|
|
import * as THREE from "three";
|
|
|
|
|
//导入轨道控制器
|
|
|
|
|
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
|
|
|
|
|
//导入GLTF模型加载器
|
|
|
|
|
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
|
|
|
|
|
|
|
|
|
class viewGlb {
|
|
|
|
|
constructor(selector) {
|
|
|
|
|
this.canvasWidth = 900;
|
|
|
|
|
this.canvasHeight = 650;
|
|
|
|
|
this.container = document.querySelector(selector); //获取容器
|
|
|
|
|
this.modelInfo = {};
|
|
|
|
|
this.scene = null;
|
|
|
|
|
this.camera = null;
|
|
|
|
|
this.renderer = null;
|
|
|
|
|
this.controls = null;
|
|
|
|
|
this.init(); //初始化
|
|
|
|
|
this.animate(); //循环函数
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
init() {
|
|
|
|
|
// 初始化场景
|
|
|
|
|
this.initScene();
|
|
|
|
|
// 初始化辅助轴
|
|
|
|
|
this.initAxesHelper();
|
|
|
|
|
// 初始化灯光
|
|
|
|
|
this.initLight();
|
|
|
|
|
// 初始化相机
|
|
|
|
|
this.initCamera();
|
|
|
|
|
// 初始化渲染器
|
|
|
|
|
this.initRender();
|
|
|
|
|
// 初始化轨道控制器
|
|
|
|
|
this.initControls();
|
|
|
|
|
// 监听场景大小改变,重新渲染尺寸
|
|
|
|
|
window.addEventListener("resize", this.onWindowResize.bind(this));
|
|
|
|
|
// this.addGLTFModel()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initScene() {
|
|
|
|
|
this.scene = new THREE.Scene();
|
|
|
|
|
// this.scene.background = new THREE.Color(0xffffff)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initAxesHelper() {
|
|
|
|
|
const axesHelper = new THREE.AxesHelper(5);
|
|
|
|
|
this.scene.add(axesHelper);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initLight() {
|
|
|
|
|
const hesLight = new THREE.HemisphereLight(0xffffff, 0x444444);
|
|
|
|
|
hesLight.intensity = 0.6;
|
|
|
|
|
this.scene.add(hesLight);
|
|
|
|
|
|
|
|
|
|
const dirLight = new THREE.DirectionalLight();
|
|
|
|
|
dirLight.position.set(5, 5, 5);
|
|
|
|
|
this.scene.add(dirLight);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initCamera() {
|
|
|
|
|
this.camera = new THREE.PerspectiveCamera(
|
|
|
|
|
75,
|
|
|
|
|
this.canvasWidth / this.canvasHeight,
|
|
|
|
|
0.1,
|
|
|
|
|
100
|
|
|
|
|
);
|
|
|
|
|
// this.camera.position.set(1.5, 1.5, 1.5)
|
|
|
|
|
this.camera.position.set(2, 2, 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initRender() {
|
|
|
|
|
this.renderer = new THREE.WebGLRenderer({
|
|
|
|
|
antialias: true,
|
|
|
|
|
alpha: true,
|
|
|
|
|
// preserveDrawingBuffer: true
|
|
|
|
|
}); //设置抗锯齿
|
|
|
|
|
//设置屏幕像素比
|
|
|
|
|
this.renderer.setPixelRatio(window.devicePixelRatio);
|
|
|
|
|
//渲染的尺寸大小
|
|
|
|
|
this.renderer.setSize(this.canvasWidth, this.canvasHeight);
|
|
|
|
|
//gltf格式模型纹理贴图
|
|
|
|
|
this.renderer.outputEncoding = THREE.sRGBEncoding;
|
|
|
|
|
// 设置背景颜色
|
|
|
|
|
this.renderer.setClearColor(0x000000, 0);
|
|
|
|
|
// 添加到容器
|
|
|
|
|
this.container.appendChild(this.renderer.domElement);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
render() {
|
|
|
|
|
this.renderer.render(this.scene, this.camera);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
animate() {
|
|
|
|
|
this.renderer.setAnimationLoop(this.render.bind(this));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initControls() {
|
|
|
|
|
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onWindowResize() {
|
|
|
|
|
this.camera.aspect = this.canvasWidth / this.canvasHeight;
|
|
|
|
|
this.camera.updateProjectionMatrix(); //更新矩阵,将3d内容投射到2d画面上转换
|
|
|
|
|
this.renderer.setSize(this.canvasWidth, this.canvasHeight);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addGLTFModel(obj) {
|
|
|
|
|
this.modelInfo = obj;
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
const loader = new GLTFLoader(); //.setPath('3dModels/')
|
|
|
|
|
loader.load(obj.model_url, (gltf) => {
|
|
|
|
|
console.log(gltf);
|
|
|
|
|
this.scene.add(gltf.scene);
|
|
|
|
|
resolve("模型添加成功");
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
canvasToBase(cb) {
|
|
|
|
|
this.renderer.render(this.scene, this.camera);
|
|
|
|
|
let imgData = this.renderer.domElement.toDataURL("image/png");
|
|
|
|
|
console.log(imgData);
|
|
|
|
|
let base64 = imgData.replace(/^data:image\/\w+;base64,/, "");
|
|
|
|
|
let dataBuffer = new Buffer(base64, "base64");
|
|
|
|
|
base64ToFile(base64, "image/png", "poster.png");
|
|
|
|
|
console.log(process.cwd());
|
|
|
|
|
$root_home_index.$sendElectronChanel("newDir", {
|
|
|
|
|
name: this.modelInfo.model_name,
|
|
|
|
|
paths: [process.cwd(), "model_thumb"],
|
|
|
|
|
buffer: dataBuffer,
|
|
|
|
|
});
|
|
|
|
|
$root_home_index.$recvElectronChanel("newDirRes", (e, res) => {
|
|
|
|
|
// $root_home_index.$message.info(res)
|
|
|
|
|
cb(res);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/*;*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clearScene() {
|
|
|
|
|
this.scene.traverse((child) => {
|
|
|
|
|
if (child.material) {
|
|
|
|
|
child.material.dispose();
|
|
|
|
|
}
|
|
|
|
|
if (child.geometry) {
|
|
|
|
|
child.geometry.dispose();
|
|
|
|
|
}
|
|
|
|
|
child = null;
|
|
|
|
|
});
|
|
|
|
|
this.container.childNodes[1].remove();
|
|
|
|
|
this.renderer.forceContextLoss();
|
|
|
|
|
this.renderer.dispose();
|
|
|
|
|
this.scene.clear();
|
|
|
|
|
this.modelInfo = {};
|
|
|
|
|
this.scene = null;
|
|
|
|
|
this.camera = null;
|
|
|
|
|
this.controls = null;
|
|
|
|
|
this.renderer.domElement = null;
|
|
|
|
|
this.renderer = null;
|
|
|
|
|
this.container = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class viewGlbByEarth {
|
|
|
|
|
constructor(selector) {
|
|
|
|
|
this.viewer = null;
|
|
|
|
|
this.modelInfo = null;
|
|
|
|
|
this.selector = selector;
|
|
|
|
|
this.init(selector);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
init(selector) {
|
|
|
|
|
this.viewer = new Cesium.Viewer(selector, {
|
|
|
|
|
skyBox: false,
|
|
|
|
|
timeline: false,
|
|
|
|
|
navigationHelpButton: false,
|
|
|
|
|
homeButton: false,
|
|
|
|
|
baseLayerPicker: false,
|
|
|
|
|
sceneModePicker: false,
|
|
|
|
|
animation: false,
|
2025-09-02 10:01:05 +08:00
|
|
|
|
geocoder: false
|
2025-07-03 17:39:09 +08:00
|
|
|
|
});
|
|
|
|
|
const scene = this.viewer.scene;
|
|
|
|
|
/*this.viewer.scene.screenSpaceCameraController.tiltEventTypes = [
|
|
|
|
|
Cesium.CameraEventType.PINCH,
|
|
|
|
|
Cesium.CameraEventType.RIGHT_DRAG,
|
|
|
|
|
]*/
|
|
|
|
|
scene.screenSpaceCameraController.zoomEventTypes = [
|
|
|
|
|
Cesium.CameraEventType.WHEEL,
|
|
|
|
|
Cesium.CameraEventType.PINCH,
|
|
|
|
|
];
|
|
|
|
|
scene.screenSpaceCameraController.tiltEventTypes = [
|
|
|
|
|
Cesium.CameraEventType.PINCH,
|
|
|
|
|
Cesium.CameraEventType.RIGHT_DRAG,
|
|
|
|
|
];
|
|
|
|
|
this.viewer._cesiumWidget._creditContainer.style.display = "none";
|
|
|
|
|
scene.globe.depthTestAgainstTerrain = true;
|
|
|
|
|
// scene.globe.show = false;
|
|
|
|
|
// scene.sun.show = false;
|
|
|
|
|
// scene.moon.show = false;
|
|
|
|
|
// scene.skyBox.show = false;
|
|
|
|
|
// scene.fog.enabled = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addGltf(obj) {
|
|
|
|
|
this.modelInfo = obj;
|
|
|
|
|
|
|
|
|
|
const czml = [
|
|
|
|
|
{
|
|
|
|
|
id: "aircraft model",
|
|
|
|
|
name: "Cesium Air",
|
|
|
|
|
position: {
|
|
|
|
|
cartographicDegrees: [-77, 37, 10000],
|
|
|
|
|
},
|
|
|
|
|
model: {
|
|
|
|
|
gltf: obj.model_url,
|
|
|
|
|
scale: 2.0,
|
|
|
|
|
minimumPixelSize: 128,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
let entity = this.viewer.entities.add({
|
|
|
|
|
position: Cesium.Cartesian3.fromRadians(
|
|
|
|
|
106.31593773128115,
|
|
|
|
|
29.625102082951624
|
|
|
|
|
),
|
|
|
|
|
model: {
|
|
|
|
|
uri: obj.model_url,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.viewer.trackedEntity = entity;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
canvasToBase(cb) {
|
|
|
|
|
// let imgData = $(`#${this.selector}`).find("canvas")[0].toDataURL("image/png");
|
|
|
|
|
// console.log(imgData)
|
|
|
|
|
this.viewer.render();
|
|
|
|
|
let imgData = this.viewer.scene.canvas.toDataURL("image/png");
|
|
|
|
|
let base64 = imgData.replace(/^data:image\/\w+;base64,/, "");
|
|
|
|
|
let dataBuffer = new Buffer(base64, "base64");
|
|
|
|
|
let file = this.base64ToFile(base64, "image/png", "poster.png");
|
|
|
|
|
// console.log("ddddddddddddd", file);
|
|
|
|
|
cb(file);
|
|
|
|
|
// $root_home_index.$sendElectronChanel("newDir", {
|
|
|
|
|
// name: this.modelInfo.model_name, //+ "_" + new Date().getTime(),
|
|
|
|
|
// paths: [process.cwd(), "model_thumb"],
|
|
|
|
|
// buffer: dataBuffer,
|
|
|
|
|
// });
|
|
|
|
|
// $root_home_index.$recvElectronChanel("newDirRes", (e, res) => {
|
|
|
|
|
// // $root_home_index.$message.info(res)
|
|
|
|
|
// cb(res);
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
/*;*/
|
|
|
|
|
}
|
|
|
|
|
base64ToFile(base64, mime, filename) {
|
|
|
|
|
// let arr = base64.split(",");
|
|
|
|
|
let type = mime || arr[0].match(/:(.*?);/)[1];
|
|
|
|
|
// let suffix = mine.split("/")[1];
|
|
|
|
|
// let fileName = filename || `未命名.${suffix}`;
|
|
|
|
|
let fileName = filename || `未命名.png`;
|
|
|
|
|
let bstr = atob(base64);
|
|
|
|
|
let n = bstr.length;
|
|
|
|
|
let u8arr = new Uint8Array(n);
|
|
|
|
|
while (n--) {
|
|
|
|
|
u8arr[n] = bstr.charCodeAt(n);
|
|
|
|
|
}
|
|
|
|
|
return new File([u8arr], fileName, { type });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clearScene() {
|
|
|
|
|
this.viewer.destroy();
|
|
|
|
|
this.viewer = null;
|
|
|
|
|
this.modelInfo = null;
|
|
|
|
|
this.selector = "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export { viewGlb, viewGlbByEarth };
|