lxc
2 years ago
18 changed files with 2067 additions and 655 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,517 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
|
|||
<head includeDefault="true"> |
|||
|
|||
<script src="./lib/statistics.js"></script> |
|||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
|||
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> |
|||
<title>3D库图显示</title> |
|||
<style> |
|||
body { |
|||
margin: 0; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
#label { |
|||
position: absolute; |
|||
padding: 10px; |
|||
background: rgba(255, 255, 255, 0.6); |
|||
line-height: 1; |
|||
border-radius: 5px; |
|||
} |
|||
|
|||
#video { |
|||
position: absolute; |
|||
width: 0; |
|||
height: 0; |
|||
} |
|||
|
|||
</style> |
|||
<script src="./lib//three.js"></script> |
|||
<script src="./lib//stats.min.js"></script> |
|||
<script src="./lib//DragControls.js"></script> |
|||
<script src="./lib//OrbitControls.js"></script> |
|||
<script src="./lib//FirstPersonControls.js"></script> |
|||
<script src="./lib//TransformControls.js"></script> |
|||
<script src="./lib//dat.gui.min.js"></script> |
|||
<script src="./lib//EffectComposer.js"></script> |
|||
<script src="./lib//RenderPass.js"></script> |
|||
<script src="./lib//OutlinePass.js"></script> |
|||
<script src="./lib//FXAAShader.js"></script> |
|||
<script src="./lib//CopyShader.js"></script> |
|||
<script src="./lib//ShaderPass.js"></script> |
|||
<script src="./lib//ThreeBSP.js"></script> |
|||
<script src="./lib/ThreeJs_Drag.js" charset="UTF-8"></script> |
|||
<script src="./lib/ThreeJs_Composer.js" charset="UTF-8"></script> |
|||
<script src="./lib/Modules.js" charset="UTF-8"></script> |
|||
<script src="./lib//Tween.js"></script> |
|||
<script src="./lib//jquery-1.11.0.min.js"></script> |
|||
<script src="./lib/echarts.min.js"></script> |
|||
<script src="./lib/config.js"></script> |
|||
</head> |
|||
|
|||
<body> |
|||
<div id="label"></div> |
|||
<div id="container"></div> |
|||
<video id="video" autoplay loop muted> |
|||
<source src="./video/videoPlane.mp4"> |
|||
</video> |
|||
|
|||
<script> |
|||
|
|||
var stats = initStats(); |
|||
var scene, camera, renderer, controls, light, composer, transformControls, options; |
|||
var matArrayA = []; //内墙 |
|||
var matArrayB = []; //外墙 |
|||
var group = new THREE.Group(); |
|||
|
|||
// 初始化场景 |
|||
function initScene() { |
|||
scene = new THREE.Scene(); |
|||
} |
|||
|
|||
// 初始化相机 |
|||
function initCamera() { |
|||
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000); |
|||
camera.position.set(0, 50, 200); |
|||
} |
|||
|
|||
// 初始化灯光 |
|||
function initLight() { |
|||
var directionalLight = new THREE.DirectionalLight(0xffffff, 0.3); //模拟远处类似太阳的光源 |
|||
directionalLight.color.setHSL(0.1, 1, 0.95); |
|||
directionalLight.position.set(0, 200, 0).normalize(); |
|||
scene.add(directionalLight); |
|||
|
|||
var ambient = new THREE.AmbientLight(0xffffff, 1); //AmbientLight,影响整个场景的光源 |
|||
ambient.position.set(0, 0, 0); |
|||
scene.add(ambient); |
|||
} |
|||
|
|||
// 初始化性能插件 |
|||
function initStats() { |
|||
var stats = new Stats(); |
|||
|
|||
stats.domElement.style.position = 'absolute'; |
|||
stats.domElement.style.left = '0px'; |
|||
stats.domElement.style.top = '0px'; |
|||
|
|||
document.body.appendChild(stats.domElement); |
|||
return stats; |
|||
} |
|||
|
|||
// 初始化GUI |
|||
function initGui() { |
|||
options = new function () { |
|||
this.batchNo = ''; this.qty = 0; this.qtyUom = ''; this.qty2 = 0; |
|||
this.实时全景监控 = function () { |
|||
window.open("3DVideo.html"); |
|||
}; |
|||
}; |
|||
var gui = new dat.GUI(); |
|||
gui.domElement.style = 'position:absolute;top:10px;right:0px;height:600px'; |
|||
gui.add(options, 'batchNo').name("物料批号:").listen(); |
|||
gui.add(options, 'qty').name("数量:").listen(); |
|||
gui.add(options, 'qtyUom').name("单位:").listen(); |
|||
gui.add(options, 'qty2').name("件数:").listen(); |
|||
gui.add(options, '实时全景监控'); |
|||
} |
|||
|
|||
// 初始化渲染器 |
|||
function initRenderer() { |
|||
renderer = new THREE.WebGLRenderer({ |
|||
antialias: true |
|||
}); |
|||
renderer.setSize(window.innerWidth, window.innerHeight); |
|||
renderer.setClearColor(0x4682B4, 1.0); |
|||
document.body.appendChild(renderer.domElement); |
|||
} |
|||
|
|||
//创建地板 |
|||
function createFloor() { |
|||
var loader = new THREE.TextureLoader(); |
|||
loader.load("./ThreeJs/images/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_left(width, height, depth, angle, x, y, z, name) { |
|||
var loader = new THREE.TextureLoader(); |
|||
loader.load("./ThreeJs/images/door_left.png", function (texture) { |
|||
var doorgeometry = new THREE.BoxGeometry(width, height, depth); |
|||
doorgeometry.translate(50, 0, 0); |
|||
var doormaterial = new THREE.MeshBasicMaterial({ |
|||
map: texture, |
|||
color: 0xffffff |
|||
}); |
|||
doormaterial.opacity = 1.0; |
|||
doormaterial.transparent = true; |
|||
var door = new THREE.Mesh(doorgeometry, doormaterial); |
|||
door.position.set(x, y, z); |
|||
door.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针 |
|||
door.name = name; |
|||
scene.add(door); |
|||
}); |
|||
} |
|||
|
|||
//创建门_右侧 |
|||
function createDoor_right(width, height, depth, angle, x, y, z, name) { |
|||
var loader = new THREE.TextureLoader(); |
|||
loader.load("./ThreeJs/images/door_right.png", function (texture) { |
|||
var doorgeometry = new THREE.BoxGeometry(width, height, depth); |
|||
doorgeometry.translate(-50, 0, 0); |
|||
var doormaterial = new THREE.MeshBasicMaterial({ |
|||
map: texture, |
|||
color: 0xffffff |
|||
}); |
|||
doormaterial.opacity = 1.0; |
|||
doormaterial.transparent = true; |
|||
var door = new THREE.Mesh(doorgeometry, doormaterial); |
|||
door.position.set(x, y, z); |
|||
door.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针8 |
|||
door.name = name; |
|||
scene.add(door); |
|||
}); |
|||
} |
|||
|
|||
//创建窗户 |
|||
function createWindow(width, height, depth, angle, x, y, z, name) { |
|||
var loader = new THREE.TextureLoader(); |
|||
loader.load("./ThreeJs/images/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); |
|||
}); |
|||
} |
|||
|
|||
//返回墙对象 |
|||
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 createWallMaterail() { |
|||
matArrayA.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //前 0xafc0ca :灰色 |
|||
matArrayA.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //后 |
|||
matArrayA.push(new THREE.MeshPhongMaterial({ color: 0xd6e4ec })); //上 0xd6e4ec: 偏白色 |
|||
matArrayA.push(new THREE.MeshPhongMaterial({ color: 0xd6e4ec })); //下 |
|||
matArrayA.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //左 0xafc0ca :灰色 |
|||
matArrayA.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //右 |
|||
|
|||
matArrayB.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //前 0xafc0ca :灰色 |
|||
matArrayB.push(new THREE.MeshPhongMaterial({ color: 0x9cb2d1 })); //后 0x9cb2d1:淡紫 |
|||
matArrayB.push(new THREE.MeshPhongMaterial({ color: 0xd6e4ec })); //上 0xd6e4ec: 偏白色 |
|||
matArrayB.push(new THREE.MeshPhongMaterial({ color: 0xd6e4ec })); //下 |
|||
matArrayB.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //左 0xafc0ca :灰色 |
|||
matArrayB.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //右 |
|||
} |
|||
|
|||
|
|||
// 初始化模型 |
|||
function initContent() { |
|||
createFloor(); |
|||
createWallMaterail(); |
|||
createCubeWall(10, 200, 1400, 0, matArrayB, -1295, 100, 0, "墙面"); |
|||
createCubeWall(10, 200, 1400, 1, matArrayB, 1295, 100, 0, "墙面"); |
|||
createCubeWall(10, 200, 2600, 1.5, matArrayB, 0, 100, -700, "墙面"); |
|||
//创建挖了门的墙 |
|||
var wall = returnWallObject(2600, 200, 10, 0, matArrayB, 0, 100, 700, "墙面"); |
|||
var door_cube1 = returnWallObject(200, 180, 10, 0, matArrayB, -600, 90, 700, "前门1"); |
|||
var door_cube2 = returnWallObject(200, 180, 10, 0, matArrayB, 600, 90, 700, "前门2"); |
|||
var window_cube1 = returnWallObject(100, 100, 10, 0, matArrayB, -900, 90, 700, "窗户1"); |
|||
var window_cube2 = returnWallObject(100, 100, 10, 0, matArrayB, 900, 90, 700, "窗户2"); |
|||
var window_cube3 = returnWallObject(100, 100, 10, 0, matArrayB, -200, 90, 700, "窗户3"); |
|||
var window_cube4 = returnWallObject(100, 100, 10, 0, matArrayB, 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_left(100, 180, 2, 0, -700, 90, 700, "左门1"); |
|||
createDoor_right(100, 180, 2, 0, -500, 90, 700, "右门1"); |
|||
createDoor_left(100, 180, 2, 0, 500, 90, 700, "左门2"); |
|||
createDoor_right(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, "窗户"); |
|||
} |
|||
|
|||
// 初始化轨迹球控件 |
|||
function initControls() { |
|||
controls = new THREE.OrbitControls(camera, renderer.domElement); |
|||
controls.enableDamping = true; |
|||
controls.dampingFactor = 0.5; |
|||
// 视角最小距离 |
|||
controls.minDistance = 100; |
|||
// 视角最远距离 |
|||
controls.maxDistance = 1000; |
|||
// 最大角度 |
|||
controls.maxPolarAngle = Math.PI / 2.2; |
|||
controls.target = new THREE.Vector3(50, 50, 0); |
|||
} |
|||
|
|||
function initEcharts() { |
|||
pieChart = echarts.init($("<canvas width='512' height='512'></canvas>")[0]); |
|||
option = { |
|||
color: ['#3398DB'], |
|||
tooltip: { |
|||
trigger: 'axis', |
|||
axisPointer: { |
|||
type: 'shadow' |
|||
} |
|||
}, |
|||
grid: { |
|||
left: '3%', |
|||
right: '4%', |
|||
bottom: '3%', |
|||
containLabel: true |
|||
}, |
|||
xAxis: [ |
|||
{ |
|||
type: 'category', |
|||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], |
|||
axisTick: { |
|||
alignWithLabel: true |
|||
} |
|||
} |
|||
], |
|||
yAxis: [ |
|||
{ |
|||
type: 'value' |
|||
} |
|||
], |
|||
series: [ |
|||
{ |
|||
name: '直接访问', |
|||
type: 'bar', |
|||
barWidth: '60%', |
|||
data: [10, 52, 200, 334, 390, 330, 220] |
|||
} |
|||
] |
|||
}; |
|||
pieChart.setOption(option); |
|||
|
|||
pieChart.on('finished', function () { |
|||
var infoEchart = new THREE.TextureLoader().load(pieChart.getDataURL()); |
|||
|
|||
var infoEchartMaterial = new THREE.MeshBasicMaterial({ |
|||
transparent: true, |
|||
map: infoEchart, |
|||
side: THREE.DoubleSide |
|||
}); |
|||
|
|||
var echartPlane = new THREE.Mesh(new THREE.PlaneGeometry(100, 100), infoEchartMaterial); |
|||
echartPlane.position.set(100, 150, 0); |
|||
scene.add(echartPlane); |
|||
|
|||
}); |
|||
|
|||
pieChart2 = echarts.init($("<canvas width='512' height='512'></canvas>")[0]); |
|||
option2 = { |
|||
title: { |
|||
text: '某站点用户访问来源', |
|||
subtext: '纯属虚构', |
|||
x: 'center' |
|||
}, |
|||
tooltip: { |
|||
trigger: 'item', |
|||
formatter: "{a} <br/>{b} : {c} ({d}%)" |
|||
}, |
|||
legend: { |
|||
orient: 'vertical', |
|||
left: 'left', |
|||
data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎'] |
|||
}, |
|||
series: [ |
|||
{ |
|||
name: '访问来源', |
|||
type: 'pie', |
|||
radius: '55%', |
|||
center: ['50%', '60%'], |
|||
data: [ |
|||
{ value: 335, name: '直接访问' }, |
|||
{ value: 310, name: '邮件营销' }, |
|||
{ value: 234, name: '联盟广告' }, |
|||
{ value: 135, name: '视频广告' }, |
|||
{ value: 1548, name: '搜索引擎' } |
|||
], |
|||
itemStyle: { |
|||
emphasis: { |
|||
shadowBlur: 10, |
|||
shadowOffsetX: 0, |
|||
shadowColor: 'rgba(0, 0, 0, 0.5)' |
|||
} |
|||
} |
|||
} |
|||
] |
|||
}; |
|||
pieChart2.setOption(option2); |
|||
|
|||
pieChart2.on('finished', function () { |
|||
var spriteMap = new THREE.TextureLoader().load(pieChart2.getDataURL()); |
|||
|
|||
var spriteMaterial = new THREE.SpriteMaterial({ |
|||
transparent: true, |
|||
map: spriteMap, |
|||
side: THREE.DoubleSide |
|||
}); |
|||
|
|||
var sprite = new THREE.Sprite(spriteMaterial); |
|||
sprite.scale.set(150, 150, 1) |
|||
sprite.position.set(-100, 180, 0); |
|||
scene.add(sprite); |
|||
|
|||
}); |
|||
} |
|||
|
|||
// 初始化 |
|||
function init() { |
|||
initMat(); |
|||
initScene(); |
|||
addSkybox(10000, scene); |
|||
addVideoPlane(0, 60, -690, 200, 100, scene, 'video'); |
|||
initCamera(); |
|||
initRenderer(); |
|||
initContent(); |
|||
initLight(); |
|||
initControls(); |
|||
initGui(); |
|||
initEcharts(); |
|||
|
|||
addArea(0, 0, 1000, 500, scene, "ID1$库区1号", "FF0000", 20, "左对齐"); |
|||
|
|||
addShelf(scene); |
|||
|
|||
//添加货物 |
|||
var shelf_list = GET_SHELF_LIST(); |
|||
for (var i = 1; i <= GET_LAYER_NUM(); i++) { |
|||
for (var j = 1; j <= GET_COLUMN_NUM(); j++) { |
|||
for (var k = 1; k <= shelf_list.length; k++) { |
|||
addOneUnitCargos(shelf_list[k - 1].shelfId, i, j, scene); |
|||
} |
|||
} |
|||
} |
|||
|
|||
//添加选中时的蒙版 |
|||
composer = new THREE.ThreeJs_Composer(renderer, scene, camera, options); |
|||
|
|||
//添加拖动效果 |
|||
// 过滤不是 Mesh 的物体,例如辅助网格 |
|||
var objects = []; |
|||
for (var i = 0; i < scene.children.length; i++) { |
|||
var Msg = scene.children[i].name.split("$"); |
|||
if (scene.children[i].isMesh && Msg[0] == "货物") { |
|||
objects.push(scene.children[i]); |
|||
} |
|||
} |
|||
|
|||
var dragControls = new THREE.DragControls(objects, camera, renderer.domElement); |
|||
dragControls.addEventListener('dragstart', function (event) { |
|||
controls.enabled = false; |
|||
isPaused = true; |
|||
}); |
|||
dragControls.addEventListener('dragend', function (event) { |
|||
controls.enabled = true; |
|||
isPaused = false; |
|||
}); |
|||
|
|||
document.addEventListener('resize', onWindowResize, false); |
|||
} |
|||
|
|||
// 窗口变动触发的方法 |
|||
function onWindowResize() { |
|||
camera.aspect = window.innerWidth / window.innerHeight; |
|||
camera.updateProjectionMatrix(); |
|||
renderer.setSize(window.innerWidth, window.innerHeight); |
|||
} |
|||
|
|||
function animate() { |
|||
requestAnimationFrame(animate); |
|||
renderer.render(scene, camera); |
|||
composer.render(); |
|||
update(); |
|||
} |
|||
|
|||
// 更新控件 |
|||
function update() { |
|||
stats.update(); |
|||
controls.update(); |
|||
TWEEN.update(); |
|||
RollTexture.offset.x += 0.001; |
|||
} |
|||
|
|||
init(); |
|||
animate(); |
|||
</script> |
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,103 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> |
|||
<title>cesium 标点</title> |
|||
<script src="https://cesium.com/downloads/cesiumjs/releases/1.82/Build/Cesium/Cesium.js"></script> |
|||
<link href="https://cesium.com/downloads/cesiumjs/releases/1.82/Build/Cesium/Widgets/widgets.css" |
|||
rel="stylesheet"> |
|||
<style> |
|||
html, |
|||
body, |
|||
#cesiumContainer { |
|||
padding: 0; |
|||
margin: 0; |
|||
width: 100%; |
|||
height: 100% |
|||
} |
|||
|
|||
</style> |
|||
|
|||
<script src="./lib/statistics.js"></script> |
|||
</head> |
|||
|
|||
<body> |
|||
<div id="cesiumContainer"></div> |
|||
<script> |
|||
// cesium 秘钥 |
|||
Cesium.Ion.defaultAccessToken = |
|||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3YjQ1ZWVhYS03NjI2LTRjYTAtOTZhYy04OGY2YmQyZTU3N2IiLCJpZCI6MTA2NjYsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1NTcxMjcxODF9.Tn2oD9D3qxEBksEZ4L1cpHq1gVT6t4_GCI4G1USewkk'; |
|||
var viewer = new Cesium.Viewer("cesiumContainer", { |
|||
geocoder: false, //是否显示地名查找控件 |
|||
sceneModePicker: false, //是否显示投影方式控件 |
|||
navigationHelpButton: false, //是否显示帮助信息控件 |
|||
baseLayerPicker: false, //是否显示图层选择控件 |
|||
homeButton: false, //是否显示Home按钮 |
|||
fullscreenButton: false, //是否显示全屏按钮 |
|||
timeline: true, //时间轴控件 |
|||
animation: true, //动画控件 |
|||
terrainProvider: Cesium.createWorldTerrain(), |
|||
}); |
|||
|
|||
var scene = viewer.scene; |
|||
var clock = viewer.clock; |
|||
|
|||
var entity; |
|||
var positionProperty; |
|||
var dataSourcePromise = Cesium.CzmlDataSource.load( |
|||
"http://localhost:8080/Apps/SampleData/ClampToGround.czml" |
|||
); |
|||
viewer.dataSources.add(dataSourcePromise).then(function (dataSource) { |
|||
entity = dataSource.entities.getById("CesiumMilkTruck"); |
|||
positionProperty = entity.position; |
|||
}); |
|||
|
|||
var tileset = scene.primitives.add( |
|||
new Cesium.Cesium3DTileset({ |
|||
url: Cesium.IonResource.fromAssetId(40866), |
|||
}) |
|||
); |
|||
|
|||
viewer.camera.setView({ |
|||
destination: new Cesium.Cartesian3( |
|||
1216403.8845586285, |
|||
-4736357.493351395, |
|||
4081299.715698949 |
|||
), |
|||
orientation: new Cesium.HeadingPitchRoll( |
|||
4.2892217081808806, |
|||
-0.4799070147502502, |
|||
6.279789177843313 |
|||
), |
|||
endTransform: Cesium.Matrix4.IDENTITY, |
|||
}); |
|||
|
|||
if (scene.clampToHeightSupported) { |
|||
tileset.initialTilesLoaded.addEventListener(start); |
|||
} else { |
|||
window.alert("This browser does not support clampToHeight."); |
|||
} |
|||
|
|||
function start() { |
|||
clock.shouldAnimate = true; |
|||
var objectsToExclude = [entity]; |
|||
scene.postRender.addEventListener(function () { |
|||
var position = positionProperty.getValue(clock.currentTime); |
|||
entity.position = scene.clampToHeight(position, objectsToExclude); |
|||
}); |
|||
} |
|||
|
|||
var tileset = new Cesium.Cesium3DTileset({ |
|||
url: Cesium.IonResource.fromAssetId(40866), |
|||
}); |
|||
|
|||
viewer.scene.primitives.add(tileset); |
|||
viewer.zoomTo(tileset); |
|||
viewer.flyTo(tileset); |
|||
</script> |
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,436 @@ |
|||
|
|||
import { OrbitControls } from 'jsm/controls/OrbitControls.js'; |
|||
|
|||
|
|||
import { CSS3DRenderer, CSS3DObject, CSS3DSprite } from 'jsm/renderers/CSS3DRenderer.js'; |
|||
import css3dlabel from './units/css3dlabel.js' |
|||
|
|||
var APP = { |
|||
|
|||
Player: function () { |
|||
|
|||
|
|||
var controls, camera, glScene, cssScene, glRenderer, cssRenderer; |
|||
var waters = []; |
|||
//CSS 标签列表
|
|||
var BIG_LABEL_ARR = []; |
|||
//刷新函数列表
|
|||
var FUN_ARR = []; |
|||
|
|||
camera = new THREE.PerspectiveCamera( |
|||
45, |
|||
window.innerWidth / window.innerHeight, |
|||
1, |
|||
10000); |
|||
|
|||
camera.position.set(-0, 60, -60); |
|||
|
|||
glRenderer = createGlRenderer(); |
|||
cssRenderer = createCssRenderer(); |
|||
|
|||
controls = new OrbitControls(camera, glRenderer.domElement); |
|||
// controls = new OrbitControls(camera, glRenderer.domElement);
|
|||
document.body.appendChild(cssRenderer.domElement); |
|||
document.body.appendChild(glRenderer.domElement); |
|||
// glRenderer.domElement.appendChild(cssRenderer.domElement);
|
|||
|
|||
glScene = new THREE.Scene(); |
|||
cssScene = new THREE.Scene(); |
|||
|
|||
|
|||
// for (var i = 0; i < 20; i++) {
|
|||
// create3dPage(
|
|||
// 1020, 680,
|
|||
// new THREE.Vector3(-2 - i, 1 + i / 3, -4.2 + i),
|
|||
// new THREE.Vector3(0, Math.PI, 0),
|
|||
// 'https://zuoben.blog.csdn.net/');
|
|||
// }
|
|||
|
|||
// initModel();
|
|||
createLights(); |
|||
|
|||
window.camera = camera; |
|||
window.scene = glScene; |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
function createGlRenderer() { |
|||
var glRenderer = new THREE.WebGLRenderer({ |
|||
antialias: true, |
|||
alpha: true |
|||
}); |
|||
|
|||
glRenderer.setClearColor(0x34495E); |
|||
glRenderer.setPixelRatio(window.devicePixelRatio); |
|||
glRenderer.setSize(window.innerWidth, window.innerHeight); |
|||
|
|||
glRenderer.domElement.style.position = 'absolute'; |
|||
glRenderer.domElement.style.zIndex = 1; |
|||
glRenderer.domElement.style.top = 0; |
|||
|
|||
return glRenderer; |
|||
} |
|||
|
|||
function createCssRenderer() { |
|||
var cssRenderer = new CSS3DRenderer(); |
|||
cssRenderer.setSize(window.innerWidth, window.innerHeight); |
|||
cssRenderer.domElement.style.position = 'absolute'; |
|||
glRenderer.domElement.style.zIndex = 0; |
|||
cssRenderer.domElement.style.top = 0; |
|||
return cssRenderer; |
|||
} |
|||
|
|||
function initDraws(child) { } |
|||
|
|||
function initFrames(child) { |
|||
child.material = new THREE.MeshBasicMaterial({ |
|||
color: 0x7f5816, |
|||
}) |
|||
} |
|||
|
|||
function initStairs(child) { |
|||
child.material = new THREE.MeshStandardMaterial({ |
|||
color: 0xd1cdb7, |
|||
}) |
|||
child.material.roughness = 0.5 |
|||
child.material.metalness = 0.6 |
|||
} |
|||
|
|||
function initWalls(child) { |
|||
child.material = new THREE.MeshStandardMaterial({ |
|||
color: 0xffffff, |
|||
}) |
|||
child.material.roughness = 0.5 |
|||
child.material.metalness = 0.6 |
|||
} |
|||
|
|||
function create3dPage(w, h, position, rotation, url) { |
|||
var plane = createPlane( |
|||
w, h, |
|||
position, |
|||
rotation); |
|||
glScene.add(plane); |
|||
|
|||
var cssObject = createCssObject( |
|||
w, h, |
|||
position, |
|||
rotation, |
|||
url); |
|||
cssScene.add(cssObject); |
|||
} |
|||
|
|||
function createLights() { |
|||
var directionalLight = new THREE.DirectionalLight(0xffffff); |
|||
directionalLight.position.set(0, 100, -50).normalize(); |
|||
glScene.add(directionalLight); |
|||
|
|||
const light = new THREE.AmbientLight("#ffffff"); |
|||
glScene.add(light); |
|||
|
|||
const light1 = new THREE.PointLight(0xffffff, 1, 20) |
|||
light1.position.set(-0, 100, 100) |
|||
glScene.add(light1) |
|||
|
|||
const light2 = new THREE.PointLight(0xffffff, 1, 20) |
|||
light2.position.set(-100, 100, 100) |
|||
glScene.add(light2) |
|||
|
|||
const light3 = new THREE.PointLight(0xffffff, 1, 20) |
|||
light3.position.set(-12, 3, 6) |
|||
glScene.add(light3) |
|||
|
|||
const light4 = new THREE.PointLight(0xffffff, 1, 20) |
|||
light4.position.set(-12, 4, -4) |
|||
glScene.add(light4) |
|||
|
|||
const light5 = new THREE.PointLight(0xffffff,1, 20) |
|||
light5.position.set(12, 4, -8) |
|||
glScene.add(light5) |
|||
|
|||
const light6 = new THREE.PointLight(0xe0ffff, 0.1, 20) |
|||
light6.position.set(12, 4, 0) |
|||
glScene.add(light6) |
|||
|
|||
const light7 = new THREE.PointLight(0xe0ffff, 0.1, 20) |
|||
light7.position.set(12, 4, 8) |
|||
glScene.add(light7) |
|||
} |
|||
|
|||
this.setClearColor = function (color) { |
|||
glRenderer.setClearColor(color); |
|||
} |
|||
//position = { x: 0, y: 0, z: 0 }, rotation= { x: 0, y: 0, z: 0 }
|
|||
this.addModels = function (value) { |
|||
|
|||
glScene.add(value); |
|||
|
|||
}; |
|||
|
|||
|
|||
this.setCamera = function (value) { |
|||
|
|||
camera = value; |
|||
camera.aspect = this.width / this.height; |
|||
camera.updateProjectionMatrix(); |
|||
// this.camera = camera;
|
|||
window.camera = camera; |
|||
|
|||
}; |
|||
|
|||
this.setScene = function (value) { |
|||
|
|||
glScene = value; |
|||
window.scene = glScene |
|||
|
|||
}; |
|||
this.addWater = function (water) { |
|||
waters.push(water); |
|||
} |
|||
this.setPixelRatio = function (pixelRatio) { |
|||
|
|||
glRenderer.setPixelRatio(pixelRatio); |
|||
|
|||
}; |
|||
|
|||
this.setSize = function (width, height) { |
|||
|
|||
this.width = width; |
|||
this.height = height; |
|||
|
|||
if (camera) { |
|||
|
|||
camera.aspect = this.width / this.height; |
|||
camera.updateProjectionMatrix(); |
|||
|
|||
} |
|||
|
|||
glRenderer.setSize(this.width, this.height); |
|||
cssRenderer.setSize(this.width, this.height); |
|||
|
|||
}; |
|||
|
|||
|
|||
|
|||
var time, startTime, prevTime; |
|||
|
|||
|
|||
|
|||
function animate() { |
|||
|
|||
|
|||
// controls.update();
|
|||
|
|||
glRenderer.render(glScene, camera); |
|||
|
|||
cssRenderer.render(cssScene, camera); |
|||
waters.forEach(water => { |
|||
// 播放特效
|
|||
water.material.uniforms['time'].value += 1.0 / 60.0; |
|||
}); |
|||
FUN_ARR.forEach( fun=> { |
|||
// 播放特效
|
|||
fun(); |
|||
}); |
|||
|
|||
|
|||
|
|||
} |
|||
|
|||
var objects = [] |
|||
this.play = function () { |
|||
|
|||
|
|||
// if (renderer.xr.enabled) dom.append(vrButton);
|
|||
|
|||
// startTime = prevTime = performance.now();
|
|||
|
|||
// document.addEventListener('keydown', onKeyDown);
|
|||
// document.addEventListener('keyup', onKeyUp);
|
|||
// document.addEventListener('pointerdown', onPointerDown);
|
|||
// document.addEventListener('pointerup', onPointerUp);
|
|||
// document.addEventListener('pointermove', onPointerMove);
|
|||
|
|||
// dispatch(events.start, arguments);
|
|||
|
|||
glRenderer.setAnimationLoop(animate); |
|||
|
|||
// const image = document.createElement('img');
|
|||
// image.addEventListener('load', function () {
|
|||
|
|||
// for (let i = 0; i < 2; i++) {
|
|||
|
|||
// const object = new CSS3DSprite(image.cloneNode());
|
|||
// object.position.x = Math.random() * 4 - 2,
|
|||
// object.position.y = Math.random() * 4 - 2,
|
|||
// object.position.z = Math.random() * 4 - 2;
|
|||
// object.scale.set(0.01, 0.01, 0.01);
|
|||
// glScene.add(object);
|
|||
|
|||
// objects.push(object);
|
|||
|
|||
// }
|
|||
|
|||
// //transition();
|
|||
|
|||
// });
|
|||
// image.src = '/assets/textures/sprite.png';
|
|||
|
|||
// cssScene.add(createSpriteShape());
|
|||
// cssScene.add(createBox13DLabel());
|
|||
|
|||
|
|||
}; |
|||
|
|||
this.stop = function () { |
|||
|
|||
if (renderer.xr.enabled) vrButton.remove(); |
|||
|
|||
// document.removeEventListener('keydown', onKeyDown);
|
|||
// document.removeEventListener('keyup', onKeyUp);
|
|||
// document.removeEventListener('pointerdown', onPointerDown);
|
|||
// document.removeEventListener('pointerup', onPointerUp);
|
|||
// document.removeEventListener('pointermove', onPointerMove);
|
|||
|
|||
dispatch(events.stop, arguments); |
|||
|
|||
glRenderer.setAnimationLoop(null); |
|||
|
|||
|
|||
}; |
|||
|
|||
|
|||
this.dispose = function () { |
|||
|
|||
glRenderer.dispose(); |
|||
cssRenderer.dispose(); |
|||
|
|||
camera = undefined; |
|||
glScene = undefined; |
|||
cssScene = undefined; |
|||
|
|||
}; |
|||
|
|||
//
|
|||
this.create3dPage = function (w, h, position, rotation, url) { |
|||
|
|||
var plane = css3dlabel.createPlane( |
|||
w, h, |
|||
position, |
|||
rotation); |
|||
glScene.add(plane); |
|||
|
|||
var cssObject = css3dlabel.createCssObject( |
|||
w, h, |
|||
position, |
|||
rotation, |
|||
url); |
|||
cssScene.add(cssObject); |
|||
} |
|||
const defaultScale = 80 |
|||
this.create3dLabel = function (parent, text, w = 100, h = 20, position, rotation) { |
|||
|
|||
|
|||
// let sprite =createBox13DLabel()
|
|||
// glScene.add(sprite)
|
|||
// return ;
|
|||
let txtlength = text.length |
|||
|
|||
var width = defaultScale * txtlength; |
|||
var height = defaultScale + 15; |
|||
|
|||
var plane = css3dlabel.createPlane( |
|||
width, height, |
|||
position, |
|||
rotation); |
|||
|
|||
glScene.add(plane); |
|||
|
|||
var cssObject = css3dlabel.createCssLabel(text, |
|||
width, height, |
|||
position, |
|||
rotation); |
|||
// if(parent){
|
|||
// parent.add(cssObject);
|
|||
BIG_LABEL_ARR.push(cssObject); |
|||
// }else{
|
|||
cssScene.add(cssObject); |
|||
// }
|
|||
//cssObject.element.textContent = 'your data'
|
|||
} |
|||
// this.create3dButton = function (parent, text, w = 100, h = 20, position, rotation,click) {
|
|||
|
|||
// let txtlength = text.length
|
|||
|
|||
// var width = defaultScale * txtlength;
|
|||
// var height = defaultScale + 15;
|
|||
|
|||
// var plane = css3dlabel.createPlane(
|
|||
// width, height,
|
|||
// position,
|
|||
// rotation);
|
|||
|
|||
// glScene.add(plane);
|
|||
|
|||
// var cssObject = css3dlabel.createButton(text,
|
|||
// position,
|
|||
// rotation,click);
|
|||
// // if(parent){
|
|||
// // parent.add(cssObject);
|
|||
|
|||
// // }else{
|
|||
// cssScene.add(cssObject);
|
|||
// // }
|
|||
// }
|
|||
function createSpriteShape() { |
|||
/*1、创建一个画布,记得设置画布的宽高,否则将使用默认宽高,有可能会导致图像显示变形*/ |
|||
let canvas = document.createElement("canvas"); |
|||
canvas.width = 120; |
|||
canvas.height = 120; |
|||
/*2、创建图形,这部分可以去看w3c canvas教程*/ |
|||
let ctx = canvas.getContext("2d"); |
|||
ctx.fillStyle = "#ff0000"; |
|||
ctx.arc(50, 50, 50, 0, 2 * Math.PI); |
|||
ctx.fill(); |
|||
/*3、将canvas作为纹理,创建Sprite*/ |
|||
let texture = new THREE.Texture(canvas); |
|||
texture.needsUpdate = true; //注意这句不能少
|
|||
let material = new THREE.SpriteMaterial({ |
|||
color: 0xff00ff,//设置精灵矩形区域颜色
|
|||
rotation: Math.PI / 4,//旋转精灵对象45度,弧度值
|
|||
map: texture,//设置精灵纹理贴图
|
|||
}); |
|||
let mesh = new THREE.Sprite(material); |
|||
mesh.position.x = 2; |
|||
mesh.position.y = 2; |
|||
/*4、放大图片,每个精灵有自己的大小,默认情况下都是很小的,如果你不放大,基本是看不到的*/ |
|||
//mesh.scale.set(100,100,1);
|
|||
return mesh; |
|||
} |
|||
function createBox13DLabel() { |
|||
const div = document.createElement("div"); |
|||
div.className = "red-box-label"; |
|||
div.textContent = "红色正方体"; |
|||
// CSS3DSprite;CSS3DObject
|
|||
const earthLabel = new CSS3DSprite(div); |
|||
earthLabel.position.set(1, 0.2, 0.5); |
|||
earthLabel.scale.set(0.01, 0.01, 0.01); |
|||
return earthLabel; |
|||
} |
|||
this.updateLabel = function (name, text) { |
|||
BIG_LABEL_ARR.forEach(tmplable => { |
|||
tmplable.element.textContent = text; |
|||
}) |
|||
} |
|||
|
|||
this.addRefeshFunction = function(fun){ |
|||
FUN_ARR.push(fun); |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
}; |
|||
|
|||
export { APP }; |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,778 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<title></title> |
|||
<meta charset="utf-8"> |
|||
<meta name="generator" content="Three.js Editor"> |
|||
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> |
|||
<style> |
|||
body { |
|||
font-family: sans-serif; |
|||
font-size: 11px; |
|||
background-color: #000; |
|||
margin: 0px; |
|||
} |
|||
|
|||
canvas { |
|||
display: block; |
|||
} |
|||
|
|||
.info { |
|||
position: absolute; |
|||
top: 10px; |
|||
width: 100%; |
|||
text-align: center; |
|||
z-index: 100; |
|||
display: block; |
|||
color: brown; |
|||
font-size: 40px; |
|||
} |
|||
|
|||
.label { |
|||
color: #ff000f; |
|||
font-family: sans-serif; |
|||
padding: 40px; |
|||
background: rgba(149, 140, 140, 0.6); |
|||
} |
|||
|
|||
.btn { |
|||
color: #ff000f; |
|||
font-family: sans-serif; |
|||
padding: 20px; |
|||
background: rgba(149, 140, 140, 0.6); |
|||
} |
|||
|
|||
.label1 { |
|||
color: #ffffff; |
|||
font-family: sans-serif; |
|||
padding: 2px; |
|||
background: rgba(0, 0, 0, .6); |
|||
} |
|||
|
|||
.container { |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
</style> |
|||
<script type="importmap"> |
|||
{ |
|||
"imports": { |
|||
"three": "./libs/three/three.module.js", |
|||
"jsm/": "./libs/three/jsm/" |
|||
} |
|||
} |
|||
</script> |
|||
<script async src="./libs/layui/layui.js"></script> |
|||
<script async src="./libs/mqtt/mqtt.min.js"></script> |
|||
<script src="./libs/Modules.js" charset="UTF-8"></script> |
|||
<script src="./lib/Tween.js"></script> |
|||
<script src="./lib/jquery-1.11.0.min.js"></script> |
|||
<script src="./libs/echarts.min.js"></script> |
|||
</head> |
|||
|
|||
<body ontouchstart=""> |
|||
<div class="info">2D数据表格显示 不旋转 厌氧系统 <button onclick="btnclick()">全开</button></div> |
|||
|
|||
<!-- <video id="video" autoplay loop muted style="position: absolute;"> |
|||
<source src="./assets/video/videoPlane.mp4"> |
|||
</video> --> |
|||
|
|||
<script type="module"> |
|||
|
|||
import * as THREE from 'three'; |
|||
import { APP } from './js/appbig.js'; |
|||
|
|||
|
|||
import { OrbitControls } from 'jsm/controls/OrbitControls.js'; |
|||
import { GLTFLoader } from 'jsm/loaders/GLTFLoader.js'; |
|||
|
|||
import { CSS3DRenderer, CSS3DObject } from 'jsm/renderers/CSS3DRenderer.js'; |
|||
import { Water } from 'jsm/objects/Water.js'; |
|||
import modellabel from './js/units/modellabel.js' |
|||
import css2dlabel from './js/units/css3dlabel.js' |
|||
|
|||
import config from './js/config.js' |
|||
|
|||
|
|||
window.THREE = THREE; // Used by APP Scripts. |
|||
var mqttclient = null; |
|||
|
|||
|
|||
var player = new APP.Player(); |
|||
//水泵列表 |
|||
var PUMP_MODEL_ARR = [] |
|||
var bigLabelArr = [] |
|||
|
|||
|
|||
//红色标签 |
|||
// const labArr = [{ name: "水泵M_1", text: "水泵1" }, { name: "水泵M_2", text: "水泵002" } |
|||
// , { name: "水泵M_3", text: "水泵003" }, { name: "水泵M_4", text: "水泵4" }, { name: "水泵M_5", text: "水泵5" } |
|||
// , { name: "OilTank001", text: "PT桶1" }, { name: "OilTank002", text: "PT桶2" }, { name: "OilTank003", text: "PT桶3" }, |
|||
|
|||
// ] |
|||
const labArr = [{ name: "水泵M_1", text: "水泵M_1", position: { x: 2.86, y: -0.34, z: -3.13 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "水泵M_2", text: "水泵M_2", position: { x: 1.22, y: -0.59, z: -3.34 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "水泵M_3", text: "水泵M_3", position: { x: -0.60, y: -0.31, z: -3.26 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "水泵M_4", text: "水泵M_4", position: { x: -1.66, y: -0.62, z: -3.26 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "水泵M_5", text: "水泵M_51", position: { x: -2.55, y: -0.3, z: -3.36 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "OilTank001", text: "罐1", position: { x: 0.61, y: 2.44, z: 3.78 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "OilTank002", text: "罐2", position: { x: -0.57, y: 2.47, z: 3.78 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "OilTank003", text: "罐3", position: { x: 0.07, y: 2.58, z: 5.39 }, rotation: { x: 0, y: Math.PI, z: 0 } } |
|||
] |
|||
//模型标签 |
|||
const remarkLabArr = [{ name: "221", text: "USAB进水", x: 2.0501311208405713, y: -0.7778027560129786, z: -5.4, ry: 360 } |
|||
, { name: "211", text: "USAB进水", x: 0.1740166304621844, y: -0.7760432883855322, z: -5.4, ry: 360 }, |
|||
{ name: "491", text: "至污泥浓缩池", x: -2.105188770141037, y: -0.7901334936138524, z: -5.4, ry: 360 }] |
|||
//大标签 |
|||
const bigLabArr = [{ name: "建筑_11", text: "建筑_1", x: 0.10, y: 0.16, z: -1.48, rx: 0, ry: 360, rz: 0 }] |
|||
init(); |
|||
function init() { |
|||
|
|||
player.play(); |
|||
player.setSize(window.innerWidth, window.innerHeight); |
|||
window.addEventListener('resize', function () { |
|||
|
|||
player.setSize(window.innerWidth, window.innerHeight); |
|||
|
|||
}); |
|||
//设置背景颜色 |
|||
player.setClearColor(0x34495E); |
|||
|
|||
initModel1() |
|||
|
|||
addRemarkLabels(); |
|||
mqttInit(); |
|||
updateLabel(); |
|||
|
|||
// for (var i = 0; i < 1; i++) { |
|||
// player.create3dPage( |
|||
// 1020, 680, |
|||
// new THREE.Vector3(-2 - i, 2 + i / 3, -4.2 + i), |
|||
// new THREE.Vector3(0, Math.PI, 0), |
|||
// 'https://zuoben.blog.csdn.net/'); |
|||
// } |
|||
|
|||
|
|||
addLEDScreen(); |
|||
// let video = addVideoPlane(0, 8, 6, 200, 100, 'video'); |
|||
// video.scale.set(0.1, 0.1, 0.1); |
|||
// scene.add(video); |
|||
|
|||
// initEcharts() |
|||
createLights(); |
|||
} |
|||
|
|||
// document.body.appendChild(player.dom); |
|||
function initModel() { |
|||
var loader = new THREE.FileLoader(); |
|||
loader.load('uasb3.json', function (text) { |
|||
|
|||
let json = JSON.parse(text); |
|||
let objloader = new THREE.ObjectLoader(); |
|||
let scene1 = objloader.parse(json.scene) |
|||
|
|||
player.addModels(scene1);//.children[3]); |
|||
|
|||
setModel(scene1, player); |
|||
AddWaters(player); |
|||
// addRemarkLabels(); |
|||
|
|||
}); |
|||
} |
|||
function createLights() { |
|||
|
|||
|
|||
var directionalLight = new THREE.DirectionalLight(0xaaaaaa); |
|||
directionalLight.position.set(-15.5, 80.5, -50).normalize(); |
|||
scene.add(directionalLight); |
|||
directionalLight = new THREE.DirectionalLight(0xaaaaaa); |
|||
directionalLight.position.set(-50.5, 80.5, -50).normalize(); |
|||
scene.add(directionalLight); |
|||
|
|||
directionalLight = new THREE.DirectionalLight(0xffffff); |
|||
directionalLight.position.set(100.5, 30.5, -0).normalize(); |
|||
scene.add(directionalLight); |
|||
directionalLight = new THREE.DirectionalLight(0xaaaaaa); |
|||
directionalLight.position.set(0.5, 40.5, 100).normalize(); |
|||
scene.add(directionalLight); |
|||
|
|||
const light = new THREE.AmbientLight("0xffffff"); |
|||
scene.add(light); |
|||
|
|||
const light1 = new THREE.PointLight(0xffffff, 2, 100) |
|||
light1.position.set(-0, 50, 100) |
|||
scene.add(light1) |
|||
|
|||
light1 = new THREE.PointLight(0xffffff, 2, 100) |
|||
light1.position.set(-0, 80, -100) |
|||
scene.add(light1) |
|||
|
|||
|
|||
} |
|||
var pieChart, pieChart1, pieChart2, option, option2 |
|||
|
|||
function initEcharts() { |
|||
pieChart = echarts.init($("<canvas width='512' height='512'></canvas>")[0]); |
|||
option = { |
|||
color: ['#3398DB'], |
|||
tooltip: { |
|||
trigger: 'axis', |
|||
axisPointer: { |
|||
type: 'shadow' |
|||
} |
|||
}, |
|||
grid: { |
|||
left: '3%', |
|||
right: '4%', |
|||
bottom: '3%', |
|||
containLabel: true |
|||
}, |
|||
xAxis: [ |
|||
{ |
|||
type: 'category', |
|||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], |
|||
axisTick: { |
|||
alignWithLabel: true |
|||
} |
|||
} |
|||
], |
|||
yAxis: [ |
|||
{ |
|||
type: 'value' |
|||
} |
|||
], |
|||
series: [ |
|||
{ |
|||
name: '直接访问', |
|||
type: 'bar', |
|||
barWidth: '60%', |
|||
data: [10, 52, 200, 334, 390, 330, 220] |
|||
} |
|||
] |
|||
}; |
|||
pieChart.setOption(option); |
|||
|
|||
pieChart.on('finished', function () { |
|||
var infoEchart = new THREE.TextureLoader().load(pieChart.getDataURL()); |
|||
|
|||
var infoEchartMaterial = new THREE.MeshBasicMaterial({ |
|||
transparent: true, |
|||
map: infoEchart, |
|||
side: THREE.DoubleSide |
|||
}); |
|||
|
|||
var echartPlane = new THREE.Mesh(new THREE.PlaneGeometry(100, 100), infoEchartMaterial); |
|||
echartPlane.position.set(10, 8, 10); |
|||
echartPlane.scale.set(0.1, 0.1, 0.1); |
|||
scene.add(echartPlane); |
|||
|
|||
}); |
|||
|
|||
pieChart2 = echarts.init($("<canvas width='512' height='512'></canvas>")[0]); |
|||
option2 = { |
|||
title: { |
|||
text: '某站点用户访问来源', |
|||
subtext: '纯属虚构', |
|||
x: 'center' |
|||
}, |
|||
tooltip: { |
|||
trigger: 'item', |
|||
formatter: "{a} <br/>{b} : {c} ({d}%)" |
|||
}, |
|||
legend: { |
|||
orient: 'vertical', |
|||
left: 'left', |
|||
data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎'] |
|||
}, |
|||
series: [ |
|||
{ |
|||
name: '访问来源', |
|||
type: 'pie', |
|||
radius: '55%', |
|||
center: ['50%', '60%'], |
|||
data: [ |
|||
{ value: 335, name: '直接访问' }, |
|||
{ value: 310, name: '邮件营销' }, |
|||
{ value: 234, name: '联盟广告' }, |
|||
{ value: 135, name: '视频广告' }, |
|||
{ value: 1548, name: '搜索引擎' } |
|||
], |
|||
itemStyle: { |
|||
emphasis: { |
|||
shadowBlur: 10, |
|||
shadowOffsetX: 0, |
|||
shadowColor: 'rgba(0, 0, 0, 0.5)' |
|||
} |
|||
} |
|||
} |
|||
] |
|||
}; |
|||
pieChart2.setOption(option2); |
|||
|
|||
pieChart2.on('finished', function () { |
|||
var spriteMap = new THREE.TextureLoader().load(pieChart2.getDataURL()); |
|||
|
|||
var spriteMaterial = new THREE.SpriteMaterial({ |
|||
transparent: true, |
|||
map: spriteMap, |
|||
side: THREE.DoubleSide |
|||
}); |
|||
|
|||
var sprite = new THREE.Sprite(spriteMaterial); |
|||
sprite.scale.set(15, 15, 1) |
|||
sprite.position.set(-10, 8, 0); |
|||
scene.add(sprite); |
|||
|
|||
}); |
|||
} |
|||
function initModel1() { |
|||
var loader = new GLTFLoader(); |
|||
loader.load('assets/models/11.glb', function (gltf) { |
|||
// gltf.scene.traverse(function (child) { |
|||
// switch (child.name) { |
|||
// case 'walls': |
|||
// initWalls(child) |
|||
// break |
|||
// case 'stairs': |
|||
// initStairs(child) |
|||
// break |
|||
// } |
|||
|
|||
// //设置展画边框贴图 |
|||
// if (child.name.includes('paint')) { |
|||
// initFrames(child) |
|||
// } |
|||
// //设置展画图片贴图 |
|||
// if (child.name.includes('draw')) { |
|||
// initDraws(child) |
|||
// } |
|||
// }) |
|||
|
|||
let tmpmodel = gltf.scene//.children[1]; |
|||
|
|||
tmpmodel.rotation.set(0, Math.PI, -0.0) |
|||
tmpmodel.scale.set(0.001, 0.001, 0.001) |
|||
tmpmodel.position.set(-10, 0.001, 10) |
|||
player.addModels(tmpmodel); |
|||
setModel(tmpmodel, player); |
|||
|
|||
}); |
|||
} |
|||
var x = 0; |
|||
// 设置标签 |
|||
function setModel(scene, player) { |
|||
|
|||
|
|||
scene.castShadow = true; // 开启阴影 |
|||
scene.receiveShadow = true; // 接受阴影 |
|||
|
|||
scene.children.forEach((item, index) => { |
|||
console.log("x=", x, "--------item ==", index, "name=", item.name, "type=", item.type); |
|||
if (item.name.indexOf('OilTank00') > -1) { |
|||
addLabel(item, 0, 0.4, 0) |
|||
} |
|||
else if (item.name.indexOf('水泵M_') > -1) { // 水泵 |
|||
x = x + 1; |
|||
PUMP_MODEL_ARR.push(item); |
|||
//debugger |
|||
if (item.name === '水泵001') { |
|||
item.material.color.set(0x00f); |
|||
} else { |
|||
item.material.color.set(0x006600); |
|||
|
|||
} |
|||
addStateLabel(item, x / 2, 2 + x / 2, x / 2) |
|||
} |
|||
|
|||
if (item.type === 'Object3D' || item.type === 'Group') { // 有下一级 |
|||
|
|||
setModel(item, player); |
|||
} |
|||
|
|||
|
|||
|
|||
}) |
|||
console.log('pumpModelArr=', PUMP_MODEL_ARR) |
|||
} |
|||
|
|||
// 设置标签 |
|||
function setModel1(scene, player) { |
|||
|
|||
|
|||
// scene.castShadow = true; // 开启阴影 |
|||
// scene.receiveShadow = true; // 接受阴影 |
|||
|
|||
scene.children.forEach((item, index) => { |
|||
|
|||
|
|||
console.log("--------item ==", index, "name=", item.name, "type=", item.type); |
|||
|
|||
if (item.name.indexOf('OilTank00') > -1) { |
|||
addLabel(item, 0, 0.4, 0) |
|||
} |
|||
else if (item.name == "水泵001") { |
|||
item.material.color.set(0xff0); |
|||
} |
|||
else if (item.name == "水泵_2") { |
|||
item.material.color.set(0xff0000); |
|||
} |
|||
else if (item.name.indexOf('水泵M_') > -1 && item.type == "Mesh") { // 水泵 |
|||
pumpModelArr.push(item); |
|||
|
|||
|
|||
// } |
|||
if (item.name === '水泵M_1') { |
|||
item.material.color.set(0xff0000); |
|||
|
|||
} else { |
|||
item.material.color.set(0x006600); |
|||
} |
|||
|
|||
addStateLabel(item, 0, 3, 0) |
|||
} |
|||
|
|||
if (item.type === 'Object3D' || item.type === 'Group') { // 有下一级 |
|||
|
|||
setModel(item, player); |
|||
} |
|||
|
|||
|
|||
}) |
|||
console.log('pumpModelArr=', pumpModelArr) |
|||
} |
|||
|
|||
//添加这个就可以用鼠标拖动 |
|||
|
|||
var raycaster = new THREE.Raycaster() |
|||
var mouse = new THREE.Vector2() |
|||
//点击模型 |
|||
// window.addEventListener('click', onMouseClick); |
|||
window.addEventListener('dblclick', onDBMouseClick); |
|||
function onMouseClick(event) { |
|||
|
|||
//将鼠标点击位置的屏幕坐标转换成threejs中的标准坐标 |
|||
mouse.x = (event.clientX / window.innerWidth) * 2 - 1 |
|||
mouse.y = -((event.clientY / window.innerHeight) * 2 - 1) |
|||
//console.log("mouse:"+mouse.x+","+mouse.y) |
|||
|
|||
// 通过鼠标点的位置和当前相机的矩阵计算出raycaster |
|||
raycaster.setFromCamera(mouse, window.camera); |
|||
|
|||
// 获取raycaster直线和所有模型相交的数组集合 |
|||
var intersects = raycaster.intersectObjects(scene.children, true); |
|||
console.log(intersects); |
|||
//debugger |
|||
//将所有的相交的模型的颜色设置为红色 |
|||
for (var i = 0; i < intersects.length; i++) { |
|||
let obj = intersects[i]; |
|||
if (obj.object) { |
|||
|
|||
if (obj.object.name == "视频监控1") { |
|||
|
|||
obj.object.material.color.set(0xff6666); |
|||
alert("视频"); |
|||
} else { |
|||
obj.object.material.color.set(0xff0000); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
function onDBMouseClick(event) { |
|||
|
|||
//将鼠标点击位置的屏幕坐标转换成threejs中的标准坐标 |
|||
mouse.x = (event.clientX / window.innerWidth) * 2 - 1 |
|||
mouse.y = -((event.clientY / window.innerHeight) * 2 - 1) |
|||
//console.log("mouse:"+mouse.x+","+mouse.y) |
|||
|
|||
// 通过鼠标点的位置和当前相机的矩阵计算出raycaster |
|||
raycaster.setFromCamera(mouse, window.camera); |
|||
|
|||
// 获取raycaster直线和所有模型相交的数组集合 |
|||
// debugger |
|||
var intersects = raycaster.intersectObjects(scene.children, true); |
|||
console.log("onclick ", intersects); |
|||
|
|||
//debugger |
|||
//将所有的相交的模型的颜色设置为红色 |
|||
for (var i = 0; i < intersects.length; i++) { |
|||
let obj = intersects[i]; |
|||
if (obj.object) { |
|||
let tmpobj = obj.object; |
|||
console.log(tmpobj) |
|||
//输出 增加标签 位置 |
|||
console.log('{name:"' + tmpobj.name + '",text:"' + tmpobj.name + '",position:{x:' + obj.point.x.toFixed(2) + ',y:' + obj.point.y.toFixed(2) + ',z:' + obj.point.z.toFixed(2) + '},rotation:{x:0,y: Math.PI,z:0}}'); |
|||
// console.log('{name:"' + tmpobj.name + '1",text:"' + tmpobj.name + '",x:' + obj.point.x.toFixed(2) + ',y:' + obj.point.y.toFixed(2) + ',z:' + obj.point.z.toFixed(2) + ',rx:0,ry:0,rz:0}'); |
|||
if (tmpobj.name.indexOf('水泵') > -1) { // 水泵 |
|||
|
|||
openDialog(tmpobj) |
|||
//alert(tmpobj.name, "双击"); |
|||
} |
|||
break; |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
//添加 模型标签 |
|||
function addRemarkLabels() { |
|||
remarkLabArr.forEach((item, index) => { |
|||
|
|||
let labelMesh = modellabel.createRemarkLabel(item.text, item.x, item.y, item.z); |
|||
labelMesh.scale.set(0.005, 0.005, 0.005); |
|||
labelMesh.rotation.y = Math.PI * (item.ry / 360); |
|||
labelMesh.rotation.x = Math.PI * (30 / 360);; |
|||
// labelMesh.rotation.x= rz; |
|||
window.scene.add(labelMesh); |
|||
|
|||
}) |
|||
bigLabArr.forEach((item, index) => { |
|||
|
|||
let labelMesh = modellabel.createRemarkLabel(item.text, item.x, item.y, item.z); |
|||
labelMesh.scale.set(0.01, 0.01, 0.01); |
|||
labelMesh.rotation.y = Math.PI * (item.ry / 360); |
|||
// labelMesh.rotation.x = Math.PI * (30 / 360);; |
|||
// labelMesh.rotation.x= rz; |
|||
window.scene.add(labelMesh); |
|||
bigLabelArr.push(labelMesh); |
|||
|
|||
}) |
|||
} |
|||
|
|||
|
|||
|
|||
//通过 模型名称获取标签名称 |
|||
async function getlabel(name) { |
|||
let result; |
|||
labArr.forEach((item, index) => { |
|||
if (item.name === name) { |
|||
result = item; |
|||
return null; |
|||
} |
|||
}) |
|||
return result |
|||
} |
|||
//普通标签 |
|||
async function addLabel(parent, x = 0, y = 0, z = 0, className = 'label') { |
|||
|
|||
if (!parent.name) { |
|||
|
|||
return; |
|||
} |
|||
console.log("parent.name2=", parent.name) |
|||
let item = await getlabel(parent.name); |
|||
// debugger |
|||
if (item) { |
|||
|
|||
player.create3dLabel(parent, item.text, |
|||
1020, 680, |
|||
item.position, |
|||
item.rotation, |
|||
); |
|||
// player.create3dLabel(parent, item.text, |
|||
// 1020, 680, |
|||
// new THREE.Vector3(x, y, z), |
|||
// new THREE.Vector3(0, Math.PI, 0), |
|||
// ); |
|||
|
|||
} |
|||
} |
|||
|
|||
|
|||
//状态标签 |
|||
async function addStateLabel(parent, x = 0, y = 0, z = 0, className = 'label') { |
|||
|
|||
if (!parent.name) { |
|||
|
|||
return; |
|||
} |
|||
console.log("parent.name2=", parent.name) |
|||
let item = await getlabel(parent.name); |
|||
if (item) { |
|||
|
|||
|
|||
player.create3dLabel(parent, item.text, |
|||
1020, 680, |
|||
item.position, |
|||
item.rotation, |
|||
); |
|||
// player.create3dButton(parent, item.text, |
|||
// 1020, 680, |
|||
// new THREE.Vector3(x, y, z), |
|||
// new THREE.Vector3(0, Math.PI, 0), |
|||
// updateLabel() |
|||
// ); |
|||
} |
|||
|
|||
} |
|||
//添加动态水 |
|||
function AddWaters(player) { |
|||
let water1 = {} |
|||
water1.position = { x: 0, y: 1, z: 0 } |
|||
water1.scale = { x: 4, y: 2.6 } |
|||
AddWater(water1, player) |
|||
let water2 = {} |
|||
water2.position = { x: 0, y: 1, z: 5 } |
|||
water2.scale = { x: 7.5, y: 8 } |
|||
AddWater(water2, player) |
|||
} |
|||
function AddWater(water, player) { |
|||
|
|||
const waterGeometry = new THREE.PlaneGeometry(water.scale.x, water.scale.y); |
|||
|
|||
let waterobj = new Water( |
|||
waterGeometry, |
|||
{ |
|||
textureWidth: 255, |
|||
textureHeight: 255, |
|||
waterNormals: new THREE.TextureLoader().load('./assets/textures/waternormals.jpg', function (texture) { |
|||
|
|||
texture.wrapS = texture.wrapT = THREE.RepeatWrapping; |
|||
|
|||
}), |
|||
sunDirection: new THREE.Vector3(), |
|||
sunColor: 0xffffff, |
|||
waterColor: 0x3498DB, |
|||
distortionScale: 0.5,//波浪大小 |
|||
fog: true// scene.fog !== undefined |
|||
} |
|||
); |
|||
waterobj.position.set(water.position.x, water.position.y, water.position.z) |
|||
waterobj.rotation.x = - Math.PI / 2; |
|||
|
|||
scene.add(waterobj); |
|||
player.addWater(waterobj); |
|||
|
|||
} |
|||
//测试用 |
|||
let clickindex = false; |
|||
//全开全关 测试 |
|||
window.btnclick = function () { |
|||
|
|||
pumpModelArr.forEach((item, index) => { |
|||
if (clickindex) { |
|||
item.material.color.set(0x00ff00); |
|||
|
|||
} else { |
|||
item.material.color.set(0x666666); |
|||
|
|||
} |
|||
clickindex = !clickindex; |
|||
|
|||
}) |
|||
} |
|||
|
|||
function mqttInit() { |
|||
var that = this; |
|||
// 连接选项 |
|||
// |
|||
const options = { |
|||
connectTimeout: 4000, // 超时时间 |
|||
// 认证信息 |
|||
clientId: 'brower_' + parseInt(Math.random() / 31.1 * 10000000000), |
|||
username: config.mqttUserName, |
|||
password: config.mqttPassword, |
|||
} |
|||
mqttclient = mqtt.connect('ws://127.0.0.1:8083/mqtt', options); |
|||
mqttclient.on('reconnect', function (error) { |
|||
console.log("reconnect"); |
|||
}) |
|||
mqttclient.on('error', function (error) { |
|||
console.log('连接失败:', error) |
|||
}) |
|||
mqttclient.on('message', function (topic, message, s) { |
|||
console.log(topic, message.toString()); |
|||
if (message.toString() == '1') { |
|||
// if (that.lastTime + 2 * 1000 < new Date().getTime()) { |
|||
// that.lastTime = new Date().getTime(); |
|||
|
|||
// } |
|||
} |
|||
}) |
|||
mqttclient.subscribe("/scene/update/*", (err) => { |
|||
if (!err) { |
|||
console.log(`订阅/scene/update/* 成功`); |
|||
} |
|||
}); |
|||
mqttclient.subscribe("RTData", (err) => { |
|||
if (!err) { |
|||
console.log(`订阅 RTData 成功`); |
|||
} |
|||
}); |
|||
mqttclient.publish('/sys/update/scene', 'scene'); |
|||
} |
|||
//打开对话框 |
|||
function openDialog(tmpobj) { |
|||
layer.open({ |
|||
type: 1 |
|||
, offset: 1 //具体配置参考:http://doc/modules/layer.html#offset |
|||
, id: 'layerDemo' + 1 //防止重复弹出 |
|||
, content: '<div style="padding: 20px 100px;">' + tmpobj.name + '</div>' |
|||
, btn: '关闭' |
|||
, btnAlign: 'c' //按钮居中 |
|||
, shade: 0 //不显示遮罩 |
|||
, yes: function () { |
|||
layer.closeAll(); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function updateLabel() { |
|||
|
|||
setTimeout(updateLabel, 1000); //5秒后执行 |
|||
let date = new Date(); |
|||
let m = date.getSeconds(); |
|||
player.updateLabel("", m); |
|||
|
|||
} |
|||
|
|||
var canvasTexture |
|||
// 创建LED电子屏幕 |
|||
function addLEDScreen() { |
|||
var canvas = document.createElement("canvas"); |
|||
canvas.width = 512; |
|||
canvas.height = 64; |
|||
var c = canvas.getContext('2d'); |
|||
// c.fillStyle = "#aaaaff"; |
|||
c.fillStyle = "#000000"; |
|||
c.fillRect(0, 0, 512, 64); |
|||
// 文字 |
|||
c.beginPath(); |
|||
c.translate(256, 32); |
|||
c.fillStyle = "#FF0000"; //文本填充颜色 |
|||
c.font = "bold 28px 宋体"; //字体样式设置 |
|||
c.textBaseline = "middle"; //文本与fillText定义的纵坐标 |
|||
c.textAlign = "center"; //文本居中(以fillText定义的横坐标) |
|||
c.fillText("欢迎领导访问指导!!!", 0, 0); |
|||
|
|||
var cubeGeometry = new THREE.BoxGeometry(512, 64, 5); |
|||
canvasTexture = new THREE.CanvasTexture(canvas); |
|||
canvasTexture.wrapS = THREE.RepeatWrapping; |
|||
var material = new THREE.MeshPhongMaterial({ |
|||
map: canvasTexture, // 设置纹理贴图 |
|||
}); |
|||
var cube = new THREE.Mesh(cubeGeometry, material); |
|||
cube.position.set(0.10, 0.56, -1.48); |
|||
cube.rotation.y += Math.PI; //-逆时针旋转,+顺时针 |
|||
cube.scale.set(0.006, 0.006, 0.01); |
|||
scene.add(cube); |
|||
player.addRefeshFunction(updatetext); |
|||
} |
|||
function updatetext() { |
|||
if (canvasTexture) { |
|||
canvasTexture.offset.x += 0.003; |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
|
|||
|
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,186 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
|
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>eg18-2: Three.js 旋转的盒子(重构)--加入阴影</title> |
|||
<script type="importmap"> |
|||
{ |
|||
"imports": { |
|||
"three": "./libs/three/three.module.js", |
|||
"jsm/": "./libs/three/jsm/" |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
</head> |
|||
<script type="module"> |
|||
import * as THREE from 'three'; |
|||
|
|||
|
|||
import { OrbitControls } from 'jsm/controls/OrbitControls.js'; |
|||
import { GLTFLoader } from 'jsm/loaders/GLTFLoader.js'; |
|||
|
|||
import { CSS3DRenderer, CSS3DObject } from 'jsm/renderers/CSS3DRenderer.js'; |
|||
var renderer = null; |
|||
//初始化渲染器 |
|||
function initThree() { |
|||
renderer = new THREE.WebGLRenderer(); |
|||
renderer.setSize(window.innerWidth, window.innerHeight); |
|||
document.body.appendChild(renderer.domElement); |
|||
} |
|||
var camera = null; |
|||
// 照像机设置 |
|||
function initCamera() { |
|||
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); |
|||
camera.position.set(10, 10, 10); |
|||
camera.lookAt(new THREE.Vector3(0, 2, 0)) |
|||
} |
|||
var scene = null; |
|||
// 场景设置 |
|||
function initScene() { |
|||
scene = new THREE.Scene(); |
|||
var axes = new THREE.AxisHelper(1000) |
|||
scene.add(axes) |
|||
} |
|||
// 灯光设置 |
|||
function initLight() { |
|||
//add |
|||
//环境光 |
|||
var ambientLight = new THREE.AmbientLight(0xffffff, 0.5); |
|||
scene.add(ambientLight); |
|||
//点光 |
|||
var pointLight = new THREE.PointLight(0xffffff, 0.8, 18); |
|||
pointLight.position.set(0, 2, 0); |
|||
// scene.add(pointLight); |
|||
} |
|||
var mesh = null; |
|||
// 几何体(物体)设置 |
|||
function initObject() { |
|||
// var geometry = new THREE.CubeGeometry(1,1,1); |
|||
// var material = new THREE.MeshBasicMaterial({color: 0x00ff00}); |
|||
// mesh = new THREE.Mesh(geometry, material); |
|||
// mesh.position.y+=1; |
|||
// scene.add(mesh); |
|||
|
|||
// meshfloor=new THREE.Mesh( |
|||
// new THREE.PlaneGeometry(10,10,10,10), |
|||
// new THREE.MeshPhongMaterial({color:0xffffff,wireframe:false,side: THREE.DoubleSide}) |
|||
// ) |
|||
// meshfloor.rotation.x -=Math.PI/2; |
|||
|
|||
|
|||
// scene.add(meshfloor); |
|||
//Create a closed wavey loop |
|||
|
|||
// 创建曲线路径 |
|||
// var curve = new THREE.CatmullRomCurve3([ |
|||
// new THREE.Vector3(-10, 0, 10), |
|||
// new THREE.Vector3(-5, 5, 5), |
|||
// new THREE.Vector3(0, 0, 0), |
|||
// new THREE.Vector3(5, -5, 5), |
|||
// new THREE.Vector3(10, 0, 10), |
|||
// new THREE.Vector3(10, 0, 10) |
|||
// ]); |
|||
|
|||
// var points = curve.getPoints(50); |
|||
// var geometry = new THREE.BufferGeometry().setFromPoints(points); |
|||
|
|||
// var material = new THREE.LineBasicMaterial({ color: 0xff0000 }); |
|||
|
|||
// // Create the final object to add to the scene |
|||
// var curveObject = new THREE.Line(geometry, material); |
|||
// scene.add(curveObject) |
|||
} |
|||
// 开始渲染 |
|||
function render() { |
|||
requestAnimationFrame(render); |
|||
// mesh.rotation.x += 0.1; |
|||
// mesh.rotation.y += 0.1; |
|||
renderer.render(scene, camera); |
|||
} |
|||
|
|||
function threeStart() { |
|||
|
|||
initThree(); // 初始化渲染器 |
|||
initCamera(); // 照像机设置 |
|||
initScene(); // 场景设置 |
|||
initLight(); // 灯光设置 |
|||
initObject(); // 几何体(物体)设置 |
|||
render(); // 开始渲染 |
|||
createTube(); |
|||
var controls = new OrbitControls(camera, renderer.domElement); |
|||
} |
|||
|
|||
function start() { |
|||
if (WEBGL.isWebGLAvailable()) { |
|||
// Initiate function or other initializations here |
|||
threeStart(); |
|||
} else { |
|||
var warning = WEBGL.getWebGLErrorMessage(); |
|||
document.getElementById('container').appendChild(warning); |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
// 此部分为了展示为hardcode |
|||
const pathArr = [ |
|||
// 4624.99, 2329.38, -5843.11, |
|||
// 4624.99, 4643.14, -5843.11, |
|||
// 1437.47, 4643.14, -5819.36, |
|||
// 1413.69, 4643.14, -1854.40, |
|||
// -6983.28, 4643.14, -1854.04, |
|||
// -7078.43, 4643.14, 2149.46 |
|||
-10, 0, 10, |
|||
-5, 5, 5, |
|||
0, 0, 0, |
|||
5, -5, 5, |
|||
10, 0, 10, |
|||
10, 10, 0 |
|||
] |
|||
const radius = 0.5; |
|||
// 动态创建一个管道 |
|||
function createTube() { |
|||
let curveArr = [] |
|||
// 三个一组取出curve数据 |
|||
for (let i = 0; i < pathArr.length; i += 3) { |
|||
curveArr.push(new THREE.Vector3(pathArr[i], pathArr[i + 1], pathArr[i + 2])) |
|||
} |
|||
var curve = new THREE.CatmullRomCurve3(curveArr); |
|||
/** |
|||
* TubeGeometry(path : Curve, tubularSegments : Integer, radius : Float, radialSegments : Integer, closed : Boolean) |
|||
*/ |
|||
var tubeGeometry = new THREE.TubeGeometry(curve, 100, radius, 50, false); |
|||
var textureLoader = new THREE.TextureLoader(); |
|||
var texture = textureLoader.load('data:application/octet-stream;base64,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'); |
|||
|
|||
// 设置阵列模式 RepeatWrapping |
|||
texture.wrapS = THREE.RepeatWrapping |
|||
texture.wrapT = THREE.RepeatWrapping |
|||
// 设置x方向的重复数(沿着管道路径方向) |
|||
// 设置y方向的重复数(环绕管道方向) |
|||
texture.repeat.x = 10; |
|||
texture.repeat.y = 4; |
|||
// 设置管道纹理偏移数,便于对中 |
|||
texture.offset.y = 0.9; |
|||
var tubeMaterial = new THREE.MeshPhongMaterial({ |
|||
map: texture, |
|||
transparent: true, |
|||
}); |
|||
var tube = new THREE.Mesh(tubeGeometry, tubeMaterial); |
|||
// 使用加减法可以设置不同的运动方向 |
|||
setInterval(() => { |
|||
texture.offset.x -= 0.003 |
|||
}) |
|||
// return tube |
|||
scene.add(tube) |
|||
} |
|||
threeStart(); |
|||
</script> |
|||
|
|||
<body > |
|||
<div id="container"></div> |
|||
</body> |
|||
|
|||
</html> |
@ -1,622 +0,0 @@ |
|||
<!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> |
Loading…
Reference in new issue