Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/src/indexcodec.cpp b/src/indexcodec.cpp
- index 4ab92cb..18ccd43 100644
- --- a/src/indexcodec.cpp
- +++ b/src/indexcodec.cpp
- @@ -7,9 +7,6 @@
- // This work is based on:
- // Fabian Giesen. Simple lossless index buffer compression & follow-up. 2013
- // Conor Stokes. Vertex Cache Optimised Index Buffer Compression. 2014
- -namespace meshopt
- -{
- -
- const unsigned char kIndexHeader = 0xe0;
- typedef unsigned int VertexFifo[16];
- @@ -53,11 +50,11 @@ static int getEdgeFifo(EdgeFifo fifo, unsigned int a, unsigned int b, unsigned i
- return -1;
- }
- -static void pushEdgeFifo(EdgeFifo fifo, unsigned int a, unsigned int b, size_t& offset)
- +static void pushEdgeFifo(EdgeFifo fifo, unsigned int a, unsigned int b, size_t* offset)
- {
- - fifo[offset][0] = a;
- - fifo[offset][1] = b;
- - offset = (offset + 1) & 15;
- + fifo[*offset][0] = a;
- + fifo[*offset][1] = b;
- + *offset = (*offset + 1) & 15;
- }
- static int getVertexFifo(VertexFifo fifo, unsigned int v, size_t offset)
- @@ -73,25 +70,25 @@ static int getVertexFifo(VertexFifo fifo, unsigned int v, size_t offset)
- return -1;
- }
- -static void pushVertexFifo(VertexFifo fifo, unsigned int v, size_t& offset, int cond = 1)
- +static void pushVertexFifo(VertexFifo fifo, unsigned int v, size_t* offset, int cond)
- {
- - fifo[offset] = v;
- - offset = (offset + cond) & 15;
- + fifo[*offset] = v;
- + *offset = (*offset + cond) & 15;
- }
- -static void encodeVByte(unsigned char*& data, unsigned int v)
- +static void encodeVByte(unsigned char** data, unsigned int v)
- {
- // encode 32-bit value in up to 5 7-bit groups
- do
- {
- - *data++ = (v & 127) | (v > 127 ? 128 : 0);
- + *(*data)++ = (v & 127) | (v > 127 ? 128 : 0);
- v >>= 7;
- } while (v);
- }
- -static unsigned int decodeVByte(const unsigned char*& data)
- +static unsigned int decodeVByte(const unsigned char** data)
- {
- - unsigned char lead = *data++;
- + unsigned char lead = *(*data)++;
- // fast path: single byte
- if (lead < 128)
- @@ -104,7 +101,7 @@ static unsigned int decodeVByte(const unsigned char*& data)
- for (int i = 0; i < 4; ++i)
- {
- - unsigned char group = *data++;
- + unsigned char group = *(*data)++;
- result |= (group & 127) << shift;
- shift += 7;
- @@ -115,22 +112,22 @@ static unsigned int decodeVByte(const unsigned char*& data)
- return result;
- }
- -static void encodeIndex(unsigned char*& data, unsigned int index, unsigned int next, unsigned int last)
- +static void encodeIndex(unsigned char** data, unsigned int index, unsigned int next, unsigned int last)
- {
- (void)next;
- unsigned int d = index - last;
- - unsigned int v = (d << 1) ^ (int(d) >> 31);
- + unsigned int v = (d << 1) ^ ((int)(d) >> 31);
- encodeVByte(data, v);
- }
- -static unsigned int decodeIndex(const unsigned char*& data, unsigned int next, unsigned int last)
- +static unsigned int decodeIndex(const unsigned char** data, unsigned int next, unsigned int last)
- {
- (void)next;
- unsigned int v = decodeVByte(data);
- - unsigned int d = (v >> 1) ^ -int(v & 1);
- + unsigned int d = (v >> 1) ^ -(int)(v & 1);
- return last + d;
- }
- @@ -148,24 +145,20 @@ static void writeTriangle(void* destination, size_t offset, size_t index_size, u
- {
- if (index_size == 2)
- {
- - static_cast<unsigned short*>(destination)[offset + 0] = static_cast<unsigned short>(a);
- - static_cast<unsigned short*>(destination)[offset + 1] = static_cast<unsigned short>(b);
- - static_cast<unsigned short*>(destination)[offset + 2] = static_cast<unsigned short>(c);
- + ((unsigned short*)destination)[offset + 0] = (unsigned short)(a);
- + ((unsigned short*)destination)[offset + 1] = (unsigned short)(b);
- + ((unsigned short*)destination)[offset + 2] = (unsigned short)(c);
- }
- else
- {
- - static_cast<unsigned int*>(destination)[offset + 0] = a;
- - static_cast<unsigned int*>(destination)[offset + 1] = b;
- - static_cast<unsigned int*>(destination)[offset + 2] = c;
- + ((unsigned int*)destination)[offset + 0] = a;
- + ((unsigned int*)destination)[offset + 1] = b;
- + ((unsigned int*)destination)[offset + 2] = c;
- }
- }
- -} // namespace meshopt
- -
- size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, const unsigned int* indices, size_t index_count)
- {
- - using namespace meshopt;
- -
- assert(index_count % 3 == 0);
- // the minimum valid encoding is header, 1 byte per triangle and a 16-byte codeaux table
- @@ -216,19 +209,19 @@ size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, cons
- int fec = (fc >= 1 && fc < 15) ? fc : (c == next) ? (next++, 0) : 15;
- - *code++ = static_cast<unsigned char>((fe << 4) | fec);
- + *code++ = (unsigned char)((fe << 4) | fec);
- // note that we need to update the last index since free indices are delta-encoded
- if (fec == 15)
- - encodeIndex(data, c, next, last), last = c;
- + encodeIndex(&data, c, next, last), last = c;
- // we only need to push third vertex since first two are likely already in the vertex fifo
- if (fec == 0 || fec == 15)
- - pushVertexFifo(vertexfifo, c, vertexfifooffset);
- + pushVertexFifo(vertexfifo, c, &vertexfifooffset, 1);
- // we only need to push two new edges to edge fifo since the third one is already there
- - pushEdgeFifo(edgefifo, c, b, edgefifooffset);
- - pushEdgeFifo(edgefifo, a, c, edgefifooffset);
- + pushEdgeFifo(edgefifo, c, b, &edgefifooffset);
- + pushEdgeFifo(edgefifo, a, c, &edgefifooffset);
- }
- else
- {
- @@ -246,44 +239,44 @@ size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, cons
- int fec = (fc >= 0 && fc < 14) ? (fc + 1) : (c == next) ? (next++, 0) : 15;
- // we encode feb & fec in 4 bits using a table if possible, and as a full byte otherwise
- - unsigned char codeaux = static_cast<unsigned char>((feb << 4) | fec);
- + unsigned char codeaux = (unsigned char)((feb << 4) | fec);
- int codeauxindex = getCodeAuxIndex(codeaux, codeaux_table);
- // <14 encodes an index into codeaux table, 14 encodes fea=0, 15 encodes fea=15
- if (fea == 0 && codeauxindex >= 0 && codeauxindex < 14)
- {
- - *code++ = static_cast<unsigned char>((15 << 4) | codeauxindex);
- + *code++ = (unsigned char)((15 << 4) | codeauxindex);
- }
- else
- {
- - *code++ = static_cast<unsigned char>((15 << 4) | 14 | fea);
- + *code++ = (unsigned char)((15 << 4) | 14 | fea);
- *data++ = codeaux;
- }
- // note that we need to update the last index since free indices are delta-encoded
- if (fea == 15)
- - encodeIndex(data, a, next, last), last = a;
- + encodeIndex(&data, a, next, last), last = a;
- if (feb == 15)
- - encodeIndex(data, b, next, last), last = b;
- + encodeIndex(&data, b, next, last), last = b;
- if (fec == 15)
- - encodeIndex(data, c, next, last), last = c;
- + encodeIndex(&data, c, next, last), last = c;
- // only push vertices that weren't already in fifo
- if (fea == 0 || fea == 15)
- - pushVertexFifo(vertexfifo, a, vertexfifooffset);
- + pushVertexFifo(vertexfifo, a, &vertexfifooffset, 1);
- if (feb == 0 || feb == 15)
- - pushVertexFifo(vertexfifo, b, vertexfifooffset);
- + pushVertexFifo(vertexfifo, b, &vertexfifooffset, 1);
- if (fec == 0 || fec == 15)
- - pushVertexFifo(vertexfifo, c, vertexfifooffset);
- + pushVertexFifo(vertexfifo, c, &vertexfifooffset, 1);
- // all three edges aren't in the fifo; pushing all of them is important so that we can match them for later triangles
- - pushEdgeFifo(edgefifo, b, a, edgefifooffset);
- - pushEdgeFifo(edgefifo, c, b, edgefifooffset);
- - pushEdgeFifo(edgefifo, a, c, edgefifooffset);
- + pushEdgeFifo(edgefifo, b, a, &edgefifooffset);
- + pushEdgeFifo(edgefifo, c, b, &edgefifooffset);
- + pushEdgeFifo(edgefifo, a, c, &edgefifooffset);
- }
- }
- @@ -315,7 +308,7 @@ size_t meshopt_encodeIndexBufferBound(size_t index_count, size_t vertex_count)
- // compute number of bits required for each index
- unsigned int vertex_bits = 1;
- - while (vertex_bits < 32 && vertex_count > size_t(1) << vertex_bits)
- + while (vertex_bits < 32 && vertex_count > (size_t)(1) << vertex_bits)
- vertex_bits++;
- // worst-case encoding is 2 header bytes + 3 varint-7 encoded index deltas
- @@ -326,8 +319,6 @@ size_t meshopt_encodeIndexBufferBound(size_t index_count, size_t vertex_count)
- int meshopt_decodeIndexBuffer(void* destination, size_t index_count, size_t index_size, const unsigned char* buffer, size_t buffer_size)
- {
- - using namespace meshopt;
- -
- assert(index_count % 3 == 0);
- assert(index_size == 2 || index_size == 4);
- @@ -392,26 +383,26 @@ int meshopt_decodeIndexBuffer(void* destination, size_t index_count, size_t inde
- writeTriangle(destination, i, index_size, a, b, c);
- // push vertex/edge fifo must match the encoding step *exactly* otherwise the data will not be decoded correctly
- - pushVertexFifo(vertexfifo, c, vertexfifooffset, fec0);
- + pushVertexFifo(vertexfifo, c, &vertexfifooffset, fec0);
- - pushEdgeFifo(edgefifo, c, b, edgefifooffset);
- - pushEdgeFifo(edgefifo, a, c, edgefifooffset);
- + pushEdgeFifo(edgefifo, c, b, &edgefifooffset);
- + pushEdgeFifo(edgefifo, a, c, &edgefifooffset);
- }
- else
- {
- unsigned int c = 0;
- // note that we need to update the last index since free indices are delta-encoded
- - last = c = decodeIndex(data, next, last);
- + last = c = decodeIndex(&data, next, last);
- // output triangle
- writeTriangle(destination, i, index_size, a, b, c);
- // push vertex/edge fifo must match the encoding step *exactly* otherwise the data will not be decoded correctly
- - pushVertexFifo(vertexfifo, c, vertexfifooffset);
- + pushVertexFifo(vertexfifo, c, &vertexfifooffset, 1);
- - pushEdgeFifo(edgefifo, c, b, edgefifooffset);
- - pushEdgeFifo(edgefifo, a, c, edgefifooffset);
- + pushEdgeFifo(edgefifo, c, b, &edgefifooffset);
- + pushEdgeFifo(edgefifo, a, c, &edgefifooffset);
- }
- }
- else
- @@ -445,13 +436,13 @@ int meshopt_decodeIndexBuffer(void* destination, size_t index_count, size_t inde
- writeTriangle(destination, i, index_size, a, b, c);
- // push vertex/edge fifo must match the encoding step *exactly* otherwise the data will not be decoded correctly
- - pushVertexFifo(vertexfifo, a, vertexfifooffset);
- - pushVertexFifo(vertexfifo, b, vertexfifooffset, feb0);
- - pushVertexFifo(vertexfifo, c, vertexfifooffset, fec0);
- + pushVertexFifo(vertexfifo, a, &vertexfifooffset, 1);
- + pushVertexFifo(vertexfifo, b, &vertexfifooffset, feb0);
- + pushVertexFifo(vertexfifo, c, &vertexfifooffset, fec0);
- - pushEdgeFifo(edgefifo, b, a, edgefifooffset);
- - pushEdgeFifo(edgefifo, c, b, edgefifooffset);
- - pushEdgeFifo(edgefifo, a, c, edgefifooffset);
- + pushEdgeFifo(edgefifo, b, a, &edgefifooffset);
- + pushEdgeFifo(edgefifo, c, b, &edgefifooffset);
- + pushEdgeFifo(edgefifo, a, c, &edgefifooffset);
- }
- else
- {
- @@ -470,25 +461,25 @@ int meshopt_decodeIndexBuffer(void* destination, size_t index_count, size_t inde
- // note that we need to update the last index since free indices are delta-encoded
- if (fea == 15)
- - last = a = decodeIndex(data, next, last);
- + last = a = decodeIndex(&data, next, last);
- if (feb == 15)
- - last = b = decodeIndex(data, next, last);
- + last = b = decodeIndex(&data, next, last);
- if (fec == 15)
- - last = c = decodeIndex(data, next, last);
- + last = c = decodeIndex(&data, next, last);
- // output triangle
- writeTriangle(destination, i, index_size, a, b, c);
- // push vertex/edge fifo must match the encoding step *exactly* otherwise the data will not be decoded correctly
- - pushVertexFifo(vertexfifo, a, vertexfifooffset);
- - pushVertexFifo(vertexfifo, b, vertexfifooffset, (feb == 0) | (feb == 15));
- - pushVertexFifo(vertexfifo, c, vertexfifooffset, (fec == 0) | (fec == 15));
- + pushVertexFifo(vertexfifo, a, &vertexfifooffset, 1);
- + pushVertexFifo(vertexfifo, b, &vertexfifooffset, (feb == 0) | (feb == 15));
- + pushVertexFifo(vertexfifo, c, &vertexfifooffset, (fec == 0) | (fec == 15));
- - pushEdgeFifo(edgefifo, b, a, edgefifooffset);
- - pushEdgeFifo(edgefifo, c, b, edgefifooffset);
- - pushEdgeFifo(edgefifo, a, c, edgefifooffset);
- + pushEdgeFifo(edgefifo, b, a, &edgefifooffset);
- + pushEdgeFifo(edgefifo, c, b, &edgefifooffset);
- + pushEdgeFifo(edgefifo, a, c, &edgefifooffset);
- }
- }
- }
- diff --git a/src/indexgenerator.cpp b/src/indexgenerator.cpp
- index 066b15e..c5eb706 100644
- --- a/src/indexgenerator.cpp
- +++ b/src/indexgenerator.cpp
- @@ -2,49 +2,48 @@
- #include "meshoptimizer.h"
- #include <assert.h>
- +#include <stdbool.h>
- +#include <stdlib.h>
- #include <string.h>
- -namespace meshopt
- -{
- -
- -struct VertexHasher
- +typedef struct VertexHasher
- {
- const char* vertices;
- size_t vertex_size;
- +} VertexHasher;
- - size_t hash(unsigned int index) const
- - {
- - // MurmurHash2
- - const unsigned int m = 0x5bd1e995;
- - const int r = 24;
- +static size_t hash(const VertexHasher* hasher, unsigned int index)
- +{
- + // MurmurHash2
- + const unsigned int m = 0x5bd1e995;
- + const int r = 24;
- - unsigned int h = 0;
- - const char* key = vertices + index * vertex_size;
- - size_t len = vertex_size;
- + unsigned int h = 0;
- + const char* key = hasher->vertices + index * hasher->vertex_size;
- + size_t len = hasher->vertex_size;
- - while (len >= 4)
- - {
- - unsigned int k = *reinterpret_cast<const unsigned int*>(key);
- -
- - k *= m;
- - k ^= k >> r;
- - k *= m;
- + while (len >= 4)
- + {
- + unsigned int k = *(const unsigned int*)(key);
- - h *= m;
- - h ^= k;
- + k *= m;
- + k ^= k >> r;
- + k *= m;
- - key += 4;
- - len -= 4;
- - }
- + h *= m;
- + h ^= k;
- - return h;
- + key += 4;
- + len -= 4;
- }
- - bool equal(unsigned int lhs, unsigned int rhs) const
- - {
- - return memcmp(vertices + lhs * vertex_size, vertices + rhs * vertex_size, vertex_size) == 0;
- - }
- -};
- + return h;
- +}
- +
- +static bool equal(const VertexHasher* hasher, unsigned int lhs, unsigned int rhs)
- +{
- + return memcmp(hasher->vertices + lhs * hasher->vertex_size, hasher->vertices + rhs * hasher->vertex_size, hasher->vertex_size) == 0;
- +}
- static size_t hashBuckets(size_t count)
- {
- @@ -55,24 +54,23 @@ static size_t hashBuckets(size_t count)
- return buckets;
- }
- -template <typename T, typename Hash>
- -static T* hashLookup(T* table, size_t buckets, const Hash& hash, const T& key, const T& empty)
- +static unsigned int* hashLookup(unsigned int* table, size_t buckets, const VertexHasher* hasher, unsigned int key, unsigned int empty)
- {
- assert(buckets > 0);
- assert((buckets & (buckets - 1)) == 0);
- size_t hashmod = buckets - 1;
- - size_t bucket = hash.hash(key) & hashmod;
- + size_t bucket = hash(hasher, key) & hashmod;
- for (size_t probe = 0; probe <= hashmod; ++probe)
- {
- - T& item = table[bucket];
- + unsigned int* item = &table[bucket];
- - if (item == empty)
- - return &item;
- + if (*item == empty)
- + return item;
- - if (hash.equal(item, key))
- - return &item;
- + if (equal(hasher, *item, key))
- + return item;
- // hash collision, quadratic probing
- bucket = (bucket + probe + 1) & hashmod;
- @@ -82,33 +80,30 @@ static T* hashLookup(T* table, size_t buckets, const Hash& hash, const T& key, c
- return 0;
- }
- -} // namespace meshopt
- -
- size_t meshopt_generateVertexRemap(unsigned int* destination, const unsigned int* indices, size_t index_count, const void* vertices, size_t vertex_count, size_t vertex_size)
- {
- - using namespace meshopt;
- -
- assert(indices || index_count == vertex_count);
- assert(index_count % 3 == 0);
- assert(vertex_size > 0 && vertex_size <= 256);
- memset(destination, -1, vertex_count * sizeof(unsigned int));
- - VertexHasher hasher = {static_cast<const char*>(vertices), vertex_size};
- + VertexHasher hasher = {(const char*)(vertices), vertex_size};
- - meshopt_Buffer<unsigned int> table(hashBuckets(vertex_count));
- - memset(table.data, -1, table.size * sizeof(unsigned int));
- + size_t buckets = hashBuckets(vertex_count);
- + unsigned int* table = malloc(buckets * sizeof(unsigned int));
- + memset(table, -1, buckets * sizeof(unsigned int));
- unsigned int next_vertex = 0;
- for (size_t i = 0; i < index_count; ++i)
- {
- - unsigned int index = indices ? indices[i] : unsigned(i);
- + unsigned int index = indices ? indices[i] : (unsigned)(i);
- assert(index < vertex_count);
- if (destination[index] == ~0u)
- {
- - unsigned int* entry = hashLookup(table.data, table.size, hasher, index, ~0u);
- + unsigned int* entry = hashLookup(table, buckets, &hasher, index, ~0u);
- if (*entry == ~0u)
- {
- @@ -125,6 +120,8 @@ size_t meshopt_generateVertexRemap(unsigned int* destination, const unsigned int
- }
- }
- + free(table);
- +
- assert(next_vertex <= vertex_count);
- return next_vertex;
- @@ -135,13 +132,13 @@ void meshopt_remapVertexBuffer(void* destination, const void* vertices, size_t v
- assert(vertex_size > 0 && vertex_size <= 256);
- // support in-place remap
- - meshopt_Buffer<char> vertices_copy;
- + char* vertices_copy = 0;
- if (destination == vertices)
- {
- - vertices_copy.allocate(vertex_count * vertex_size);
- - memcpy(vertices_copy.data, vertices, vertex_count * vertex_size);
- - vertices = vertices_copy.data;
- + vertices_copy = malloc(vertex_count * vertex_size);
- + memcpy(vertices_copy, vertices, vertex_count * vertex_size);
- + vertices = vertices_copy;
- }
- for (size_t i = 0; i < vertex_count; ++i)
- @@ -150,9 +147,11 @@ void meshopt_remapVertexBuffer(void* destination, const void* vertices, size_t v
- {
- assert(remap[i] < vertex_count);
- - memcpy(static_cast<char*>(destination) + remap[i] * vertex_size, static_cast<const char*>(vertices) + i * vertex_size, vertex_size);
- + memcpy((char*)(destination) + remap[i] * vertex_size, (const char*)(vertices) + i * vertex_size, vertex_size);
- }
- }
- +
- + free(vertices_copy);
- }
- void meshopt_remapIndexBuffer(unsigned int* destination, const unsigned int* indices, size_t index_count, const unsigned int* remap)
- @@ -161,7 +160,7 @@ void meshopt_remapIndexBuffer(unsigned int* destination, const unsigned int* ind
- for (size_t i = 0; i < index_count; ++i)
- {
- - unsigned int index = indices ? indices[i] : unsigned(i);
- + unsigned int index = indices ? indices[i] : (unsigned)(i);
- assert(remap[index] != ~0u);
- destination[i] = remap[index];
- diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h
- index a9850bd..6219397 100644
- --- a/src/meshoptimizer.h
- +++ b/src/meshoptimizer.h
- @@ -212,7 +212,7 @@ MESHOPTIMIZER_API struct meshopt_VertexFetchStatistics meshopt_analyzeVertexFetc
- #endif
- /* Quantization into commonly supported data formats */
- -#ifdef __cplusplus
- +#if 1 // todo: c99?
- /**
- * Quantize a float in [0..1] range into an N-bit fixed point unorm value
- * Assumes reconstruction function (q / (2^N-1)), which is the case for fixed-function normalized fixed point conversion
- @@ -429,27 +429,27 @@ inline meshopt_VertexFetchStatistics meshopt_analyzeVertexFetch(const T* indices
- #endif
- /* Inline implementation */
- -#ifdef __cplusplus
- +#if 1 // todo: C99?
- inline int meshopt_quantizeUnorm(float v, int N)
- {
- - const float scale = float((1 << N) - 1);
- + const float scale = (float)((1 << N) - 1);
- v = (v >= 0) ? v : 0;
- v = (v <= 1) ? v : 1;
- - return int(v * scale + 0.5f);
- + return (int)(v * scale + 0.5f);
- }
- inline int meshopt_quantizeSnorm(float v, int N)
- {
- - const float scale = float((1 << (N - 1)) - 1);
- + const float scale = (float)((1 << (N - 1)) - 1);
- float round = (v >= 0 ? 0.5f : -0.5f);
- v = (v >= -1) ? v : -1;
- v = (v <= +1) ? v : +1;
- - return int(v * scale + round);
- + return (int)(v * scale + round);
- }
- inline unsigned short meshopt_quantizeHalf(float v)
- diff --git a/src/overdrawanalyzer.cpp b/src/overdrawanalyzer.cpp
- index aad88b9..0cbde43 100644
- --- a/src/overdrawanalyzer.cpp
- +++ b/src/overdrawanalyzer.cpp
- @@ -7,25 +7,30 @@
- // This work is based on:
- // Nicolas Capens. Advanced Rasterization. 2004
- -namespace meshopt
- -{
- -
- -const int kViewport = 256;
- +enum { kViewport = 256 };
- -struct OverdrawBuffer
- +typedef struct OverdrawBuffer
- {
- float z[kViewport][kViewport][2];
- unsigned int overdraw[kViewport][kViewport][2];
- -};
- +} OverdrawBuffer;
- -template <typename T>
- -static T min(T a, T b)
- +static float minf(float a, float b)
- {
- return a < b ? a : b;
- }
- -template <typename T>
- -static T max(T a, T b)
- +static int mini(int a, int b)
- +{
- + return a < b ? a : b;
- +}
- +
- +static float maxf(float a, float b)
- +{
- + return a > b ? a : b;
- +}
- +
- +static int maxi(int a, int b)
- {
- return a > b ? a : b;
- }
- @@ -37,7 +42,7 @@ static float det2x2(float a, float b, float c, float d)
- return a * d - b * c;
- }
- -static float computeDepthGradients(float& dzdx, float& dzdy, float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3)
- +static float computeDepthGradients(float* dzdx, float* dzdy, float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3)
- {
- // z2 = z1 + dzdx * (x2 - x1) + dzdy * (y2 - y1)
- // z3 = z1 + dzdx * (x3 - x1) + dzdy * (y3 - y1)
- @@ -47,8 +52,8 @@ static float computeDepthGradients(float& dzdx, float& dzdy, float x1, float y1,
- float det = det2x2(x2 - x1, y2 - y1, x3 - x1, y3 - y1);
- float invdet = (det == 0) ? 0 : 1 / det;
- - dzdx = det2x2(z2 - z1, y2 - y1, z3 - z1, y3 - y1) * invdet;
- - dzdy = det2x2(x2 - x1, z2 - z1, x3 - x1, z3 - z1) * invdet;
- + *dzdx = det2x2(z2 - z1, y2 - y1, z3 - z1, y3 - y1) * invdet;
- + *dzdy = det2x2(x2 - x1, z2 - z1, x3 - x1, z3 - z1) * invdet;
- return det;
- }
- @@ -58,7 +63,7 @@ static void rasterize(OverdrawBuffer* buffer, float v1x, float v1y, float v1z, f
- {
- // compute depth gradients
- float DZx, DZy;
- - float det = computeDepthGradients(DZx, DZy, v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z);
- + float det = computeDepthGradients(&DZx, &DZy, v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z);
- int sign = det > 0;
- // flip backfacing triangles to simplify rasterization logic
- @@ -77,22 +82,22 @@ static void rasterize(OverdrawBuffer* buffer, float v1x, float v1y, float v1z, f
- }
- // coordinates, 28.4 fixed point
- - int X1 = int(16.0f * v1x + 0.5f);
- - int X2 = int(16.0f * v2x + 0.5f);
- - int X3 = int(16.0f * v3x + 0.5f);
- + int X1 = (int)(16.0f * v1x + 0.5f);
- + int X2 = (int)(16.0f * v2x + 0.5f);
- + int X3 = (int)(16.0f * v3x + 0.5f);
- - int Y1 = int(16.0f * v1y + 0.5f);
- - int Y2 = int(16.0f * v2y + 0.5f);
- - int Y3 = int(16.0f * v3y + 0.5f);
- + int Y1 = (int)(16.0f * v1y + 0.5f);
- + int Y2 = (int)(16.0f * v2y + 0.5f);
- + int Y3 = (int)(16.0f * v3y + 0.5f);
- // bounding rectangle, clipped against viewport
- // since we rasterize pixels with covered centers, min >0.5 should round up
- // as for max, due to top-left filling convention we will never rasterize right/bottom edges
- // so max >= 0.5 should round down
- - int minx = max((min(X1, min(X2, X3)) + 7) >> 4, 0);
- - int maxx = min((max(X1, max(X2, X3)) + 7) >> 4, kViewport);
- - int miny = max((min(Y1, min(Y2, Y3)) + 7) >> 4, 0);
- - int maxy = min((max(Y1, max(Y2, Y3)) + 7) >> 4, kViewport);
- + int minx = maxi((mini(X1, mini(X2, X3)) + 7) >> 4, 0);
- + int maxx = mini((maxi(X1, maxi(X2, X3)) + 7) >> 4, kViewport);
- + int miny = maxi((mini(Y1, mini(Y2, Y3)) + 7) >> 4, 0);
- + int maxy = mini((maxi(Y1, maxi(Y2, Y3)) + 7) >> 4, kViewport);
- // deltas, 28.4 fixed point
- int DX12 = X1 - X2;
- @@ -115,7 +120,7 @@ static void rasterize(OverdrawBuffer* buffer, float v1x, float v1y, float v1z, f
- int CY1 = DX12 * (FY - Y1) - DY12 * (FX - X1) + TL1 - 1;
- int CY2 = DX23 * (FY - Y2) - DY23 * (FX - X2) + TL2 - 1;
- int CY3 = DX31 * (FY - Y3) - DY31 * (FX - X3) + TL3 - 1;
- - float ZY = v1z + (DZx * float(FX - X1) + DZy * float(FY - Y1)) * (1 / 16.f);
- + float ZY = v1z + (DZx * (float)(FX - X1) + DZy * (float)(FY - Y1)) * (1 / 16.f);
- for (int y = miny; y < maxy; y++)
- {
- @@ -149,19 +154,15 @@ static void rasterize(OverdrawBuffer* buffer, float v1x, float v1y, float v1z, f
- }
- }
- -} // namespace meshopt
- -
- -meshopt_OverdrawStatistics meshopt_analyzeOverdraw(const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride)
- +struct meshopt_OverdrawStatistics meshopt_analyzeOverdraw(const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride)
- {
- - using namespace meshopt;
- -
- assert(index_count % 3 == 0);
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
- assert(vertex_positions_stride % sizeof(float) == 0);
- size_t vertex_stride_float = vertex_positions_stride / sizeof(float);
- - meshopt_OverdrawStatistics result = {};
- + struct meshopt_OverdrawStatistics result = {};
- float minv[3] = {FLT_MAX, FLT_MAX, FLT_MAX};
- float maxv[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
- @@ -172,15 +173,15 @@ meshopt_OverdrawStatistics meshopt_analyzeOverdraw(const unsigned int* indices,
- for (int j = 0; j < 3; ++j)
- {
- - minv[j] = min(minv[j], v[j]);
- - maxv[j] = max(maxv[j], v[j]);
- + minv[j] = minf(minv[j], v[j]);
- + maxv[j] = maxf(maxv[j], v[j]);
- }
- }
- - float extent = max(maxv[0] - minv[0], max(maxv[1] - minv[1], maxv[2] - minv[2]));
- + float extent = maxf(maxv[0] - minv[0], maxf(maxv[1] - minv[1], maxv[2] - minv[2]));
- float scale = kViewport / extent;
- - meshopt_Buffer<float> triangles(index_count * 3);
- + float* triangles = malloc(index_count * 3 * sizeof(float));
- for (size_t i = 0; i < index_count; ++i)
- {
- @@ -194,8 +195,7 @@ meshopt_OverdrawStatistics meshopt_analyzeOverdraw(const unsigned int* indices,
- triangles[i * 3 + 2] = (v[2] - minv[2]) * scale;
- }
- - meshopt_Buffer<OverdrawBuffer> buffer_storage(1);
- - OverdrawBuffer* buffer = buffer_storage.data;
- + OverdrawBuffer* buffer = malloc(sizeof(OverdrawBuffer));
- for (int axis = 0; axis < 3; ++axis)
- {
- @@ -232,7 +232,10 @@ meshopt_OverdrawStatistics meshopt_analyzeOverdraw(const unsigned int* indices,
- }
- }
- - result.overdraw = result.pixels_covered ? float(result.pixels_shaded) / float(result.pixels_covered) : 0.f;
- + free(buffer);
- + free(triangles);
- +
- + result.overdraw = result.pixels_covered ? (float)(result.pixels_shaded) / (float)(result.pixels_covered) : 0.f;
- return result;
- }
- diff --git a/src/overdrawoptimizer.cpp b/src/overdrawoptimizer.cpp
- index c3d7724..216001e 100644
- --- a/src/overdrawoptimizer.cpp
- +++ b/src/overdrawoptimizer.cpp
- @@ -7,8 +7,6 @@
- // This work is based on:
- // Pedro Sander, Diego Nehab and Joshua Barczak. Fast Triangle Reordering for Vertex Locality and Reduced Overdraw. 2007
- -namespace meshopt
- -{
- static void calculateSortData(float* sort_data, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_positions_stride, const unsigned int* clusters, size_t cluster_count)
- {
- @@ -119,7 +117,7 @@ static void calculateSortOrderRadix(unsigned int* sort_order, const float* sort_
- for (size_t i = 0; i < 1 << sort_bits; ++i)
- {
- size_t count = histogram[i];
- - histogram[i] = unsigned(histogram_sum);
- + histogram[i] = (unsigned)(histogram_sum);
- histogram_sum += count;
- }
- @@ -128,30 +126,30 @@ static void calculateSortOrderRadix(unsigned int* sort_order, const float* sort_
- // compute sort order based on offsets
- for (size_t i = 0; i < cluster_count; ++i)
- {
- - sort_order[histogram[sort_keys[i]]++] = unsigned(i);
- + sort_order[histogram[sort_keys[i]]++] = (unsigned)(i);
- }
- }
- -static unsigned int updateCache(unsigned int a, unsigned int b, unsigned int c, unsigned int cache_size, unsigned int* cache_timestamps, unsigned int& timestamp)
- +static unsigned int updateCache(unsigned int a, unsigned int b, unsigned int c, unsigned int cache_size, unsigned int* cache_timestamps, unsigned int* timestamp)
- {
- unsigned int cache_misses = 0;
- // if vertex is not in cache, put it in cache
- - if (timestamp - cache_timestamps[a] > cache_size)
- + if (*timestamp - cache_timestamps[a] > cache_size)
- {
- - cache_timestamps[a] = timestamp++;
- + cache_timestamps[a] = *timestamp++;
- cache_misses++;
- }
- - if (timestamp - cache_timestamps[b] > cache_size)
- + if (*timestamp - cache_timestamps[b] > cache_size)
- {
- - cache_timestamps[b] = timestamp++;
- + cache_timestamps[b] = *timestamp++;
- cache_misses++;
- }
- - if (timestamp - cache_timestamps[c] > cache_size)
- + if (*timestamp - cache_timestamps[c] > cache_size)
- {
- - cache_timestamps[c] = timestamp++;
- + cache_timestamps[c] = *timestamp++;
- cache_misses++;
- }
- @@ -160,8 +158,8 @@ static unsigned int updateCache(unsigned int a, unsigned int b, unsigned int c,
- static size_t generateHardBoundaries(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count, unsigned int cache_size)
- {
- - meshopt_Buffer<unsigned int> cache_timestamps(vertex_count);
- - memset(cache_timestamps.data, 0, vertex_count * sizeof(unsigned int));
- + unsigned int* cache_timestamps = malloc(vertex_count * sizeof(unsigned int));
- + memset(cache_timestamps, 0, vertex_count * sizeof(unsigned int));
- unsigned int timestamp = cache_size + 1;
- @@ -171,7 +169,7 @@ static size_t generateHardBoundaries(unsigned int* destination, const unsigned i
- for (size_t i = 0; i < face_count; ++i)
- {
- - unsigned int m = updateCache(indices[i * 3 + 0], indices[i * 3 + 1], indices[i * 3 + 2], cache_size, &cache_timestamps[0], timestamp);
- + unsigned int m = updateCache(indices[i * 3 + 0], indices[i * 3 + 1], indices[i * 3 + 2], cache_size, &cache_timestamps[0], ×tamp);
- // when all three vertices are not in the cache it's usually relatively safe to assume that this is a new patch in the mesh
- // that is disjoint from previous vertices; sometimes it might come back to reference existing vertices but that frequently
- @@ -179,10 +177,12 @@ static size_t generateHardBoundaries(unsigned int* destination, const unsigned i
- // usually the first triangle has 3 misses unless it's degenerate - thus we make sure the first cluster always starts with 0
- if (i == 0 || m == 3)
- {
- - destination[result++] = unsigned(i);
- + destination[result++] = (unsigned)(i);
- }
- }
- + free(cache_timestamps);
- +
- assert(result <= index_count / 3);
- return result;
- @@ -190,8 +190,8 @@ static size_t generateHardBoundaries(unsigned int* destination, const unsigned i
- static size_t generateSoftBoundaries(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count, const unsigned int* clusters, size_t cluster_count, unsigned int cache_size, float threshold)
- {
- - meshopt_Buffer<unsigned int> cache_timestamps(vertex_count);
- - memset(cache_timestamps.data, 0, vertex_count * sizeof(unsigned int));
- + unsigned int* cache_timestamps = malloc(vertex_count * sizeof(unsigned int));
- + memset(cache_timestamps, 0, vertex_count * sizeof(unsigned int));
- unsigned int timestamp = 0;
- @@ -211,15 +211,15 @@ static size_t generateSoftBoundaries(unsigned int* destination, const unsigned i
- for (size_t i = start; i < end; ++i)
- {
- - unsigned int m = updateCache(indices[i * 3 + 0], indices[i * 3 + 1], indices[i * 3 + 2], cache_size, &cache_timestamps[0], timestamp);
- + unsigned int m = updateCache(indices[i * 3 + 0], indices[i * 3 + 1], indices[i * 3 + 2], cache_size, &cache_timestamps[0], ×tamp);
- cluster_misses += m;
- }
- - float cluster_threshold = threshold * (float(cluster_misses) / float(end - start));
- + float cluster_threshold = threshold * ((float)(cluster_misses) / (float)(end - start));
- // first cluster always starts from the hard cluster boundary
- - destination[result++] = unsigned(start);
- + destination[result++] = (unsigned)(start);
- // reset cache
- timestamp += cache_size + 1;
- @@ -229,17 +229,17 @@ static size_t generateSoftBoundaries(unsigned int* destination, const unsigned i
- for (size_t i = start; i < end; ++i)
- {
- - unsigned int m = updateCache(indices[i * 3 + 0], indices[i * 3 + 1], indices[i * 3 + 2], cache_size, &cache_timestamps[0], timestamp);
- + unsigned int m = updateCache(indices[i * 3 + 0], indices[i * 3 + 1], indices[i * 3 + 2], cache_size, &cache_timestamps[0], ×tamp);
- running_misses += m;
- running_faces += 1;
- - if (float(running_misses) / float(running_faces) <= cluster_threshold)
- + if ((float)(running_misses) / (float)(running_faces) <= cluster_threshold)
- {
- // we have reached the target ACMR with the current triangle so we need to start a new cluster on the next one
- // note that this may mean that we add 'end` to destination for the last triangle, which will imply that the last
- // cluster is empty; however, the 'pop_back' after the loop will clean it up
- - destination[result++] = unsigned(i + 1);
- + destination[result++] = (unsigned)(i + 1);
- // reset cache
- timestamp += cache_size + 1;
- @@ -261,18 +261,16 @@ static size_t generateSoftBoundaries(unsigned int* destination, const unsigned i
- }
- }
- + free(cache_timestamps);
- +
- assert(result >= cluster_count);
- assert(result <= index_count / 3);
- return result;
- }
- -} // namespace meshopt
- -
- void meshopt_optimizeOverdraw(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, float threshold)
- {
- - using namespace meshopt;
- -
- assert(index_count % 3 == 0);
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
- assert(vertex_positions_stride % sizeof(float) == 0);
- @@ -282,35 +280,35 @@ void meshopt_optimizeOverdraw(unsigned int* destination, const unsigned int* ind
- return;
- // support in-place optimization
- - meshopt_Buffer<unsigned int> indices_copy;
- + unsigned int* indices_copy = 0;
- if (destination == indices)
- {
- - indices_copy.allocate(index_count);
- - memcpy(indices_copy.data, indices, index_count * sizeof(unsigned int));
- - indices = indices_copy.data;
- + indices_copy = malloc(index_count * sizeof(unsigned int));
- + memcpy(indices_copy, indices, index_count * sizeof(unsigned int));
- + indices = indices_copy;
- }
- unsigned int cache_size = 16;
- // generate hard boundaries from full-triangle cache misses
- - meshopt_Buffer<unsigned int> hard_clusters(index_count / 3);
- + unsigned int* hard_clusters = malloc((index_count / 3) * sizeof(unsigned int));
- size_t hard_cluster_count = generateHardBoundaries(&hard_clusters[0], indices, index_count, vertex_count, cache_size);
- // generate soft boundaries
- - meshopt_Buffer<unsigned int> soft_clusters(index_count / 3 + 1);
- + unsigned int* soft_clusters = malloc((index_count / 3 + 1) * sizeof(unsigned int));
- size_t soft_cluster_count = generateSoftBoundaries(&soft_clusters[0], indices, index_count, vertex_count, &hard_clusters[0], hard_cluster_count, cache_size, threshold);
- const unsigned int* clusters = &soft_clusters[0];
- size_t cluster_count = soft_cluster_count;
- // fill sort data
- - meshopt_Buffer<float> sort_data(cluster_count);
- + float* sort_data = malloc(cluster_count * sizeof(float));
- calculateSortData(&sort_data[0], indices, index_count, vertex_positions, vertex_positions_stride, clusters, cluster_count);
- // sort clusters using sort data
- - meshopt_Buffer<unsigned short> sort_keys(cluster_count);
- - meshopt_Buffer<unsigned int> sort_order(cluster_count);
- + unsigned short* sort_keys = malloc(cluster_count * sizeof(unsigned short));
- + unsigned int* sort_order = malloc(cluster_count * sizeof(unsigned int));
- calculateSortOrderRadix(&sort_order[0], &sort_data[0], &sort_keys[0], cluster_count);
- // fill output buffer
- @@ -330,4 +328,11 @@ void meshopt_optimizeOverdraw(unsigned int* destination, const unsigned int* ind
- }
- assert(offset == index_count);
- +
- + free(sort_order);
- + free(sort_keys);
- + free(sort_data);
- + free(soft_clusters);
- + free(hard_clusters);
- + free(indices_copy);
- }
- diff --git a/src/simplifier.cpp b/src/simplifier.cpp
- index cfc4880..2ba40f4 100644
- --- a/src/simplifier.cpp
- +++ b/src/simplifier.cpp
- @@ -13,35 +13,26 @@
- // This work is based on:
- // Michael Garland and Paul S. Heckbert. Surface simplification using quadric error metrics. 1997
- -namespace meshopt
- -{
- -struct EdgeAdjacency
- +typedef struct EdgeAdjacency
- {
- - meshopt_Buffer<unsigned int> counts;
- - meshopt_Buffer<unsigned int> offsets;
- - meshopt_Buffer<unsigned int> data;
- -
- - EdgeAdjacency(size_t index_count, size_t vertex_count)
- - : counts(vertex_count)
- - , offsets(vertex_count)
- - , data(index_count)
- - {
- - }
- -};
- + unsigned int* counts;
- + unsigned int* offsets;
- + unsigned int* data;
- +} EdgeAdjacency;
- -static void buildEdgeAdjacency(EdgeAdjacency& adjacency, const unsigned int* indices, size_t index_count, size_t vertex_count)
- +static void buildEdgeAdjacency(EdgeAdjacency* adjacency, const unsigned int* indices, size_t index_count, size_t vertex_count)
- {
- size_t face_count = index_count / 3;
- // fill edge counts
- - memset(adjacency.counts.data, 0, vertex_count * sizeof(unsigned int));
- + memset(adjacency->counts, 0, vertex_count * sizeof(unsigned int));
- for (size_t i = 0; i < index_count; ++i)
- {
- assert(indices[i] < vertex_count);
- - adjacency.counts[indices[i]]++;
- + adjacency->counts[indices[i]]++;
- }
- // fill offset table
- @@ -49,8 +40,8 @@ static void buildEdgeAdjacency(EdgeAdjacency& adjacency, const unsigned int* ind
- for (size_t i = 0; i < vertex_count; ++i)
- {
- - adjacency.offsets[i] = offset;
- - offset += adjacency.counts[i];
- + adjacency->offsets[i] = offset;
- + offset += adjacency->counts[i];
- }
- assert(offset == index_count);
- @@ -60,24 +51,24 @@ static void buildEdgeAdjacency(EdgeAdjacency& adjacency, const unsigned int* ind
- {
- unsigned int a = indices[i * 3 + 0], b = indices[i * 3 + 1], c = indices[i * 3 + 2];
- - adjacency.data[adjacency.offsets[a]++] = b;
- - adjacency.data[adjacency.offsets[b]++] = c;
- - adjacency.data[adjacency.offsets[c]++] = a;
- + adjacency->data[adjacency->offsets[a]++] = b;
- + adjacency->data[adjacency->offsets[b]++] = c;
- + adjacency->data[adjacency->offsets[c]++] = a;
- }
- // fix offsets that have been disturbed by the previous pass
- for (size_t i = 0; i < vertex_count; ++i)
- {
- - assert(adjacency.offsets[i] >= adjacency.counts[i]);
- + assert(adjacency->offsets[i] >= adjacency->counts[i]);
- - adjacency.offsets[i] -= adjacency.counts[i];
- + adjacency->offsets[i] -= adjacency->counts[i];
- }
- }
- -static bool findEdge(const EdgeAdjacency& adjacency, unsigned int a, unsigned int b)
- +static bool findEdge(const EdgeAdjacency* adjacency, unsigned int a, unsigned int b)
- {
- - unsigned int count = adjacency.counts[a];
- - const unsigned int* data = adjacency.data.data + adjacency.offsets[a];
- + unsigned int count = adjacency->counts[a];
- + const unsigned int* data = adjacency->data + adjacency->offsets[a];
- for (size_t i = 0; i < count; ++i)
- if (data[i] == b)
- @@ -86,40 +77,40 @@ static bool findEdge(const EdgeAdjacency& adjacency, unsigned int a, unsigned in
- return false;
- }
- -struct PositionHasher
- +typedef struct PositionHasher
- {
- const float* vertex_positions;
- size_t vertex_stride_float;
- +} PositionHasher;
- - size_t hash(unsigned int index) const
- - {
- - // MurmurHash2
- - const unsigned int m = 0x5bd1e995;
- - const int r = 24;
- +static size_t hash2(const PositionHasher* hasher, unsigned int index)
- +{
- + // MurmurHash2
- + const unsigned int m = 0x5bd1e995;
- + const int r = 24;
- - unsigned int h = 0;
- - const unsigned int* key = reinterpret_cast<const unsigned int*>(vertex_positions + index * vertex_stride_float);
- + unsigned int h = 0;
- + const unsigned int* key = (const unsigned int*)(hasher->vertex_positions + index * hasher->vertex_stride_float);
- - for (size_t i = 0; i < 3; ++i)
- - {
- - unsigned int k = key[i];
- -
- - k *= m;
- - k ^= k >> r;
- - k *= m;
- + for (size_t i = 0; i < 3; ++i)
- + {
- + unsigned int k = key[i];
- - h *= m;
- - h ^= k;
- - }
- + k *= m;
- + k ^= k >> r;
- + k *= m;
- - return h;
- + h *= m;
- + h ^= k;
- }
- - bool equal(unsigned int lhs, unsigned int rhs) const
- - {
- - return memcmp(vertex_positions + lhs * vertex_stride_float, vertex_positions + rhs * vertex_stride_float, 12) == 0;
- - }
- -};
- + return h;
- +}
- +
- +static bool equal2(const PositionHasher* hasher, unsigned int lhs, unsigned int rhs)
- +{
- + return memcmp(hasher->vertex_positions + lhs * hasher->vertex_stride_float, hasher->vertex_positions + rhs * hasher->vertex_stride_float, 12) == 0;
- +}
- // TODO: is there a better way to resolve naming conflicts with indexgenerator.cpp?
- static size_t hashBuckets2(size_t count)
- @@ -132,24 +123,23 @@ static size_t hashBuckets2(size_t count)
- }
- // TODO: is there a better way to resolve naming conflicts with indexgenerator.cpp?
- -template <typename T, typename Hash>
- -static T* hashLookup2(T* table, size_t buckets, const Hash& hash, const T& key, const T& empty)
- +static unsigned int* hashLookup2(unsigned int* table, size_t buckets, const PositionHasher* hasher, unsigned int key, unsigned int empty)
- {
- assert(buckets > 0);
- assert((buckets & (buckets - 1)) == 0);
- size_t hashmod = buckets - 1;
- - size_t bucket = hash.hash(key) & hashmod;
- + size_t bucket = hash2(hasher, key) & hashmod;
- for (size_t probe = 0; probe <= hashmod; ++probe)
- {
- - T& item = table[bucket];
- + unsigned int* item = &table[bucket];
- - if (item == empty)
- - return &item;
- + if (*item == empty)
- + return item;
- - if (hash.equal(item, key))
- - return &item;
- + if (equal2(hasher, *item, key))
- + return item;
- // hash collision, quadratic probing
- bucket = (bucket + probe + 1) & hashmod;
- @@ -163,15 +153,16 @@ static void buildPositionRemap(unsigned int* remap, unsigned int* reverse_remap,
- {
- PositionHasher hasher = {vertex_positions_data, vertex_positions_stride / sizeof(float)};
- - meshopt_Buffer<unsigned int> table(hashBuckets2(vertex_count));
- - memset(table.data, -1, table.size * sizeof(unsigned int));
- + size_t buckets = hashBuckets2(vertex_count);
- + unsigned int* table = malloc(buckets * sizeof(unsigned int));
- + memset(table, -1, buckets * sizeof(unsigned int));
- // build forward remap: for each vertex, which other (canonical) vertex does it map to?
- // we use position equivalence for this, and remap vertices to other existing vertices
- for (size_t i = 0; i < vertex_count; ++i)
- {
- - unsigned int index = unsigned(i);
- - unsigned int* entry = hashLookup2(table.data, table.size, hasher, index, ~0u);
- + unsigned int index = (unsigned)(i);
- + unsigned int* entry = hashLookup2(table, buckets, &hasher, index, ~0u);
- if (*entry == ~0u)
- {
- @@ -190,18 +181,20 @@ static void buildPositionRemap(unsigned int* remap, unsigned int* reverse_remap,
- // build reverse remap table: for each vertex, which other vertex remaps to this one?
- // this is a many-to-one relationship, but we only identify vertices for which it's 2-1 (so a pair of vertices)
- for (size_t i = 0; i < vertex_count; ++i)
- - reverse_remap[i] = unsigned(i);
- + reverse_remap[i] = (unsigned)(i);
- for (size_t i = 0; i < vertex_count; ++i)
- if (remap[i] != i)
- {
- // first vertex to remap to remap[i]: keep
- if (reverse_remap[remap[i]] == remap[i])
- - reverse_remap[remap[i]] = unsigned(i);
- + reverse_remap[remap[i]] = (unsigned)(i);
- // more than one vertex, invalidate entry
- else
- reverse_remap[remap[i]] = ~0u;
- }
- +
- + free(table);
- }
- enum VertexKind
- @@ -224,12 +217,12 @@ const char kCanCollapse[Kind_Count][Kind_Count] = {
- {0, 0, 0, 0},
- };
- -static size_t countOpenEdges(const EdgeAdjacency& adjacency, unsigned int vertex, unsigned int* last = 0)
- +static size_t countOpenEdges(const EdgeAdjacency* adjacency, unsigned int vertex, unsigned int* last)
- {
- size_t result = 0;
- - unsigned int count = adjacency.counts[vertex];
- - const unsigned int* data = adjacency.data.data + adjacency.offsets[vertex];
- + unsigned int count = adjacency->counts[vertex];
- + const unsigned int* data = adjacency->data + adjacency->offsets[vertex];
- for (size_t i = 0; i < count; ++i)
- if (!findEdge(adjacency, data[i], vertex))
- @@ -243,7 +236,7 @@ static size_t countOpenEdges(const EdgeAdjacency& adjacency, unsigned int vertex
- return result;
- }
- -static void classifyVertices(unsigned char* result, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* reverse_remap, size_t lockedstats[4])
- +static void classifyVertices(unsigned char* result, size_t vertex_count, const EdgeAdjacency* adjacency, const unsigned int* remap, const unsigned int* reverse_remap, size_t lockedstats[4])
- {
- for (size_t i = 0; i < vertex_count; ++i)
- {
- @@ -252,7 +245,8 @@ static void classifyVertices(unsigned char* result, size_t vertex_count, const E
- if (reverse_remap[i] == i)
- {
- // no attribute seam, need to check if it's manifold
- - size_t edges = countOpenEdges(adjacency, unsigned(i));
- + unsigned int dummy;
- + size_t edges = countOpenEdges(adjacency, (unsigned)(i), &dummy);
- // note: we classify any vertices with no open edges as manifold
- // this is technically incorrect - if 4 triangles share an edge, we'll classify vertices as manifold
- @@ -270,7 +264,7 @@ static void classifyVertices(unsigned char* result, size_t vertex_count, const E
- {
- // attribute seam; need to distinguish between Seam and Locked
- unsigned int a = 0;
- - size_t a_count = countOpenEdges(adjacency, unsigned(i), &a);
- + size_t a_count = countOpenEdges(adjacency, (unsigned)(i), &a);
- unsigned int b = 0;
- size_t b_count = countOpenEdges(adjacency, reverse_remap[i], &b);
- @@ -282,7 +276,7 @@ static void classifyVertices(unsigned char* result, size_t vertex_count, const E
- unsigned int bf = (remap[b] == b) ? reverse_remap[b] : remap[b];
- if (af != ~0u && findEdge(adjacency, af, reverse_remap[i]) &&
- - bf != ~0u && findEdge(adjacency, bf, unsigned(i)))
- + bf != ~0u && findEdge(adjacency, bf, (unsigned)(i)))
- result[i] = Kind_Seam;
- else
- result[i] = Kind_Locked, lockedstats[1]++;
- @@ -307,20 +301,20 @@ static void classifyVertices(unsigned char* result, size_t vertex_count, const E
- }
- }
- -struct Vector3
- +typedef struct Vector3
- {
- float x, y, z;
- -};
- +} Vector3;
- -struct Quadric
- +typedef struct Quadric
- {
- float a00;
- float a10, a11;
- float a20, a21, a22;
- float b0, b1, b2, c;
- -};
- +} Quadric;
- -struct Collapse
- +typedef struct Collapse
- {
- unsigned int v0;
- unsigned int v1;
- @@ -329,87 +323,87 @@ struct Collapse
- float error;
- unsigned int errorui;
- };
- -};
- +} Collapse;
- -static float normalize(Vector3& v)
- +static float normalize(Vector3* v)
- {
- - float length = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
- + float length = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
- if (length > 0)
- {
- - v.x /= length;
- - v.y /= length;
- - v.z /= length;
- + v->x /= length;
- + v->y /= length;
- + v->z /= length;
- }
- return length;
- }
- -static void quadricAdd(Quadric& Q, const Quadric& R)
- +static void quadricAdd(Quadric* Q, const Quadric* R)
- {
- - Q.a00 += R.a00;
- - Q.a10 += R.a10;
- - Q.a11 += R.a11;
- - Q.a20 += R.a20;
- - Q.a21 += R.a21;
- - Q.a22 += R.a22;
- - Q.b0 += R.b0;
- - Q.b1 += R.b1;
- - Q.b2 += R.b2;
- - Q.c += R.c;
- + Q->a00 += R->a00;
- + Q->a10 += R->a10;
- + Q->a11 += R->a11;
- + Q->a20 += R->a20;
- + Q->a21 += R->a21;
- + Q->a22 += R->a22;
- + Q->b0 += R->b0;
- + Q->b1 += R->b1;
- + Q->b2 += R->b2;
- + Q->c += R->c;
- }
- -static void quadricMul(Quadric& Q, float s)
- +static void quadricMul(Quadric* Q, float s)
- {
- - Q.a00 *= s;
- - Q.a10 *= s;
- - Q.a11 *= s;
- - Q.a20 *= s;
- - Q.a21 *= s;
- - Q.a22 *= s;
- - Q.b0 *= s;
- - Q.b1 *= s;
- - Q.b2 *= s;
- - Q.c *= s;
- + Q->a00 *= s;
- + Q->a10 *= s;
- + Q->a11 *= s;
- + Q->a20 *= s;
- + Q->a21 *= s;
- + Q->a22 *= s;
- + Q->b0 *= s;
- + Q->b1 *= s;
- + Q->b2 *= s;
- + Q->c *= s;
- }
- -static float quadricError(Quadric& Q, const Vector3& v)
- +static float quadricError(Quadric* Q, const Vector3* v)
- {
- - float xx = v.x * v.x;
- - float xy = v.x * v.y;
- - float xz = v.x * v.z;
- - float yy = v.y * v.y;
- - float yz = v.y * v.z;
- - float zz = v.z * v.z;
- + float xx = v->x * v->x;
- + float xy = v->x * v->y;
- + float xz = v->x * v->z;
- + float yy = v->y * v->y;
- + float yz = v->y * v->z;
- + float zz = v->z * v->z;
- - float vTQv = Q.a00 * xx + Q.a10 * xy * 2 + Q.a11 * yy + Q.a20 * xz * 2 + Q.a21 * yz * 2 + Q.a22 * zz + Q.b0 * v.x * 2 + Q.b1 * v.y * 2 + Q.b2 * v.z * 2 + Q.c;
- + float vTQv = Q->a00 * xx + Q->a10 * xy * 2 + Q->a11 * yy + Q->a20 * xz * 2 + Q->a21 * yz * 2 + Q->a22 * zz + Q->b0 * v->x * 2 + Q->b1 * v->y * 2 + Q->b2 * v->z * 2 + Q->c;
- return fabsf(vTQv);
- }
- -static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d)
- +static void quadricFromPlane(Quadric* Q, float a, float b, float c, float d)
- {
- - Q.a00 = a * a;
- - Q.a10 = b * a;
- - Q.a11 = b * b;
- - Q.a20 = c * a;
- - Q.a21 = c * b;
- - Q.a22 = c * c;
- - Q.b0 = d * a;
- - Q.b1 = d * b;
- - Q.b2 = d * c;
- - Q.c = d * d;
- + Q->a00 = a * a;
- + Q->a10 = b * a;
- + Q->a11 = b * b;
- + Q->a20 = c * a;
- + Q->a21 = c * b;
- + Q->a22 = c * c;
- + Q->b0 = d * a;
- + Q->b1 = d * b;
- + Q->b2 = d * c;
- + Q->c = d * d;
- }
- -static void quadricFromTriangle(Quadric& Q, const Vector3& p0, const Vector3& p1, const Vector3& p2)
- +static void quadricFromTriangle(Quadric* Q, const Vector3* p0, const Vector3* p1, const Vector3* p2)
- {
- - Vector3 p10 = {p1.x - p0.x, p1.y - p0.y, p1.z - p0.z};
- - Vector3 p20 = {p2.x - p0.x, p2.y - p0.y, p2.z - p0.z};
- + Vector3 p10 = {p1->x - p0->x, p1->y - p0->y, p1->z - p0->z};
- + Vector3 p20 = {p2->x - p0->x, p2->y - p0->y, p2->z - p0->z};
- Vector3 normal = {p10.y * p20.z - p10.z * p20.y, p10.z * p20.x - p10.x * p20.z, p10.x * p20.y - p10.y * p20.x};
- - float area = normalize(normal);
- + float area = normalize(&normal);
- - float distance = normal.x * p0.x + normal.y * p0.y + normal.z * p0.z;
- + float distance = normal.x * p0->x + normal.y * p0->y + normal.z * p0->z;
- quadricFromPlane(Q, normal.x, normal.y, normal.z, -distance);
- @@ -419,18 +413,18 @@ static void quadricFromTriangle(Quadric& Q, const Vector3& p0, const Vector3& p1
- quadricMul(Q, area);
- }
- -static void quadricFromTriangleEdge(Quadric& Q, const Vector3& p0, const Vector3& p1, const Vector3& p2, float weight)
- +static void quadricFromTriangleEdge(Quadric* Q, const Vector3* p0, const Vector3* p1, const Vector3* p2, float weight)
- {
- - Vector3 p10 = {p1.x - p0.x, p1.y - p0.y, p1.z - p0.z};
- - float length = normalize(p10);
- + Vector3 p10 = {p1->x - p0->x, p1->y - p0->y, p1->z - p0->z};
- + float length = normalize(&p10);
- - Vector3 p20 = {p2.x - p0.x, p2.y - p0.y, p2.z - p0.z};
- + Vector3 p20 = {p2->x - p0->x, p2->y - p0->y, p2->z - p0->z};
- float p20p = p20.x * p10.x + p20.y * p10.y + p20.z * p10.z;
- Vector3 normal = {p20.x - p10.x * p20p, p20.y - p10.y * p20p, p20.z - p10.z * p20p};
- - normalize(normal);
- + normalize(&normal);
- - float distance = normal.x * p0.x + normal.y * p0.y + normal.z * p0.z;
- + float distance = normal.x * p0->x + normal.y * p0->y + normal.z * p0->z;
- // TODO: We should be able to encode squared distance to the edge here?
- quadricFromPlane(Q, normal.x, normal.y, normal.z, -distance);
- @@ -459,7 +453,7 @@ static void sortEdgeCollapses(unsigned int* sort_order, const Collapse* collapse
- for (size_t i = 0; i < 1 << sort_bits; ++i)
- {
- size_t count = histogram[i];
- - histogram[i] = unsigned(histogram_sum);
- + histogram[i] = (unsigned)(histogram_sum);
- histogram_sum += count;
- }
- @@ -470,19 +464,15 @@ static void sortEdgeCollapses(unsigned int* sort_order, const Collapse* collapse
- {
- unsigned int key = (collapses[i].errorui << 1) >> (32 - sort_bits);
- - sort_order[histogram[key]++] = unsigned(i);
- + sort_order[histogram[key]++] = (unsigned)(i);
- }
- }
- -} // namespace meshopt
- -
- // TODO: this is necessary for lodviewer but will go away at some point
- unsigned char* meshopt_simplifyDebugKind = 0;
- size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count)
- {
- - using namespace meshopt;
- -
- assert(index_count % 3 == 0);
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
- assert(vertex_positions_stride % sizeof(float) == 0);
- @@ -491,13 +481,17 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- unsigned int* result = destination;
- // build adjacency information
- - EdgeAdjacency adjacency(index_count, vertex_count);
- - buildEdgeAdjacency(adjacency, indices, index_count, vertex_count);
- + EdgeAdjacency adjacency = {};
- + adjacency.counts = malloc(vertex_count * sizeof(unsigned int));
- + adjacency.offsets = malloc(vertex_count * sizeof(unsigned int));
- + adjacency.data = malloc(index_count * sizeof(unsigned int));
- +
- + buildEdgeAdjacency(&adjacency, indices, index_count, vertex_count);
- // build position remap that maps each vertex to the one with identical position
- - meshopt_Buffer<unsigned int> remap(vertex_count);
- - meshopt_Buffer<unsigned int> reverse_remap(vertex_count);
- - buildPositionRemap(remap.data, reverse_remap.data, vertex_positions_data, vertex_count, vertex_positions_stride);
- + unsigned int* remap = malloc(vertex_count * sizeof(unsigned int));
- + unsigned int* reverse_remap = malloc(vertex_count * sizeof(unsigned int));
- + buildPositionRemap(remap, reverse_remap, vertex_positions_data, vertex_count, vertex_positions_stride);
- // TODO: maybe make this an option? this disables seam awareness
- // for (size_t i = 0; i < vertex_count; ++i) remap[i] = reverse_remap[i] = unsigned(i);
- @@ -505,11 +499,11 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- size_t lockedstats[4] = {};
- // classify vertices; vertex kind determines collapse rules, see kCanCollapse
- - meshopt_Buffer<unsigned char> vertex_kind(vertex_count);
- - classifyVertices(vertex_kind.data, vertex_count, adjacency, remap.data, reverse_remap.data, lockedstats);
- + unsigned char* vertex_kind = malloc(vertex_count);
- + classifyVertices(vertex_kind, vertex_count, &adjacency, remap, reverse_remap, lockedstats);
- if (meshopt_simplifyDebugKind)
- - memcpy(meshopt_simplifyDebugKind, vertex_kind.data, vertex_count);
- + memcpy(meshopt_simplifyDebugKind, vertex_kind, vertex_count);
- #if TRACE
- size_t unique_positions = 0;
- @@ -530,7 +524,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- size_t vertex_stride_float = vertex_positions_stride / sizeof(float);
- - meshopt_Buffer<Vector3> vertex_positions(vertex_count);
- + Vector3* vertex_positions = malloc(vertex_count * sizeof(Vector3));
- // copy positions to make code slightly simpler and improve cache efficiency
- for (size_t i = 0; i < vertex_count; ++i)
- @@ -542,8 +536,8 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- vertex_positions[i].z = v[2];
- }
- - meshopt_Buffer<Quadric> vertex_quadrics(vertex_count);
- - memset(vertex_quadrics.data, 0, vertex_count * sizeof(Quadric));
- + Quadric* vertex_quadrics = malloc(vertex_count * sizeof(Quadric));
- + memset(vertex_quadrics, 0, vertex_count * sizeof(Quadric));
- // face quadrics
- for (size_t i = 0; i < index_count; i += 3)
- @@ -556,11 +550,11 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- // assert(i0 != i1 && i0 != i2 && i1 != i2);
- Quadric Q;
- - quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2]);
- + quadricFromTriangle(&Q, &vertex_positions[i0], &vertex_positions[i1], &vertex_positions[i2]);
- - quadricAdd(vertex_quadrics[remap[i0]], Q);
- - quadricAdd(vertex_quadrics[remap[i1]], Q);
- - quadricAdd(vertex_quadrics[remap[i2]], Q);
- + quadricAdd(&vertex_quadrics[remap[i0]], &Q);
- + quadricAdd(&vertex_quadrics[remap[i1]], &Q);
- + quadricAdd(&vertex_quadrics[remap[i2]], &Q);
- }
- // edge quadrics for boundary edges
- @@ -578,7 +572,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- if (vertex_kind[i0] != Kind_Border && vertex_kind[i0] != Kind_Seam)
- continue;
- - if (findEdge(adjacency, i1, i0))
- + if (findEdge(&adjacency, i1, i0))
- continue;
- unsigned int i2 = indices[i + next[next[e]]];
- @@ -589,10 +583,10 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- float edgeWeight = vertex_kind[i0] == Kind_Seam ? 1.f : 10.f;
- Quadric Q;
- - quadricFromTriangleEdge(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], edgeWeight);
- + quadricFromTriangleEdge(&Q, &vertex_positions[i0], &vertex_positions[i1], &vertex_positions[i2], edgeWeight);
- - quadricAdd(vertex_quadrics[remap[i0]], Q);
- - quadricAdd(vertex_quadrics[remap[i1]], Q);
- + quadricAdd(&vertex_quadrics[remap[i0]], &Q);
- + quadricAdd(&vertex_quadrics[remap[i1]], &Q);
- boundary++;
- }
- @@ -610,10 +604,10 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- size_t pass_count = 0;
- float worst_error = 0;
- - meshopt_Buffer<Collapse> edge_collapses(index_count);
- - meshopt_Buffer<unsigned int> collapse_order(index_count);
- - meshopt_Buffer<unsigned int> collapse_remap(vertex_count);
- - meshopt_Buffer<char> collapse_locked(vertex_count);
- + Collapse* edge_collapses = malloc(index_count * sizeof(unsigned int));
- + unsigned int* collapse_order = malloc(index_count * sizeof(unsigned int));
- + unsigned int* collapse_remap = malloc(vertex_count * sizeof(unsigned int));
- + char* collapse_locked = malloc(vertex_count);
- while (index_count > target_index_count)
- {
- @@ -640,8 +634,8 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- if (vertex_kind[i0] == vertex_kind[i1])
- {
- // TODO: Garland97 uses Q1+Q2 for error estimation; here we asssume that V1 produces zero error for Q1 but it actually gets larger with more collapses
- - Collapse c01 = {i0, i1, {quadricError(vertex_quadrics[remap[i0]], vertex_positions[i1])}};
- - Collapse c10 = {i1, i0, {quadricError(vertex_quadrics[remap[i1]], vertex_positions[i0])}};
- + Collapse c01 = {i0, i1, {quadricError(&vertex_quadrics[remap[i0]], &vertex_positions[i1])}};
- + Collapse c10 = {i1, i0, {quadricError(&vertex_quadrics[remap[i1]], &vertex_positions[i0])}};
- Collapse c = c01.error <= c10.error ? c01 : c10;
- assert(c.error >= 0);
- @@ -649,7 +643,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- }
- else
- {
- - Collapse c = {i0, i1, {quadricError(vertex_quadrics[remap[i0]], vertex_positions[i1])}};
- + Collapse c = {i0, i1, {quadricError(&vertex_quadrics[remap[i0]], &vertex_positions[i1])}};
- assert(c.error >= 0);
- edge_collapses[edge_collapse_count++] = c;
- @@ -661,14 +655,14 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- if (edge_collapse_count == 0)
- break;
- - sortEdgeCollapses(collapse_order.data, edge_collapses.data, edge_collapse_count);
- + sortEdgeCollapses(collapse_order, edge_collapses, edge_collapse_count);
- for (size_t i = 0; i < vertex_count; ++i)
- {
- - collapse_remap[i] = unsigned(i);
- + collapse_remap[i] = (unsigned)(i);
- }
- - memset(collapse_locked.data, 0, vertex_count);
- + memset(collapse_locked, 0, vertex_count);
- // each collapse removes 2 triangles
- size_t edge_collapse_goal = (index_count - target_index_count) / 6 + 1;
- @@ -681,15 +675,15 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- for (size_t i = 0; i < edge_collapse_count; ++i)
- {
- - const Collapse& c = edge_collapses[collapse_order[i]];
- + const Collapse* c = &edge_collapses[collapse_order[i]];
- - unsigned int r0 = remap[c.v0];
- - unsigned int r1 = remap[c.v1];
- + unsigned int r0 = remap[c->v0];
- + unsigned int r1 = remap[c->v1];
- if (collapse_locked[r0] || collapse_locked[r1])
- continue;
- - if (c.error > error_limit)
- + if (c->error > error_limit)
- break;
- #if TRACE > 1
- @@ -702,32 +696,32 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- assert(collapse_remap[r0] == r0);
- assert(collapse_remap[r1] == r1);
- - quadricAdd(vertex_quadrics[r1], vertex_quadrics[r0]);
- + quadricAdd(&vertex_quadrics[r1], &vertex_quadrics[r0]);
- - if (vertex_kind[c.v0] == Kind_Seam)
- + if (vertex_kind[c->v0] == Kind_Seam)
- {
- // remap v0 to v1 and seam pair of v0 to seam pair of v1
- - unsigned int s0 = c.v0 == r0 ? reverse_remap[r0] : r0;
- - unsigned int s1 = c.v1 == r1 ? reverse_remap[r1] : r1;
- + unsigned int s0 = c->v0 == r0 ? reverse_remap[r0] : r0;
- + unsigned int s1 = c->v1 == r1 ? reverse_remap[r1] : r1;
- - assert(s0 != ~0u && s0 != c.v0);
- - assert(s1 != ~0u && s1 != c.v1);
- + assert(s0 != ~0u && s0 != c->v0);
- + assert(s1 != ~0u && s1 != c->v1);
- - collapse_remap[c.v0] = c.v1;
- + collapse_remap[c->v0] = c->v1;
- collapse_remap[s0] = s1;
- }
- else
- {
- - assert(c.v0 == r0 && reverse_remap[r0] == r0);
- + assert(c->v0 == r0 && reverse_remap[r0] == r0);
- - collapse_remap[c.v0] = c.v1;
- + collapse_remap[c->v0] = c->v1;
- }
- collapse_locked[r0] = 1;
- collapse_locked[r1] = 1;
- collapses++;
- - pass_error = c.error;
- + pass_error = c->error;
- if (collapses >= edge_collapse_goal)
- break;
- @@ -796,5 +790,18 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- printf("locked collapses %d -> %d: %d\n", k0, k1, int(locked_collapses[k0][k1]));
- #endif
- + free(collapse_locked);
- + free(collapse_remap);
- + free(collapse_order);
- + free(edge_collapses);
- + free(vertex_quadrics);
- + free(vertex_positions);
- + free(vertex_kind);
- + free(reverse_remap);
- + free(remap);
- + free(adjacency.data);
- + free(adjacency.offsets);
- + free(adjacency.counts);
- +
- return index_count;
- }
- diff --git a/src/stripifier.cpp b/src/stripifier.cpp
- index e08189d..8493e7c 100644
- --- a/src/stripifier.cpp
- +++ b/src/stripifier.cpp
- @@ -4,9 +4,6 @@
- #include <limits.h>
- #include <string.h>
- -namespace meshopt
- -{
- -
- static unsigned int findStripFirst(const unsigned int buffer[][3], unsigned int buffer_size, const unsigned int* valence)
- {
- unsigned int index = 0;
- @@ -19,7 +16,7 @@ static unsigned int findStripFirst(const unsigned int buffer[][3], unsigned int
- if (v < iv)
- {
- - index = unsigned(i);
- + index = (unsigned)(i);
- iv = v;
- }
- }
- @@ -34,26 +31,22 @@ static int findStripNext(const unsigned int buffer[][3], unsigned int buffer_siz
- unsigned int a = buffer[i][0], b = buffer[i][1], c = buffer[i][2];
- if (e0 == a && e1 == b)
- - return (int(i) << 2) | 2;
- + return ((int)(i) << 2) | 2;
- else if (e0 == b && e1 == c)
- - return (int(i) << 2) | 0;
- + return ((int)(i) << 2) | 0;
- else if (e0 == c && e1 == a)
- - return (int(i) << 2) | 1;
- + return ((int)(i) << 2) | 1;
- }
- return -1;
- }
- -} // namespace meshopt
- -
- size_t meshopt_stripify(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count)
- {
- assert(destination != indices);
- assert(index_count % 3 == 0);
- - using namespace meshopt;
- -
- - const size_t buffer_capacity = 8;
- + enum { buffer_capacity = 8 };
- unsigned int buffer[buffer_capacity][3] = {};
- unsigned int buffer_size = 0;
- @@ -66,8 +59,8 @@ size_t meshopt_stripify(unsigned int* destination, const unsigned int* indices,
- size_t strip_size = 0;
- // compute vertex valence; this is used to prioritize starting triangle for strips
- - meshopt_Buffer<unsigned int> valence(vertex_count);
- - memset(valence.data, 0, vertex_count * sizeof(unsigned int));
- + unsigned int* valence = malloc(vertex_count * sizeof(unsigned int));
- + memset(valence, 0, vertex_count * sizeof(unsigned int));
- for (size_t i = 0; i < index_count; ++i)
- {
- @@ -81,7 +74,7 @@ size_t meshopt_stripify(unsigned int* destination, const unsigned int* indices,
- while (buffer_size > 0 || index_offset < index_count)
- {
- - assert(next < 0 || (size_t(next >> 2) < buffer_size && (next & 3) < 3));
- + assert(next < 0 || ((size_t)(next >> 2) < buffer_size && (next & 3) < 3));
- // fill triangle buffer
- while (buffer_size < buffer_capacity && index_offset < index_count)
- @@ -208,6 +201,8 @@ size_t meshopt_stripify(unsigned int* destination, const unsigned int* indices,
- }
- }
- + free(valence);
- +
- return strip_size;
- }
- diff --git a/src/vcacheanalyzer.cpp b/src/vcacheanalyzer.cpp
- index c673352..d7712d9 100644
- --- a/src/vcacheanalyzer.cpp
- +++ b/src/vcacheanalyzer.cpp
- @@ -4,19 +4,19 @@
- #include <assert.h>
- #include <string.h>
- -meshopt_VertexCacheStatistics meshopt_analyzeVertexCache(const unsigned int* indices, size_t index_count, size_t vertex_count, unsigned int cache_size, unsigned int warp_size, unsigned int primgroup_size)
- +struct meshopt_VertexCacheStatistics meshopt_analyzeVertexCache(const unsigned int* indices, size_t index_count, size_t vertex_count, unsigned int cache_size, unsigned int warp_size, unsigned int primgroup_size)
- {
- assert(index_count % 3 == 0);
- assert(cache_size >= 3);
- assert(warp_size == 0 || warp_size >= 3);
- - meshopt_VertexCacheStatistics result = {};
- + struct meshopt_VertexCacheStatistics result = {};
- unsigned int warp_offset = 0;
- unsigned int primgroup_offset = 0;
- - meshopt_Buffer<unsigned int> cache_timestamps(vertex_count);
- - memset(cache_timestamps.data, 0, vertex_count * sizeof(unsigned int));
- + unsigned int* cache_timestamps = malloc(vertex_count * sizeof(unsigned int));
- + memset(cache_timestamps, 0, vertex_count * sizeof(unsigned int));
- unsigned int timestamp = cache_size + 1;
- @@ -64,8 +64,10 @@ meshopt_VertexCacheStatistics meshopt_analyzeVertexCache(const unsigned int* ind
- result.warps_executed += warp_offset > 0;
- - result.acmr = index_count == 0 ? 0 : float(result.vertices_transformed) / float(index_count / 3);
- - result.atvr = unique_vertex_count == 0 ? 0 : float(result.vertices_transformed) / float(unique_vertex_count);
- + result.acmr = index_count == 0 ? 0 : (float)(result.vertices_transformed) / (float)(index_count / 3);
- + result.atvr = unique_vertex_count == 0 ? 0 : (float)(result.vertices_transformed) / (float)(unique_vertex_count);
- +
- + free(cache_timestamps);
- return result;
- }
- diff --git a/src/vcacheoptimizer.cpp b/src/vcacheoptimizer.cpp
- index 865d5a2..ac1aacc 100644
- --- a/src/vcacheoptimizer.cpp
- +++ b/src/vcacheoptimizer.cpp
- @@ -8,11 +8,9 @@
- // This work is based on:
- // Tom Forsyth. Linear-Speed Vertex Cache Optimisation. 2006
- // Pedro Sander, Diego Nehab and Joshua Barczak. Fast Triangle Reordering for Vertex Locality and Reduced Overdraw. 2007
- -namespace meshopt
- -{
- -const size_t max_cache_size = 16;
- -const size_t max_valence = 8;
- +enum { max_cache_size = 16 };
- +enum { max_valence = 8 };
- static const float vertex_score_table_cache[1 + max_cache_size] = {
- 0.f,
- @@ -22,32 +20,25 @@ static const float vertex_score_table_live[1 + max_valence] = {
- 0.f,
- 0.994f, 0.721f, 0.479f, 0.423f, 0.174f, 0.080f, 0.249f, 0.056f};
- -struct TriangleAdjacency
- +typedef struct TriangleAdjacency
- {
- - meshopt_Buffer<unsigned int> counts;
- - meshopt_Buffer<unsigned int> offsets;
- - meshopt_Buffer<unsigned int> data;
- -
- - TriangleAdjacency(size_t index_count, size_t vertex_count)
- - : counts(vertex_count)
- - , offsets(vertex_count)
- - , data(index_count)
- - {
- - }
- -};
- + unsigned int* counts;
- + unsigned int* offsets;
- + unsigned int* data;
- +} TriangleAdjacency;
- -static void buildTriangleAdjacency(TriangleAdjacency& adjacency, const unsigned int* indices, size_t index_count, size_t vertex_count)
- +static void buildTriangleAdjacency(TriangleAdjacency* adjacency, const unsigned int* indices, size_t index_count, size_t vertex_count)
- {
- size_t face_count = index_count / 3;
- // fill triangle counts
- - memset(adjacency.counts.data, 0, vertex_count * sizeof(unsigned int));
- + memset(adjacency->counts, 0, vertex_count * sizeof(unsigned int));
- for (size_t i = 0; i < index_count; ++i)
- {
- assert(indices[i] < vertex_count);
- - adjacency.counts[indices[i]]++;
- + adjacency->counts[indices[i]]++;
- }
- // fill offset table
- @@ -55,8 +46,8 @@ static void buildTriangleAdjacency(TriangleAdjacency& adjacency, const unsigned
- for (size_t i = 0; i < vertex_count; ++i)
- {
- - adjacency.offsets[i] = offset;
- - offset += adjacency.counts[i];
- + adjacency->offsets[i] = offset;
- + offset += adjacency->counts[i];
- }
- assert(offset == index_count);
- @@ -66,38 +57,38 @@ static void buildTriangleAdjacency(TriangleAdjacency& adjacency, const unsigned
- {
- unsigned int a = indices[i * 3 + 0], b = indices[i * 3 + 1], c = indices[i * 3 + 2];
- - adjacency.data[adjacency.offsets[a]++] = unsigned(i);
- - adjacency.data[adjacency.offsets[b]++] = unsigned(i);
- - adjacency.data[adjacency.offsets[c]++] = unsigned(i);
- + adjacency->data[adjacency->offsets[a]++] = (unsigned)(i);
- + adjacency->data[adjacency->offsets[b]++] = (unsigned)(i);
- + adjacency->data[adjacency->offsets[c]++] = (unsigned)(i);
- }
- // fix offsets that have been disturbed by the previous pass
- for (size_t i = 0; i < vertex_count; ++i)
- {
- - assert(adjacency.offsets[i] >= adjacency.counts[i]);
- + assert(adjacency->offsets[i] >= adjacency->counts[i]);
- - adjacency.offsets[i] -= adjacency.counts[i];
- + adjacency->offsets[i] -= adjacency->counts[i];
- }
- }
- -static unsigned int getNextVertexDeadEnd(const unsigned int* dead_end, unsigned int& dead_end_top, unsigned int& input_cursor, const unsigned int* live_triangles, size_t vertex_count)
- +static unsigned int getNextVertexDeadEnd(const unsigned int* dead_end, unsigned int* dead_end_top, unsigned int* input_cursor, const unsigned int* live_triangles, size_t vertex_count)
- {
- // check dead-end stack
- - while (dead_end_top)
- + while (*dead_end_top)
- {
- - unsigned int vertex = dead_end[--dead_end_top];
- + unsigned int vertex = dead_end[--*dead_end_top];
- if (live_triangles[vertex] > 0)
- return vertex;
- }
- // input order
- - while (input_cursor < vertex_count)
- + while (*input_cursor < vertex_count)
- {
- - if (live_triangles[input_cursor] > 0)
- - return input_cursor;
- + if (live_triangles[*input_cursor] > 0)
- + return *input_cursor;
- - ++input_cursor;
- + ++*input_cursor;
- }
- return ~0u;
- @@ -136,33 +127,29 @@ static unsigned int getNextVertexNeighbour(const unsigned int* next_candidates_b
- static float vertexScore(int cache_position, unsigned int live_triangles)
- {
- - assert(cache_position >= -1 && cache_position < int(max_cache_size));
- + assert(cache_position >= -1 && cache_position < (int)(max_cache_size));
- unsigned int live_triangles_clamped = live_triangles < max_valence ? live_triangles : max_valence;
- return vertex_score_table_cache[1 + cache_position] + vertex_score_table_live[live_triangles_clamped];
- }
- -static unsigned int getNextTriangleDeadEnd(unsigned int& input_cursor, const char* emitted_flags, size_t face_count)
- +static unsigned int getNextTriangleDeadEnd(unsigned int* input_cursor, const char* emitted_flags, size_t face_count)
- {
- // input order
- - while (input_cursor < face_count)
- + while (*input_cursor < face_count)
- {
- - if (!emitted_flags[input_cursor])
- - return input_cursor;
- + if (!emitted_flags[*input_cursor])
- + return *input_cursor;
- - ++input_cursor;
- + ++*input_cursor;
- }
- return ~0u;
- }
- -} // namespace meshopt
- -
- void meshopt_optimizeVertexCache(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count)
- {
- - using namespace meshopt;
- -
- assert(index_count % 3 == 0);
- // guard for empty meshes
- @@ -170,13 +157,13 @@ void meshopt_optimizeVertexCache(unsigned int* destination, const unsigned int*
- return;
- // support in-place optimization
- - meshopt_Buffer<unsigned int> indices_copy;
- + unsigned int* indices_copy = 0;
- if (destination == indices)
- {
- - indices_copy.allocate(index_count);
- - memcpy(indices_copy.data, indices, index_count * sizeof(unsigned int));
- - indices = indices_copy.data;
- + indices_copy = malloc(index_count * sizeof(unsigned int));
- + memcpy(indices_copy, indices, index_count * sizeof(unsigned int));
- + indices = indices_copy;
- }
- unsigned int cache_size = 16;
- @@ -185,19 +172,22 @@ void meshopt_optimizeVertexCache(unsigned int* destination, const unsigned int*
- size_t face_count = index_count / 3;
- // build adjacency information
- - TriangleAdjacency adjacency(index_count, vertex_count);
- - buildTriangleAdjacency(adjacency, indices, index_count, vertex_count);
- + TriangleAdjacency adjacency = {};
- + adjacency.counts = malloc(vertex_count * sizeof(unsigned int));
- + adjacency.offsets = malloc(vertex_count * sizeof(unsigned int));
- + adjacency.data = malloc(index_count * sizeof(unsigned int));
- + buildTriangleAdjacency(&adjacency, indices, index_count, vertex_count);
- // live triangle counts
- - meshopt_Buffer<unsigned int> live_triangles(vertex_count);
- - memcpy(live_triangles.data, adjacency.counts.data, vertex_count * sizeof(unsigned int));
- + unsigned int* live_triangles = malloc(vertex_count * sizeof(unsigned int));
- + memcpy(live_triangles, adjacency.counts, vertex_count * sizeof(unsigned int));
- // emitted flags
- - meshopt_Buffer<char> emitted_flags(face_count);
- - memset(emitted_flags.data, 0, face_count);
- + char* emitted_flags = malloc(face_count);
- + memset(emitted_flags, 0, face_count);
- // compute initial vertex scores
- - meshopt_Buffer<float> vertex_scores(vertex_count);
- + float* vertex_scores = malloc(vertex_count * sizeof(float));
- for (size_t i = 0; i < vertex_count; ++i)
- {
- @@ -205,7 +195,7 @@ void meshopt_optimizeVertexCache(unsigned int* destination, const unsigned int*
- }
- // compute triangle scores
- - meshopt_Buffer<float> triangle_scores(face_count);
- + float* triangle_scores = malloc(face_count * sizeof(float));
- for (size_t i = 0; i < face_count; ++i)
- {
- @@ -300,7 +290,7 @@ void meshopt_optimizeVertexCache(unsigned int* destination, const unsigned int*
- {
- unsigned int index = cache[i];
- - int cache_position = i >= cache_size ? -1 : int(i);
- + int cache_position = i >= cache_size ? -1 : (int)(i);
- // update vertex score
- float score = vertexScore(cache_position, live_triangles[index]);
- @@ -335,18 +325,25 @@ void meshopt_optimizeVertexCache(unsigned int* destination, const unsigned int*
- if (current_triangle == ~0u)
- {
- - current_triangle = getNextTriangleDeadEnd(input_cursor, &emitted_flags[0], face_count);
- + current_triangle = getNextTriangleDeadEnd(&input_cursor, &emitted_flags[0], face_count);
- }
- }
- assert(input_cursor == face_count);
- assert(output_triangle == face_count);
- +
- + free(triangle_scores);
- + free(vertex_scores);
- + free(emitted_flags);
- + free(live_triangles);
- + free(adjacency.data);
- + free(adjacency.offsets);
- + free(adjacency.counts);
- + free(indices_copy);
- }
- void meshopt_optimizeVertexCacheFifo(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count, unsigned int cache_size)
- {
- - using namespace meshopt;
- -
- assert(index_count % 3 == 0);
- assert(cache_size >= 3);
- @@ -355,36 +352,39 @@ void meshopt_optimizeVertexCacheFifo(unsigned int* destination, const unsigned i
- return;
- // support in-place optimization
- - meshopt_Buffer<unsigned int> indices_copy;
- + unsigned int* indices_copy = 0;
- if (destination == indices)
- {
- - indices_copy.allocate(index_count);
- - memcpy(indices_copy.data, indices, index_count * sizeof(unsigned int));
- - indices = indices_copy.data;
- + indices_copy = malloc(index_count * sizeof(unsigned int));
- + memcpy(indices_copy, indices, index_count * sizeof(unsigned int));
- + indices = indices_copy;
- }
- size_t face_count = index_count / 3;
- // build adjacency information
- - TriangleAdjacency adjacency(index_count, vertex_count);
- - buildTriangleAdjacency(adjacency, indices, index_count, vertex_count);
- + TriangleAdjacency adjacency = {};
- + adjacency.counts = malloc(vertex_count * sizeof(unsigned int));
- + adjacency.offsets = malloc(vertex_count * sizeof(unsigned int));
- + adjacency.data = malloc(index_count * sizeof(unsigned int));
- + buildTriangleAdjacency(&adjacency, indices, index_count, vertex_count);
- // live triangle counts
- - meshopt_Buffer<unsigned int> live_triangles(vertex_count);
- - memcpy(live_triangles.data, adjacency.counts.data, vertex_count * sizeof(unsigned int));
- + unsigned int* live_triangles = malloc(vertex_count * sizeof(unsigned int));
- + memcpy(live_triangles, adjacency.counts, vertex_count * sizeof(unsigned int));
- // cache time stamps
- - meshopt_Buffer<unsigned int> cache_timestamps(vertex_count);
- - memset(cache_timestamps.data, 0, vertex_count * sizeof(unsigned int));
- + unsigned int* cache_timestamps = malloc(vertex_count * sizeof(unsigned int));
- + memset(cache_timestamps, 0, vertex_count * sizeof(unsigned int));
- // dead-end stack
- - meshopt_Buffer<unsigned int> dead_end(index_count);
- + unsigned int* dead_end = malloc(index_count * sizeof(unsigned int));
- unsigned int dead_end_top = 0;
- // emitted flags
- - meshopt_Buffer<char> emitted_flags(face_count);
- - memset(emitted_flags.data, 0, face_count);
- + char* emitted_flags = malloc(face_count);
- + memset(emitted_flags, 0, face_count);
- unsigned int current_vertex = 0;
- @@ -450,9 +450,18 @@ void meshopt_optimizeVertexCacheFifo(unsigned int* destination, const unsigned i
- if (current_vertex == ~0u)
- {
- - current_vertex = getNextVertexDeadEnd(&dead_end[0], dead_end_top, input_cursor, &live_triangles[0], vertex_count);
- + current_vertex = getNextVertexDeadEnd(&dead_end[0], &dead_end_top, &input_cursor, &live_triangles[0], vertex_count);
- }
- }
- assert(output_triangle == face_count);
- +
- + free(emitted_flags);
- + free(dead_end);
- + free(cache_timestamps);
- + free(live_triangles);
- + free(adjacency.data);
- + free(adjacency.offsets);
- + free(adjacency.counts);
- + free(indices_copy);
- }
- diff --git a/src/vertexcodec.cpp b/src/vertexcodec.cpp
- index ba9d546..28d8391 100644
- --- a/src/vertexcodec.cpp
- +++ b/src/vertexcodec.cpp
- @@ -26,9 +26,6 @@
- #include <arm_neon.h>
- #endif
- -namespace meshopt
- -{
- -
- const unsigned char kVertexHeader = 0xa0;
- const size_t kVertexBlockSizeBytes = 8192;
- @@ -72,7 +69,7 @@ static size_t encodeBytesGroupMeasure(const unsigned char* buffer, int bits)
- assert(bits >= 1 && bits <= 8);
- if (bits == 1)
- - return encodeBytesGroupZero(buffer) ? 0 : size_t(-1);
- + return encodeBytesGroupZero(buffer) ? 0 : (size_t)(-1);
- if (bits == 8)
- return kByteGroupSize;
- @@ -142,7 +139,7 @@ static unsigned char* encodeBytes(unsigned char* data, unsigned char* data_end,
- // round number of groups to 4 to get number of header bytes
- size_t header_size = (buffer_size / kByteGroupSize + 3) / 4;
- - if (size_t(data_end - data) < header_size)
- + if ((size_t)(data_end - data) < header_size)
- return 0;
- data += header_size;
- @@ -151,7 +148,7 @@ static unsigned char* encodeBytes(unsigned char* data, unsigned char* data_end,
- for (size_t i = 0; i < buffer_size; i += kByteGroupSize)
- {
- - if (size_t(data_end - data) < kTailMaxSize)
- + if ((size_t)(data_end - data) < kTailMaxSize)
- return 0;
- int best_bits = 8;
- @@ -278,14 +275,14 @@ static const unsigned char* decodeBytes(const unsigned char* data, const unsigne
- // round number of groups to 4 to get number of header bytes
- size_t header_size = (buffer_size / kByteGroupSize + 3) / 4;
- - if (size_t(data_end - data) < header_size)
- + if ((size_t)(data_end - data) < header_size)
- return 0;
- data += header_size;
- for (size_t i = 0; i < buffer_size; i += kByteGroupSize)
- {
- - if (size_t(data_end - data) < kTailMaxSize)
- + if ((size_t)(data_end - data) < kTailMaxSize)
- return 0;
- size_t header_offset = i / kByteGroupSize;
- @@ -609,7 +606,7 @@ static const unsigned char* decodeBytesSimd(const unsigned char* data, const uns
- // round number of groups to 4 to get number of header bytes
- size_t header_size = (buffer_size / kByteGroupSize + 3) / 4;
- - if (size_t(data_end - data) < header_size)
- + if ((size_t)(data_end - data) < header_size)
- return 0;
- data += header_size;
- @@ -617,7 +614,7 @@ static const unsigned char* decodeBytesSimd(const unsigned char* data, const uns
- size_t i = 0;
- // fast-path: process 4 groups at a time, do a shared bounds check - each group reads <=32b
- - for (; i + kByteGroupSize * 4 <= buffer_size && size_t(data_end - data) >= kTailMaxSize * 4; i += kByteGroupSize * 4)
- + for (; i + kByteGroupSize * 4 <= buffer_size && (size_t)(data_end - data) >= kTailMaxSize * 4; i += kByteGroupSize * 4)
- {
- size_t header_offset = i / kByteGroupSize;
- unsigned char header_byte = header[header_offset / 4];
- @@ -631,7 +628,7 @@ static const unsigned char* decodeBytesSimd(const unsigned char* data, const uns
- // slow-path: process remaining groups
- for (; i < buffer_size; i += kByteGroupSize)
- {
- - if (size_t(data_end - data) < kTailMaxSize)
- + if ((size_t)(data_end - data) < kTailMaxSize)
- return 0;
- size_t header_offset = i / kByteGroupSize;
- @@ -735,21 +732,17 @@ static const unsigned char* decodeVertexBlockSimd(const unsigned char* data, con
- }
- #endif
- -} // namespace meshopt
- -
- size_t meshopt_encodeVertexBuffer(unsigned char* buffer, size_t buffer_size, const void* vertices, size_t vertex_count, size_t vertex_size)
- {
- - using namespace meshopt;
- -
- assert(vertex_size > 0 && vertex_size <= 256);
- assert(vertex_size % 4 == 0);
- - const unsigned char* vertex_data = static_cast<const unsigned char*>(vertices);
- + const unsigned char* vertex_data = (const unsigned char*)(vertices);
- unsigned char* data = buffer;
- unsigned char* data_end = buffer + buffer_size;
- - if (size_t(data_end - data) < 1 + vertex_size)
- + if ((size_t)(data_end - data) < 1 + vertex_size)
- return 0;
- *data++ = kVertexHeader;
- @@ -775,7 +768,7 @@ size_t meshopt_encodeVertexBuffer(unsigned char* buffer, size_t buffer_size, con
- size_t tail_size = vertex_size < kTailMaxSize ? kTailMaxSize : vertex_size;
- - if (size_t(data_end - data) < tail_size)
- + if ((size_t)(data_end - data) < tail_size)
- return 0;
- // write first vertex to the end of the stream and pad it to 32 bytes; this is important to simplify bounds checks in decoder
- @@ -796,8 +789,6 @@ size_t meshopt_encodeVertexBuffer(unsigned char* buffer, size_t buffer_size, con
- size_t meshopt_encodeVertexBufferBound(size_t vertex_count, size_t vertex_size)
- {
- - using namespace meshopt;
- -
- assert(vertex_size > 0 && vertex_size <= 256);
- assert(vertex_size % 4 == 0);
- @@ -814,8 +805,6 @@ size_t meshopt_encodeVertexBufferBound(size_t vertex_count, size_t vertex_size)
- int meshopt_decodeVertexBuffer(void* destination, size_t vertex_count, size_t vertex_size, const unsigned char* buffer, size_t buffer_size)
- {
- - using namespace meshopt;
- -
- assert(vertex_size > 0 && vertex_size <= 256);
- assert(vertex_size % 4 == 0);
- @@ -835,12 +824,12 @@ int meshopt_decodeVertexBuffer(void* destination, size_t vertex_count, size_t ve
- assert(gDecodeBytesGroupInitialized);
- #endif
- - unsigned char* vertex_data = static_cast<unsigned char*>(destination);
- + unsigned char* vertex_data = (unsigned char*)(destination);
- const unsigned char* data = buffer;
- const unsigned char* data_end = buffer + buffer_size;
- - if (size_t(data_end - data) < 1 + vertex_size)
- + if ((size_t)(data_end - data) < 1 + vertex_size)
- return -2;
- if (*data++ != kVertexHeader)
- @@ -866,7 +855,7 @@ int meshopt_decodeVertexBuffer(void* destination, size_t vertex_count, size_t ve
- size_t tail_size = vertex_size < kTailMaxSize ? kTailMaxSize : vertex_size;
- - if (size_t(data_end - data) != tail_size)
- + if ((size_t)(data_end - data) != tail_size)
- return -3;
- return 0;
- diff --git a/src/vfetchanalyzer.cpp b/src/vfetchanalyzer.cpp
- index 8a96c0b..dc0d17e 100644
- --- a/src/vfetchanalyzer.cpp
- +++ b/src/vfetchanalyzer.cpp
- @@ -4,18 +4,18 @@
- #include <assert.h>
- #include <string.h>
- -meshopt_VertexFetchStatistics meshopt_analyzeVertexFetch(const unsigned int* indices, size_t index_count, size_t vertex_count, size_t vertex_size)
- +struct meshopt_VertexFetchStatistics meshopt_analyzeVertexFetch(const unsigned int* indices, size_t index_count, size_t vertex_count, size_t vertex_size)
- {
- assert(index_count % 3 == 0);
- assert(vertex_size > 0 && vertex_size <= 256);
- - meshopt_VertexFetchStatistics result = {};
- + struct meshopt_VertexFetchStatistics result = {};
- - meshopt_Buffer<char> vertex_visited(vertex_count);
- - memset(vertex_visited.data, 0, vertex_count);
- + char* vertex_visited = malloc(vertex_count);
- + memset(vertex_visited, 0, vertex_count);
- - const size_t kCacheLine = 64;
- - const size_t kCacheSize = 128 * 1024;
- + enum { kCacheLine = 64 };
- + enum { kCacheSize = 128 * 1024 };
- // simple direct mapped cache; on typical mesh data this is close to 4-way cache, and this model is a gross approximation anyway
- size_t cache[kCacheSize / kCacheLine] = {};
- @@ -50,7 +50,9 @@ meshopt_VertexFetchStatistics meshopt_analyzeVertexFetch(const unsigned int* ind
- for (size_t i = 0; i < vertex_count; ++i)
- unique_vertex_count += vertex_visited[i];
- - result.overfetch = unique_vertex_count == 0 ? 0 : float(result.bytes_fetched) / float(unique_vertex_count * vertex_size);
- + result.overfetch = unique_vertex_count == 0 ? 0 : (float)(result.bytes_fetched) / (float)(unique_vertex_count * vertex_size);
- +
- + free(vertex_visited);
- return result;
- }
- diff --git a/src/vfetchoptimizer.cpp b/src/vfetchoptimizer.cpp
- index 55825a4..b9c6cb7 100644
- --- a/src/vfetchoptimizer.cpp
- +++ b/src/vfetchoptimizer.cpp
- @@ -34,18 +34,18 @@ size_t meshopt_optimizeVertexFetch(void* destination, unsigned int* indices, siz
- assert(vertex_size > 0 && vertex_size <= 256);
- // support in-place optimization
- - meshopt_Buffer<char> vertices_copy;
- + char* vertices_copy = 0;
- if (destination == vertices)
- {
- - vertices_copy.allocate(vertex_count * vertex_size);
- - memcpy(vertices_copy.data, vertices, vertex_count * vertex_size);
- - vertices = vertices_copy.data;
- + vertices_copy = malloc(vertex_count * vertex_size);
- + memcpy(vertices_copy, vertices, vertex_count * vertex_size);
- + vertices = vertices_copy;
- }
- // build vertex remap table
- - meshopt_Buffer<unsigned int> vertex_remap(vertex_count);
- - memset(vertex_remap.data, -1, vertex_remap.size * sizeof(unsigned int));
- + unsigned int* vertex_remap = malloc(vertex_count * sizeof(unsigned int));
- + memset(vertex_remap, -1, vertex_count * sizeof(unsigned int));
- unsigned int next_vertex = 0;
- @@ -54,21 +54,24 @@ size_t meshopt_optimizeVertexFetch(void* destination, unsigned int* indices, siz
- unsigned int index = indices[i];
- assert(index < vertex_count);
- - unsigned int& remap = vertex_remap[index];
- + unsigned int* remap = &vertex_remap[index];
- - if (remap == ~0u) // vertex was not added to destination VB
- + if (*remap == ~0u) // vertex was not added to destination VB
- {
- // add vertex
- - memcpy(static_cast<char*>(destination) + next_vertex * vertex_size, static_cast<const char*>(vertices) + index * vertex_size, vertex_size);
- + memcpy((char*)(destination) + next_vertex * vertex_size, (const char*)(vertices) + index * vertex_size, vertex_size);
- - remap = next_vertex++;
- + *remap = next_vertex++;
- }
- // modify indices in place
- - indices[i] = remap;
- + indices[i] = *remap;
- }
- assert(next_vertex <= vertex_count);
- + free(vertex_remap);
- + free(vertices_copy);
- +
- return next_vertex;
- }
Add Comment
Please, Sign In to add comment