1、首先创建一个场景、相机和渲染器
// 创建一个场景
var scene = new THREE.Scene();
// 创建一个相机
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 创建一个渲染器
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
2、使用GLTFLoader加载GLB文件,并遍历场景中的子对象。
对于每个Group,我们将其添加到场景中,并为其添加鼠标移入和移出事件监听器。
// 加载GLB文件
var loader = new THREE.GLTFLoader();
loader.load('path/to/your/file.glb', function (gltf) {
// 获取GLTF场景
var gltfScene = gltf.scene;
// 遍历场景中的子对象,将Group添加到场景中
gltfScene.traverse(function (child) {
if (child instanceof THREE.Group) {
scene.add(child);
// 添加鼠标移入和移出事件监听器
child.addEventListener('mouseover', function () {
createEdges(child);
});
child.addEventListener('mouseout', function () {
var edgesMesh = child.getObjectByName("edgesMesh");
if (edgesMesh) {
child.remove(edgesMesh);
}
});
}
});
}, undefined, function (error) {
console.error(error);
});
3、在鼠标移入,移出
移入时,我们使用createEdges
函数创建边框几何体,并将其添加到当前Group中。
移出时,我们使用getObjectByName
方法找到边框几何体,并将其从Group中移除。
// 添加鼠标事件监听器
document.addEventListener('mousemove', onMouseMove, false);
function onMouseMove(event) {
// 计算鼠标在屏幕上的位置
var mouse = new THREE.Vector2();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
// 创建一个射线投射器
var raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
// 检测与射线相交的物体
var intersects = raycaster.intersectObjects(scene.children, true);
// 遍历相交的物体,判断是否是Group
for (var i = 0; i < intersects.length; i++) {
var obj = intersects[i].object;
if (obj instanceof THREE.Group) {
// 鼠标移入Group
if (!obj.userData.hovered) {
createEdges(obj);
obj.userData.hovered = true;
}
} else {
// 鼠标移出Group
if (obj.parent instanceof THREE.Group) {
var group = obj.parent;
if (group.userData.hovered) {
var edgesMesh = group.getObjectByName("edgesMesh");
if (edgesMesh) {
group.remove(edgesMesh);
}
group.userData.hovered = false;
}
}
}
}
}
4、全部代码
请注意,我们为每个Group添加了userData.hovered
属性来跟踪Group是否已经被鼠标移入过
// 创建一个场景
var scene = new THREE.Scene();
// 创建一个相机
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 创建一个渲染器
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 创建边框材质
var edgeMaterial = new THREE.LineBasicMaterial({ color: 0xff0000 });
// 创建边框几何体函数
function createEdges(group) {
var edges = new THREE.EdgesGeometry(group.children[0].geometry);
var edgesMesh = new THREE.LineSegments(edges, edgeMaterial);
group.add(edgesMesh);
}
// 加载GLB文件
var loader = new THREE.GLTFLoader();
loader.load('path/to/your/file.glb', function (gltf) {
// 获取GLTF场景
var gltfScene = gltf.scene;
// 遍历场景中的子对象,将Group添加到场景中
gltfScene.traverse(function (child) {
if (child instanceof THREE.Group) {
scene.add(child);
// 添加鼠标移入和移出事件监听器
child.addEventListener('mouseover', function () {
createEdges(child);
});
child.addEventListener('mouseout', function () {
var edgesMesh = child.getObjectByName("edgesMesh");
if (edgesMesh) {
child.remove(edgesMesh);
}
});
}
});
}, undefined, function (error) {
console.error(error);
});
// 添加鼠标事件监听器
document.addEventListener('mousemove', onMouseMove, false);
function onMouseMove(event) {
// 计算鼠标在屏幕上的位置
var mouse = new THREE.Vector2();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
// 创建一个射线投射器
var raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
// 检测与射线相交的物体
var intersects = raycaster.intersectObjects(scene.children, true);
// 遍历相交的物体,判断是否是Group
for (var i = 0; i < intersects.length; i++) {
var obj = intersects[i].object;
if (obj instanceof THREE.Group) {
// 鼠标移入Group
if (!obj.userData.hovered) {
createEdges(obj);
obj.userData.hovered = true;
}
} else {
// 鼠标移出Group
if (obj.parent instanceof THREE.Group) {
var group = obj.parent;
if (group.userData.hovered) {
var edgesMesh = group.getObjectByName("edgesMesh");
if (edgesMesh) {
group.remove(edgesMesh);
}
group.userData.hovered = false;
}
}
}
}
}
// 渲染场景
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();