简体   繁体   中英

Threejs: How can one export with GLTFExporter an indexed geometry with draw range?

I have a specific problem, I would like to export an indexed geomtry that has a drawrange. Using the GLTFExporter, after having faced the issue with typescript integration (known issue apparently), I had the bad luck to discover that this was not implemented in the exporter:

// @TODO Indexed buffer geometry with drawRange not supported yet

https://github.com/mrdoob/three.js/blob/master/examples/js/exporters/GLTFExporter.js line 564

Checking the commit history showed me that the last update was 3 months ago and I don't think this is gonna come any time soon. I tried to remove the index buffer and rewrite my position bufferattribute array base on my draw range but I must do something wrong because it does not work, it simply breaks my geometry. Would any of you have a work around for me or some explainations on how to proceed with my geometry?

Thank you in advance.

EDIT:

My current work-around is to "de-index" my geometry for the export and keep the drawRange, this case is handled by the exporter. It is not ideal, and it forces me to recreate a full new geometry with new BufferAttributes. But since this operation is only done for the export, I can even have this process happening in an asynchronous way. I wish there was a better way.

Regarding the two variables, this is something I'm going to address in the following PR to make it part of the WebGLUtils and just import it. It doesn't make sense that each one that needs these constants need to redefine them again every time.

As mentionned in my edit, I bypassed my problem by de-indexing of my geometry, it is not the best solution, but since I only need it for this export, here is how I proceeded:

// original attributes
const vertices  = geometryTmp.getAttribute("position");
const normals  = geometryTmp.getAttribute("normal");
const uv  = geometryTmp.getAttribute("uv");

// new buffer arrays
let verticesTmp = new Float32Array(3 * geometryTmp.index.array.length);
let normalTmp = new Float32Array(3 * geometryTmp.index.array.length);
let uvTmp = new Float32Array(2 * geometryTmp.index.array.length);


let j = 0;
for(let i = 0; i < verticesTmp.length; i += 3) {
    let index = geometryTmp.index.array[j];
    verticesTmp[i] = vertices.getX(index);
    verticesTmp[i+1] = vertices.getY(index);
    verticesTmp[i+2] = vertices.getZ(index);

    normalTmp[i] = normals.getX(index);
    normalTmp[i+1] = normals.getY(index);
    normalTmp[i+2] = normals.getZ(index);
    j++;

}

j = 0;
for(let i = 0; i < uvTmp.length; i += 2) {
    let index = geometryTmp.index.array[j];
    uvTmp[i] = uv.getX(index);
    uvTmp[i+1] = uv.getY(index);
    j++;
}

let newGeomtry = new THREE.BufferGeometry();
newGeomtry.addAttribute( 'position', new THREE.BufferAttribute( verticesTmp, 3 ) );
newGeomtry.addAttribute( 'normal', new THREE.BufferAttribute( normalTmp, 3 ) );
newGeomtry.addAttribute( 'uv', new THREE.BufferAttribute( uvTmp, 2 ) );

newGeomtry.drawRange = geometryTmp.drawRange;
mesh.geometry = newGeomtry;  

// After I do that to all the meshes I need, them to a new THREE.Scene that will be given to the exporter with truncateDrawRange = true

I hope it helps someone too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM