three 基础库
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.

899 lines
28 KiB

2 years ago
<!DOCTYPE html>
<!-- saved from url=(0037)http://three.zuoben.top/case-031.html -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Threejs实现数字化工厂安全生产监控</title>
<script src="./hm.js"></script><script type="text/javascript" src="./statistics(1).js"></script>
<!-- <script type="text/javascript" src="./steak(1).js"></script> -->
<script type="text/javascript" src="./three.js"></script>
<script type="text/javascript" src="./OrbitControls.js"></script>
<script type="text/javascript" src="./GLTFLoader.js"></script>
<script type="text/javascript" src="./ThreeBSP.js"></script>
<script type="text/javascript" src="./dat.gui.js"></script><style type="text/css">.dg {
/** Clear list styles */
/* Auto-place container */
/* Auto-placed GUI's */
/* Line items that don't contain folders. */
/** Folder names */
/** Hides closed items */
/** Controller row */
/** Name-half (left) */
/** Controller-half (right) */
/** Controller placement */
/** Shorter number boxes when slider is present. */
/** Ensure the entire boolean and function row shows a hand */ }
.dg ul {
list-style: none;
margin: 0;
padding: 0;
width: 100%;
clear: both; }
.dg.ac {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 0;
z-index: 0; }
.dg:not(.ac) .main {
/** Exclude mains in ac so that we don't hide close button */
overflow: hidden; }
.dg.main {
-webkit-transition: opacity 0.1s linear;
-o-transition: opacity 0.1s linear;
-moz-transition: opacity 0.1s linear;
transition: opacity 0.1s linear; }
.dg.main.taller-than-window {
overflow-y: auto; }
.dg.main.taller-than-window .close-button {
opacity: 1;
/* TODO, these are style notes */
margin-top: -1px;
border-top: 1px solid #2c2c2c; }
.dg.main ul.closed .close-button {
opacity: 1 !important; }
.dg.main:hover .close-button,
.dg.main .close-button.drag {
opacity: 1; }
.dg.main .close-button {
/*opacity: 0;*/
-webkit-transition: opacity 0.1s linear;
-o-transition: opacity 0.1s linear;
-moz-transition: opacity 0.1s linear;
transition: opacity 0.1s linear;
border: 0;
position: absolute;
line-height: 19px;
height: 20px;
/* TODO, these are style notes */
cursor: pointer;
text-align: center;
background-color: #000; }
.dg.main .close-button:hover {
background-color: #111; }
.dg.a {
float: right;
margin-right: 15px;
overflow-x: hidden; }
.dg.a.has-save > ul {
margin-top: 27px; }
.dg.a.has-save > ul.closed {
margin-top: 0; }
.dg.a .save-row {
position: fixed;
top: 0;
z-index: 1002; }
.dg li {
-webkit-transition: height 0.1s ease-out;
-o-transition: height 0.1s ease-out;
-moz-transition: height 0.1s ease-out;
transition: height 0.1s ease-out; }
.dg li:not(.folder) {
cursor: auto;
height: 27px;
line-height: 27px;
overflow: hidden;
padding: 0 4px 0 5px; }
.dg li.folder {
padding: 0;
border-left: 4px solid rgba(0, 0, 0, 0); }
.dg li.title {
cursor: pointer;
margin-left: -4px; }
.dg .closed li:not(.title),
.dg .closed ul li,
.dg .closed ul li > * {
height: 0;
overflow: hidden;
border: 0; }
.dg .cr {
clear: both;
padding-left: 3px;
height: 27px; }
.dg .property-name {
cursor: default;
float: left;
clear: left;
width: 40%;
overflow: hidden;
text-overflow: ellipsis; }
.dg .c {
float: left;
width: 60%; }
.dg .c input[type=text] {
border: 0;
margin-top: 4px;
padding: 3px;
width: 100%;
float: right; }
.dg .has-slider input[type=text] {
width: 30%;
/*display: none;*/
margin-left: 0; }
.dg .slider {
float: left;
width: 66%;
margin-left: -5px;
margin-right: 0;
height: 19px;
margin-top: 4px; }
.dg .slider-fg {
height: 100%; }
.dg .c input[type=checkbox] {
margin-top: 9px; }
.dg .c select {
margin-top: 5px; }
.dg .cr.function,
.dg .cr.function .property-name,
.dg .cr.function *,
.dg .cr.boolean,
.dg .cr.boolean * {
cursor: pointer; }
.dg .selector {
display: none;
position: absolute;
margin-left: -9px;
margin-top: 23px;
z-index: 10; }
.dg .c:hover .selector,
.dg .selector.drag {
display: block; }
.dg li.save-row {
padding: 0; }
.dg li.save-row .button {
display: inline-block;
padding: 0px 6px; }
.dg.dialogue {
background-color: #222;
width: 460px;
padding: 15px;
font-size: 13px;
line-height: 15px; }
/* TODO Separate style and structure */
#dg-new-constructor {
padding: 10px;
color: #222;
font-family: Monaco, monospace;
font-size: 10px;
border: 0;
resize: none;
box-shadow: inset 1px 1px 1px #888;
word-wrap: break-word;
margin: 12px 0;
display: block;
width: 440px;
overflow-y: scroll;
height: 100px;
position: relative; }
#dg-local-explain {
display: none;
font-size: 11px;
line-height: 17px;
border-radius: 3px;
background-color: #333;
padding: 8px;
margin-top: 10px; }
#dg-local-explain code {
font-size: 10px; }
#dat-gui-save-locally {
display: none; }
/** Main type */
.dg {
color: #eee;
font: 11px 'Lucida Grande', sans-serif;
text-shadow: 0 -1px 0 #111;
/** Auto place */
/* Controller row, <li> */
/** Controllers */ }
.dg.main {
/** Scrollbar */ }
.dg.main::-webkit-scrollbar {
width: 5px;
background: #1a1a1a; }
.dg.main::-webkit-scrollbar-corner {
height: 0;
display: none; }
.dg.main::-webkit-scrollbar-thumb {
border-radius: 5px;
background: #676767; }
.dg li:not(.folder) {
background: #1a1a1a;
border-bottom: 1px solid #2c2c2c; }
.dg li.save-row {
line-height: 25px;
background: #dad5cb;
border: 0; }
.dg li.save-row select {
margin-left: 5px;
width: 108px; }
.dg li.save-row .button {
margin-left: 5px;
margin-top: 1px;
border-radius: 2px;
font-size: 9px;
line-height: 7px;
padding: 4px 4px 5px 4px;
background: #c5bdad;
color: #fff;
text-shadow: 0 1px 0 #b0a58f;
box-shadow: 0 -1px 0 #b0a58f;
cursor: pointer; }
.dg li.save-row .button.gears {
background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;
height: 7px;
width: 8px; }
.dg li.save-row .button:hover {
background-color: #bab19e;
box-shadow: 0 -1px 0 #b0a58f; }
.dg li.folder {
border-bottom: 0; }
.dg li.title {
padding-left: 16px;
background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;
cursor: pointer;
border-bottom: 1px solid rgba(255, 255, 255, 0.2); }
.dg .closed li.title {
background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }
.dg .cr.boolean {
border-left: 3px solid #806787; }
.dg .cr.function {
border-left: 3px solid #e61d5f; }
.dg .cr.number {
border-left: 3px solid #2fa1d6; }
.dg .cr.number input[type=text] {
color: #2fa1d6; }
.dg .cr.string {
border-left: 3px solid #1ed36f; }
.dg .cr.string input[type=text] {
color: #1ed36f; }
.dg .cr.function:hover, .dg .cr.boolean:hover {
background: #111; }
.dg .c input[type=text] {
background: #303030;
outline: none; }
.dg .c input[type=text]:hover {
background: #3c3c3c; }
.dg .c input[type=text]:focus {
background: #494949;
color: #fff; }
.dg .c .slider {
background: #303030;
cursor: ew-resize; }
.dg .c .slider-fg {
background: #2fa1d6; }
.dg .c .slider:hover {
background: #3c3c3c; }
.dg .c .slider:hover .slider-fg {
background: #44abda; }
</style>
<script type="text/javascript" charset="UTF-8" src="./Tween.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="dom"><canvas width="1427" height="794" style="width: 1427px; height: 794px;"></canvas></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 = [
'assets/bgImage/skyBox6/posx.jpg',
'assets/bgImage/skyBox6/negx.jpg',
'assets/bgImage/skyBox6/posy.jpg',
'assets/bgImage/skyBox6/negy.jpg',
'assets/bgImage/skyBox6/posz.jpg',
'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('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("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('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("assets/textures/door_left.png")
});
doormaterial_left.opacity = 1.0;
doormaterial_left.transparent = true;
var doormaterial_right = new THREE.MeshPhongMaterial({
map: loader.load("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>