You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
622 lines
21 KiB
622 lines
21 KiB
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
<title>Threejs实现数字化工厂安全生产监控</title>
|
|
<meta charset="UTF-8">
|
|
<script type="text/javascript" src="lib/statistics.js"></script>
|
|
<!-- <script type="text/javascript" src="lib/steak.js"></script> -->
|
|
<script type="text/javascript" src="lib/three.js"></script>
|
|
<script type="text/javascript" src="lib/OrbitControls.js"></script>
|
|
<script type="text/javascript" src="lib/GLTFLoader.js"></script>
|
|
<script type="text/javascript" src="lib/ThreeBSP.js"></script>
|
|
<script type="text/javascript" src="lib/dat.gui.js"></script>
|
|
<script type="text/javascript" charset="UTF-8" src="lib/Tween.min.js"></script>
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div id="dom"></div>
|
|
<script type="text/javascript">
|
|
var camera;
|
|
var renderer;
|
|
var peopleMesh;
|
|
var peopleMixer;
|
|
var mixer;
|
|
var matArrayA = []; //内墙
|
|
var matArr = []; //外墙
|
|
var texture;
|
|
var textureSecure;
|
|
var curve;
|
|
|
|
function init() {
|
|
var urls = [
|
|
'http://zuoben.top/#3-8/assets/bgImage/skyBox6/posx.jpg',
|
|
'http://zuoben.top/#3-8/assets/bgImage/skyBox6/negx.jpg',
|
|
'http://zuoben.top/#3-8/assets/bgImage/skyBox6/posy.jpg',
|
|
'http://zuoben.top/#3-8/assets/bgImage/skyBox6/negy.jpg',
|
|
'http://zuoben.top/#3-8/assets/bgImage/skyBox6/posz.jpg',
|
|
'http://zuoben.top/#3-8/assets/bgImage/skyBox6/negz.jpg'
|
|
];
|
|
// 创建一个场景,它将包含我们所有的元素,如物体,相机和灯光。
|
|
var scene = new THREE.Scene();
|
|
var cubeLoader = new THREE.CubeTextureLoader();
|
|
// scene.background = cubeLoader.load(urls);
|
|
scene.opacity = 0;
|
|
|
|
// 创建一个摄像机,它定义了我们正在看的地方
|
|
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100000);
|
|
// 将摄像机对准场景的中心
|
|
camera.position.z = 2000;
|
|
camera.position.y = 800;
|
|
camera.lookAt(scene.position);
|
|
var orbit = new THREE.OrbitControls(camera);
|
|
|
|
// 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景
|
|
renderer = new THREE.WebGLRenderer({
|
|
antialias: true,
|
|
logarithmicDepthBuffer: true,
|
|
});
|
|
renderer.setClearColor(new THREE.Color("#0e0934"));
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
|
|
var ambientLight = new THREE.AmbientLight("#ffffff", 1);
|
|
scene.add(ambientLight);
|
|
|
|
// 将呈现器的输出添加到HTML元素
|
|
document.getElementById("dom").appendChild(renderer.domElement);
|
|
|
|
// 启动动画
|
|
renderScene();
|
|
initContent();
|
|
initSloganModel();
|
|
|
|
for (var i = 0; i < 8; i++) {
|
|
let px = 1060 - i * 300;
|
|
addArea(px, -400, 200, 500, scene, "库区1-" + (i + 1) + "号", "FF0000", 20, "居中");
|
|
}
|
|
for (var i = 0; i < 8; i++) {
|
|
let px = 1060 - i * 300;
|
|
if (i != 1 && i != 2 && i != 5 && i != 6) {
|
|
addArea(px, 400, 200, 500, scene, "库区2-" + (i + 1) + "号", "FF0000", 20, "居中");
|
|
}
|
|
}
|
|
initSecureModel();
|
|
|
|
// 初始化模型
|
|
function initContent() {
|
|
createFloor();
|
|
createWallMaterail();
|
|
var mat = new THREE.MeshPhongMaterial({
|
|
color: 0xafc0ca
|
|
});
|
|
createCubeWall(10, 200, 1400, 0, matArr, -1295, 100, 0, "墙面");
|
|
createCubeWall(10, 200, 1400, 1, matArr, 1295, 100, 0, "墙面");
|
|
createCubeWall(10, 200, 2600, 1.5, matArr, 0, 100, -700, "墙面");
|
|
//创建挖了门的墙
|
|
var wall = returnWallObject(2600, 200, 10, 0, mat, 0, 100, 700, "墙面");
|
|
var door_cube1 = returnWallObject(200, 180, 10, 0, mat, -600, 90, 700, "前门1");
|
|
var door_cube2 = returnWallObject(200, 180, 10, 0, mat, 600, 90, 700, "前门2");
|
|
var window_cube1 = returnWallObject(100, 100, 10, 0, mat, -900, 90, 700, "窗户1");
|
|
var window_cube2 = returnWallObject(100, 100, 10, 0, mat, 900, 90, 700, "窗户2");
|
|
var window_cube3 = returnWallObject(100, 100, 10, 0, mat, -200, 90, 700, "窗户3");
|
|
var window_cube4 = returnWallObject(100, 100, 10, 0, mat, 200, 90, 700, "窗户4");
|
|
var objects_cube = [];
|
|
objects_cube.push(door_cube1);
|
|
objects_cube.push(door_cube2);
|
|
objects_cube.push(window_cube1);
|
|
objects_cube.push(window_cube2);
|
|
objects_cube.push(window_cube3);
|
|
objects_cube.push(window_cube4);
|
|
createResultBsp(wall, objects_cube);
|
|
// 为墙面安装门
|
|
createDoor(100, 180, 2, 0, -700, 90, 700, "左门1");
|
|
createDoor(100, 180, 2, 0, -500, 90, 700, "右门1");
|
|
createDoor(100, 180, 2, 0, 500, 90, 700, "左门2");
|
|
createDoor(100, 180, 2, 0, 700, 90, 700, "右门2");
|
|
// 为墙面安装窗户
|
|
createWindow(100, 100, 2, 0, -900, 90, 700, "窗户");
|
|
createWindow(100, 100, 2, 0, 900, 90, 700, "窗户");
|
|
createWindow(100, 100, 2, 0, -200, 90, 700, "窗户");
|
|
createWindow(100, 100, 2, 0, 200, 90, 700, "窗户");
|
|
}
|
|
|
|
setTimeout(function () {
|
|
doorOpenColse(true);
|
|
}, 2000);
|
|
setTimeout(function () {
|
|
initPeople();
|
|
}, 2500);
|
|
|
|
// 添加人物模型
|
|
function initPeople() {
|
|
var loader = new THREE.GLTFLoader();
|
|
loader.load('http://zuoben.top/#3-8/assets/models/man/man.gltf', function (result) {
|
|
console.log(result)
|
|
result.scene.scale.set(50, 50, 50);
|
|
// result.scene.rotation.y = Math.PI / 2;
|
|
peopleMesh = result.scene;
|
|
scene.add(peopleMesh);
|
|
|
|
peopleMixer = new THREE.AnimationMixer(peopleMesh);
|
|
let AnimationAction = peopleMixer.clipAction(result.animations[0]);
|
|
AnimationAction.play();
|
|
|
|
motion()
|
|
});
|
|
}
|
|
|
|
function motion() {
|
|
// 通过类CatmullRomCurve3创建一个3D样条曲线
|
|
curve = new THREE.CatmullRomCurve3([
|
|
new THREE.Vector3(602, 3, 790),
|
|
new THREE.Vector3(597, 3, -3),
|
|
new THREE.Vector3(-605, 3, -3),
|
|
new THREE.Vector3(-602, 3, 790)
|
|
], false, "catmullrom", 0.01);
|
|
// 样条曲线均匀分割100分,返回51个顶点坐标
|
|
var points = curve.getPoints(100);
|
|
var geometry = new THREE.Geometry();
|
|
// 把从曲线轨迹上获得的顶点坐标赋值给几何体
|
|
geometry.vertices = points
|
|
var material = new THREE.LineBasicMaterial({
|
|
color: 0x4488ff
|
|
});
|
|
var line = new THREE.Line(geometry, material);
|
|
// scene.add(line)
|
|
|
|
// 通过Threejs的帧动画相关API播放网格模型沿着曲线做动画运动
|
|
// 声明一个数组用于存储时间序列
|
|
let arr = []
|
|
for (let i = 0; i < 101; i++) {
|
|
arr.push(i)
|
|
}
|
|
// 生成一个时间序列
|
|
var times = new Float32Array(arr);
|
|
|
|
var posArr = []
|
|
points.forEach(elem => {
|
|
posArr.push(elem.x, elem.y, elem.z)
|
|
});
|
|
// 创建一个和时间序列相对应的位置坐标系列
|
|
var values = new Float32Array(posArr);
|
|
// 创建一个帧动画的关键帧数据,曲线上的位置序列对应一个时间序列
|
|
var posTrack = new THREE.KeyframeTrack('.position', times, values);
|
|
let duration = 101;
|
|
let clip = new THREE.AnimationClip("default", duration, [posTrack]);
|
|
mixer = new THREE.AnimationMixer(peopleMesh);
|
|
let AnimationAction = mixer.clipAction(clip);
|
|
AnimationAction.play();
|
|
}
|
|
|
|
function changeLookAt(t) {
|
|
// 当前点在线条上的位置
|
|
var position = curve.getPointAt(t);
|
|
peopleMesh.position.copy(position);
|
|
if (position.z < 0) {
|
|
peopleMesh.rotation.y = Math.PI;
|
|
// camera.position.set(position.x + 200, 70, position.z);
|
|
}
|
|
if (position.z > 0 && position.x > 0) {
|
|
peopleMesh.rotation.y = Math.PI / 2;
|
|
// camera.position.set(position.x , 70, position.z+ 200);
|
|
}
|
|
if (position.z > 0 && position.x < 0) {
|
|
peopleMesh.rotation.y = -Math.PI / 2;
|
|
// camera.position.set(position.x , 70, position.z - 200);
|
|
}
|
|
// console.log(position)
|
|
// camera.position.set(position.x / 2, 69, position.z / 2);
|
|
camera.lookAt(position);
|
|
// camera.lookAt(position);659.0248303057256, y: 69.31162905236907, z: 921
|
|
|
|
|
|
// 返回一个点t在曲线上位置向量的法线向量
|
|
const tangent = curve.getTangentAt(t);
|
|
// 位置向量和切线向量相加即为所需朝向的点向量
|
|
const lookAtVec = tangent.add(position);
|
|
// peopleMesh.lookAt(lookAtVec);
|
|
}
|
|
|
|
//Secure 安全通道
|
|
function initSecureModel() {
|
|
var planGeometry = new THREE.PlaneGeometry(680, 40);
|
|
textureSecure = new THREE.TextureLoader().load('assets/textures/roll.png');
|
|
textureSecure.wrapS = THREE.RepeatWrapping
|
|
|
|
var tubeMaterial = new THREE.MeshBasicMaterial({
|
|
map: textureSecure,
|
|
transparent: true,
|
|
side: THREE.DoubleSide,
|
|
});
|
|
|
|
// 设置数组材质对象作为网格模型材质参数
|
|
var obj = new THREE.Mesh(planGeometry, tubeMaterial); //网格模型对象Mesh
|
|
obj.position.z = 350;
|
|
obj.position.y = 1.5;
|
|
obj.position.x = 599;
|
|
obj.rotateX(Math.PI / 2.0);
|
|
obj.rotateZ(Math.PI / 2.0);
|
|
var obj2 = obj.clone();
|
|
obj2.translateY(1200);
|
|
obj2.rotateZ(Math.PI);
|
|
|
|
var geometry2 = new THREE.PlaneGeometry(1230, 40);
|
|
var obj3 = new THREE.Mesh(geometry2, tubeMaterial);
|
|
obj3.position.set(0, 1.5, -10);
|
|
obj3.rotation.x = -Math.PI / 2.0;
|
|
|
|
var group = new THREE.Group();
|
|
group.add(obj);
|
|
group.add(obj2);
|
|
group.add(obj3);
|
|
scene.add(group);
|
|
}
|
|
|
|
//region 矩形区域
|
|
function addPlane(x, z, width, length, scene) {
|
|
var LineMat = new THREE.MeshLambertMaterial();
|
|
new THREE.TextureLoader().load("http://zuoben.top/#3-8/assets/textures/line.png", function (map) {
|
|
LineMat.map = map;
|
|
LineMat.needsUpdate = true;
|
|
});
|
|
var lineWidth = 8
|
|
var geometry = new THREE.PlaneGeometry(lineWidth, length);
|
|
var obj = new THREE.Mesh(geometry, LineMat);
|
|
obj.position.set(x, 1.5, z);
|
|
obj.rotation.x = -Math.PI / 2.0;
|
|
var obj2 = obj.clone();
|
|
obj2.translateX(width);
|
|
|
|
var geometry2 = new THREE.PlaneGeometry(lineWidth, width);
|
|
var obj3 = new THREE.Mesh(geometry2, LineMat);
|
|
obj3.position.set(x + width / 2, 1.5, z - length / 2 + lineWidth / 2);
|
|
obj3.rotation.x = -Math.PI / 2.0;
|
|
obj3.rotation.z = -Math.PI / 2.0;
|
|
var obj4 = obj3.clone();
|
|
obj4.translateX(length - lineWidth);
|
|
|
|
var group = new THREE.Group();
|
|
group.add(obj);
|
|
group.add(obj2);
|
|
group.add(obj3);
|
|
group.add(obj4);
|
|
group.translateX(-width / 2);
|
|
scene.add(group);
|
|
}
|
|
|
|
// 口号标语
|
|
function initSloganModel() {
|
|
var planGeometry = new THREE.PlaneGeometry(500, 35);
|
|
texture = new THREE.TextureLoader().load('assets/textures/biaoyu.png');
|
|
texture.wrapS = THREE.RepeatWrapping
|
|
|
|
var tubeMaterial = new THREE.MeshBasicMaterial({
|
|
map: texture,
|
|
transparent: true,
|
|
side: THREE.DoubleSide,
|
|
});
|
|
|
|
// 设置数组材质对象作为网格模型材质参数
|
|
var mesh = new THREE.Mesh(planGeometry, tubeMaterial); //网格模型对象Mesh
|
|
mesh.position.y = 175;
|
|
mesh.position.z = 710;
|
|
// mesh.rotateZ(3.14);
|
|
scene.add(mesh); //网格模型添加到场景中
|
|
}
|
|
|
|
//region 库区
|
|
/** 放置虚线框区域和库区名称 */
|
|
function addArea(x, z, width, length, scene, name, textColor, font_size, textposition) {
|
|
addPlane(x, z, width, length, scene);
|
|
|
|
new THREE.FontLoader().load('http://zuoben.top/#3-8/font/FZYaoTi_Regular.json', function (font) {
|
|
//加入立体文字
|
|
var text = new THREE.TextGeometry(name, {
|
|
// 设定文字字体
|
|
font: font,
|
|
//尺寸
|
|
size: font_size,
|
|
//厚度
|
|
height: 0.01
|
|
});
|
|
text.computeBoundingBox();
|
|
//3D文字材质
|
|
var m = new THREE.MeshStandardMaterial({
|
|
color: "#" + textColor
|
|
});
|
|
var mesh = new THREE.Mesh(text, m)
|
|
if (textposition == "左对齐") {
|
|
mesh.position.x = x - width / 2 + 10;
|
|
} else if (textposition == "居中") {
|
|
mesh.position.x = x - 65;
|
|
} else if (textposition == "右对齐") {
|
|
mesh.position.x = x + width / 2 - 60;
|
|
}
|
|
mesh.position.y = 1.3;
|
|
mesh.position.z = z + length / 2 - 20;
|
|
mesh.rotation.x = -Math.PI / 2.0;
|
|
scene.add(mesh);
|
|
});
|
|
}
|
|
|
|
//创建墙纹理
|
|
function createWallMaterail() {
|
|
matArr.push(new THREE.MeshPhongMaterial({
|
|
color: 0xafc0ca
|
|
})); //前 0xafc0ca :灰色
|
|
matArr.push(new THREE.MeshPhongMaterial({
|
|
color: 0x9cb2d1
|
|
})); //后 0x9cb2d1:淡紫
|
|
matArr.push(new THREE.MeshPhongMaterial({
|
|
color: 0xd6e4ec
|
|
})); //上 0xd6e4ec: 偏白色
|
|
matArr.push(new THREE.MeshPhongMaterial({
|
|
color: 0xd6e4ec
|
|
})); //下
|
|
matArr.push(new THREE.MeshPhongMaterial({
|
|
color: 0xafc0ca
|
|
})); //左 0xafc0ca :灰色
|
|
matArr.push(new THREE.MeshPhongMaterial({
|
|
color: 0xafc0ca
|
|
})); //右
|
|
}
|
|
|
|
//返回墙对象
|
|
function returnWallObject(width, height, depth, angle, material, x, y, z, name) {
|
|
var cubeGeometry = new THREE.BoxGeometry(width, height, depth);
|
|
var cube = new THREE.Mesh(cubeGeometry, material);
|
|
cube.position.x = x;
|
|
cube.position.y = y;
|
|
cube.position.z = z;
|
|
cube.rotation.y += angle * Math.PI;
|
|
cube.name = name;
|
|
return cube;
|
|
}
|
|
|
|
//墙上挖门,通过两个几何体生成BSP对象
|
|
function createResultBsp(bsp, objects_cube) {
|
|
var material = new THREE.MeshPhongMaterial({
|
|
color: 0x9cb2d1,
|
|
specular: 0x9cb2d1,
|
|
shininess: 30,
|
|
transparent: true,
|
|
opacity: 1
|
|
});
|
|
var BSP = new ThreeBSP(bsp);
|
|
for (var i = 0; i < objects_cube.length; i++) {
|
|
var less_bsp = new ThreeBSP(objects_cube[i]);
|
|
BSP = BSP.subtract(less_bsp);
|
|
}
|
|
var result = BSP.toMesh(material);
|
|
result.material.flatshading = THREE.FlatShading;
|
|
result.geometry.computeFaceNormals(); //重新计算几何体侧面法向量
|
|
result.geometry.computeVertexNormals();
|
|
result.material.needsUpdate = true; //更新纹理
|
|
result.geometry.buffersNeedUpdate = true;
|
|
result.geometry.uvsNeedUpdate = true;
|
|
scene.add(result);
|
|
}
|
|
|
|
//创建地板
|
|
function createFloor() {
|
|
var loader = new THREE.TextureLoader();
|
|
loader.load("assets/textures/floor.jpg", function (texture) {
|
|
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
|
|
texture.repeat.set(10, 10);
|
|
var floorGeometry = new THREE.BoxGeometry(2600, 1400, 1);
|
|
var floorMaterial = new THREE.MeshBasicMaterial({
|
|
map: texture,
|
|
});
|
|
var floor = new THREE.Mesh(floorGeometry, floorMaterial);
|
|
floor.rotation.x = -Math.PI / 2;
|
|
floor.name = "地面";
|
|
scene.add(floor);
|
|
});
|
|
}
|
|
|
|
//创建墙
|
|
function createCubeWall(width, height, depth, angle, material, x, y, z, name) {
|
|
var cubeGeometry = new THREE.BoxGeometry(width, height, depth);
|
|
var cube = new THREE.Mesh(cubeGeometry, material);
|
|
cube.position.x = x;
|
|
cube.position.y = y;
|
|
cube.position.z = z;
|
|
cube.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针
|
|
cube.name = name;
|
|
scene.add(cube);
|
|
}
|
|
|
|
//创建门
|
|
function createDoor(width, height, depth, angle, x, y, z, name) {
|
|
var loader = new THREE.TextureLoader();
|
|
|
|
var doorgeometry = new THREE.BoxGeometry(width, height, depth);
|
|
var doormaterial_left = new THREE.MeshPhongMaterial({
|
|
map: loader.load("http://zuoben.top/#3-8/assets/textures/door_left.png")
|
|
});
|
|
doormaterial_left.opacity = 1.0;
|
|
doormaterial_left.transparent = true;
|
|
var doormaterial_right = new THREE.MeshPhongMaterial({
|
|
map: loader.load("http://zuoben.top/#3-8/assets/textures/door_right.png")
|
|
});
|
|
doormaterial_right.opacity = 1.0;
|
|
doormaterial_right.transparent = true;
|
|
|
|
var doormaterialArr = [];
|
|
if (name.indexOf("左门") > -1) {
|
|
doorgeometry.translate(50, 0, 0);
|
|
doormaterialArr = [doormaterial_left, doormaterial_left, doormaterial_left,
|
|
doormaterial_left, doormaterial_left, doormaterial_right
|
|
];
|
|
} else {
|
|
doorgeometry.translate(-50, 0, 0);
|
|
doormaterialArr = [doormaterial_right, doormaterial_right, doormaterial_right,
|
|
doormaterial_right, doormaterial_right, doormaterial_left
|
|
];
|
|
}
|
|
|
|
var door = new THREE.Mesh(doorgeometry, doormaterialArr);
|
|
door.position.set(x, y, z);
|
|
door.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针
|
|
door.name = name;
|
|
scene.add(door);
|
|
}
|
|
|
|
//创建窗户
|
|
function createWindow(width, height, depth, angle, x, y, z, name) {
|
|
var loader = new THREE.TextureLoader();
|
|
loader.load("assets/textures/window.png", function (texture) {
|
|
var windowgeometry = new THREE.BoxGeometry(width, height, depth);
|
|
var windowmaterial = new THREE.MeshBasicMaterial({
|
|
map: texture,
|
|
color: 0xffffff
|
|
});
|
|
windowmaterial.opacity = 1.0;
|
|
windowmaterial.transparent = true;
|
|
var window = new THREE.Mesh(windowgeometry, windowmaterial);
|
|
window.position.set(x, y, z);
|
|
window.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针
|
|
window.name = name;
|
|
scene.add(window);
|
|
});
|
|
}
|
|
|
|
// 键盘事件
|
|
document.onkeydown = function (event) {
|
|
// 打开
|
|
if (event.keyCode == 79) {
|
|
doorOpenColse(true);
|
|
}
|
|
// 关闭
|
|
if (event.keyCode == 67) {
|
|
doorOpenColse(false);
|
|
}
|
|
}
|
|
|
|
// 门打开关闭
|
|
function doorOpenColse(bool) {
|
|
|
|
var l1 = scene.getObjectByName("左门1");
|
|
var l2 = scene.getObjectByName("左门2");
|
|
var r1 = scene.getObjectByName("右门1");
|
|
var r2 = scene.getObjectByName("右门2");
|
|
// 打开
|
|
if (bool) {
|
|
new TWEEN.Tween({
|
|
lv: 0,
|
|
rv: 0,
|
|
})
|
|
.to({
|
|
lv: -0.5 * Math.PI,
|
|
rv: 0.5 * Math.PI,
|
|
}, 1000)
|
|
.easing(TWEEN.Easing.Bounce.Out)
|
|
.onUpdate(function () {
|
|
l1.rotation.y = this.lv;
|
|
l2.rotation.y = this.lv;
|
|
r1.rotation.y = this.rv;
|
|
r2.rotation.y = this.rv;
|
|
})
|
|
.start();
|
|
}
|
|
// 关闭
|
|
if (!bool) {
|
|
new TWEEN.Tween({
|
|
lv: -0.5 * Math.PI,
|
|
rv: 0.5 * Math.PI,
|
|
})
|
|
.to({
|
|
lv: 0,
|
|
rv: 0,
|
|
}, 1000)
|
|
.easing(TWEEN.Easing.Bounce.Out)
|
|
.onUpdate(function () {
|
|
l1.rotation.y = this.lv;
|
|
l2.rotation.y = this.lv;
|
|
r1.rotation.y = this.rv;
|
|
r2.rotation.y = this.rv;
|
|
})
|
|
.start();
|
|
}
|
|
}
|
|
|
|
// 拾取对象
|
|
function pickupObjects(event) {
|
|
// 点击屏幕创建一个向量
|
|
var raycaster = new THREE.Raycaster();
|
|
var vector = new THREE.Vector2((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window
|
|
.innerHeight) * 2 + 1);
|
|
var fxl = new THREE.Vector3(0, 1, 0);
|
|
var groundplane = new THREE.Plane(fxl, 0);
|
|
raycaster.setFromCamera(vector, camera);
|
|
var ray = raycaster.ray;
|
|
let intersects = ray.intersectPlane(groundplane);
|
|
console.log(intersects)
|
|
|
|
|
|
// 点击屏幕创建一个向量
|
|
var vector1 = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window
|
|
.innerHeight) * 2 + 1, 0.5);
|
|
vector1 = vector1.unproject(camera); // 将屏幕的坐标转换成三维场景中的坐标
|
|
var raycaster = new THREE.Raycaster(camera.position, vector1.sub(camera.position).normalize());
|
|
var intersects1 = raycaster.intersectObjects(scene.children, true);
|
|
if (intersects1.length > 0) {
|
|
console.log(intersects1)
|
|
// intersects1[0].object.material.color.set("#ff0000");
|
|
}
|
|
}
|
|
document.addEventListener('click', pickupObjects, false); //监听单击拾取对象初始化球体
|
|
|
|
var clock = new THREE.Clock(); //声明一个时钟对象
|
|
const loopTime = 50 * 1000; // loopTime: 循环一圈的时间
|
|
function renderScene() {
|
|
orbit.update();
|
|
TWEEN.update();
|
|
// 使用requestAnimationFrame函数进行渲染
|
|
requestAnimationFrame(renderScene);
|
|
renderer.render(scene, camera);
|
|
// 更新帧动画的时间
|
|
if (mixer) {
|
|
// mixer.update(clock.getDelta());
|
|
}
|
|
if (peopleMixer) {
|
|
peopleMixer.update(clock.getDelta());
|
|
}
|
|
|
|
if (curve) {
|
|
let time = Date.now();
|
|
let t = (time % loopTime) / loopTime; // 计算当前时间进度百分比
|
|
changeLookAt(t);
|
|
}
|
|
|
|
if (textureSecure) {
|
|
texture.offset.x += 0.004;
|
|
textureSecure.offset.x += 0.0005;
|
|
}
|
|
// console.log(camera.position)
|
|
}
|
|
|
|
// 渲染的场景
|
|
renderer.render(scene, camera);
|
|
}
|
|
window.onload = init;
|
|
|
|
// 随着窗体的变化修改场景
|
|
function onResize() {
|
|
camera.aspect = window.innerWidth / window.innerHeight;
|
|
camera.updateProjectionMatrix();
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
}
|
|
// 监听窗体调整大小事件
|
|
window.addEventListener('resize', onResize, false);
|
|
</script>
|
|
</body>
|
|
|
|
</html>
|
|
|