一、添加包围框
我添加包围框的作用是为了分割模型,使模型的每个部分看起来更立体。通过一段数据来定义这个包围框,这段数据包括(模型的最大x、y、z坐标和最小x、y、z坐标,以及模型的中心位置)。
add_box(data, scene) { for (let i = 0; i < data.maxxyz.length; i++) { const maxX = data.maxxyz[i][0], maxY = data.maxxyz[i][1], maxZ = data.maxxyz[i][2]; const minX = data.minxyz[i][0], minY = data.minxyz[i][1], minZ = data.minxyz[i][2]; const location = new THREE.Vector3(data.location[i][0], -data.location[i][2], data.location[i][1]); // 计算包围盒的尺寸 const width = Math.abs(maxX - minX); const height = Math.abs(maxY - minY); const depth = Math.abs(maxZ - minZ); // 创建长方体的几何体 const boxGeometry = new THREE.BoxGeometry(width, depth, height); // 创建包围盒的材质,这里使用线框材质以展示边框 const boxMaterial = new THREE.LineBasicMaterial({color: 0xff0000}); const boundingBoxMesh = new THREE.LineSegments(new THREE.EdgesGeometry(boxGeometry), boxMaterial); // 设置包围盒的位置为指定位置 boundingBoxMesh.position.copy(location); // 将包围盒添加到场景中 scene.add(boundingBoxMesh); } }
const location = new THREE.Vector3(data.location[i][0], -data.location[i][2], data.location[i][1]);和const boxGeometry = new THREE.BoxGeometry(width, depth, height);这两段代码中原本的顺序是width, height, depth,但因为模型的坐标系与three中的坐标系不同,所以做了调整。顺便说一下,这种方法画包围框不会连接对角线。
二、添加文字
添加文字的作用是标明模型每个部分具体的名称 ,所以就要使用数据中的name数据
for (let i = 0; i < data.location.length; i++) { let height = data.location[i] // 创建文本标签 const labelCanvas = document.createElement('canvas'); const context = labelCanvas.getContext('2d'); const location = new THREE.Vector3(data.location[i][0], -data.location[i][2], data.location[i][1]); context.font = 'Bold 20px Arial'; context.fillStyle = 'rgba(0, 255, 0, 0.8)'; context.fillText(data.name[i], 0, 20); const labelTexture = new THREE.CanvasTexture(labelCanvas); const labelMaterial = new THREE.SpriteMaterial({map: labelTexture}); const labelSprite = new THREE.Sprite(labelMaterial); // 设置标签的位置为包围盒的位置偏移一些距离,可以根据需求调整偏移量 labelSprite.position.copy(location.clone().add(new THREE.Vector3(0.6, -(height[2] / 2 + 0.5)*6, 0))); labelSprite.scale.set(6, 5, 5); // 调整标签的大小 scene.add(labelSprite); }
const location = new THREE.Vector3(data.location[i][0], -data.location[i][2], data.location[i][1]);和 labelSprite.position.copy(location.clone().add(new THREE.Vector3(0.6, -(height[2] / 2 + 0.5)*6, 0)));这两段代码这样写的原因和上面的相同。