Skip to content

Commit f187ad1

Browse files
committed
added tests
1 parent 2c260c6 commit f187ad1

File tree

5 files changed

+337
-0
lines changed

5 files changed

+337
-0
lines changed

tests/coplanar.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<html>
2+
<body style="margin:0;overflow:hidden;">
3+
<script src="../csg.js"></script>
4+
<script src="lightgl.js"></script>
5+
<script src="coplanar.js"></script>
6+
</body>
7+
</html>

tests/coplanar.js

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
var angleX = 20;
2+
var angleY = 20;
3+
var shader;
4+
var meshes = [];
5+
6+
function setup() {
7+
function setPolygonColor(solid, color) {
8+
solid.toPolygons().map(function(polygon) {
9+
polygon.shared = color;
10+
});
11+
}
12+
13+
// Test coplanar cases
14+
var a = CSG.cube();
15+
var b = CSG.cylinder({ slices: 8, start: new CSG.Vector(-1, 0, 0), end: new CSG.Vector(1, 0, 0) });
16+
b = b.union(CSG.cylinder({ slices: 8, start: new CSG.Vector(0, -1, 0), end: new CSG.Vector(0, 1, 0) }));
17+
b = b.union(CSG.cylinder({ slices: 8, start: new CSG.Vector(0, 0, -1), end: new CSG.Vector(0, 0, 1) }));
18+
var c = CSG.cube({ radius: 0.5 });
19+
var d = CSG.cylinder({ radius: 0.5, slices: 8, start: new CSG.Vector(-1, 0, 0), end: new CSG.Vector(-0.5, 0, 0) });
20+
d = d.union(CSG.cylinder({ radius: 0.5, slices: 8, start: new CSG.Vector(0.5, 0, 0), end: new CSG.Vector(1, 0, 0) }));
21+
d = d.union(CSG.cylinder({ radius: 0.5, slices: 8, start: new CSG.Vector(0, -1, 0), end: new CSG.Vector(0, -0.5, 0) }));
22+
d = d.union(CSG.cylinder({ radius: 0.5, slices: 8, start: new CSG.Vector(0, 0.5, 0), end: new CSG.Vector(0, 1, 0) }));
23+
d = d.union(CSG.cylinder({ radius: 0.5, slices: 8, start: new CSG.Vector(0, 0, -1), end: new CSG.Vector(0, 0, -0.5) }));
24+
d = d.union(CSG.cylinder({ radius: 0.5, slices: 8, start: new CSG.Vector(0, 0, 0.5), end: new CSG.Vector(0, 0, 1) }));
25+
setPolygonColor(a, new CSG.Vector(1, 0, 0));
26+
setPolygonColor(b, new CSG.Vector(0, 0, 1));
27+
setPolygonColor(c, new CSG.Vector(0, 1, 0));
28+
setPolygonColor(d, new CSG.Vector(1, 1, 0));
29+
var operations = [
30+
a,
31+
b,
32+
a.inverse(),
33+
b.inverse(),
34+
a.union(b),
35+
b.union(a),
36+
a.subtract(b),
37+
b.subtract(a),
38+
a.intersect(b),
39+
b.intersect(a),
40+
c,
41+
d,
42+
c.inverse(),
43+
d.inverse(),
44+
c.union(d),
45+
d.union(c),
46+
c.subtract(d),
47+
d.subtract(c),
48+
c.intersect(d),
49+
d.intersect(c)
50+
];
51+
52+
// Build meshes from operations
53+
for (var i = 0; i < operations.length; i++) {
54+
var polygons = operations[i].toPolygons();
55+
var indexer = new Indexer();
56+
mesh = new Mesh({ normals: true, colors: true });
57+
polygons.map(function(polygon) {
58+
var indices = polygon.vertices.map(function(vertex) {
59+
vertex.color = polygon.shared;
60+
return indexer.add(vertex);
61+
});
62+
for (var i = 2; i < indices.length; i++) {
63+
mesh.triangles.push([indices[0], indices[i - 1], indices[i]]);
64+
}
65+
});
66+
mesh.vertices = indexer.unique.map(function(v) { return [v.pos.x, v.pos.y, v.pos.z]; });
67+
mesh.normals = indexer.unique.map(function(v) { return [v.normal.x, v.normal.y, v.normal.z]; });
68+
mesh.colors = indexer.unique.map(function(v) { return [v.color.x, v.color.y, v.color.z]; });
69+
mesh.compile();
70+
meshes.push(mesh);
71+
}
72+
73+
// Use diffuse and specular lighting
74+
shader = new Shader('\
75+
varying vec3 color;\
76+
varying vec3 normal;\
77+
varying vec3 vertex;\
78+
varying vec3 light;\
79+
void main() {\
80+
const vec3 lightDir = vec3(1.0, 2.0, 3.0) / 3.741657386773941;\
81+
light = (gl_ModelViewMatrix * vec4(lightDir, 0.0)).xyz;\
82+
color = gl_Color;\
83+
normal = (gl_ModelViewMatrix * vec4(gl_Normal, 0.0)).xyz;\
84+
vertex = (gl_ModelViewMatrix * vec4(gl_Vertex, 1.0)).xyz;\
85+
gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex, 1.0);\
86+
}\
87+
', '\
88+
varying vec3 color;\
89+
varying vec3 normal;\
90+
varying vec3 vertex;\
91+
varying vec3 light;\
92+
void main() {\
93+
vec3 n = normalize(normal);\
94+
float diffuse = max(0.0, dot(light, n));\
95+
float specular = pow(max(0.0, dot(reflect(light, n), normalize(vertex))), 32.0) * sqrt(diffuse);\
96+
gl_FragColor = vec4(mix(color * (0.2 + 0.8 * diffuse), vec3(1.0), specular), 1.0);\
97+
}\
98+
');
99+
100+
gl.clearColor(0.75, 0.75, 0.75, 0);
101+
gl.fullscreen();
102+
gl.enable(gl.CULL_FACE);
103+
gl.autoDraw = false;
104+
draw();
105+
}
106+
107+
function mouseDragged() {
108+
angleX += deltaMouseY;
109+
angleY += deltaMouseX;
110+
angleX = Math.max(-90, Math.min(90, angleX));
111+
draw();
112+
}
113+
114+
function draw() {
115+
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
116+
117+
var scale = 5;
118+
var countX = Math.ceil(Math.sqrt(meshes.length));
119+
var countY = Math.ceil(meshes.length / countX);
120+
for (var i = 0; i < meshes.length; i++) {
121+
var mesh = meshes[i];
122+
var x = Math.floor(i % countX) / (countX - 1) * +2 - 1;
123+
var y = Math.floor(i / countX) / (countY - 1) * -2 + 1;
124+
gl.loadIdentity();
125+
gl.translate(x * scale * 1.5, y * scale, -3.5 * scale);
126+
gl.rotate(angleX, 1, 0, 0);
127+
gl.rotate(angleY, 0, 1, 0);
128+
129+
gl.enable(gl.POLYGON_OFFSET_FILL);
130+
gl.polygonOffset(1, 1);
131+
shader.draw(mesh);
132+
gl.disable(gl.POLYGON_OFFSET_FILL);
133+
134+
gl.enable(gl.BLEND);
135+
gl.disable(gl.DEPTH_TEST);
136+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
137+
gl.color(0, 0, 0, 0.2);
138+
gl.begin(gl.LINES);
139+
for (var j = 0; j < mesh.triangles.length; j++) {
140+
var tri = mesh.triangles[j];
141+
var a = Vector.fromArray(mesh.vertices[tri[0]]);
142+
var b = Vector.fromArray(mesh.vertices[tri[1]]);
143+
var c = Vector.fromArray(mesh.vertices[tri[2]]);
144+
gl.vertex(a); gl.vertex(b);
145+
gl.vertex(b); gl.vertex(c);
146+
gl.vertex(c); gl.vertex(a);
147+
}
148+
gl.end();
149+
gl.disable(gl.BLEND);
150+
gl.enable(gl.DEPTH_TEST);
151+
}
152+
}

0 commit comments

Comments
 (0)