xxxxxxxxxx
227
const testNewMethod = true
if (testNewMethod) p5.RendererGL.prototype._tesselateShape = function() {
this.immediateMode.shapeMode = TRIANGLES; //constants.TRIANGLES;
// const faceNormal = createVector(...computeFaceNormal(this.immediateMode.geometry.vertices));
let uDir, vDir, center;
const z = this.immediateMode.geometry.vertices[0].z;
let allSameZ = true;
for (const v of this.immediateMode.geometry.vertices) {
if (v.z !== z) {
allSameZ = false;
break;
}
}
if (!allSameZ) {
const faceNormal = createVector(computeFaceNormal(this.immediateMode.geometry.vertices));
const other = (faceNormal.y === 0 && faceNormal.z === 0)
? createVector(0, 1, 0)
: createVector(1, 0, 0);
uDir = faceNormal.cross(other).normalize();
vDir = faceNormal.cross(uDir);
center = this.immediateMode.geometry.vertices[0];
}
const contours = [
this._flatten(this.immediateMode.geometry.vertices.map((vert, i) => {
let u, v;
if (allSameZ) {
u = vert.x;
v = vert.y;
} else {
const relative = [vert.x - center.x, vert.y - center.y, vert.z - center.z];
u = relative[0]*uDir.x + relative[1]*uDir.y + relative[2]*uDir.z;
v = relative[0]*vDir.x + relative[1]*vDir.y + relative[2]*vDir.z;
}
return [
u,
v,
i,
// vert.x,
// vert.y,
// vert.z,
// this.immediateMode.geometry.uvs[i * 2],
// this.immediateMode.geometry.uvs[i * 2 + 1],
// this.immediateMode.geometry.vertexColors[i * 4],
// this.immediateMode.geometry.vertexColors[i * 4 + 1],
// this.immediateMode.geometry.vertexColors[i * 4 + 2],
// this.immediateMode.geometry.vertexColors[i * 4 + 3],
// this.immediateMode.geometry.vertexNormals[i].x,
// this.immediateMode.geometry.vertexNormals[i].y,
// this.immediateMode.geometry.vertexNormals[i].z
]
}))
];
const data = [];
const holes = [];
contours.forEach((contour, i) => {
if (i > 0) {
holes.push(data.length);
}
data.push(contour);
});
const dim = 3
const triangles = earcut(data, holes, dim);
const vertices = this.immediateMode.geometry.vertices;
const vertexNormals = this.immediateMode.geometry.vertexNormals;
const uvs = this.immediateMode.geometry.uvs;
this.immediateMode.geometry.vertices = [];
this.immediateMode.geometry.vertexNormals = [];
this.immediateMode.geometry.uvs = [];
const colors = [];
for (let k = 0; k < triangles.length; k++) {
const j = triangles[k];
const i = data[j * dim + 2];
colors.push(this.immediateMode.geometry.vertexColors.slice(i*4, i*4 + 4));
this.normal(vertexNormals[i].array());
this.vertex(
vertices[i].array(),
uvs[2 * i],
uvs[2 * i + 1],
);
// colors.push(...data.slice(j + 5 + 2, j + 9 + 2));
// this.normal(...data.slice(j + 9 + 2, j + 12 + 2));
// this.vertex(...data.slice(j + 2, j + 5 + 2));
}
this.immediateMode.geometry.vertexColors = colors;
};
function computeFaceNormal(vertices) {
const norm = [0, 0, 0];
const MAX_COORD = 1e50
var maxVal = [
-2 * MAX_COORD,
-2 * MAX_COORD,
-2 * MAX_COORD
];
var minVal = [
2 * MAX_COORD,
2 * MAX_COORD,
2 * MAX_COORD
];
var maxVert = [];
var minVert = [];
var v;
for (const v of vertices) {
if (v.x < minVal[0]) { minVal[0] = v.x; minVert[0] = v; }
if (v.x > maxVal[0]) { maxVal[0] = v.x; maxVert[0] = v; }
if (v.y < minVal[1]) { minVal[1] = v.y; minVert[1] = v; }
if (v.y > maxVal[1]) { maxVal[1] = v.y; maxVert[1] = v; }
if (v.z < minVal[2]) { minVal[2] = v.z; minVert[2] = v; }
if (v.z > maxVal[2]) { maxVal[2] = v.z; maxVert[2] = v; }
}
// Find two vertices separated by at least 1/sqrt(3) of the maximum
// distance between any two vertices
var index = 0;
if (maxVal[1] - minVal[1] > maxVal[0] - minVal[0]) { index = 1; }
if (maxVal[2] - minVal[2] > maxVal[index] - minVal[index]) { index = 2; }
if (minVal[index] >= maxVal[index]) {
// All vertices are the same -- normal doesn't matter
norm[0] = 0; norm[1] = 0; norm[2] = 1;
return norm;
}
// Look for a third vertex which forms the triangle with maximum area
// (Length of normal == twice the triangle area)
var maxLen2 = 0;
var v1 = minVert[index];
var v2 = maxVert[index];
var tNorm = [0, 0, 0];
var d1 = [
v1.x - v2.x,
v1.y - v2.y,
v1.z - v2.z
];
var d2 = [0, 0, 0];
for (const v of vertices) {
d2[0] = v.x - v2.x;
d2[1] = v.y - v2.y;
d2[2] = v.z - v2.z;
tNorm[0] = d1[1] * d2[2] - d1[2] * d2[1];
tNorm[1] = d1[2] * d2[0] - d1[0] * d2[2];
tNorm[2] = d1[0] * d2[1] - d1[1] * d2[0];
var tLen2 = tNorm[0] * tNorm[0] + tNorm[1] * tNorm[1] + tNorm[2] * tNorm[2];
if (tLen2 > maxLen2) {
maxLen2 = tLen2;
norm[0] = tNorm[0];
norm[1] = tNorm[1];
norm[2] = tNorm[2];
}
}
if (maxLen2 <= 0) {
// All points lie on a single line -- any decent normal will do
norm[0] = norm[1] = norm[2] = 0;
norm[longAxis(d1)] = 1;
}
return norm;
}
function longAxis(v) {
var i = 0;
if (Math.abs(v[1]) > Math.abs(v[0])) {
i = 1;
}
if (Math.abs(v[2]) > Math.abs(v[i])) {
i = 2;
}
return i;
};
let tree
var a,b,c,d,e;
var qube;
let avgFrameRates = [];
let frameRateSum = 0;
const numSamples = 30;
function setup(){
fps = createP()
createCanvas(600,600, WEBGL)
setAttributes({ antialias: true })
a = CSG.cube();
b = CSG.sphere({ radius: 1.35, stacks: 12 });
c = CSG.cylinder({ radius: 0.7, start: [-1, 0, 0], end: [1, 0, 0] });
d = CSG.cylinder({ radius: 0.7, start: [0, -1, 0], end: [0, 1, 0] });
e = CSG.cylinder({ radius: 0.7, start: [0, 0, -1], end: [0, 0, 1] });
// qube = a.intersect(b)
// qube = qube.subtract(c.union(d).union(e))
qube = a.intersect(b).subtract(c.union(d).union(e)).toPolygons()
}
function draw(){
textureMode(NORMAL)
background(127)
orbitControl();
push()
//translate(120,0,0)
fill(200)
makeCSG()
pop()
const rate = frameRate() / numSamples;
avgFrameRates.push(rate);
frameRateSum += rate;
if (avgFrameRates.length > numSamples) frameRateSum -= avgFrameRates.shift();
fps.html(round(frameRateSum) + ' avg fps');
}
function makeCSG(){
for(let p=0; p<qube.length; p++){
myp = qube[p]
beginShape(TESS)
for(let v=0; v<myp.vertices.length; v++){
myv = myp.vertices[v].pos
// print(myv)
vertex(myv.x*100,myv.y*100,myv.z*100)
}
endShape()
}
}