Hello,
I started working with a library called IFC.js which is a library that helps visualize IFC files (architectural 3D models).
This library works with BufferGeometry without uv - because these files doesn’t have this information.
So I found an algorithm that should calculate the uv automatically so I can put textures on objects.
The problem is that the texture loading on the object looks exactly the same before and after this algorithm - it looks like one color and not like the image.
I tried to set the uv values randomly just to see a change, but nothing changes.
Here is my code - its very ugly because i just wanted it to work:
function assignUVs(geometry: BufferGeometry) {
const positionsArray = geometry.getAttribute('position').array;
const normalsArray = geometry.getAttribute('normal').array;
const vertices = [];
const normals = [];
for (let i = 0; i < positionsArray.length; i=i+3){
vertices.push(new THREE.Vector3(positionsArray[i], positionsArray[i+1], positionsArray[i+2]));
normals.push(new THREE.Vector3(normalsArray[i], normalsArray[i+1], normalsArray[i+2]));
}
const uvs = new Float32Array(vertices.length * 2);
let uvsIdx = 0;
const indices = geometry.index?.array || [];
for (let i = 0; i < indices.length; i=i+3){
const normal = new THREE.Vector3().crossVectors(
new THREE.Vector3().subVectors(normals[indices[i+1]], normals[indices[i]]),
new THREE.Vector3().subVectors(normals[indices[i+2]], normals[indices[i]])
)
const face = {
a: vertices[indices[i]],
b: vertices[indices[i+1]],
c: vertices[indices[i+2]],
normal
}
var components = ['x', 'y', 'z'].sort(function(a, b) {
return Math.abs((face.normal as any)[a]) > Math.abs((face.normal as any)[b]) ? 1 : 0;
});
var v1 = face.a;
var v2 = face.b;
var v3 = face.c;
uvs[uvsIdx] = (v1 as any)[components[0]];
uvs[uvsIdx+1] = (v1 as any)[components[1]];
uvs[uvsIdx+2] = (v2 as any)[components[0]];
uvs[uvsIdx+3] = (v2 as any)[components[1]];
uvs[uvsIdx+4] = (v3 as any)[components[0]];
uvs[uvsIdx+5] = (v3 as any)[components[1]];
uvsIdx = uvsIdx + 6;
}
const attr = new THREE.BufferAttribute(uvs, 2);
attr.needsUpdate = true;
geometry.setAttribute('uv', attr);
}
and this is the code outside of this function:
assignUVs(subset.geometry);
const floorTexture = new THREE.TextureLoader().load( '../../textures/door3.jpg' );
const floorMaterial = new THREE.MeshBasicMaterial( { map: floorTexture } );
subset.material = floorMaterial;
Does anyone has any idea?
Thanks a lot!