Files
4.0/src/renderer/components/three/viewGlb.js
2025-09-02 10:01:05 +08:00

281 lines
7.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 };