281 lines
7.6 KiB
JavaScript
281 lines
7.6 KiB
JavaScript
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 };
|