Skip to content

Instantly share code, notes, and snippets.

@Ni55aN
Created December 20, 2017 21:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ni55aN/94d322d304a8ffc417dc0cf05d3ad531 to your computer and use it in GitHub Desktop.
Save Ni55aN/94d322d304a8ffc417dc0cf05d3ad531 to your computer and use it in GitHub Desktop.
const fs = require('fs');
const draco3d = require('draco3d');
const js2obj = require('./js2obj');
const decoderModule = draco3d.createDecoderModule({});
const encoderModule = draco3d.createEncoderModule({});
var data = fs.readFileSync('./testdata/bunny.drc');
const decoder = new decoderModule.Decoder();
const decodedGeometry = decodeDracoData(data);
fs.writeFileSync('bunny_10.drc', encodeMeshToBuffer(decodedGeometry), 'binary')
///fs.writeFileSync('bunny.obj', meshToObj(decodedGeometry));
decoderModule.destroy(decoder);
decoderModule.destroy(decodedGeometry);
function decodeDracoData(rawBuffer) {
const buffer = new decoderModule.DecoderBuffer();
buffer.Init(new Int8Array(rawBuffer), rawBuffer.byteLength);
const geometryType = decoder.GetEncodedGeometryType(buffer);
let dracoGeometry;
let status;
if (geometryType === decoderModule.TRIANGULAR_MESH) {
dracoGeometry = new decoderModule.Mesh();
status = decoder.DecodeBufferToMesh(buffer, dracoGeometry);
} else if (geometryType === decoderModule.POINT_CLOUD) {
dracoGeometry = new decoderModule.PointCloud();
status = decoder.DecodeBufferToPointCloud(buffer, dracoGeometry);
} else {
const errorMsg = 'Error: Unknown geometry type.';
console.error(errorMsg);
}
decoderModule.destroy(buffer);
return dracoGeometry;
}
function getObjData(mesh) {
const numFaces = mesh.num_faces();
const numPoints = mesh.num_points();
const indices = new Uint32Array(numFaces * 3);
console.log('Number of faces ' + numFaces+', Number of points:'+numPoints);
const ia = new decoderModule.DracoInt32Array();
for (let i = 0; i < numFaces; ++i) {
decoder.GetFaceFromMesh(mesh, i, ia);
const index = i * 3;
indices[index] = ia.GetValue(0);
indices[index + 1] = ia.GetValue(1);
indices[index + 2] = ia.GetValue(2);
}
decoderModule.destroy(ia);
const attrs = {POSITION: 3, NORMAL: 3, COLOR: 3, TEX_COORD: 2};
var attributes = [];
Object.keys(attrs).forEach(attr => {
const stride = attrs[attr];
const numValues = numPoints * stride;
const decoderAttr = decoderModule[attr];
const attrId = decoder.GetAttributeId(mesh, decoderAttr);
if (attrId < 0) {
return;
}
console.log('Adding %s attribute', attr);
const attribute = decoder.GetAttribute(mesh, attrId);
const attributeData = new decoderModule.DracoFloat32Array();
decoder.GetAttributeFloatForAllPoints(mesh, attribute, attributeData);
attributes[attr] = new Float32Array(numValues);
for (let i = 0; i < numValues; ++i) {
attributes[attr][i] = attributeData.GetValue(i);
}
decoderModule.destroy(attributeData);
});
return { indices, attributes };
}
function meshToObj(mesh) {
var { indices, attributes } = getObjData(mesh);
return js2obj(indices, attributes['POSITION']);
}
function encodeMeshToBuffer(mesh) {
const encoder = new encoderModule.Encoder();
const meshBuilder = new encoderModule.MeshBuilder();
const newMesh = new encoderModule.Mesh();
const numPoints = mesh.num_points();
var { indices, attributes } = getObjData(mesh);
meshBuilder.AddFacesToMesh(newMesh, mesh.num_faces(), indices);
const attrs = {POSITION: 3, NORMAL: 3, COLOR: 3, TEX_COORD: 2};
Object.keys(attrs).forEach((attr) => {
const stride = attrs[attr];
const encoderAttr = encoderModule[attr];
if (!attributes[attr])
return;
meshBuilder.AddFloatAttributeToMesh(newMesh, encoderAttr, numPoints,
stride, attributes[attr]);
});
let encodedData = new encoderModule.DracoInt8Array();
encoder.SetSpeedOptions(5, 5);
encoder.SetAttributeQuantization(encoderModule.POSITION, 10);
encoder.SetEncodingMethod(encoderModule.MESH_EDGEBREAKER_ENCODING);
console.log('Encoding...');
const encodedLen = encoder.EncodeMeshToDracoBuffer(newMesh,
encodedData);
encoderModule.destroy(newMesh);
if (encodedLen > 0) {
console.log('Encoded size is ' + encodedLen);
} else {
console.log('Error: Encoding failed.');
}
// Copy encoded data to buffer.
const outputBuffer = new ArrayBuffer(encodedLen);
const outputData = new Int8Array(outputBuffer);
for (let i = 0; i < encodedLen; ++i) {
outputData[i] = encodedData.GetValue(i);
}
encoderModule.destroy(encodedData);
encoderModule.destroy(encoder);
encoderModule.destroy(meshBuilder);
return Buffer(outputBuffer);
}
function createObj(indices, positions) {
var lines = '';
for (var i = 0; i < positions.length; i += 3) {
var p1 = positions[i];
var p2 = positions[i+1];
var p3 = positions[i + 2];
lines += `v ${p1} ${p2} ${p3}\n`;
}
for (var i = 0; i < indices.length; i += 3) {
var f1 = indices[i];
var f2 = indices[i+1];
var f3 = indices[i + 2];
lines += `f ${f1+1} ${f2+1} ${f3+1}\n`;
}
return lines;
}
module.exports = createObj;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment