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, geocoder: false }); 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 };