使用three.js展示模型,实现鼠标移入模型高亮
先看效果图
参照官网例子webgl_interactive_cubes.html
学习实现模型高亮分了三步:
- 修改代码展示的BoxGeometry替换成官方提供的的obj模型(因为我直接加载自己的模型不能实现高亮效果,猜测可能是模型格式不同)
var OBJLoaderA = new OBJLoader();
var MTLLoaderA = new MTLLoader();
MTLLoaderA.load("models/obj/male02/male02.mtl", function (materials) {
OBJLoaderA.setMaterials(materials);
OBJLoaderA.load("models/obj/male02/male02.obj", function (obj) {
obj.translateY(-108);
scene.add(obj);
});
});
关闭模型自动旋转,调整模型大小后,可以实现鼠标移入高亮.
- 修改模型为自己的obj模型 模型引入代码同上,更换路径即可
function render() {// theta += 0.1;
camera.position.x = radius * Math.sin(THREE.MathUtils.degToRad(theta));
camera.position.y = radius * Math.sin(THREE.MathUtils.degToRad(theta));
camera.position.z = radius * Math.cos(THREE.MathUtils.degToRad(theta));
camera.lookAt(scene.position);
camera.updateMatrixWorld();
raycaster.setFromCamera(pointer, camera);
// 获取所有的子对象,计算物体和射线的焦点,第二个参数是用来判断是否获取所有的物体对象的,即开启检查所有后代
const intersects = raycaster.intersectObjects(scene.children, true);
if (intersects.length > 0) {
if (INTERSECTED != intersects[0].object) {
if (INTERSECTED) {
for (let i = 0; i < INTERSECTED.material.length; i++) {
INTERSECTED.material[i].emissive.setHex(INTERSECTED.currentHex);
}}
INTERSECTED = intersects[0].object;
for (let i = 0; i < INTERSECTED.material.length; i++) {
INTERSECTED.currentHex = INTERSECTED.material[i].emissive.getHex();
INTERSECTED.material[i].emissive.setHex(0xff0000);
}
}
}
else {
if (INTERSECTED) {
for (let i = 0; i < INTERSECTED.material.length; i++){
INTERSECTED.material[i].emissive.setHex(INTERSECTED.currentHex);
}
}
INTERSECTED = null;
}
renderer.render(scene, camera);
}
修改render函数是因为发现我自己的obj模型和three.js官方提供模型在获取intersects[0].object.material时得到的结果不同,我获取的是个数组,官方获取的是个对象,并且会鼠标移入不同位置时候获取不同的材质对象,我分析是模型的问题,但是因为我对模型这里还不是很了解,只是暂时发现了这个问题,是什么导致出现这个问题的还没有搞清楚。 这是鼠标移入获取的intersects[0].object.material数据
图一为官方模型获取的数据
图二为我自己的obj模型获取的数据
- 移入项目中,更改坐标转换关系,因为在项目中模型不是在全屏展示的,是在一个占部分区域的dom内展示的,所以需要做坐标转换,把mousemove获取的坐标转化为vector2坐标
document.getElementById("showmodels")?.addEventListener("mousemove", onPointerMove);
width = document.getElementById("showmodels")?.clientWidth;
height = document.getElementById("showmodels")?.clientHeight;
function onPointerMove(event) {
pointer.x = (event.offsetX / width) * 2 - 1;
pointer.y = -(event.offsetY / height) * 2 + 1;
}