<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.elementTag {
width: 200px;
height: 200px;
padding: 10px;
background: blue;
}
</style>
<script src="http://www.yanhuangxueyuan.com/threejs/build/three.min.js"></script>
<script src="http://www.yanhuangxueyuan.com/threejs/examples/js/controls/OrbitControls.js"></script>
<script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/GLTFLoader.js"></script>
<script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/DRACOLoader.js"></script>
</head>
<body>
<div id="webgl"></div>
</body>
</html>
<script>
var scene, camera, renderer;
init();
function init() {
//场景
scene = new THREE.Scene();
//相机设置为世界坐标原点
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(100, 100, 100);
scene.add(camera);//添加相机
//添加坐标轴
var axes = new THREE.AxesHelper(500);//500表示xyz轴的长度,红:x,绿:y,蓝:z
scene.add(axes);
addGlb('./model/floor2.glb');
render();
animate();
}
async function addGlb(filepath) {
const loader = new THREE.GLTFLoader();
const dracoloader = getDracoLoader();
loader.setDRACOLoader(dracoloader);//注入loader
//加载模型
const floor = await loadGlb(filepath, loader);
scene.add(floor.scene);
}
function getDracoLoader() {
//对模型解压
const dracoloader = new THREE.DRACOLoader();
dracoloader.setDecoderPath("./draco/");//把examples\jsm\libs\draco这个文件夹复制过来
dracoloader.setDecoderConfig({ type: "js" })
dracoloader.preload();
return dracoloader;
}
function loadGlb(filepath, loader) {
return new Promise((resolve, reject) => {
loader.setCrossOrigin('Anonymous');//跨域问题
loader.load(filepath, (gltf) => {
console.log('gltf>>>', gltf);
//处理材质丢失的情况
gltf.scene.traverse(child => {
if (child.isMesh) {
child.material.emissive = child.material.color;
child.material.emissiveMap = child.material.map;
}
});
resolve(gltf);
}, undefined, (error) => {
console.error(error);
reject(error);
});
});
}
//元素拾取
function getXYZ(renderer, camera, scene) {
const raycaster = new THREE.Raycaster(); //光线投射,用于确定鼠标点击位置
const mouse = new THREE.Vector2(); //创建二维平面
window.addEventListener("mousedown", mousedown); //页面绑定鼠标点击事件
//点击方法
function mousedown(e) {
//将html坐标系转化为webgl坐标系,并确定鼠标点击位置
mouse.x = (e.clientX / renderer.domElement.clientWidth) * 2 - 1;
mouse.y = -((e.clientY / renderer.domElement.clientHeight) * 2) + 1;
//以camera为z坐标,确定所点击物体的3D空间位置
raycaster.setFromCamera(mouse, camera);
//确定所点击位置上的物体数量
const intersects = raycaster.intersectObjects(scene.children);
//选中后进行的操作
if (intersects.length) {
var selected = intersects[0]; //取第一个物体
console.log(selected);
console.log("x坐标:" + selected.point.x);
console.log("y坐标:" + selected.point.y);
console.log("z坐标:" + selected.point.z);
}
}
}
function render() {
renderer = new THREE.WebGLRenderer({
antialias: true,
});//画布
renderer.setSize(window.innerWidth, window.innerHeight);//设置渲染区域尺寸
renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
});
//将渲染好的canvas追加到dom
var cont = document.getElementById('webgl');
cont.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
getXYZ(renderer, camera, scene);
}
function animate() {
renderer.render(scene, camera);//开始渲染
requestAnimationFrame(animate);
}
</script>
网友评论