You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
8.0 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 }