mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-09-12 23:13:16 +08:00
Updating draco decoder javascript API and other minor changes.
1. Javascript decoder is now exported as a module using DracoModule() function that needs to be instantiated on the client. 2. Updated Javascript example applications and README.md 3. Added normalization function to VectorD 4. Added support for converting a single signed value to symbol for entropy coding and vice versa 5. Minor code cleaning
This commit is contained in:
parent
931a1de144
commit
127484be47
@ -56,6 +56,9 @@ ALL_C_OPTS += -O3
|
|||||||
ALL_C_OPTS += -s ALLOW_MEMORY_GROWTH=1
|
ALL_C_OPTS += -s ALLOW_MEMORY_GROWTH=1
|
||||||
#ALL_C_OPTS += -s TOTAL_MEMORY=67108864
|
#ALL_C_OPTS += -s TOTAL_MEMORY=67108864
|
||||||
|
|
||||||
|
# Export the main module as "DracoModule".
|
||||||
|
ALL_C_OPTS += -s MODULARIZE=1 -s EXPORT_NAME="'DracoModule'"
|
||||||
|
|
||||||
# Do not create a .mem file.
|
# Do not create a .mem file.
|
||||||
ALL_C_OPTS += --memory-init-file 0
|
ALL_C_OPTS += --memory-init-file 0
|
||||||
|
|
||||||
|
16
README.md
16
README.md
@ -319,28 +319,30 @@ Javascript Decoder API
|
|||||||
|
|
||||||
The Javascript decoder is located in `javascript/draco_decoder.js`. The
|
The Javascript decoder is located in `javascript/draco_decoder.js`. The
|
||||||
Javascript decoder can decode mesh and point cloud. In order to use the
|
Javascript decoder can decode mesh and point cloud. In order to use the
|
||||||
decoder you must first create `DecoderBuffer` and `WebIDLWrapper` objects. Set
|
decoder, you must first create an instance of `DracoModule`. The instance is
|
||||||
|
then used to create `DecoderBuffer` and `WebIDLWrapper` objects. Set
|
||||||
the encoded data in the `DecoderBuffer`. Then call `GetEncodedGeometryType()`
|
the encoded data in the `DecoderBuffer`. Then call `GetEncodedGeometryType()`
|
||||||
to identify the type of geometry, e.g. mesh or point cloud. Then call either
|
to identify the type of geometry, e.g. mesh or point cloud. Then call either
|
||||||
`DecodeMeshFromBuffer()` or `DecodePointCloudFromBuffer()`, which will return
|
`DecodeMeshFromBuffer()` or `DecodePointCloudFromBuffer()`, which will return
|
||||||
a Mesh object or a point cloud. For example:
|
a Mesh object or a point cloud. For example:
|
||||||
|
|
||||||
~~~~~ js
|
~~~~~ js
|
||||||
const buffer = new Module.DecoderBuffer();
|
const dracoDecoder = DracoModule();
|
||||||
|
const buffer = new dracoDecoder.DecoderBuffer();
|
||||||
buffer.Init(encFileData, encFileData.length);
|
buffer.Init(encFileData, encFileData.length);
|
||||||
|
|
||||||
const wrapper = new Module.WebIDLWrapper();
|
const wrapper = new dracoDecoder.WebIDLWrapper();
|
||||||
const geometryType = wrapper.GetEncodedGeometryType(buffer);
|
const geometryType = wrapper.GetEncodedGeometryType(buffer);
|
||||||
let outputGeometry;
|
let outputGeometry;
|
||||||
if (geometryType == Module.TRIANGULAR_MESH) {
|
if (geometryType == dracoDecoder.TRIANGULAR_MESH) {
|
||||||
outputGeometry = wrapper.DecodeMeshFromBuffer(buffer);
|
outputGeometry = wrapper.DecodeMeshFromBuffer(buffer);
|
||||||
} else {
|
} else {
|
||||||
outputGeometry = wrapper.DecodePointCloudFromBuffer(buffer);
|
outputGeometry = wrapper.DecodePointCloudFromBuffer(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Module.destroy(outputGeometry);
|
dracoDecoder.destroy(outputGeometry);
|
||||||
Module.destroy(wrapper);
|
dracoDecoder.destroy(wrapper);
|
||||||
Module.destroy(buffer);
|
dracoDecoder.destroy(buffer);
|
||||||
~~~~~
|
~~~~~
|
||||||
|
|
||||||
Please see `javascript/emscripten/draco_web.idl` for the full API.
|
Please see `javascript/emscripten/draco_web.idl` for the full API.
|
||||||
|
@ -25,16 +25,19 @@ namespace draco {
|
|||||||
void ConvertSymbolsToSignedInts(const uint32_t *in, int in_values,
|
void ConvertSymbolsToSignedInts(const uint32_t *in, int in_values,
|
||||||
int32_t *out) {
|
int32_t *out) {
|
||||||
for (int i = 0; i < in_values; ++i) {
|
for (int i = 0; i < in_values; ++i) {
|
||||||
uint32_t val = in[i];
|
out[i] = ConvertSymbolToSignedInt(in[i]);
|
||||||
const bool is_negative = (val & 1);
|
|
||||||
val >>= 1;
|
|
||||||
int32_t ret = static_cast<int32_t>(val);
|
|
||||||
if (is_negative)
|
|
||||||
ret = -ret - 1;
|
|
||||||
out[i] = ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t ConvertSymbolToSignedInt(uint32_t val) {
|
||||||
|
const bool is_negative = (val & 1);
|
||||||
|
val >>= 1;
|
||||||
|
int32_t ret = static_cast<int32_t>(val);
|
||||||
|
if (is_negative)
|
||||||
|
ret = -ret - 1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
template <template <int> class SymbolDecoderT>
|
template <template <int> class SymbolDecoderT>
|
||||||
bool DecodeTaggedSymbols(int num_values, int num_components,
|
bool DecodeTaggedSymbols(int num_values, int num_components,
|
||||||
DecoderBuffer *src_buffer, uint32_t *out_values);
|
DecoderBuffer *src_buffer, uint32_t *out_values);
|
||||||
|
@ -24,6 +24,10 @@ namespace draco {
|
|||||||
void ConvertSymbolsToSignedInts(const uint32_t *in, int in_values,
|
void ConvertSymbolsToSignedInts(const uint32_t *in, int in_values,
|
||||||
int32_t *out);
|
int32_t *out);
|
||||||
|
|
||||||
|
// Converts a single unsigned integer symbol encoded with an entropy encoder
|
||||||
|
// back to a signed value.
|
||||||
|
int32_t ConvertSymbolToSignedInt(uint32_t val);
|
||||||
|
|
||||||
// Decodes an array of symbols that was previously encoded with an entropy code.
|
// Decodes an array of symbols that was previously encoded with an entropy code.
|
||||||
// Returns false on error.
|
// Returns false on error.
|
||||||
bool DecodeSymbols(int num_values, int num_components,
|
bool DecodeSymbols(int num_values, int num_components,
|
||||||
|
@ -33,17 +33,20 @@ void ConvertSignedIntsToSymbols(const int32_t *in, int in_values,
|
|||||||
// encoding.
|
// encoding.
|
||||||
// Put the sign bit into LSB pos and shift the rest one bit left.
|
// Put the sign bit into LSB pos and shift the rest one bit left.
|
||||||
for (int i = 0; i < in_values; ++i) {
|
for (int i = 0; i < in_values; ++i) {
|
||||||
int32_t val = in[i];
|
out[i] = ConvertSignedIntToSymbol(in[i]);
|
||||||
const bool is_negative = (val < 0);
|
|
||||||
if (is_negative)
|
|
||||||
val = -val - 1; // Map -1 to 0, -2 to -1, etc..
|
|
||||||
val <<= 1;
|
|
||||||
if (is_negative)
|
|
||||||
val |= 1;
|
|
||||||
out[i] = static_cast<uint32_t>(val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ConvertSignedIntToSymbol(int32_t val) {
|
||||||
|
const bool is_negative = (val < 0);
|
||||||
|
if (is_negative)
|
||||||
|
val = -val - 1; // Map -1 to 0, -2 to -1, etc..
|
||||||
|
val <<= 1;
|
||||||
|
if (is_negative)
|
||||||
|
val |= 1;
|
||||||
|
return static_cast<uint32_t>(val);
|
||||||
|
}
|
||||||
|
|
||||||
// Computes bit lengths of the input values. If num_components > 1, the values
|
// Computes bit lengths of the input values. If num_components > 1, the values
|
||||||
// are processed in "num_components" sized chunks and the bit length is always
|
// are processed in "num_components" sized chunks and the bit length is always
|
||||||
// computed for the largest value from the chunk.
|
// computed for the largest value from the chunk.
|
||||||
|
@ -24,6 +24,10 @@ namespace draco {
|
|||||||
void ConvertSignedIntsToSymbols(const int32_t *in, int in_values,
|
void ConvertSignedIntsToSymbols(const int32_t *in, int in_values,
|
||||||
uint32_t *out);
|
uint32_t *out);
|
||||||
|
|
||||||
|
// Helper function that converts a single signed integer value into an unsigned
|
||||||
|
// integer symbol that can be encoded using an entropy encoder.
|
||||||
|
uint32_t ConvertSignedIntToSymbol(int32_t val);
|
||||||
|
|
||||||
// Encodes an array of symbols using an entropy coding. This function
|
// Encodes an array of symbols using an entropy coding. This function
|
||||||
// automatically decides whether to encode the symbol values using using bit
|
// automatically decides whether to encode the symbol values using using bit
|
||||||
// length tags (see EncodeTaggedSymbols), or whether to encode them directly
|
// length tags (see EncodeTaggedSymbols), or whether to encode them directly
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#define DRACO_CORE_VECTOR_D_H_
|
#define DRACO_CORE_VECTOR_D_H_
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "core/macros.h"
|
#include "core/macros.h"
|
||||||
@ -149,6 +150,15 @@ class VectorD {
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
void Normalize() {
|
||||||
|
const CoeffT magnitude = sqrt(this->SquaredNorm());
|
||||||
|
if (magnitude == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < dimension_t; ++i) {
|
||||||
|
(*this)[i] /= magnitude;
|
||||||
|
}
|
||||||
|
}
|
||||||
CoeffT *data() { return &(v_[0]); }
|
CoeffT *data() { return &(v_[0]); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -47,7 +47,7 @@ TEST_F(VectorDTest, TestOperators) {
|
|||||||
ASSERT_EQ(v[1], 0);
|
ASSERT_EQ(v[1], 0);
|
||||||
ASSERT_EQ(v[2], 0);
|
ASSERT_EQ(v[2], 0);
|
||||||
}
|
}
|
||||||
const Vector3f v(1, 2, 3);
|
Vector3f v(1, 2, 3);
|
||||||
ASSERT_EQ(v[0], 1);
|
ASSERT_EQ(v[0], 1);
|
||||||
ASSERT_EQ(v[1], 2);
|
ASSERT_EQ(v[1], 2);
|
||||||
ASSERT_EQ(v[2], 3);
|
ASSERT_EQ(v[2], 3);
|
||||||
@ -83,6 +83,25 @@ TEST_F(VectorDTest, TestOperators) {
|
|||||||
|
|
||||||
ASSERT_EQ(v.SquaredNorm(), 14);
|
ASSERT_EQ(v.SquaredNorm(), 14);
|
||||||
ASSERT_EQ(v.Dot(v), 14);
|
ASSERT_EQ(v.Dot(v), 14);
|
||||||
|
|
||||||
|
Vector3f new_v = v;
|
||||||
|
new_v.Normalize();
|
||||||
|
const float eps = 0.001;
|
||||||
|
const float magnitude = sqrt(v.SquaredNorm());
|
||||||
|
const float new_magnitude = sqrt(new_v.SquaredNorm());
|
||||||
|
ASSERT_LE(new_magnitude, 1 + eps);
|
||||||
|
ASSERT_GE(new_magnitude, 1 - eps);
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
new_v[i] *= magnitude;
|
||||||
|
ASSERT_LE(new_v[i], v[i] + eps);
|
||||||
|
ASSERT_GE(new_v[i], v[i] - eps);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3f x(0, 0, 0);
|
||||||
|
x.Normalize();
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
ASSERT_EQ(0, x[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VectorDTest, TestSquaredDistance) {
|
TEST_F(VectorDTest, TestSquaredDistance) {
|
||||||
|
File diff suppressed because one or more lines are too long
@ -44,17 +44,17 @@ THREE.DRACOLoader.prototype = {
|
|||||||
/*
|
/*
|
||||||
* Here is how to use Draco Javascript decoder and get the geometry.
|
* Here is how to use Draco Javascript decoder and get the geometry.
|
||||||
*/
|
*/
|
||||||
const buffer = new DracoModule.DecoderBuffer();
|
const buffer = new dracoDecoder.DecoderBuffer();
|
||||||
buffer.Init(new Int8Array(rawBuffer), rawBuffer.byteLength);
|
buffer.Init(new Int8Array(rawBuffer), rawBuffer.byteLength);
|
||||||
const wrapper = new DracoModule.WebIDLWrapper();
|
const wrapper = new dracoDecoder.WebIDLWrapper();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine what type is this file, mesh or point cloud.
|
* Determine what type is this file: mesh or point cloud.
|
||||||
*/
|
*/
|
||||||
const geometryType = wrapper.GetEncodedGeometryType(buffer);
|
const geometryType = wrapper.GetEncodedGeometryType(buffer);
|
||||||
if (geometryType == DracoModule.TRIANGULAR_MESH) {
|
if (geometryType == dracoDecoder.TRIANGULAR_MESH) {
|
||||||
fileDisplayArea.innerText = "Loaded a mesh.\n";
|
fileDisplayArea.innerText = "Loaded a mesh.\n";
|
||||||
} else if (geometryType == DracoModule.POINT_CLOUD) {
|
} else if (geometryType == dracoDecoder.POINT_CLOUD) {
|
||||||
fileDisplayArea.innerText = "Loaded a point cloud.\n";
|
fileDisplayArea.innerText = "Loaded a point cloud.\n";
|
||||||
} else {
|
} else {
|
||||||
const errorMsg = "Error: Unknown geometry type.";
|
const errorMsg = "Error: Unknown geometry type.";
|
||||||
@ -67,13 +67,13 @@ THREE.DRACOLoader.prototype = {
|
|||||||
convertDracoGeometryTo3JS: function(wrapper, geometryType, buffer) {
|
convertDracoGeometryTo3JS: function(wrapper, geometryType, buffer) {
|
||||||
let dracoGeometry;
|
let dracoGeometry;
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (geometryType == DracoModule.TRIANGULAR_MESH) {
|
if (geometryType == dracoDecoder.TRIANGULAR_MESH) {
|
||||||
dracoGeometry = wrapper.DecodeMeshFromBuffer(buffer);
|
dracoGeometry = wrapper.DecodeMeshFromBuffer(buffer);
|
||||||
} else {
|
} else {
|
||||||
dracoGeometry = wrapper.DecodePointCloudFromBuffer(buffer);
|
dracoGeometry = wrapper.DecodePointCloudFromBuffer(buffer);
|
||||||
}
|
}
|
||||||
const decode_end = performance.now();
|
const decode_end = performance.now();
|
||||||
DracoModule.destroy(buffer);
|
dracoDecoder.destroy(buffer);
|
||||||
/*
|
/*
|
||||||
* Example on how to retrieve mesh and attributes.
|
* Example on how to retrieve mesh and attributes.
|
||||||
*/
|
*/
|
||||||
@ -81,7 +81,7 @@ THREE.DRACOLoader.prototype = {
|
|||||||
let numVertexCoordinates, numTextureCoordinates, numAttributes;
|
let numVertexCoordinates, numTextureCoordinates, numAttributes;
|
||||||
// For output basic geometry information.
|
// For output basic geometry information.
|
||||||
let geometryInfoStr;
|
let geometryInfoStr;
|
||||||
if (geometryType == DracoModule.TRIANGULAR_MESH) {
|
if (geometryType == dracoDecoder.TRIANGULAR_MESH) {
|
||||||
numFaces = dracoGeometry.num_faces();
|
numFaces = dracoGeometry.num_faces();
|
||||||
geometryInfoStr += "Number of faces loaded: " + numFaces.toString()
|
geometryInfoStr += "Number of faces loaded: " + numFaces.toString()
|
||||||
+ ".\n";
|
+ ".\n";
|
||||||
@ -99,50 +99,51 @@ THREE.DRACOLoader.prototype = {
|
|||||||
|
|
||||||
// Get position attribute. Must exists.
|
// Get position attribute. Must exists.
|
||||||
const posAttId = wrapper.GetAttributeId(dracoGeometry,
|
const posAttId = wrapper.GetAttributeId(dracoGeometry,
|
||||||
Module.POSITION);
|
dracoDecoder.POSITION);
|
||||||
if (posAttId == -1) {
|
if (posAttId == -1) {
|
||||||
const errorMsg = "No position attribute found in the mesh.";
|
const errorMsg = "No position attribute found in the mesh.";
|
||||||
fileDisplayArea.innerText = errorMsg;
|
fileDisplayArea.innerText = errorMsg;
|
||||||
DracoModule.destroy(wrapper);
|
dracoDecoder.destroy(wrapper);
|
||||||
DracoModule.destroy(dracoGeometry);
|
dracoDecoder.destroy(dracoGeometry);
|
||||||
throw new Error(errorMsg);
|
throw new Error(errorMsg);
|
||||||
}
|
}
|
||||||
const posAttribute = wrapper.GetAttribute(dracoGeometry, posAttId);
|
const posAttribute = wrapper.GetAttribute(dracoGeometry, posAttId);
|
||||||
const posAttributeData = new DracoModule.DracoFloat32Array();
|
const posAttributeData = new dracoDecoder.DracoFloat32Array();
|
||||||
wrapper.GetAttributeFloatForAllPoints(
|
wrapper.GetAttributeFloatForAllPoints(
|
||||||
dracoGeometry, posAttribute, posAttributeData);
|
dracoGeometry, posAttribute, posAttributeData);
|
||||||
// Get color attributes if exists.
|
// Get color attributes if exists.
|
||||||
const colorAttId = wrapper.GetAttributeId(dracoGeometry, Module.COLOR);
|
const colorAttId = wrapper.GetAttributeId(dracoGeometry,
|
||||||
|
dracoDecoder.COLOR);
|
||||||
let colAttributeData;
|
let colAttributeData;
|
||||||
if (colorAttId != -1) {
|
if (colorAttId != -1) {
|
||||||
geometryInfoStr += "\nLoaded color attribute.\n";
|
geometryInfoStr += "\nLoaded color attribute.\n";
|
||||||
const colAttribute = wrapper.GetAttribute(dracoGeometry, colorAttId);
|
const colAttribute = wrapper.GetAttribute(dracoGeometry, colorAttId);
|
||||||
colAttributeData = new DracoModule.DracoFloat32Array();
|
colAttributeData = new dracoDecoder.DracoFloat32Array();
|
||||||
wrapper.GetAttributeFloatForAllPoints(dracoGeometry, colAttribute,
|
wrapper.GetAttributeFloatForAllPoints(dracoGeometry, colAttribute,
|
||||||
colAttributeData);
|
colAttributeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get normal attributes if exists.
|
// Get normal attributes if exists.
|
||||||
const normalAttId =
|
const normalAttId =
|
||||||
wrapper.GetAttributeId(dracoGeometry, Module.NORMAL);
|
wrapper.GetAttributeId(dracoGeometry, dracoDecoder.NORMAL);
|
||||||
let norAttributeData;
|
let norAttributeData;
|
||||||
if (normalAttId != -1) {
|
if (normalAttId != -1) {
|
||||||
geometryInfoStr += "\nLoaded normal attribute.\n";
|
geometryInfoStr += "\nLoaded normal attribute.\n";
|
||||||
const norAttribute = wrapper.GetAttribute(dracoGeometry, normalAttId);
|
const norAttribute = wrapper.GetAttribute(dracoGeometry, normalAttId);
|
||||||
norAttributeData = new DracoModule.DracoFloat32Array();
|
norAttributeData = new dracoDecoder.DracoFloat32Array();
|
||||||
wrapper.GetAttributeFloatForAllPoints(dracoGeometry, norAttribute,
|
wrapper.GetAttributeFloatForAllPoints(dracoGeometry, norAttribute,
|
||||||
norAttributeData);
|
norAttributeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get texture coord attributes if exists.
|
// Get texture coord attributes if exists.
|
||||||
const texCoordAttId =
|
const texCoordAttId =
|
||||||
wrapper.GetAttributeId(dracoGeometry, Module.TEX_COORD);
|
wrapper.GetAttributeId(dracoGeometry, dracoDecoder.TEX_COORD);
|
||||||
let textCoordAttributeData;
|
let textCoordAttributeData;
|
||||||
if (texCoordAttId != -1) {
|
if (texCoordAttId != -1) {
|
||||||
geometryInfoStr += "\nLoaded texture coordinate attribute.\n";
|
geometryInfoStr += "\nLoaded texture coordinate attribute.\n";
|
||||||
const texCoordAttribute = wrapper.GetAttribute(dracoGeometry,
|
const texCoordAttribute = wrapper.GetAttribute(dracoGeometry,
|
||||||
texCoordAttId);
|
texCoordAttId);
|
||||||
textCoordAttributeData = new DracoModule.DracoFloat32Array();
|
textCoordAttributeData = new dracoDecoder.DracoFloat32Array();
|
||||||
wrapper.GetAttributeFloatForAllPoints(dracoGeometry,
|
wrapper.GetAttributeFloatForAllPoints(dracoGeometry,
|
||||||
texCoordAttribute,
|
texCoordAttribute,
|
||||||
textCoordAttributeData);
|
textCoordAttributeData);
|
||||||
@ -189,17 +190,17 @@ THREE.DRACOLoader.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DracoModule.destroy(posAttributeData);
|
dracoDecoder.destroy(posAttributeData);
|
||||||
if (colorAttId != -1)
|
if (colorAttId != -1)
|
||||||
DracoModule.destroy(colAttributeData);
|
dracoDecoder.destroy(colAttributeData);
|
||||||
if (normalAttId != -1)
|
if (normalAttId != -1)
|
||||||
DracoModule.destroy(norAttributeData);
|
dracoDecoder.destroy(norAttributeData);
|
||||||
if (texCoordAttId != -1)
|
if (texCoordAttId != -1)
|
||||||
DracoModule.destroy(textCoordAttributeData);
|
dracoDecoder.destroy(textCoordAttributeData);
|
||||||
|
|
||||||
// For mesh, we need to generate the faces.
|
// For mesh, we need to generate the faces.
|
||||||
if (geometryType == DracoModule.TRIANGULAR_MESH) {
|
if (geometryType == dracoDecoder.TRIANGULAR_MESH) {
|
||||||
const ia = new DracoInt32Array();
|
const ia = new dracoDecoder.DracoInt32Array();
|
||||||
for (let i = 0; i < numFaces; ++i) {
|
for (let i = 0; i < numFaces; ++i) {
|
||||||
wrapper.GetFaceFromMesh(dracoGeometry, i, ia);
|
wrapper.GetFaceFromMesh(dracoGeometry, i, ia);
|
||||||
const index = i * 3;
|
const index = i * 3;
|
||||||
@ -207,16 +208,16 @@ THREE.DRACOLoader.prototype = {
|
|||||||
geometryBuffer.indices[index + 1] = ia.GetValue(1);
|
geometryBuffer.indices[index + 1] = ia.GetValue(1);
|
||||||
geometryBuffer.indices[index + 2] = ia.GetValue(2);
|
geometryBuffer.indices[index + 2] = ia.GetValue(2);
|
||||||
}
|
}
|
||||||
DracoModule.destroy(ia);
|
dracoDecoder.destroy(ia);
|
||||||
}
|
}
|
||||||
DracoModule.destroy(wrapper);
|
dracoDecoder.destroy(wrapper);
|
||||||
DracoModule.destroy(dracoGeometry);
|
dracoDecoder.destroy(dracoGeometry);
|
||||||
|
|
||||||
fileDisplayArea.innerText += geometryInfoStr;
|
fileDisplayArea.innerText += geometryInfoStr;
|
||||||
|
|
||||||
// Import data to Three JS geometry.
|
// Import data to Three JS geometry.
|
||||||
const geometry = new THREE.BufferGeometry();
|
const geometry = new THREE.BufferGeometry();
|
||||||
if (geometryType == DracoModule.TRIANGULAR_MESH) {
|
if (geometryType == dracoDecoder.TRIANGULAR_MESH) {
|
||||||
geometry.setIndex(new(geometryBuffer.indices.length > 65535 ?
|
geometry.setIndex(new(geometryBuffer.indices.length > 65535 ?
|
||||||
THREE.Uint32BufferAttribute : THREE.Uint16BufferAttribute)
|
THREE.Uint32BufferAttribute : THREE.Uint16BufferAttribute)
|
||||||
(geometryBuffer.indices, 1));
|
(geometryBuffer.indices, 1));
|
||||||
|
@ -47,8 +47,7 @@
|
|||||||
<script>
|
<script>
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// Module that exposes all the core funcionality of the Draco decoder.
|
const dracoDecoder = DracoModule();
|
||||||
const DracoModule = Module;
|
|
||||||
|
|
||||||
let container;
|
let container;
|
||||||
let camera, cameraTarget, scene, renderer;
|
let camera, cameraTarget, scene, renderer;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
// String to hold table output.
|
// String to hold table output.
|
||||||
let dt = '';
|
let dt = '';
|
||||||
|
const dracoDecoder = DracoModule();
|
||||||
|
|
||||||
function startTable() {
|
function startTable() {
|
||||||
dt += '<table><tr>';
|
dt += '<table><tr>';
|
||||||
@ -62,15 +63,15 @@ function TestMeshDecodingAsync(filenameList, index) {
|
|||||||
|
|
||||||
const total_t0 = performance.now();
|
const total_t0 = performance.now();
|
||||||
|
|
||||||
const buffer = new Module.DecoderBuffer();
|
const buffer = new dracoDecoder.DecoderBuffer();
|
||||||
buffer.Init(byteArray, byteArray.length);
|
buffer.Init(byteArray, byteArray.length);
|
||||||
|
|
||||||
const wrapper = new Module.WebIDLWrapper();
|
const wrapper = new dracoDecoder.WebIDLWrapper();
|
||||||
|
|
||||||
const decode_t0 = performance.now();
|
const decode_t0 = performance.now();
|
||||||
const geometryType = wrapper.GetEncodedGeometryType(buffer);
|
const geometryType = wrapper.GetEncodedGeometryType(buffer);
|
||||||
let outputGeometry;
|
let outputGeometry;
|
||||||
if (geometryType == Module.TRIANGULAR_MESH) {
|
if (geometryType == dracoDecoder.TRIANGULAR_MESH) {
|
||||||
outputGeometry = wrapper.DecodeMeshFromBuffer(buffer);
|
outputGeometry = wrapper.DecodeMeshFromBuffer(buffer);
|
||||||
} else {
|
} else {
|
||||||
outputGeometry = wrapper.DecodePointCloudFromBuffer(buffer);
|
outputGeometry = wrapper.DecodePointCloudFromBuffer(buffer);
|
||||||
@ -83,9 +84,9 @@ function TestMeshDecodingAsync(filenameList, index) {
|
|||||||
addCell('' + byteArray.length, false);
|
addCell('' + byteArray.length, false);
|
||||||
addCell('' + outputGeometry.num_points(), false);
|
addCell('' + outputGeometry.num_points(), false);
|
||||||
|
|
||||||
Module.destroy(outputGeometry);
|
dracoDecoder.destroy(outputGeometry);
|
||||||
Module.destroy(wrapper);
|
dracoDecoder.destroy(wrapper);
|
||||||
Module.destroy(buffer);
|
dracoDecoder.destroy(buffer);
|
||||||
|
|
||||||
if (index < filenameList.length - 1) {
|
if (index < filenameList.length - 1) {
|
||||||
index = index + 1;
|
index = index + 1;
|
||||||
|
@ -80,6 +80,7 @@ template <class TraversalProcessorT, class TraversalObserverT,
|
|||||||
class EdgeBreakerObserverT = EdgeBreakerObserver>
|
class EdgeBreakerObserverT = EdgeBreakerObserver>
|
||||||
class EdgeBreakerTraverser {
|
class EdgeBreakerTraverser {
|
||||||
public:
|
public:
|
||||||
|
typedef TraversalProcessorT TraversalProcessor;
|
||||||
typedef typename TraversalProcessorT::CornerTable CornerTable;
|
typedef typename TraversalProcessorT::CornerTable CornerTable;
|
||||||
|
|
||||||
EdgeBreakerTraverser() {}
|
EdgeBreakerTraverser() {}
|
||||||
@ -98,6 +99,13 @@ class EdgeBreakerTraverser {
|
|||||||
Init(processor, traversal_observer);
|
Init(processor, traversal_observer);
|
||||||
edgebreaker_observer_ = edgebreaker_observer;
|
edgebreaker_observer_ = edgebreaker_observer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called before any traversing starts.
|
||||||
|
void OnTraversalStart() {}
|
||||||
|
|
||||||
|
// Called when all the traversing is done.
|
||||||
|
void OnTraversalEnd() {}
|
||||||
|
|
||||||
void TraverseFromCorner(CornerIndex corner_id) {
|
void TraverseFromCorner(CornerIndex corner_id) {
|
||||||
if (processor_.IsFaceVisited(corner_id))
|
if (processor_.IsFaceVisited(corner_id))
|
||||||
return; // Already traversed.
|
return; // Already traversed.
|
||||||
@ -198,6 +206,9 @@ class EdgeBreakerTraverser {
|
|||||||
|
|
||||||
const CornerTable *corner_table() const { return corner_table_; }
|
const CornerTable *corner_table() const { return corner_table_; }
|
||||||
const TraversalProcessorT &traversal_processor() const { return processor_; }
|
const TraversalProcessorT &traversal_processor() const { return processor_; }
|
||||||
|
const TraversalObserverT &traversal_observer() const {
|
||||||
|
return traversal_observer_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const CornerTable *corner_table_;
|
const CornerTable *corner_table_;
|
||||||
|
@ -101,7 +101,6 @@ class Mesh : public PointCloud {
|
|||||||
// that converts vertex indices into attribute indices.
|
// that converts vertex indices into attribute indices.
|
||||||
IndexTypeVector<FaceIndex, Face> faces_;
|
IndexTypeVector<FaceIndex, Face> faces_;
|
||||||
|
|
||||||
friend class MeshBuilder;
|
|
||||||
friend struct MeshHasher;
|
friend struct MeshHasher;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user