Created
December 20, 2017 21:34
-
-
Save Ni55aN/94d322d304a8ffc417dc0cf05d3ad531 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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