diff options
Diffstat (limited to 'thirdparty/thekla_atlas/nvmesh/MeshBuilder.cpp')
-rw-r--r-- | thirdparty/thekla_atlas/nvmesh/MeshBuilder.cpp | 1000 |
1 files changed, 0 insertions, 1000 deletions
diff --git a/thirdparty/thekla_atlas/nvmesh/MeshBuilder.cpp b/thirdparty/thekla_atlas/nvmesh/MeshBuilder.cpp deleted file mode 100644 index 24d8ddff89..0000000000 --- a/thirdparty/thekla_atlas/nvmesh/MeshBuilder.cpp +++ /dev/null @@ -1,1000 +0,0 @@ -// This code is in the public domain -- castanyo@yahoo.es - -#include "nvmesh.h" // pch - -#include "MeshBuilder.h" -#include "TriMesh.h" -#include "QuadTriMesh.h" -#include "halfedge/Mesh.h" -#include "halfedge/Vertex.h" -#include "halfedge/Face.h" - -#include "weld/Weld.h" - -#include "nvmath/Box.h" -#include "nvmath/Vector.inl" - -#include "nvcore/StrLib.h" -#include "nvcore/RadixSort.h" -#include "nvcore/Ptr.h" -#include "nvcore/Array.inl" -#include "nvcore/HashMap.inl" - - -using namespace nv; - -/* -By default the mesh builder creates 3 streams (position, normal, texcoord), I'm planning to add support for extra streams as follows: - -enum StreamType { StreamType_Float, StreamType_Vector2, StreamType_Vector3, StreamType_Vector4 }; - -uint addStream(const char *, uint idx, StreamType); - -uint addAttribute(float) -uint addAttribute(Vector2) -uint addAttribute(Vector3) -uint addAttribute(Vector4) - -struct Vertex -{ - uint pos; - uint nor; - uint tex; - uint * attribs; // NULL or NIL terminated array? -}; - -All streams must be added before hand, so that you know the size of the attribs array. - -The vertex hash function could be kept as is, but the == operator should be extended to test -the extra atributes when available. - -That might require a custom hash implementation, or an extension of the current one. How to -handle the variable number of attributes in the attribs array? - -bool operator()(const Vertex & a, const Vertex & b) const -{ - if (a.pos != b.pos || a.nor != b.nor || a.tex != b.tex) return false; - if (a.attribs == NULL && b.attribs == NULL) return true; - return 0 == memcmp(a.attribs, b.attribs, ???); -} - -We could use a NIL terminated array, or provide custom user data to the equals functor. - -vertexMap.setUserData((void *)vertexAttribCount); - -bool operator()(const Vertex & a, const Vertex & b, void * userData) const { ... } - -*/ - - - -namespace -{ - struct Material - { - Material() : faceCount(0) {} - Material(const String & str) : name(str), faceCount(0) {} - - String name; - uint faceCount; - }; - - struct Vertex - { - //Vertex() {} - //Vertex(uint p, uint n, uint t0, uint t1, uint c) : pos(p), nor(n), tex0(t0), tex1(t1), col(c) {} - - friend bool operator==(const Vertex & a, const Vertex & b) - { - return a.pos == b.pos && a.nor == b.nor && a.tex[0] == b.tex[0] && a.tex[1] == b.tex[1] && a.col[0] == b.col[0] && a.col[1] == b.col[1] && a.col[2] == b.col[2]; - } - - uint pos; - uint nor; - uint tex[2]; - uint col[3]; - }; - - struct Face - { - uint id; - uint firstIndex; - uint indexCount; - uint material; - uint group; - }; - -} // namespace - - -namespace nv -{ - // This is a much better hash than the default and greatly improves performance! - template <> struct Hash<Vertex> - { - uint operator()(const Vertex & v) const { return v.pos + v.nor + v.tex[0]/* + v.col*/; } - }; -} - -struct MeshBuilder::PrivateData -{ - PrivateData() : currentGroup(NIL), currentMaterial(NIL), maxFaceIndexCount(0) {} - - uint pushVertex(uint p, uint n, uint t0, uint t1, uint c0, uint c1, uint c2); - uint pushVertex(const Vertex & v); - - Array<Vector3> posArray; - Array<Vector3> norArray; - Array<Vector2> texArray[2]; - Array<Vector4> colArray[3]; - - Array<Vertex> vertexArray; - HashMap<Vertex, uint> vertexMap; - - HashMap<String, uint> materialMap; - Array<Material> materialArray; - - uint currentGroup; - uint currentMaterial; - - Array<uint> indexArray; - Array<Face> faceArray; - - uint maxFaceIndexCount; -}; - - -uint MeshBuilder::PrivateData::pushVertex(uint p, uint n, uint t0, uint t1, uint c0, uint c1, uint c2) -{ - Vertex v; - v.pos = p; - v.nor = n; - v.tex[0] = t0; - v.tex[1] = t1; - v.col[0] = c0; - v.col[1] = c1; - v.col[2] = c2; - return pushVertex(v); -} - -uint MeshBuilder::PrivateData::pushVertex(const Vertex & v) -{ - // Lookup vertex v in map. - uint idx; - if (vertexMap.get(v, &idx)) - { - return idx; - } - - idx = vertexArray.count(); - vertexArray.pushBack(v); - vertexMap.add(v, idx); - - return idx; -} - - -MeshBuilder::MeshBuilder() : d(new PrivateData()) -{ -} - -MeshBuilder::~MeshBuilder() -{ - nvDebugCheck(d != NULL); - delete d; -} - - -// Builder methods. -uint MeshBuilder::addPosition(const Vector3 & v) -{ - d->posArray.pushBack(validate(v)); - return d->posArray.count() - 1; -} - -uint MeshBuilder::addNormal(const Vector3 & v) -{ - d->norArray.pushBack(validate(v)); - return d->norArray.count() - 1; -} - -uint MeshBuilder::addTexCoord(const Vector2 & v, uint set/*=0*/) -{ - d->texArray[set].pushBack(validate(v)); - return d->texArray[set].count() - 1; -} - -uint MeshBuilder::addColor(const Vector4 & v, uint set/*=0*/) -{ - d->colArray[set].pushBack(validate(v)); - return d->colArray[set].count() - 1; -} - -void MeshBuilder::beginGroup(uint id) -{ - d->currentGroup = id; -} - -void MeshBuilder::endGroup() -{ - d->currentGroup = NIL; -} - -// Add named material, check for uniquenes. -uint MeshBuilder::addMaterial(const char * name) -{ - uint index; - if (d->materialMap.get(name, &index)) { - nvDebugCheck(d->materialArray[index].name == name); - } - else { - index = d->materialArray.count(); - d->materialMap.add(name, index); - - Material material(name); - d->materialArray.append(material); - } - return index; -} - -void MeshBuilder::beginMaterial(uint id) -{ - d->currentMaterial = id; -} - -void MeshBuilder::endMaterial() -{ - d->currentMaterial = NIL; -} - -void MeshBuilder::beginPolygon(uint id/*=0*/) -{ - Face face; - face.id = id; - face.firstIndex = d->indexArray.count(); - face.indexCount = 0; - face.material = d->currentMaterial; - face.group = d->currentGroup; - - d->faceArray.pushBack(face); -} - -uint MeshBuilder::addVertex(uint p, uint n/*= NIL*/, uint t0/*= NIL*/, uint t1/*= NIL*/, uint c0/*= NIL*/, uint c1/*= NIL*/, uint c2/*= NIL*/) -{ - // @@ In theory there's no need to add vertices before faces, but I'm adding this to debug problems in our maya exporter: - nvDebugCheck(p < d->posArray.count()); - nvDebugCheck(n == NIL || n < d->norArray.count()); - nvDebugCheck(t0 == NIL || t0 < d->texArray[0].count()); - nvDebugCheck(t1 == NIL || t1 < d->texArray[1].count()); - //nvDebugCheck(c0 == NIL || c0 < d->colArray[0].count()); - if (c0 > d->colArray[0].count()) c0 = NIL; // @@ This seems to be happening in loc_swamp_catwalk.mb! No idea why. - nvDebugCheck(c1 == NIL || c1 < d->colArray[1].count()); - nvDebugCheck(c2 == NIL || c2 < d->colArray[2].count()); - - uint idx = d->pushVertex(p, n, t0, t1, c0, c1, c2); - d->indexArray.pushBack(idx); - d->faceArray.back().indexCount++; - return idx; -} - -uint MeshBuilder::addVertex(const Vector3 & pos) -{ - uint p = addPosition(pos); - return addVertex(p); -} - -#if 0 -uint MeshBuilder::addVertex(const Vector3 & pos, const Vector3 & nor, const Vector2 & tex0, const Vector2 & tex1, const Vector4 & col0, const Vector4 & col1) -{ - uint p = addPosition(pos); - uint n = addNormal(nor); - uint t0 = addTexCoord(tex0, 0); - uint t1 = addTexCoord(tex1, 1); - uint c0 = addColor(col0); - uint c1 = addColor(col1); - return addVertex(p, n, t0, t1, c0, c1); -} -#endif - -// Return true if the face is valid and was added to the mesh. -bool MeshBuilder::endPolygon() -{ - const Face & face = d->faceArray.back(); - const uint count = face.indexCount; - - // Validate polygon here. - bool invalid = count <= 2; - - if (!invalid) { - // Skip zero area polygons. Or polygons with degenerate edges (which will result in zero-area triangles). - const uint first = face.firstIndex; - for (uint j = count - 1, i = 0; i < count; j = i, i++) { - uint v0 = d->indexArray[first + i]; - uint v1 = d->indexArray[first + j]; - - uint p0 = d->vertexArray[v0].pos; - uint p1 = d->vertexArray[v1].pos; - - if (p0 == p1) { - invalid = true; - break; - } - - if (equal(d->posArray[p0], d->posArray[p1], FLT_EPSILON)) { - invalid = true; - break; - } - } - - uint v0 = d->indexArray[first]; - uint p0 = d->vertexArray[v0].pos; - Vector3 x0 = d->posArray[p0]; - - float area = 0.0f; - for (uint j = 1, i = 2; i < count; j = i, i++) { - uint v1 = d->indexArray[first + i]; - uint v2 = d->indexArray[first + j]; - - uint p1 = d->vertexArray[v1].pos; - uint p2 = d->vertexArray[v2].pos; - - Vector3 x1 = d->posArray[p1]; - Vector3 x2 = d->posArray[p2]; - - area += length(cross(x1-x0, x2-x0)); - } - - if (0.5 * area < 1e-6) { // Reduce this threshold if artists have legitimate complains. - invalid = true; - } - - // @@ This is not complete. We may still get zero area triangles after triangulation. - // However, our plugin triangulates before building the mesh, so hopefully that's not a problem. - - } - - if (invalid) - { - d->indexArray.resize(d->indexArray.size() - count); - d->faceArray.popBack(); - return false; - } - else - { - if (d->currentMaterial != NIL) { - d->materialArray[d->currentMaterial].faceCount++; - } - - d->maxFaceIndexCount = max(d->maxFaceIndexCount, count); - return true; - } -} - - -uint MeshBuilder::weldPositions() -{ - Array<uint> xrefs; - Weld<Vector3> weldVector3; - - if (d->posArray.count()) { - // Weld vertex attributes. - weldVector3(d->posArray, xrefs); - - // Remap vertex indices. - const uint vertexCount = d->vertexArray.count(); - for (uint v = 0; v < vertexCount; v++) - { - Vertex & vertex = d->vertexArray[v]; - if (vertex.pos != NIL) vertex.pos = xrefs[vertex.pos]; - } - } - - return d->posArray.count(); -} - -uint MeshBuilder::weldNormals() -{ - Array<uint> xrefs; - Weld<Vector3> weldVector3; - - if (d->norArray.count()) { - // Weld vertex attributes. - weldVector3(d->norArray, xrefs); - - // Remap vertex indices. - const uint vertexCount = d->vertexArray.count(); - for (uint v = 0; v < vertexCount; v++) - { - Vertex & vertex = d->vertexArray[v]; - if (vertex.nor != NIL) vertex.nor = xrefs[vertex.nor]; - } - } - - return d->norArray.count(); -} - -uint MeshBuilder::weldTexCoords(uint set/*=0*/) -{ - Array<uint> xrefs; - Weld<Vector2> weldVector2; - - if (d->texArray[set].count()) { - // Weld vertex attributes. - weldVector2(d->texArray[set], xrefs); - - // Remap vertex indices. - const uint vertexCount = d->vertexArray.count(); - for (uint v = 0; v < vertexCount; v++) - { - Vertex & vertex = d->vertexArray[v]; - if (vertex.tex[set] != NIL) vertex.tex[set] = xrefs[vertex.tex[set]]; - } - } - - return d->texArray[set].count(); -} - -uint MeshBuilder::weldColors(uint set/*=0*/) -{ - Array<uint> xrefs; - Weld<Vector4> weldVector4; - - if (d->colArray[set].count()) { - // Weld vertex attributes. - weldVector4(d->colArray[set], xrefs); - - // Remap vertex indices. - const uint vertexCount = d->vertexArray.count(); - for (uint v = 0; v < vertexCount; v++) - { - Vertex & vertex = d->vertexArray[v]; - if (vertex.col[set] != NIL) vertex.col[set] = xrefs[vertex.col[set]]; - } - } - - return d->colArray[set].count(); -} - -void MeshBuilder::weldVertices() { - - if (d->vertexArray.count() == 0) { - // Nothing to do. - return; - } - - Array<uint> xrefs; - Weld<Vertex> weldVertex; - - // Weld vertices. - weldVertex(d->vertexArray, xrefs); - - // Remap face indices. - const uint indexCount = d->indexArray.count(); - for (uint i = 0; i < indexCount; i++) - { - d->indexArray[i] = xrefs[d->indexArray[i]]; - } - - // Remap vertex map. - foreach(i, d->vertexMap) - { - d->vertexMap[i].value = xrefs[d->vertexMap[i].value]; - } -} - - -void MeshBuilder::optimize() -{ - if (d->vertexArray.count() == 0) - { - return; - } - - weldPositions(); - weldNormals(); - weldTexCoords(0); - weldTexCoords(1); - weldColors(); - - weldVertices(); -} - - - - - - -void MeshBuilder::removeUnusedMaterials(Array<uint> & newMaterialId) -{ - uint materialCount = d->materialArray.count(); - - // Reset face counts. - for (uint i = 0; i < materialCount; i++) { - d->materialArray[i].faceCount = 0; - } - - // Count faces. - foreach(i, d->faceArray) { - Face & face = d->faceArray[i]; - - if (face.material != NIL) { - nvDebugCheck(face.material < materialCount); - - d->materialArray[face.material].faceCount++; - } - } - - // Remove unused materials. - newMaterialId.resize(materialCount); - - for (uint i = 0, m = 0; i < materialCount; i++) - { - if (d->materialArray[m].faceCount > 0) - { - newMaterialId[i] = m++; - } - else - { - newMaterialId[i] = NIL; - d->materialArray.removeAt(m); - } - } - - materialCount = d->materialArray.count(); - - // Update face material ids. - foreach(i, d->faceArray) { - Face & face = d->faceArray[i]; - - if (face.material != NIL) { - uint id = newMaterialId[face.material]; - nvDebugCheck(id != NIL && id < materialCount); - - face.material = id; - } - } -} - -void MeshBuilder::sortFacesByGroup() -{ - const uint faceCount = d->faceArray.count(); - - Array<uint> faceGroupArray; - faceGroupArray.resize(faceCount); - - for (uint i = 0; i < faceCount; i++) { - faceGroupArray[i] = d->faceArray[i].group; - } - - RadixSort radix; - radix.sort(faceGroupArray); - - Array<Face> newFaceArray; - newFaceArray.resize(faceCount); - - for (uint i = 0; i < faceCount; i++) { - newFaceArray[i] = d->faceArray[radix.rank(i)]; - } - - swap(newFaceArray, d->faceArray); -} - -void MeshBuilder::sortFacesByMaterial() -{ - const uint faceCount = d->faceArray.count(); - - Array<uint> faceMaterialArray; - faceMaterialArray.resize(faceCount); - - for (uint i = 0; i < faceCount; i++) { - faceMaterialArray[i] = d->faceArray[i].material; - } - - RadixSort radix; - radix.sort(faceMaterialArray); - - Array<Face> newFaceArray; - newFaceArray.resize(faceCount); - - for (uint i = 0; i < faceCount; i++) { - newFaceArray[i] = d->faceArray[radix.rank(i)]; - } - - swap(newFaceArray, d->faceArray); -} - - -void MeshBuilder::reset() -{ - nvDebugCheck(d != NULL); - delete d; - d = new PrivateData(); -} - -void MeshBuilder::done() -{ - if (d->currentGroup != NIL) { - endGroup(); - } - - if (d->currentMaterial != NIL) { - endMaterial(); - } -} - -// Hints. -void MeshBuilder::hintTriangleCount(uint count) -{ - d->indexArray.reserve(d->indexArray.count() + count * 4); -} - -void MeshBuilder::hintVertexCount(uint count) -{ - d->vertexArray.reserve(d->vertexArray.count() + count); - d->vertexMap.resize(d->vertexMap.count() + count); -} - -void MeshBuilder::hintPositionCount(uint count) -{ - d->posArray.reserve(d->posArray.count() + count); -} - -void MeshBuilder::hintNormalCount(uint count) -{ - d->norArray.reserve(d->norArray.count() + count); -} - -void MeshBuilder::hintTexCoordCount(uint count, uint set/*=0*/) -{ - d->texArray[set].reserve(d->texArray[set].count() + count); -} - -void MeshBuilder::hintColorCount(uint count, uint set/*=0*/) -{ - d->colArray[set].reserve(d->colArray[set].count() + count); -} - - -// Helpers. -void MeshBuilder::addTriangle(uint v0, uint v1, uint v2) -{ - beginPolygon(); - addVertex(v0); - addVertex(v1); - addVertex(v2); - endPolygon(); -} - -void MeshBuilder::addQuad(uint v0, uint v1, uint v2, uint v3) -{ - beginPolygon(); - addVertex(v0); - addVertex(v1); - addVertex(v2); - addVertex(v3); - endPolygon(); -} - - -// Get tri mesh. -TriMesh * MeshBuilder::buildTriMesh() const -{ - const uint faceCount = d->faceArray.count(); - uint triangleCount = 0; - for (uint f = 0; f < faceCount; f++) { - triangleCount += d->faceArray[f].indexCount - 2; - } - - const uint vertexCount = d->vertexArray.count(); - TriMesh * mesh = new TriMesh(triangleCount, vertexCount); - - // Build faces. - Array<TriMesh::Face> & faces = mesh->faces(); - - for(uint f = 0; f < faceCount; f++) - { - int firstIndex = d->faceArray[f].firstIndex; - int indexCount = d->faceArray[f].indexCount; - - int v0 = d->indexArray[firstIndex + 0]; - int v1 = d->indexArray[firstIndex + 1]; - - for(int t = 0; t < indexCount - 2; t++) { - int v2 = d->indexArray[firstIndex + t + 2]; - - TriMesh::Face face; - face.id = faces.count(); - face.v[0] = v0; - face.v[1] = v1; - face.v[2] = v2; - faces.append(face); - - v1 = v2; - } - } - - // Build vertices. - Array<BaseMesh::Vertex> & vertices = mesh->vertices(); - - for(uint i = 0; i < vertexCount; i++) - { - BaseMesh::Vertex vertex; - vertex.id = i; - if (d->vertexArray[i].pos != NIL) vertex.pos = d->posArray[d->vertexArray[i].pos]; - if (d->vertexArray[i].nor != NIL) vertex.nor = d->norArray[d->vertexArray[i].nor]; - if (d->vertexArray[i].tex[0] != NIL) vertex.tex = d->texArray[0][d->vertexArray[i].tex[0]]; - - vertices.append(vertex); - } - - return mesh; -} - -// Get quad/tri mesh. -QuadTriMesh * MeshBuilder::buildQuadTriMesh() const -{ - const uint faceCount = d->faceArray.count(); - const uint vertexCount = d->vertexArray.count(); - QuadTriMesh * mesh = new QuadTriMesh(faceCount, vertexCount); - - // Build faces. - Array<QuadTriMesh::Face> & faces = mesh->faces(); - - for (uint f = 0; f < faceCount; f++) - { - int firstIndex = d->faceArray[f].firstIndex; - int indexCount = d->faceArray[f].indexCount; - - QuadTriMesh::Face face; - face.id = f; - - face.v[0] = d->indexArray[firstIndex + 0]; - face.v[1] = d->indexArray[firstIndex + 1]; - face.v[2] = d->indexArray[firstIndex + 2]; - - // Only adds triangles and quads. Ignores polygons. - if (indexCount == 3) { - face.v[3] = NIL; - faces.append(face); - } - else if (indexCount == 4) { - face.v[3] = d->indexArray[firstIndex + 3]; - faces.append(face); - } - } - - // Build vertices. - Array<BaseMesh::Vertex> & vertices = mesh->vertices(); - - for(uint i = 0; i < vertexCount; i++) - { - BaseMesh::Vertex vertex; - vertex.id = i; - if (d->vertexArray[i].pos != NIL) vertex.pos = d->posArray[d->vertexArray[i].pos]; - if (d->vertexArray[i].nor != NIL) vertex.nor = d->norArray[d->vertexArray[i].nor]; - if (d->vertexArray[i].tex[0] != NIL) vertex.tex = d->texArray[0][d->vertexArray[i].tex[0]]; - - vertices.append(vertex); - } - - return mesh; -} - -// Get half edge mesh. -HalfEdge::Mesh * MeshBuilder::buildHalfEdgeMesh(bool weldPositions, Error * error/*=NULL*/, Array<uint> * badFaces/*=NULL*/) const -{ - if (error != NULL) *error = Error_None; - - const uint vertexCount = d->vertexArray.count(); - AutoPtr<HalfEdge::Mesh> mesh(new HalfEdge::Mesh()); - - for(uint v = 0; v < vertexCount; v++) - { - HalfEdge::Vertex * vertex = mesh->addVertex(d->posArray[d->vertexArray[v].pos]); - if (d->vertexArray[v].nor != NIL) vertex->nor = d->norArray[d->vertexArray[v].nor]; - if (d->vertexArray[v].tex[0] != NIL) vertex->tex = Vector2(d->texArray[0][d->vertexArray[v].tex[0]]); - if (d->vertexArray[v].col[0] != NIL) vertex->col = d->colArray[0][d->vertexArray[v].col[0]]; - } - - if (weldPositions) { - mesh->linkColocals(); - } - else { - // Build canonical map from position indices. - Array<uint> canonicalMap(vertexCount); - - foreach (i, d->vertexArray) { - canonicalMap.append(d->vertexArray[i].pos); - } - - mesh->linkColocalsWithCanonicalMap(canonicalMap); - } - - const uint faceCount = d->faceArray.count(); - for (uint f = 0; f < faceCount; f++) - { - const uint firstIndex = d->faceArray[f].firstIndex; - const uint indexCount = d->faceArray[f].indexCount; - - HalfEdge::Face * face = mesh->addFace(d->indexArray, firstIndex, indexCount); - - // @@ This is too late, removing the face here will leave the mesh improperly connected. - /*if (face->area() <= FLT_EPSILON) { - mesh->remove(face); - face = NULL; - }*/ - - if (face == NULL) { - // Non manifold mesh. - if (error != NULL) *error = Error_NonManifoldEdge; - if (badFaces != NULL) { - badFaces->append(d->faceArray[f].id); - } - //return NULL; // IC: Ignore error and continue building the mesh. - } - - if (face != NULL) { - face->group = d->faceArray[f].group; - face->material = d->faceArray[f].material; - } - } - - mesh->linkBoundary(); - - // We cannot fix functions here, because this would introduce new vertices and these vertices won't have the corresponding builder data. - - // Maybe the builder should perform the search for T-junctions and update the vertex data directly. - - // For now, we don't fix T-junctions at export time, but only during parameterization. - - //mesh->fixBoundaryJunctions(); - - //mesh->sewBoundary(); - - return mesh.release(); -} - - -bool MeshBuilder::buildPositions(Array<Vector3> & positionArray) -{ - const uint vertexCount = d->vertexArray.count(); - positionArray.resize(vertexCount); - - for (uint v = 0; v < vertexCount; v++) - { - nvDebugCheck(d->vertexArray[v].pos != NIL); - positionArray[v] = d->posArray[d->vertexArray[v].pos]; - } - - return true; -} - -bool MeshBuilder::buildNormals(Array<Vector3> & normalArray) -{ - bool anyNormal = false; - - const uint vertexCount = d->vertexArray.count(); - normalArray.resize(vertexCount); - - for (uint v = 0; v < vertexCount; v++) - { - if (d->vertexArray[v].nor == NIL) { - normalArray[v] = Vector3(0, 0, 1); - } - else { - anyNormal = true; - normalArray[v] = d->norArray[d->vertexArray[v].nor]; - } - } - - return anyNormal; -} - -bool MeshBuilder::buildTexCoords(Array<Vector2> & texCoordArray, uint set/*=0*/) -{ - bool anyTexCoord = false; - - const uint vertexCount = d->vertexArray.count(); - texCoordArray.resize(vertexCount); - - for (uint v = 0; v < vertexCount; v++) - { - if (d->vertexArray[v].tex[set] == NIL) { - texCoordArray[v] = Vector2(0, 0); - } - else { - anyTexCoord = true; - texCoordArray[v] = d->texArray[set][d->vertexArray[v].tex[set]]; - } - } - - return anyTexCoord; -} - -bool MeshBuilder::buildColors(Array<Vector4> & colorArray, uint set/*=0*/) -{ - bool anyColor = false; - - const uint vertexCount = d->vertexArray.count(); - colorArray.resize(vertexCount); - - for (uint v = 0; v < vertexCount; v++) - { - if (d->vertexArray[v].col[set] == NIL) { - colorArray[v] = Vector4(0, 0, 0, 1); - } - else { - anyColor = true; - colorArray[v] = d->colArray[set][d->vertexArray[v].col[set]]; - } - } - - return anyColor; -} - -void MeshBuilder::buildVertexToPositionMap(Array<int> &map) -{ - const uint vertexCount = d->vertexArray.count(); - map.resize(vertexCount); - - foreach (i, d->vertexArray) { - map[i] = d->vertexArray[i].pos; - } -} - - - -uint MeshBuilder::vertexCount() const -{ - return d->vertexArray.count(); -} - - -uint MeshBuilder::positionCount() const -{ - return d->posArray.count(); -} - -uint MeshBuilder::normalCount() const -{ - return d->norArray.count(); -} - -uint MeshBuilder::texCoordCount(uint set/*=0*/) const -{ - return d->texArray[set].count(); -} - -uint MeshBuilder::colorCount(uint set/*=0*/) const -{ - return d->colArray[set].count(); -} - - -uint MeshBuilder::materialCount() const -{ - return d->materialArray.count(); -} - -const char * MeshBuilder::material(uint i) const -{ - return d->materialArray[i].name; -} - - -uint MeshBuilder::positionIndex(uint vertex) const -{ - return d->vertexArray[vertex].pos; -} -uint MeshBuilder::normalIndex(uint vertex) const -{ - return d->vertexArray[vertex].nor; -} -uint MeshBuilder::texCoordIndex(uint vertex, uint set/*=0*/) const -{ - return d->vertexArray[vertex].tex[set]; -} -uint MeshBuilder::colorIndex(uint vertex, uint set/*=0*/) const -{ - return d->vertexArray[vertex].col[set]; -} |