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

9 months ago
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 }