清理BSP代码

pull/247/MERGE
ChenX 6 years ago
parent 20320d6f81
commit 3353bdbdee

@ -328,6 +328,7 @@ export class ExtureSolid extends Entity
AppendGroove(groove: ExtureSolid) AppendGroove(groove: ExtureSolid)
{ {
this.WriteAllObjectRecord();
if (this.GrooveCheckPosition(groove) === Status.True) if (this.GrooveCheckPosition(groove) === Status.True)
{ {
this.grooves.push(groove); this.grooves.push(groove);

@ -1,4 +1,4 @@
import { Face3, Face4, Geometry, Material, Matrix4, Mesh, Vector2, Vector3, BufferGeometry } from "three"; import { BufferGeometry, Face3, Geometry, Material, Matrix4, Mesh, Vector2, Vector3 } from "three";
const EPSILON = 1e-5, const EPSILON = 1e-5,
COPLANAR = 0, //共面 COPLANAR = 0, //共面
@ -12,17 +12,9 @@ export default class ThreeBSP
matrix: Matrix4; matrix: Matrix4;
Node: Node; Node: Node;
Vertex: Vertex[]; Vertex: Vertex[];
Polygon: Polygon[]; Polygon: Polygon[] = [];
constructor(obj: Geometry | Mesh | Node) constructor(obj: Geometry | Mesh | Node)
{ {
// Convert Geometry to ThreeBSP
let i, _length_i,
face, vertex, faceVertexUvs, uvs,
polygon,
polygons = [];
this.Polygon = polygons;
this.Vertex = vertex;
let geometry: Geometry; let geometry: Geometry;
if (obj instanceof Geometry) if (obj instanceof Geometry)
{ {
@ -38,7 +30,6 @@ export default class ThreeBSP
geometry = new Geometry().fromBufferGeometry(geo); geometry = new Geometry().fromBufferGeometry(geo);
else else
geometry = geo; geometry = geo;
} }
else if (obj instanceof Node) else if (obj instanceof Node)
{ {
@ -51,71 +42,41 @@ export default class ThreeBSP
throw 'ThreeBSP: Given geometry is unsupported'; throw 'ThreeBSP: Given geometry is unsupported';
} }
for (i = 0, _length_i = geometry.faces.length; i < _length_i; i++)
for (let i = 0; i < geometry.faces.length; i++)
{ {
face = geometry.faces[i]; let face = geometry.faces[i];
faceVertexUvs = geometry.faceVertexUvs[0][i]; let faceVertexUvs = geometry.faceVertexUvs[0][i];
polygon = new Polygon(); let polygon = new Polygon();
if (face instanceof Face3) if (face instanceof Face3)
{ {
vertex = geometry.vertices[face.a]; let vertex = geometry.vertices[face.a];
uvs = faceVertexUvs ? new Vector2(faceVertexUvs[0].x, faceVertexUvs[0].y) : null; let uvs = faceVertexUvs ? new Vector2(faceVertexUvs[0].x, faceVertexUvs[0].y) : null;
vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs); let vertex1 = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs);
vertex.applyMatrix4(this.matrix); vertex1.applyMatrix4(this.matrix);
polygon.vertices.push(vertex); polygon.vertices.push(vertex1);
vertex = geometry.vertices[face.b]; vertex = geometry.vertices[face.b];
uvs = faceVertexUvs ? new Vector2(faceVertexUvs[1].x, faceVertexUvs[1].y) : null; uvs = faceVertexUvs ? new Vector2(faceVertexUvs[1].x, faceVertexUvs[1].y) : null;
vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[1], uvs); let vertex2 = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[1], uvs);
vertex.applyMatrix4(this.matrix); vertex2.applyMatrix4(this.matrix);
polygon.vertices.push(vertex); polygon.vertices.push(vertex2);
vertex = geometry.vertices[face.c]; vertex = geometry.vertices[face.c];
uvs = faceVertexUvs ? new Vector2(faceVertexUvs[2].x, faceVertexUvs[2].y) : null; uvs = faceVertexUvs ? new Vector2(faceVertexUvs[2].x, faceVertexUvs[2].y) : null;
vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs); let vertex3 = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs);
vertex.applyMatrix4(this.matrix); vertex3.applyMatrix4(this.matrix);
polygon.vertices.push(vertex); polygon.vertices.push(vertex3);
}
else if (typeof Face4)
{
vertex = geometry.vertices[face.a];
uvs = faceVertexUvs ? new Vector2(faceVertexUvs[0].x, faceVertexUvs[0].y) : null;
vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs);
vertex.applyMatrix4(this.matrix);
polygon.vertices.push(vertex);
vertex = geometry.vertices[face.b];
uvs = faceVertexUvs ? new Vector2(faceVertexUvs[1].x, faceVertexUvs[1].y) : null;
vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[1], uvs);
vertex.applyMatrix4(this.matrix);
polygon.vertices.push(vertex);
vertex = geometry.vertices[face.c];
uvs = faceVertexUvs ? new Vector2(faceVertexUvs[2].x, faceVertexUvs[2].y) : null;
vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs);
vertex.applyMatrix4(this.matrix);
polygon.vertices.push(vertex);
vertex = geometry.vertices[face.d];
uvs = faceVertexUvs ? new Vector2(faceVertexUvs[3].x, faceVertexUvs[3].y) : null;
vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[3], uvs);
vertex.applyMatrix4(this.matrix);
polygon.vertices.push(vertex);
}
else
{
throw 'Invalid face type at index ' + i;
} }
polygon.calculateProperties(); polygon.calculateProperties();
polygons.push(polygon); this.Polygon.push(polygon);
} }
this.tree = new Node(polygons); this.tree = new Node(this.Polygon);
} }
//减
subtract(other_tree: ThreeBSP) subtract(other_tree: ThreeBSP)
{ {
let a = this.tree.clone(), let a = this.tree.clone(),
@ -134,7 +95,6 @@ export default class ThreeBSP
return bsp; return bsp;
} }
//结合
union(other_tree: ThreeBSP) union(other_tree: ThreeBSP)
{ {
let a = this.tree.clone(), let a = this.tree.clone(),
@ -151,7 +111,6 @@ export default class ThreeBSP
return bsp; return bsp;
} }
//相交
intersect(other_tree: ThreeBSP) intersect(other_tree: ThreeBSP)
{ {
let a = this.tree.clone(), let a = this.tree.clone(),
@ -171,68 +130,65 @@ export default class ThreeBSP
toGeometry() toGeometry()
{ {
let i, j, let
matrix = new Matrix4().getInverse(this.matrix), matrix = new Matrix4().getInverse(this.matrix),
geometry = new Geometry(), geometry = new Geometry(),
polygons = this.tree.allPolygons(), polygons = this.tree.allPolygons(),
polygon_count = polygons.length, polygon_count = polygons.length,
polygon, polygon_vertice_count,
vertice_dict = {}, vertice_dict = {},
vertex_idx_a, vertex_idx_b, vertex_idx_c, vertex_idx_a: number, vertex_idx_b: number, vertex_idx_c: number;
vertex, face,
verticeUvs;
for (i = 0; i < polygon_count; i++) for (let i = 0; i < polygon_count; i++)
{ {
polygon = polygons[i]; let polygon = polygons[i];
polygon_vertice_count = polygon.vertices.length; let polygon_vertice_count = polygon.vertices.length;
for (j = 2; j < polygon_vertice_count; j++) for (let j = 2; j < polygon_vertice_count; j++)
{ {
verticeUvs = []; let verticeUvs = [];
vertex = polygon.vertices[0]; let vertex = polygon.vertices[0];
verticeUvs.push(new Vector2(vertex.uv.x, vertex.uv.y)); verticeUvs.push(new Vector2(vertex.uv.x, vertex.uv.y));
vertex = new Vector3(vertex.x, vertex.y, vertex.z); let vertex1 = new Vector3(vertex.x, vertex.y, vertex.z);
vertex.applyMatrix4(matrix); vertex1.applyMatrix4(matrix);
if (typeof vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] !== 'undefined') if (typeof vertice_dict[vertex1.x + ',' + vertex1.y + ',' + vertex1.z] !== 'undefined')
{ {
vertex_idx_a = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z]; vertex_idx_a = vertice_dict[vertex1.x + ',' + vertex1.y + ',' + vertex1.z];
} else } else
{ {
geometry.vertices.push(vertex); geometry.vertices.push(vertex1);
vertex_idx_a = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] = geometry.vertices.length - 1; vertex_idx_a = vertice_dict[vertex1.x + ',' + vertex1.y + ',' + vertex1.z] = geometry.vertices.length - 1;
} }
vertex = polygon.vertices[j - 1]; vertex = polygon.vertices[j - 1];
verticeUvs.push(new Vector2(vertex.uv.x, vertex.uv.y)); verticeUvs.push(new Vector2(vertex.uv.x, vertex.uv.y));
vertex = new Vector3(vertex.x, vertex.y, vertex.z); let vertex2 = new Vector3(vertex.x, vertex.y, vertex.z);
vertex.applyMatrix4(matrix); vertex2.applyMatrix4(matrix);
if (typeof vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] !== 'undefined') if (typeof vertice_dict[vertex2.x + ',' + vertex2.y + ',' + vertex2.z] !== 'undefined')
{ {
vertex_idx_b = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z]; vertex_idx_b = vertice_dict[vertex2.x + ',' + vertex2.y + ',' + vertex2.z];
} else } else
{ {
geometry.vertices.push(vertex); geometry.vertices.push(vertex2);
vertex_idx_b = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] = geometry.vertices.length - 1; vertex_idx_b = vertice_dict[vertex2.x + ',' + vertex2.y + ',' + vertex2.z] = geometry.vertices.length - 1;
} }
vertex = polygon.vertices[j]; vertex = polygon.vertices[j];
verticeUvs.push(new Vector2(vertex.uv.x, vertex.uv.y)); verticeUvs.push(new Vector2(vertex.uv.x, vertex.uv.y));
vertex = new Vector3(vertex.x, vertex.y, vertex.z); let vertex3 = new Vector3(vertex.x, vertex.y, vertex.z);
vertex.applyMatrix4(matrix); vertex3.applyMatrix4(matrix);
if (typeof vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] !== 'undefined') if (typeof vertice_dict[vertex3.x + ',' + vertex3.y + ',' + vertex3.z] !== 'undefined')
{ {
vertex_idx_c = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z]; vertex_idx_c = vertice_dict[vertex3.x + ',' + vertex3.y + ',' + vertex3.z];
} }
else else
{ {
geometry.vertices.push(vertex); geometry.vertices.push(vertex3);
vertex_idx_c = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] = geometry.vertices.length - 1; vertex_idx_c = vertice_dict[vertex3.x + ',' + vertex3.y + ',' + vertex3.z] = geometry.vertices.length - 1;
} }
face = new Face3( let face = new Face3(
vertex_idx_a, vertex_idx_a,
vertex_idx_b, vertex_idx_b,
vertex_idx_c, vertex_idx_c,
@ -257,7 +213,6 @@ export default class ThreeBSP
} }
} }
//多边形
export class Polygon export class Polygon
{ {
w: number; w: number;
@ -298,10 +253,8 @@ export class Polygon
clone() clone()
{ {
let i, vertice_count, let polygon = new Polygon();
polygon = new Polygon(); for (let i = 0, vertice_count = this.vertices.length; i < vertice_count; i++)
for (i = 0, vertice_count = this.vertices.length; i < vertice_count; i++)
{ {
polygon.vertices.push(this.vertices[i].clone()); polygon.vertices.push(this.vertices[i].clone());
} }
@ -312,12 +265,12 @@ export class Polygon
flip() flip()
{ {
let i, vertices = []; let vertices = [];
this.normal.multiplyScalar(-1); this.normal.multiplyScalar(-1);
this.w *= -1; this.w *= -1;
for (i = this.vertices.length - 1; i >= 0; i--) for (let i = this.vertices.length - 1; i >= 0; i--)
{ {
vertices.push(this.vertices[i]); vertices.push(this.vertices[i]);
} }
@ -327,7 +280,7 @@ export class Polygon
} }
//划分? //划分?
classifyVertex(vertex: Vector3) classifyVertex(vertex: Vector3 | Vertex)
{ {
let side_value = this.normal.dot(vertex) - this.w; let side_value = this.normal.dot(vertex) - this.w;
@ -346,38 +299,29 @@ export class Polygon
//划分边? //划分边?
classifySide(polygon: Polygon) classifySide(polygon: Polygon)
{ {
let i, vertex, classification, let num_positive = 0,
num_positive = 0,
num_negative = 0, num_negative = 0,
vertice_count = polygon.vertices.length; vertice_count = polygon.vertices.length;
for (i = 0; i < vertice_count; i++) for (let i = 0; i < vertice_count; i++)
{ {
vertex = polygon.vertices[i]; let vertex = polygon.vertices[i];
classification = this.classifyVertex(vertex); let classification = this.classifyVertex(vertex);
if (classification === FRONT) if (classification === FRONT)
{
num_positive++; num_positive++;
} else if (classification === BACK) else if (classification === BACK)
{
num_negative++; num_negative++;
} }
}
if (num_positive > 0 && num_negative === 0) if (num_positive > 0 && num_negative === 0)
{
return FRONT; return FRONT;
} else if (num_positive === 0 && num_negative > 0) else if (num_positive === 0 && num_negative > 0)
{
return BACK; return BACK;
} else if (num_positive === 0 && num_negative === 0) else if (num_positive === 0 && num_negative === 0)
{
return COPLANAR; return COPLANAR;
} else else
{
return SPANNING; return SPANNING;
} }
}
//分解 分离 区域? //分解 分离 区域?
splitPolygon(polygon: Polygon, coplanar_front: Polygon[], coplanar_back: Polygon[], front: Polygon[], back: Polygon[]) splitPolygon(polygon: Polygon, coplanar_front: Polygon[], coplanar_back: Polygon[], front: Polygon[], back: Polygon[])
@ -386,55 +330,48 @@ export class Polygon
if (classification === COPLANAR) if (classification === COPLANAR)
{ {
(this.normal.dot(polygon.normal) > 0 ? coplanar_front : coplanar_back).push(polygon); (this.normal.dot(polygon.normal) > 0 ? coplanar_front : coplanar_back).push(polygon);
}
} else if (classification === FRONT) else if (classification === FRONT)
{ {
front.push(polygon); front.push(polygon);
}
} else if (classification === BACK) else if (classification === BACK)
{ {
back.push(polygon); back.push(polygon);
}
} else else
{ {
let f = [];
let b = [];
let vertice_count, for (let i = 0, vertice_count = polygon.vertices.length; i < vertice_count; i++)
i, j, ti, tj, vi, vj,
t, v,
f = [],
b = [];
for (i = 0, vertice_count = polygon.vertices.length; i < vertice_count; i++)
{ {
let j = (i + 1) % vertice_count;
j = (i + 1) % vertice_count; let vi = polygon.vertices[i];
vi = polygon.vertices[i]; let vj = polygon.vertices[j];
vj = polygon.vertices[j]; let ti = this.classifyVertex(vi);
ti = this.classifyVertex(vi); let tj = this.classifyVertex(vj);
tj = this.classifyVertex(vj);
if (ti != BACK) f.push(vi); if (ti != BACK) f.push(vi);
if (ti != FRONT) b.push(vi); if (ti != FRONT) b.push(vi);
if ((ti | tj) === SPANNING) if ((ti | tj) === SPANNING)
{ {
t = (this.w - this.normal.dot(vi)) / this.normal.dot(vj.clone().subtract(vi)); let t = (this.w - this.normal.dot(vi)) / this.normal.dot(vj.clone().subtract(vi));
v = vi.interpolate(vj, t); let v = vi.interpolate(vj, t);
f.push(v); f.push(v);
b.push(v); b.push(v);
} }
} }
if (f.length >= 3) front.push(new Polygon(f).calculateProperties()); if (f.length >= 3) front.push(new Polygon(f).calculateProperties());
if (b.length >= 3) back.push(new Polygon(b).calculateProperties()); if (b.length >= 3) back.push(new Polygon(b).calculateProperties());
} }
} }
} }
type v3 = Vector3 | Vertex;
class Vertex class Vertex
{ {
@ -457,7 +394,7 @@ class Vertex
return new Vertex(this.x, this.y, this.z, this.normal.clone(), this.uv.clone()); return new Vertex(this.x, this.y, this.z, this.normal.clone(), this.uv.clone());
} }
add(vertex) add(vertex: v3)
{ {
this.x += vertex.x; this.x += vertex.x;
this.y += vertex.y; this.y += vertex.y;
@ -465,7 +402,7 @@ class Vertex
return this; return this;
} }
subtract(vertex) subtract(vertex: v3)
{ {
this.x -= vertex.x; this.x -= vertex.x;
this.y -= vertex.y; this.y -= vertex.y;
@ -482,7 +419,7 @@ class Vertex
} }
//×乘 //×乘
cross(vertex) cross(vertex: v3)
{ {
let x = this.x, let x = this.x,
y = this.y, y = this.y,
@ -507,7 +444,7 @@ class Vertex
} }
//点乘 //点乘
dot(vertex) dot(vertex: v3)
{ {
return this.x * vertex.x + this.y * vertex.y + this.z * vertex.z; return this.x * vertex.x + this.y * vertex.y + this.z * vertex.z;
} }
@ -538,9 +475,7 @@ class Vertex
applyMatrix4(m) applyMatrix4(m)
{ {
// input: Matrix4 affine matrix // input: Matrix4 affine matrix
let x = this.x, y = this.y, z = this.z; let x = this.x, y = this.y, z = this.z;
let e = m.elements; let e = m.elements;
@ -561,8 +496,7 @@ class Node
polygons: Polygon[]; polygons: Polygon[];
constructor(polygons?: Polygon[]) constructor(polygons?: Polygon[])
{ {
let i, polygon_count, let front = [],
front = [],
back = []; back = [];
this.polygons = []; this.polygons = [];
@ -572,7 +506,7 @@ class Node
this.divider = polygons[0].clone(); this.divider = polygons[0].clone();
for (i = 0, polygon_count = polygons.length; i < polygon_count; i++) for (let i = 0, polygon_count = polygons.length; i < polygon_count; i++)
{ {
this.divider.splitPolygon(polygons[i], this.polygons, this.polygons, front, back); this.divider.splitPolygon(polygons[i], this.polygons, this.polygons, front, back);
} }
@ -588,13 +522,11 @@ class Node
} }
} }
//是凸的? 凸包?
isConvex(polygons: Polygon[]) isConvex(polygons: Polygon[])
{ {
let i, j; for (let i = 0; i < polygons.length; i++)
for (i = 0; i < polygons.length; i++)
{ {
for (j = 0; j < polygons.length; j++) for (let j = 0; j < polygons.length; j++)
{ {
if (i !== j && polygons[i].classifySide(polygons[j]) !== BACK) if (i !== j && polygons[i].classifySide(polygons[j]) !== BACK)
{ {
@ -607,8 +539,7 @@ class Node
build(polygons: Polygon[]) build(polygons: Polygon[])
{ {
let i, polygon_count, let front = [],
front = [],
back = []; back = [];
if (!this.divider) if (!this.divider)
@ -616,7 +547,7 @@ class Node
this.divider = polygons[0].clone(); this.divider = polygons[0].clone();
} }
for (i = 0, polygon_count = polygons.length; i < polygon_count; i++) for (let i = 0, polygon_count = polygons.length; i < polygon_count; i++)
{ {
this.divider.splitPolygon(polygons[i], this.polygons, this.polygons, front, back); this.divider.splitPolygon(polygons[i], this.polygons, this.polygons, front, back);
} }
@ -660,9 +591,7 @@ class Node
//反转 //反转
invert() invert()
{ {
let i, polygon_count, temp; for (let i = 0, polygon_count = this.polygons.length; i < polygon_count; i++)
for (i = 0, polygon_count = this.polygons.length; i < polygon_count; i++)
{ {
this.polygons[i].flip(); this.polygons[i].flip();
} }
@ -671,7 +600,7 @@ class Node
if (this.front) this.front.invert(); if (this.front) this.front.invert();
if (this.back) this.back.invert(); if (this.back) this.back.invert();
temp = this.front; let temp = this.front;
this.front = this.back; this.front = this.back;
this.back = temp; this.back = temp;
@ -681,15 +610,12 @@ class Node
// //
clipPolygons(polygons: Polygon[]) clipPolygons(polygons: Polygon[])
{ {
let i, polygon_count,
front, back;
if (!this.divider) return polygons.slice(); if (!this.divider) return polygons.slice();
front = []; let front = [];
back = []; let back = [];
for (i = 0, polygon_count = polygons.length; i < polygon_count; i++) for (let i = 0, polygon_count = polygons.length; i < polygon_count; i++)
{ {
this.divider.splitPolygon(polygons[i], front, back, front, back); this.divider.splitPolygon(polygons[i], front, back, front, back);
} }

Loading…
Cancel
Save