threejs使用MeshBasicMaterial画矩形
let materail = new THREE.MeshBasicMaterial({
color: currentcolor,
side: THREE.DoubleSide,
});
let geometry = new THREE.Geometry();
let points = [[-1,0,0],[0,10,0],[10,0,0],[0,-1,0]];
for (let i = 0; i < points.length; i++) {
geometry.vertices.push(new THREE.Vector3(points[i][0], points[i][1], points[i][2]));
}
let line = new THREE.LineLoop(geometry, materail);
引入LineMaterial 和 Line2,需要的文件如下:
改为LineMaterial材质的代码实现width加粗
let points = [[-1,0,0],[0,10,0],[10,0,0],[0,-1,0]];
let material = new THREE.LineMaterial({
side: THREE.DoubleSide,
color: this.draw.color,
linewidth: 6,
dashed: true,
dashScale: 0.5,
dashSize: 2,
gapSize: 1,
})
material.resolution.set(this.canvas.width, this.canvas.height)
const geometry = new THREE.LineGeometry()
const pointArray = []
for (let i = 0; i < points.length; i++) {
pointArray.push(points[i][0])
pointArray.push(points[i][1])
pointArray.push(points[i][2])
}
//添加起点,形成闭环
pointArray.push(points[0][0])
pointArray.push(points[0][1])
pointArray.push(points[0][2])
geometry.setPositions(pointArray)
const vertices = []
for (let i = 0; i < points.length; i++) {
vertices.push(new THREE.Vector3(points[i][0], points[i][1], points[i][2]))
}
//添加起点,形成闭环
vertices.push(new THREE.Vector3(points[0][0], points[0][1], points[0][2]))
geometry.vertices = vertices
const line = new THREE.Line2(geometry, material)
line.computeLineDistances()
遇到的问题:
1、引入LineMaterial材质,相关JS文件引用失败
一般项目使用如下es6语法引用,代码如下所示
import * as THREE from 'three'
import OrbitControls from 'three-orbitcontrols'
import { Line2 } from 'three/examples/jsm/lines/Line2'
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry'
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial'
但是,我当前使用的项目只支持ES5语法,所以需要将所有需要的文件都由ES6改成ES5。
以Line2.js文件为例,展示更改前后的对比
// 变更前
import LineSegments2 from "./LineSegments2.js";
import LineGeometry from "./LineGeometry.js";
import LineMaterial from "./LineMaterial.js";
class Line2 extends THREE.LineSegments2 {
constructor(geometry = new LineGeometry(), material = new LineMaterial({
color: Math.random() * 0xffffff
})) {
super(geometry, material);
this.type = 'Line2';
}
}
Line2.prototype.isLine2 = true;
export { Line2 }
// 变更后
(function() {
class Line2 extends THREE.LineSegments2 {
constructor(geometry = new LineGeometry(), material = new LineMaterial({
color: Math.random() * 0xffffff
})) {
super(geometry, material);
this.type = 'Line2';
}
}
Line2.prototype.isLine2 = true;
THREE.Line2 = Line2
})();
去除ES6 import和export,添加立即执行函数,并将值赋值给THREE
2、引入LineMaterial材质导致获取边界范围不正确
setFromObject( object: Object3D )
计算和世界轴对齐的一个对象 Object3D (含其子对象)的包围盒,计算对象和子对象的世界坐标变换。
var boxObject = new THREE.Mesh( new THREE.BoxGeometry(5, 5, 5), new THREE.MeshBasicMaterial({ color: 0xffaa00 }) );
var box = new THREE.Box3().setFromObject(boxObject);
把正方体网格作为参数,实际上是根据geometry.vertices的Vector3点集和computeBoundingBox()方法计算的。
setFromPoints( points: Vector3[] )
设置此包围盒的上边界和下边界,以包含数组 points 中的所有点。
var box = new THREE.Box3().setFromPoints([new THREE.Vector3(-2,-2,-2),
new THREE.Vector3(2,2,2)]);//返回的包围盒和上面的包围盒相同
参考: https://blog.csdn.net/m0_49399323/article/details/107461063
解决方案:
原来的:
box.setFromObject(child); //line 材质的边界值判断
更改为:
box.setFromPoints(child.geometry.vertices); //line2材质的边界值判断
相关技术点可以参考博文:
- http://www.yanhuangxueyuan.com/doc/Three.js/lineWidth.html
- https://segmentfault.com/a/1190000019456297