假如有一个私有格式的3D文件(3dfile.jw3d),我们根绝制定的数据规则将私有格式的3D文件解析成threejs的geometry对象
function parse(data) {
const headerObj = readHeader(data)
const arrayBuffer = text;
let buffer = {
indices: [], // 面对应的顶点索引
vertices: [], //顶点数据
normals: [], //法向量
uvs: [], // uv坐标
faceVerticesUvs:[], // 面上顶点uv
color: [] // 颜色
}
const body = new DataView(data);
let offset = 16; //头文件长度
// 取出 xyz 和 rgb
for (let i = 0; i < headerObj.vertex_count; i++) {
buffer.vertices.push(
body.getFloat32(offset, true), // V
body.getFloat32(offset+4*1, true), // Y
body.getFloat32(offset+4*2, true), // Z
)
buffer.colors.push(
body.getFloat32(offset+4*3, true), // R
body.getFloat32(offset+4*4, true), // G
body.getFloat32(offset+4*5, true), // B
)
offset += 4*6;
}
for (let i = 0; i < headerObj.face_count; i++) {
buffer.indices.push(
body.getInt32(offset, true),
body.getInt32(offset+4*1, true),
body.getInt32(offset+4*2, true),
)
offset += 4*3;
}
let geometry = new BufferGeometry();
if (buffer.indices.length > 0) {
geometry.setIndex(buffer.indices);
}
geometry.setAttribute('position', new Float32BufferAttribute(buffer.vertices, 3));
if (buffer.normals.length) {
geometry.setAttribute('normal', new Float32BufferAttribute(buffer.normals, 3));
}
if (buffer.uvs.length) {
geometry.setAttribute('uv', new Float32BufferAttribute(buffer.uvs, 2));
}
if (buffer.color.length) {
geometry.setAttribute('uv', new Float32BufferAttribute(buffer.color, 3));
}
if (buffer.faceVerticesUvs.length) {
geometry = geometry.toNonIndexed();
geometry.setAttribute('uv', new Float32BufferAttribute(buffer.faceVerticesUvs, 2));
}
geometry.computeBoundingSphere();
return geometry;
}
function readHeader(data) {
const header = new Uint32Array(data);
const vertex_count = header[2];
const face_count = header[3];
return {vertex_count, face_count}
}