Files
4.0/src/renderer/components/three/viewGlb.js

281 lines
7.6 KiB
JavaScript
Raw Normal View History

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