1 | // This file is part of meshoptimizer library; see meshoptimizer.h for version/license details |
2 | #include "meshoptimizer.h" |
3 | |
4 | #include <assert.h> |
5 | #include <string.h> |
6 | |
7 | size_t meshopt_optimizeVertexFetchRemap(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count) |
8 | { |
9 | assert(index_count % 3 == 0); |
10 | |
11 | memset(destination, -1, vertex_count * sizeof(unsigned int)); |
12 | |
13 | unsigned int next_vertex = 0; |
14 | |
15 | for (size_t i = 0; i < index_count; ++i) |
16 | { |
17 | unsigned int index = indices[i]; |
18 | assert(index < vertex_count); |
19 | |
20 | if (destination[index] == ~0u) |
21 | { |
22 | destination[index] = next_vertex++; |
23 | } |
24 | } |
25 | |
26 | assert(next_vertex <= vertex_count); |
27 | |
28 | return next_vertex; |
29 | } |
30 | |
31 | size_t meshopt_optimizeVertexFetch(void* destination, unsigned int* indices, size_t index_count, const void* vertices, size_t vertex_count, size_t vertex_size) |
32 | { |
33 | assert(index_count % 3 == 0); |
34 | assert(vertex_size > 0 && vertex_size <= 256); |
35 | |
36 | meshopt_Allocator allocator; |
37 | |
38 | // support in-place optimization |
39 | if (destination == vertices) |
40 | { |
41 | unsigned char* vertices_copy = allocator.allocate<unsigned char>(vertex_count * vertex_size); |
42 | memcpy(vertices_copy, vertices, vertex_count * vertex_size); |
43 | vertices = vertices_copy; |
44 | } |
45 | |
46 | // build vertex remap table |
47 | unsigned int* vertex_remap = allocator.allocate<unsigned int>(vertex_count); |
48 | memset(vertex_remap, -1, vertex_count * sizeof(unsigned int)); |
49 | |
50 | unsigned int next_vertex = 0; |
51 | |
52 | for (size_t i = 0; i < index_count; ++i) |
53 | { |
54 | unsigned int index = indices[i]; |
55 | assert(index < vertex_count); |
56 | |
57 | unsigned int& remap = vertex_remap[index]; |
58 | |
59 | if (remap == ~0u) // vertex was not added to destination VB |
60 | { |
61 | // add vertex |
62 | memcpy(static_cast<unsigned char*>(destination) + next_vertex * vertex_size, static_cast<const unsigned char*>(vertices) + index * vertex_size, vertex_size); |
63 | |
64 | remap = next_vertex++; |
65 | } |
66 | |
67 | // modify indices in place |
68 | indices[i] = remap; |
69 | } |
70 | |
71 | assert(next_vertex <= vertex_count); |
72 | |
73 | return next_vertex; |
74 | } |
75 | |