700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > three.js之高级几何体-使用二元操作组合网格(vue中使用three.js38)

three.js之高级几何体-使用二元操作组合网格(vue中使用three.js38)

时间:2023-08-20 21:17:22

相关推荐

three.js之高级几何体-使用二元操作组合网格(vue中使用three.js38)

二元操作组合网格介绍

1.ThreeBSP方法介绍2.ThreeBSP方法使用步骤2.1ThreeBSP库引入2.2使用二元操作方法3.demo说明4.demo代码

1.ThreeBSP方法介绍

目前我们创建几何体都是一次单独创建一个。实际上我们有一个库专门用来对网格对象进行相交、联合和相减的操作,这个库就是THREEBSP,我们通过它可以更加高效的创建出想要的三维图形,这个库提供了以下三个方法:

2.ThreeBSP方法使用步骤

2.1ThreeBSP库引入

示例中使用的threebsp.js库是为了满足在vue中使用,稍稍做了调整。引入时要先引入THREE然后在引入threebsp.js库中的getThreeBSP 方法,这里给大家一个下载链,如果需要请点击这里下载threebsp.js

引入过程如下:

import * as THREE from 'three'import getThreeBSP from './threebsp.js'

注意:

1.库文件与工作文件在同一目录下

2.2使用二元操作方法

在使用该库中的方法时,首先要调用getThreeBSP方法与THREE绑定,才能调用库中的方法,具体操作如下

const ThreeBSP = getThreeBSP(THREE)//获取库中二元操作的方法const sphereGeometry = new THREE.SphereGeometry(14, 20, 20)const cubeGeometry = new THREE.BoxGeometry(30, 30, 15)const meshMaterial1 = new THREE.MeshLambertMaterial({color: 0x7777ff})const meshMaterial2 = new THREE.MeshLambertMaterial({color: 0xff77ff})this.cube = new THREE.Mesh(cubeGeometry, meshMaterial2)this.cube.position.set(this.properties.cubeX.value,this.properties.cubeY.value,this.properties.cubeZ.value)this.cube.scale.set(this.properties.cubeScale.value,this.properties.cubeScale.value,this.properties.cubeScale.value)this.sphere = new THREE.Mesh(sphereGeometry, meshMaterial1)this.sphere.position.set(this.properties.sphereX.value,this.properties.sphereY.value,this.properties.sphereZ.value)this.sphere.scale.set(this.properties.sphereScale.value,this.properties.sphereScale.value,this.properties.sphereScale.value)const bsp1 = new ThreeBSP(this.cube)const bsp2 = new ThreeBSP(this.sphere)let result = nullswitch (this.properties.operateType) {case 'intersect':result = bsp1.intersect(bsp2)breakcase 'union':result = bsp1.union(bsp2)breakcase 'subtract':result = bsp1.subtract(bsp2)break}this.lastResultMesh = result.toMesh()this.puteFaceNormals()this.puteVertexNormals()this.scene.add(this.lastResultMesh)

3.demo说明

如上图,该示例可以调整球体和方块的x轴、y轴、z轴和缩放比例,并通过operateType

属性决定做相交、联合还是相减操作

4.demo代码

