Mike_Device
Mike_Device

Reputation: 672

Draw .obj file with Three.js without native OBJLoader

I need to draw .obj file, without its loading. For example I have .obj file with follow content

v 0.1 0.2 0.3
v 0.2 0.1 0.5
vt 0.5 -1.3
vn 0.7 0.0 0.7
f 1 2 3

I read this file, parse content and have its data in a JavaScript object.

{
  v: [
    {x:0.1, 0.2, 0.3}
    {x:0.2, 0.1, 0.5}
  ],
  vt: [
    {u: 0.5, v: -1.3}
  ],
  vn: [
    {x: 0.7, 0.0, 0.7}
  ],
  f: [
    // ...
  ]
}

Next I need to draw this data with three.js. I read documentation, but can't find any example or description how to do it. Who knows? Is there any method for that purpose?

Upvotes: 0

Views: 214

Answers (1)

Rasheduzzaman Sourov
Rasheduzzaman Sourov

Reputation: 1515

First question is, why wont you use THREE.ObjLoader ? The reason is not clear to me. There could be so much different test cases for loading obj file. Its better to use THREE.ObjLoader.

If you cant use that then My preferred way would be to create a THREE.BufferGeometry. We are going to create some THREE.BufferAttribute from the arrays of your javascript object. One THREE.BufferAttribute for each vertex attribute. Also, we gonna set the index buffer. Here is a function to do it -

function make_3D_object(js_object) {

    let vertices = new Float32Array(js_object.v);
    let uvs = new Float32Array(js_object.vt);
    let normals = new Float32Array(js_object.vn);

    let indices = new Uint8Array(js_object.f);

    // this is to make it 0 indexed
    for(let i = 0; i < indices.length; i++)
        indices[i]--;


    let geom = new THREE.BufferGeometry();
    geom.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
    geom.addAttribute('normal', new THREE.BufferAttribute(normals, 3));
    geom.addAttribute('uv', new THREE.BufferAttribute(uvs, 2));
    geom.setIndex(new THREE.BufferAttribute(indices, 1));


    let material = new THREE.MeshPhongMaterial( {
        map: js_object.texture, // assuming you have texture
        color: new THREE.Color().setRGB(1, 1, 1),
        specular: new THREE.Color().setRGB(0, 0,0 )
    } );


    let obj_mesh = new THREE.Mesh(geom, material);

    return obj_mesh;
}

In this code i have assumed you have only a single body, a single material with only a texture. Also this code is not tested.

Upvotes: 1

Related Questions