先展示效果图
适用场景:加载的obj模型需要发生形变,同时还要展示模型的纹理效果,可以使用到面料模拟或者弹性物体的模拟当中
具体实现方案:
1、读取obj文件中的vt的值,存起来
2、读取f值,存v索引和vt索引
3、根据存储的v索引和vt索引新增uv数据
4、将整个uv数组放入到模型当中
5、读取模型的uv,使用纹理加载器加载图片,放入到模型上
然后就是上代码了~
function loadFromUrl(url) {
return fetch(url)
.then(response => response.text())
.then(objData => {
const lines = objData.split('\n');
let vertices = [];
let faceTriIds = [];
let vt = [];
let uv = [];
let uvIndex = [];
for (const line of lines) {
const parts = line.split(' ').filter(part => part!== '');
if (parts[0] === 'v') {
// 将顶点坐标依次存入一维数组
vertices.push(parseFloat(parts[1]));
vertices.push(parseFloat(parts[2]));
vertices.push(parseFloat(parts[3]));
} else if (parts[0] === 'f') {
const facePart = parts[1].split('/');
const facePart02 = parts[2].split('/');
const facePart03 = parts[3].split('/');
faceTriIds.push(Number(facePart[0])-1,Number(facePart02[0])-1,Number(facePart03[0])-1);
// 获取uv的索引-->找到值存入uv中
uvIndex[Number(facePart[0])-1] = Number(facePart[1])-1
uvIndex[Number(facePart02[0])-1] = Number(facePart02[1])-1
uvIndex[Number(facePart03[0])-1] = Number(facePart03[1])-1
} else if (parts[0] === 'vt') {
vt.push(parseFloat(parts[1]),parseFloat(parts[2]))
}
}
// 遍历uv --> 根据索引找到具体的uv值
for (let i = 0; i < uvIndex.length; i++) {
uv[i*2] = vt[uvIndex[i]*2]
uv[i*2+1] = vt[uvIndex[i]*2+1]
}
return { vertices, faceTriIds, uv };
})
.catch(error => {
console.error('Error loading OBJ file from URL:', error);
return null;
});
}
export default loadFromUrl;
应该还算清晰明了的吧
就这样~~~~