import { drawAxis, drawAxis2D } from './drawHistory.js'; let renderer, scene, camera, controls, renderer2D, scene2D, camera2D, controls2D; let axis = new THREE.Group(); let axis2D = new THREE.Group(); let initAxis = 80;//正值最大值 let minNum = 0;//负值最大值 let planes = [];//截断面 let maxRange = 100; const lut = new THREE.Lut(); lut.addColorMap('axis', [[0.0, 0x00ee00], [0.25, 0xeeee00], [0.75, 0xee0000], [1.0, 0x4e0211]],); lut.setColorMap('axis', 500) let meshList = new THREE.Group();//图例柱子 meshList.name = 'chartsMesh'; const dummy = new THREE.Object3D(); let pointsList = new THREE.Group();//图例散点 pointsList.name = 'chartsPoint'; // 周期,相位 柱子数 let period = 50, phase = 128, count = period * phase; const geometry = new THREE.BoxGeometry(0.6, 1, 2.5); geometry.computeVertexNormals(); //非光泽表面的材质,没有镜面高光 //const initInstancedMesh = new THREE.InstancedMesh(geometry, new THREE.MeshLambertMaterial(), count); //最佳性能材质 const initInstancedMesh = new THREE.InstancedMesh(geometry, new THREE.MeshBasicMaterial(), count); initInstancedMesh.name = 'initInstancedMesh'; /* prpd初始Instanced点 */ let initInstancedPoints,//prpd实例 pointPositions, pointColors,//PRPS位置及颜色的集合 pointsGeometry = new THREE.BufferGeometry(), pointCount; init(); init2D(); render(); render2D(); onWindowResize() //prps or prpd 切换 $('#prps').click(function () { $('#box3D1').toggle(); $('#box2D1').toggle(); $(this).toggleClass('ready') $('#prpd').toggleClass('ready') }) $('#prpd').click(function () { $('#box2D1').toggle(); $('#box3D1').toggle(); $(this).toggleClass('ready') $('#prps').toggleClass('ready') }) $(window).resize(function () { window.requestAnimationFrame(function () { onWindowResize() }) }) //prps初始化 function init() { let box = $('#box3D1'); let width = box.width(); let height = box.height(); renderer = new THREE.WebGLRenderer({ logarithmicDepthBuffer: true, antialias: true, preserveDrawingBuffer: true, });//preserveDrawingBuffer保存three.js canvas画布上的信息 renderer.localClippingEnabled = true let constant = (360 / (initAxis)) * initAxis + 1 planes = [ new THREE.Plane(new THREE.Vector3(0, -1, 0), constant), //y轴正值截取 ] renderer.clippingPlanes = planes renderer.setSize(width, height);//设置渲染区域尺寸 renderer.setClearColor(0xffffff, 1); //设置背景颜色 //renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色 renderer.setPixelRatio(window.devicePixelRatio)//设备像素比,优化渲染效果 box?.append(renderer.domElement); //body元素中插入canvas对象 scene = new THREE.Scene(); scene.add(meshList, axis, pointsList); /* var point = new THREE.PointLight(0xffffff); point.position.set(600, 600, 600); //点光源位置 scene.add(point); //点光源添加到场景中 var ambient = new THREE.AmbientLight(0x444444); scene.add(ambient); */ drawAxis(initAxis, minNum, true) var k = width / height; //窗口宽高比 var s = 420; //三维场景显示范围控制系数,系数越大,显示的范围越大 //创建相机对象 camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1600); camera.position.set(500, 200, 500); //设置相机位置 camera.lookAt(scene.position); //设置相机方向(指向的场景对象) controls = new THREE.OrbitControls(camera, renderer.domElement); // 设置左右方向的最大、最小角度限制为 90 度和 0 度 controls.minAzimuthAngle = 0; controls.maxAzimuthAngle = Math.PI / 2; // 设置上下方向的最大、最小角度限制为 90 度和 0 度 controls.minPolarAngle = 0; controls.maxPolarAngle = Math.PI / 2; //设置放大缩小上下限 controls.minZoom = 0.5; controls.maxZoom = 2; //controls.enablePan = false; //设置控制器中心点 controls.target.set(25, 0, 180); renderer.render(scene, camera); //controls.addEventListener('change', render); } //prpd初始化 function init2D() { let box = $('#box2D1'); let width = box.width(); let height = box.height(); renderer2D = new THREE.WebGLRenderer({ logarithmicDepthBuffer: true, antialias: true, preserveDrawingBuffer: true, });//preserveDrawingBuffer保存three.js canvas画布上的信息\ renderer2D.localClippingEnabled = true let constant = (360 / (initAxis)) * initAxis + 1 planes = [ new THREE.Plane(new THREE.Vector3(0, -1, 0), constant), //y轴正值截取 ] renderer2D.clippingPlanes = planes renderer2D.setSize(width, height);//设置渲染区域尺寸 renderer2D.setClearColor(0xffffff, 1); //设置背景颜色 renderer2D.setPixelRatio(window.devicePixelRatio)//设备像素比,优化渲染效果 box?.append(renderer2D.domElement); //body元素中插入canvas对象 scene2D = new THREE.Scene(); const List = pointsList.clone() scene2D.add(axis2D, List, pointsList) drawAxis2D(initAxis, minNum) // 辅助坐标系 参数250表示坐标系大小,可以根据场景大小去设置 // let axisHelper = new THREE.AxesHelper(250); // scene2D.add(axisHelper); var k = width / height; //窗口宽高比 var s = 380; //三维场景显示范围控制系数,系数越大,显示的范围越大 //创建相机对象 camera2D = new THREE.OrthographicCamera(-s * k - 200, s * k - 200, s + 160, -s + 160, 1, 1200); camera2D.position.set(600, 0, 0); //设置相机位置 camera2D.lookAt(scene2D.position); //设置相机方向(指向的场景对象) controls2D = new THREE.OrbitControls(camera2D, renderer2D.domElement); controls2D.enablePan = false//右键位移禁用 controls2D.enableZoom = false//放大缩小禁用 //设置放大缩小上下限 controls2D.minZoom = 0.5; controls2D.maxZoom = 2; controls2D.enableRotate = false renderer2D.render(scene2D, camera2D); controls2D.addEventListener('change', render2D); } function onWindowResize() { let h = $(window).height(); let w = $(window).width(); $(".loading-box").css('height', h * 0.95) let box = $('#box3D1'); let width = box.width(); let height = box.height(); let k = width / height; //窗口宽高比 let s = 350; //三维场景显示范围控制系数,系数越大,显示的范围越大 camera.left = -s * k - 20; camera.right = s * k - 20; camera.top = s + (minNum ? -80 : 60); camera.bottom = -s + (minNum ? -80 : 60); camera.aspect = k; camera.updateProjectionMatrix(); renderer.setSize(width, height); renderer.setPixelRatio(window.devicePixelRatio)//设备像素比,优化渲染效果 let s2D = 270; camera2D.left = -s2D * k - 200; camera2D.right = s2D * k - 200; camera2D.top = s2D + (minNum ? -30 : 155); camera2D.bottom = -s2D + (minNum ? -30 : 155); camera2D.aspect = k; camera2D.updateProjectionMatrix(); renderer2D.setSize(width, height); renderer2D.setPixelRatio(window.devicePixelRatio)//设备像素比,优化渲染效果 } function render() { // 获取摄像机的视锥体 const frustum = new THREE.Frustum(); const cameraViewProjectionMatrix = new THREE.Matrix4(); camera.updateMatrixWorld(); // 确保摄像机的世界矩阵已更新 cameraViewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); frustum.setFromProjectionMatrix(cameraViewProjectionMatrix); // 遍历场景中的每个对象,并根据视锥体进行剔除 scene.traverse((object) => { if (object.isMesh) { object.visible = frustum.intersectsObject(object); } }); // 更新帧率显示器 //stats.update(); renderer.render(scene, camera); requestAnimationFrame(render) } function render2D() { //scene.rotateY(0.001);//每次绕y轴旋转0.01弧度 requestAnimationFrame(render2D) renderer2D.render(scene2D, camera2D); } export { scene, axis, meshList, pointsList, axis2D, scene2D }