<template><div><div id="container"></div><div class="controls-box"><section><el-row><div v-for="(item,key) in properties" :key="key"><div v-if="item&&item.name!=undefined"><el-col :span="8"><span class="vertice-span">{{item.name}}</span></el-col><el-col :span="13"><el-slider v-model="item.value" :min="item.min" :max="item.max" :step="item.step" :format-tooltip="formatTooltip" @change="reDraw"></el-slider></el-col><el-col :span="3"><span class="vertice-span">{{item.value}}</span></el-col></div></div></el-row><el-row><el-col :span="8" class="label-col"><label>operateType</label></el-col><el-col :span="16"><el-select v-model="properties.operateType" placeholder="请选择" @change="reDraw"><el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value"></el-option></el-select></el-col></el-row></section></div></div></template><script>import * as THREE from 'three'import getThreeBSP from './threebsp.js'import {OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'export default {data() {return {properties: {cubeX: {name: 'cubeX',value: 0,min: -100,max: 100,step: 1},cubeY: {name: 'cubeY',value: 0,min: -100,max: 100,step: 1},cubeZ: {name: 'cubeZ',value: 0,min: -100,max: 100,step: 1},cubeScale: {name: 'cubeScale',value: 1,min: -10,max: 10,step: 1},sphereX: {name: 'sphereX',value: 0,min: -100,max: 100,step: 1},sphereY: {name: 'sphereY',value: 0,min: -100,max: 100,step: 1},sphereZ: {name: 'sphereZ',value: 0,min: -100,max: 100,step: 1},sphereScale: {name: 'sphereScale',value: 1,min: -10,max: 10,step: 1},operateType: 'intersect'},typeOptions: [{value: 'intersect',label: 'intersect'},{value: 'union',label: 'union'},{value: 'subtract',label: 'subtract'}],lastResultMesh: null,camera: null,scene: null,renderer: null,controls: null}},mounted() {this.init()},methods: {formatTooltip(val) {return val},// 初始化init() {this.createScene() // 创建场景this.createMesh() // 创建网格模型this.createLight() // 创建光源this.createCamera() // 创建相机this.createRender() // 创建渲染器this.createControls() // 创建控件对象this.render() // 渲染},// 创建场景createScene() {this.scene = new THREE.Scene()},// 创建网格模型createMesh() {const ThreeBSP = getThreeBSP(THREE)const sphereGeometry = new THREE.SphereGeometry(14, 20, 20)const cubeGeometry = new THREE.BoxGeometry(30, 30, 15)const meshMaterial1 = new THREE.MeshLambertMaterial({color: 0x7777ff})const meshMaterial2 = new THREE.MeshLambertMaterial({color: 0xff77ff})this.cube = new THREE.Mesh(cubeGeometry, meshMaterial2)this.cube.position.set(this.properties.cubeX.value,this.properties.cubeY.value,this.properties.cubeZ.value)this.cube.scale.set(this.properties.cubeScale.value,this.properties.cubeScale.value,this.properties.cubeScale.value)this.sphere = new THREE.Mesh(sphereGeometry, meshMaterial1)this.sphere.position.set(this.properties.sphereX.value,this.properties.sphereY.value,this.properties.sphereZ.value)this.sphere.scale.set(this.properties.sphereScale.value,this.properties.sphereScale.value,this.properties.sphereScale.value)const bsp1 = new ThreeBSP(this.cube)const bsp2 = new ThreeBSP(this.sphere)let result = nullswitch (this.properties.operateType) {case 'intersect':result = bsp1.intersect(bsp2)breakcase 'union':result = bsp1.union(bsp2)breakcase 'subtract':result = bsp1.subtract(bsp2)break}this.lastResultMesh = result.toMesh()this.puteFaceNormals()this.puteVertexNormals()this.scene.add(this.lastResultMesh)},// 创建光源createLight() {// 环境光const ambientLight = new THREE.AmbientLight(0xffffff, 0.1) // 创建环境光this.scene.add(ambientLight) // 将环境光添加到场景const spotLight = new THREE.SpotLight(0xffffff) // 创建聚光灯spotLight.position.set(-40, 60, -10)spotLight.castShadow = truethis.scene.add(spotLight)},// 创建相机createCamera() {const element = document.getElementById('container')const width = element.clientWidth // 窗口宽度const height = element.clientHeight // 窗口高度const k = width / height // 窗口宽高比// PerspectiveCamera( fov, aspect, near, far )this.camera = new THREE.PerspectiveCamera(35, k, 0.1, 1000)this.camera.position.set(-80, 60, 40) // 设置相机位置this.camera.lookAt(new THREE.Vector3(10, 0, 0)) // 设置相机方向this.scene.add(this.camera)},// 创建渲染器createRender() {const element = document.getElementById('container')this.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true })this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸this.renderer.shadowMap.enabled = true // 显示阴影this.renderer.shadowMap.type = THREE.PCFSoftShadowMapthis.renderer.setClearColor(0x3f3f3f, 1) // 设置背景颜色element.appendChild(this.renderer.domElement)},// 重绘图形reDraw() {this.scene.remove(this.lastResultMesh)this.createMesh()},render() {this.renderer.render(this.scene, this.camera)requestAnimationFrame(this.render)},// 创建控件对象createControls() {this.controls = new OrbitControls(this.camera, this.renderer.domElement)}}}</script><style>#container {position: absolute;width: 100%;height: 100%;}.controls-box {position: absolute;right: 5px;top: 5px;width: 300px;padding: 10px;background-color: #fff;border: 1px solid #c3c3c3;}.vertice-span {line-height: 38px;padding: 0 2px 0 10px;}.label-col {padding: 8px 5px 8px 12px;}</style>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。