|
|
|
@ -2,6 +2,8 @@ |
|
|
|
<div class="model3d-view"> |
|
|
|
<el-space :gutter="10" class="toolbar"> |
|
|
|
<el-button type="primary" @click="test1">测试1</el-button> |
|
|
|
<el-button type="primary" @click="test2">测试2</el-button> |
|
|
|
<el-button type="primary" @click="test3">测试3</el-button> |
|
|
|
<div class="demo-color-block"> |
|
|
|
<span class="demonstration">物体数:<el-text type="danger">{{ restate.objects }}</el-text></span> |
|
|
|
<span class="demonstration"> 顶点数:<el-text type="danger">{{ restate.vertices }}</el-text></span> |
|
|
|
@ -54,9 +56,10 @@ const pointMaterial = new THREE.SpriteMaterial({ |
|
|
|
const lineMaterial = new LineMaterial({ |
|
|
|
color: 0xFF8C00, |
|
|
|
linewidth: 5 |
|
|
|
}); |
|
|
|
}) |
|
|
|
|
|
|
|
function test1() { |
|
|
|
cleanupThree() |
|
|
|
const xcount = 100 |
|
|
|
const zcount = 100 |
|
|
|
const dist = 1.25 |
|
|
|
@ -78,78 +81,160 @@ function test1() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// // 绘制线段 |
|
|
|
// const lines = [] |
|
|
|
// |
|
|
|
// // 绘制线段(每两个点一组) |
|
|
|
// for (let z = 0; z < zcount; z++) { |
|
|
|
// for (let x = 0; x < xcount - 1; x++) { |
|
|
|
// const i = z * xcount + x |
|
|
|
// drawLine(points[i], points[i + 1]) |
|
|
|
// } |
|
|
|
// } |
|
|
|
// |
|
|
|
// for (let z = 0; z < zcount - 1; z++) { |
|
|
|
// for (let x = 0; x < xcount; x++) { |
|
|
|
// const i = z * xcount + x |
|
|
|
// const belowIndex = (z + 1) * xcount + x |
|
|
|
// drawLine(points[i], points[belowIndex]) |
|
|
|
// } |
|
|
|
// } |
|
|
|
const positions = []; |
|
|
|
function drawLine(p1: THREE.Vector3, p2: THREE.Vector3) { |
|
|
|
const geometry = new LineGeometry() |
|
|
|
geometry.setPositions([p1.x, p1.y, p1.z, p2.x, p2.y, p2.z]) |
|
|
|
|
|
|
|
// const material = new LineMaterial({ |
|
|
|
// color: 0xFF8C00, |
|
|
|
// linewidth: 5 |
|
|
|
// }); |
|
|
|
|
|
|
|
const line = new Line2(geometry, lineMaterial) |
|
|
|
line.computeLineDistances() |
|
|
|
|
|
|
|
scene.add(line) |
|
|
|
} |
|
|
|
|
|
|
|
// 绘制线段(每两个点一组) |
|
|
|
for (let z = 0; z < zcount; z++) { |
|
|
|
for (let x = 0; x < xcount - 1; x++) { |
|
|
|
const i = z * xcount + x |
|
|
|
drawLine(points[i], points[i + 1]) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for (let z = 0; z < zcount - 1; z++) { |
|
|
|
for (let x = 0; x < xcount; x++) { |
|
|
|
const i = z * xcount + x |
|
|
|
const belowIndex = (z + 1) * xcount + x |
|
|
|
drawLine(points[i], points[belowIndex]) |
|
|
|
} |
|
|
|
} |
|
|
|
refreshCount() |
|
|
|
} |
|
|
|
|
|
|
|
function test2() { |
|
|
|
cleanupThree() |
|
|
|
const xcount = 100 |
|
|
|
const zcount = 100 |
|
|
|
const dist = 1.25 |
|
|
|
const spacing = dist |
|
|
|
const y = 0.1 |
|
|
|
|
|
|
|
const points = [] |
|
|
|
|
|
|
|
// 创建所有点 |
|
|
|
for (let z = 0; z < zcount; z++) { |
|
|
|
for (let x = 0; x < xcount; x++) { |
|
|
|
const px = x * dist |
|
|
|
const pz = z * dist |
|
|
|
const point = new THREE.Sprite(pointMaterial) |
|
|
|
point.position.set(px, y, pz) |
|
|
|
point.scale.set(0.25, 0.25, 1) // 设置大小 |
|
|
|
scene.add(point) |
|
|
|
points.push(point.position.clone()) |
|
|
|
} |
|
|
|
} |
|
|
|
const positions = [] |
|
|
|
|
|
|
|
// 横向连接(右) |
|
|
|
for (let z = 0; z < zcount; z++) { |
|
|
|
for (let x = 0; x < xcount - 1; x++) { |
|
|
|
const x1 = x * spacing; |
|
|
|
const z1 = z * spacing; |
|
|
|
const x2 = (x + 1) * spacing; |
|
|
|
const z2 = z * spacing; |
|
|
|
positions.push(x1, y, z1, x2, y, z2); |
|
|
|
const x1 = x * spacing |
|
|
|
const z1 = z * spacing |
|
|
|
const x2 = (x + 1) * spacing |
|
|
|
const z2 = z * spacing |
|
|
|
positions.push(x1, y, z1, x2, y, z2) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 纵向连接(下) |
|
|
|
for (let z = 0; z < zcount - 1; z++) { |
|
|
|
for (let x = 0; x < xcount; x++) { |
|
|
|
const x1 = x * spacing; |
|
|
|
const z1 = z * spacing; |
|
|
|
const x2 = x * spacing; |
|
|
|
const z2 = (z + 1) * spacing; |
|
|
|
positions.push(x1, y, z1, x2, y, z2); |
|
|
|
const x1 = x * spacing |
|
|
|
const z1 = z * spacing |
|
|
|
const x2 = x * spacing |
|
|
|
const z2 = (z + 1) * spacing |
|
|
|
positions.push(x1, y, z1, x2, y, z2) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const geometry = new LineSegmentsGeometry(); |
|
|
|
geometry.setPositions(positions); // [x1,y1,z1, x2,y2,z2, ...] |
|
|
|
const geometry = new LineSegmentsGeometry() |
|
|
|
geometry.setPositions(positions) |
|
|
|
|
|
|
|
const material = new LineMaterial({ |
|
|
|
color: 0xFF8C00, |
|
|
|
linewidth: 5, |
|
|
|
vertexColors: false |
|
|
|
}); |
|
|
|
}) |
|
|
|
|
|
|
|
const lineSegments = new LineSegments2(geometry, material); |
|
|
|
lineSegments.computeLineDistances(); // 必须调用一次 |
|
|
|
lineSegments.name = 'grid-lines'; |
|
|
|
scene.add(lineSegments); |
|
|
|
const lineSegments = new LineSegments2(geometry, material) |
|
|
|
lineSegments.computeLineDistances() // 必须调用一次 |
|
|
|
lineSegments.name = 'grid-lines' |
|
|
|
scene.add(lineSegments) |
|
|
|
refreshCount() |
|
|
|
} |
|
|
|
|
|
|
|
function drawLine(p1: THREE.Vector3, p2: THREE.Vector3) { |
|
|
|
const geometry = new LineGeometry(); |
|
|
|
geometry.setPositions([p1.x, p1.y, p1.z, p2.x, p2.y, p2.z]); |
|
|
|
|
|
|
|
// const material = new LineMaterial({ |
|
|
|
// color: 0xFF8C00, |
|
|
|
// linewidth: 5 |
|
|
|
// }); |
|
|
|
function test3() { |
|
|
|
cleanupThree() |
|
|
|
const xcount = 100 |
|
|
|
const zcount = 100 |
|
|
|
const dist = 1.25 |
|
|
|
const spacing = dist |
|
|
|
const y = 0.1 |
|
|
|
|
|
|
|
const points = [] |
|
|
|
|
|
|
|
// 创建所有点 |
|
|
|
for (let z = 0; z < zcount; z++) { |
|
|
|
for (let x = 0; x < xcount; x++) { |
|
|
|
const px = x * dist |
|
|
|
const pz = z * dist |
|
|
|
const point = new THREE.Sprite(pointMaterial) |
|
|
|
point.position.set(px, y, pz) |
|
|
|
point.scale.set(0.25, 0.25, 1) // 设置大小 |
|
|
|
scene.add(point) |
|
|
|
points.push(point.position.clone()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const line = new Line2(geometry, lineMaterial); |
|
|
|
line.computeLineDistances(); |
|
|
|
const positions = [] |
|
|
|
|
|
|
|
// 横向连接(右) |
|
|
|
for (let z = 0; z < zcount; z++) { |
|
|
|
for (let x = 0; x < xcount - 1; x++) { |
|
|
|
const x1 = x * spacing |
|
|
|
const z1 = z * spacing |
|
|
|
const x2 = (x + 1) * spacing |
|
|
|
const z2 = z * spacing |
|
|
|
positions.push(x1, y, z1, x2, y, z2) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 纵向连接(下) |
|
|
|
for (let z = 0; z < zcount - 1; z++) { |
|
|
|
for (let x = 0; x < xcount; x++) { |
|
|
|
const x1 = x * spacing |
|
|
|
const z1 = z * spacing |
|
|
|
const x2 = x * spacing |
|
|
|
const z2 = (z + 1) * spacing |
|
|
|
positions.push(x1, y, z1, x2, y, z2) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
scene.add(line) |
|
|
|
const positionNums = new Float32Array(positions) |
|
|
|
const geometry = new THREE.BufferGeometry() |
|
|
|
geometry.setAttribute('position', new THREE.BufferAttribute(positionNums, 3)) |
|
|
|
const material = new THREE.LineBasicMaterial({ color: 0xFF8C00 }) |
|
|
|
const lineSegments = new THREE.LineSegments(geometry, material) |
|
|
|
lineSegments.name = 'grid-lines' |
|
|
|
scene.add(lineSegments) |
|
|
|
refreshCount() |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const restate = reactive({ |
|
|
|
targetColor: '#ff0000', |
|
|
|
loadScale: 1, |
|
|
|
@ -381,13 +466,46 @@ function renderView() { |
|
|
|
renderer?.render(scene, camera) |
|
|
|
} |
|
|
|
|
|
|
|
function refreshCount() { |
|
|
|
// 遍历场景中的所有对象 |
|
|
|
let totalObjects = 0 |
|
|
|
let totalVertices = 0 |
|
|
|
let totalFaces = 0 |
|
|
|
scene.traverse(function(child) { |
|
|
|
if (child.isMesh) { |
|
|
|
totalObjects++ |
|
|
|
|
|
|
|
// 获取几何体 |
|
|
|
const geometry = child.geometry |
|
|
|
|
|
|
|
// 如果几何体是 BufferGeometry 类型 |
|
|
|
if (geometry.isBufferGeometry) { |
|
|
|
// 计算顶点数 |
|
|
|
if (geometry.attributes.position) { |
|
|
|
totalVertices += geometry.attributes.position.count |
|
|
|
} |
|
|
|
|
|
|
|
// 计算面数(假设每个面都是由三个顶点组成的三角形) |
|
|
|
if (geometry.index) { |
|
|
|
totalFaces += geometry.index.count / 3 |
|
|
|
} else if (geometry.attributes.position) { |
|
|
|
// 如果没有索引,计算非索引几何体的面数 |
|
|
|
totalFaces += geometry.attributes.position.count / 3 |
|
|
|
} |
|
|
|
} |
|
|
|
// 如果几何体是 Geometry 类型(较旧的版本使用) |
|
|
|
else if (geometry.isGeometry) { |
|
|
|
// 计算顶点数 |
|
|
|
totalVertices += geometry.vertices.length |
|
|
|
|
|
|
|
function cleaupModel() { |
|
|
|
if (modelGroup) { |
|
|
|
scene.remove(modelGroup) |
|
|
|
} |
|
|
|
tcontrols.detach() |
|
|
|
transformEditCtl.value.detach() |
|
|
|
// 计算面数 |
|
|
|
totalFaces += geometry.faces.length |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
restate.objects = totalObjects |
|
|
|
restate.vertices = totalVertices |
|
|
|
restate.faces = totalFaces |
|
|
|
} |
|
|
|
|
|
|
|
function cleanupThree() { |
|
|
|
@ -412,37 +530,12 @@ function cleanupThree() { |
|
|
|
if (obj.texture) { |
|
|
|
obj.texture.dispose() |
|
|
|
} |
|
|
|
|
|
|
|
// 释放渲染目标 |
|
|
|
if (obj.renderTarget) { |
|
|
|
obj.renderTarget.dispose() |
|
|
|
} |
|
|
|
|
|
|
|
// 移除事件监听(如 OrbitControls) |
|
|
|
if (obj.dispose) { |
|
|
|
obj.dispose() |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
if (modelGroup) { |
|
|
|
scene.remove(modelGroup) |
|
|
|
} |
|
|
|
// 清空场景 |
|
|
|
scene.children = [] |
|
|
|
|
|
|
|
modelGroup = null |
|
|
|
} |
|
|
|
|
|
|
|
if (statsControls) { |
|
|
|
statsControls.dom.remove() |
|
|
|
} |
|
|
|
|
|
|
|
if (renderer) { |
|
|
|
renderer.dispose() |
|
|
|
renderer.forceContextLoss() |
|
|
|
console.log('WebGL disposed, memory:', renderer.info.memory) |
|
|
|
renderer.domElement = null |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|