Hi,
I’m having an issue displaying a generated mesh.
The weird thing is that when I display it as wireframe, everything is fine. But when I want to display the faces themselves, I only get a few.
Here’s my code :
function generateCylinderMeshFromArmature(armature, cylinderResolution, cylinderRadius)
{
const armatureCount = armature.length;
//generate vertices
let generatedVertices = [];
//for each armature vertex
for (let armatureVertexIndex = 0; armatureVertexIndex < armatureCount; armatureVertexIndex++) {
const currentVertice = armature[armatureVertexIndex];
let previousVertice = undefined;
if(armatureVertexIndex > 0)
{
previousVertice = armature[armatureVertexIndex - 1];
}
let nextVertice = undefined;
if(armatureVertexIndex < armatureCount - 1)
{
nextVertice = armature[armatureVertexIndex + 1];
}
let averageForwardDirection = new Vector3(0,0,0);
if(previousVertice && nextVertice)
{
const previousToCurrent = new Vector3(0,0,0);
previousToCurrent.subVectors(currentVertice, previousVertice);
previousToCurrent.normalize();
const currentToNext = new Vector3(0,0,0);
currentToNext.subVectors(nextVertice, currentVertice);
currentToNext.normalize();
averageForwardDirection.addVectors(previousToCurrent, currentToNext);
}
else if(previousVertice)
{
averageForwardDirection.subVectors(currentVertice, previousVertice);
}
else if(nextVertice)
{
averageForwardDirection.subVectors(nextVertice, currentVertice);
}
else
{
console.warn('Error : couldn\'t get direction of vertice');
}
averageForwardDirection.normalize();
const random = new Vector3(0, 1, 0)
var up = new Vector3(0,0,0);
up.crossVectors(averageForwardDirection, random);
var right = new Vector3(0,0,0);
right.crossVectors(averageForwardDirection,up);
up.normalize();
right.normalize();
//for each vertex of the circle
for(let meshCircleIndex = 0; meshCircleIndex < cylinderResolution; meshCircleIndex++)
{
let verticalComponent = new Vector3(0,0,0);
verticalComponent.copy(up);
verticalComponent.multiplyScalar(Math.cos((meshCircleIndex / cylinderResolution) * 2 * Math.PI) * cylinderRadius);
let horizontalComponent = new Vector3(0,0,0);
horizontalComponent.copy(right);
horizontalComponent.multiplyScalar(Math.sin((meshCircleIndex / cylinderResolution) * 2 * Math.PI) * cylinderRadius);
let newVertice = new Vector3(0,0,0);
newVertice.copy(currentVertice);
newVertice.add(verticalComponent);
newVertice.add(horizontalComponent);
generatedVertices[armatureVertexIndex * cylinderResolution + meshCircleIndex] = newVertice;
}
}
generatedVertices.push(armature[0]);
generatedVertices.push(armature[armatureCount - 1]);
//generate triangles
// const generatedTriangles = new Uint32Array(cylinderResolution * (armatureCount - 1) * 2 * 3 + 2 * cylinderResolution * 3);
const generatedTriangles = [];
for (let armatureVertexIndex = 0; armatureVertexIndex < armatureCount - 1; armatureVertexIndex++)
{
for(let meshCircleIndex = 0; meshCircleIndex < cylinderResolution - 1; meshCircleIndex++)
{
generatedTriangles[armatureVertexIndex * cylinderResolution * 2 * 3 + meshCircleIndex * 2 * 3 + 1] = armatureVertexIndex * cylinderResolution + meshCircleIndex + 1;
generatedTriangles[armatureVertexIndex * cylinderResolution * 2 * 3 + meshCircleIndex * 2 * 3 + 0] = armatureVertexIndex * cylinderResolution + meshCircleIndex;
generatedTriangles[armatureVertexIndex * cylinderResolution * 2 * 3 + meshCircleIndex * 2 * 3 + 2] = (armatureVertexIndex + 1) * cylinderResolution + meshCircleIndex;
generatedTriangles[armatureVertexIndex * cylinderResolution * 2 * 3 + meshCircleIndex * 2 * 3 + 4] = (armatureVertexIndex + 1) * cylinderResolution + meshCircleIndex + 1;
generatedTriangles[armatureVertexIndex * cylinderResolution * 2 * 3 + meshCircleIndex * 2 * 3 + 3] = armatureVertexIndex * cylinderResolution + meshCircleIndex + 1;
generatedTriangles[armatureVertexIndex * cylinderResolution * 2 * 3 + meshCircleIndex * 2 * 3 + 5] = (armatureVertexIndex + 1) * cylinderResolution + meshCircleIndex;
}
//for the last face of the cylinder contour
generatedTriangles[armatureVertexIndex * cylinderResolution * 2 * 3 + (cylinderResolution - 1) * 2 * 3 + 1] = armatureVertexIndex * cylinderResolution + 0;
generatedTriangles[armatureVertexIndex * cylinderResolution * 2 * 3 + (cylinderResolution - 1) * 2 * 3 + 0] = armatureVertexIndex * cylinderResolution + (cylinderResolution - 1);
generatedTriangles[armatureVertexIndex * cylinderResolution * 2 * 3 + (cylinderResolution - 1) * 2 * 3 + 2] = (armatureVertexIndex + 1) * cylinderResolution + (cylinderResolution - 1);
generatedTriangles[armatureVertexIndex * cylinderResolution * 2 * 3 + (cylinderResolution - 1) * 2 * 3 + 4] = (armatureVertexIndex + 1) * cylinderResolution + 0;
generatedTriangles[armatureVertexIndex * cylinderResolution * 2 * 3 + (cylinderResolution - 1) * 2 * 3 + 3] = armatureVertexIndex * cylinderResolution + 0;
generatedTriangles[armatureVertexIndex * cylinderResolution * 2 * 3 + (cylinderResolution - 1) * 2 * 3 + 5] = (armatureVertexIndex + 1) * cylinderResolution + (cylinderResolution - 1);
}
let generatedTrianglesIndex = cylinderResolution * (armatureCount - 1) * 2 * 3;
for(let i = 0; i < cylinderResolution - 1; i++)
{
generatedTriangles[generatedTrianglesIndex++] = i;
generatedTriangles[generatedTrianglesIndex++] = i + 1;
generatedTriangles[generatedTrianglesIndex++] = generatedVertices.length - 2;
generatedTriangles[generatedTrianglesIndex++] = generatedVertices.length - 2 - cylinderResolution + i;
generatedTriangles[generatedTrianglesIndex++] = generatedVertices.length - 2 - cylinderResolution + i + 1;
generatedTriangles[generatedTrianglesIndex++] = generatedVertices.length - 1;
}
generatedTriangles[generatedTrianglesIndex++] = cylinderResolution - 1;
generatedTriangles[generatedTrianglesIndex++] = 0;
generatedTriangles[generatedTrianglesIndex++] = generatedVertices.length - 2;
generatedTriangles[generatedTrianglesIndex++] = generatedVertices.length - 3;
generatedTriangles[generatedTrianglesIndex++] = generatedVertices.length - 2 - cylinderResolution;
generatedTriangles[generatedTrianglesIndex++] = generatedVertices.length - 1;
//generate mesh
const geom = new THREE.BufferGeometry();
geom.setAttribute('position', new THREE.Float32BufferAttribute(vector3ArrayToFloat32Array(generatedVertices), 3));
geom.setIndex( new THREE.Uint32BufferAttribute(generatedTriangles, 3));
// geom.setIndex(generatedTriangles);
// geom.computeFaceNormals();
const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
// var material = new THREE.MeshPhongMaterial({ color: 0xff0000 } );
const wireframeMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe : true } );
const wireframeMesh = new THREE.Mesh(geom, wireframeMaterial);
scene.add(wireframeMesh);
const generatedMesh = new THREE.Mesh(geom, material);
generatedMesh.position.set( 0, 0, 0);
generatedMesh.updateMatrix();
generatedMesh.geometry.computeFaceNormals();
return generatedMesh;
}
The function takes as a parameter an armature around which I have to draw the cylinder. I also have a resolution (the number of vertices per cylinder circle), and a radius.
I call he function like so :
let armature = [];
armature.push(new Vector3(0,0,0));
armature.push(new Vector3(0,0,1));
armature.push(new Vector3(1,0,1));
armature.push(new Vector3(1,0,-1));
armature.push(new Vector3(-1,0,-1));
armature.push(new Vector3(-1,0,2));
armature.push(new Vector3(2,0,2));
armature.push(new Vector3(2,0,-2));
armature.push(new Vector3(-2,0,-2));
armature.push(new Vector3(-2,0,3));
armature.push(new Vector3(3,0,3));
const armaturesCylinderMesh = generateCylinderMeshFromArmature(armature, 10, 0.3);
scene.add(armaturesCylinderMesh);
As you can see, I commented some of the instructions I tried to solve the problem.
Also, interesting fact, when i use
geom.setIndex( new THREE.Int32BufferAttribute(generatedTriangles, 3));
instead of
geom.setIndex( new THREE.Uint32BufferAttribute(generatedTriangles, 3));
, I get this error : GL_INVALID_ENUM: Enum is not currently supported.
which makes no sense at all…
Any ideas ? Thanks