diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /KaplaDemo/samples/sampleViewer3/Fracture/Mesh.cpp | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'KaplaDemo/samples/sampleViewer3/Fracture/Mesh.cpp')
| -rw-r--r-- | KaplaDemo/samples/sampleViewer3/Fracture/Mesh.cpp | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/KaplaDemo/samples/sampleViewer3/Fracture/Mesh.cpp b/KaplaDemo/samples/sampleViewer3/Fracture/Mesh.cpp new file mode 100644 index 00000000..5296e79c --- /dev/null +++ b/KaplaDemo/samples/sampleViewer3/Fracture/Mesh.cpp @@ -0,0 +1,165 @@ +#include <foundation/PxBounds3.h> + +#include "Mesh.h" +#include <algorithm> +#include <iostream> + +// ------------------------------------------------------------------- +struct SimpleVertexRef { + int vert, normal, texCoord; + int indexNr, subMeshNr; + bool operator < (const SimpleVertexRef &r) const { + if (vert < r.vert) return true; + if (vert > r.vert) return false; + if (normal < r.normal) return true; + if (normal > r.normal) return false; + return texCoord < r.texCoord; + } + bool operator == (const SimpleVertexRef &r) const { + return vert == r.vert && normal == r.normal && texCoord == r.texCoord; + } + void parse(char *s, int indexNr) { + int nr[3] = {0,0,0}; + char *p = s; + for (int i = 0; i < 3; i++) { + while (*p != 0 && *p != '/') p++; + bool end = (*p == 0); + *p = 0; + sscanf_s(s, "%i", &nr[i]); + if (end) break; + p++; s = p; + } + vert = nr[0]-1; texCoord = nr[1]-1; normal = nr[2]-1; + this->indexNr = indexNr; + } +}; + +#define OBJ_STR_LEN 256 +// ------------------------------------------------------------------- +bool Mesh::loadFromObjFile(const std::string &filename) +{ + const int maxVertsPerFace = 8; + + char s[OBJ_STR_LEN], ps[maxVertsPerFace][OBJ_STR_LEN], sub[OBJ_STR_LEN]; + int matNr = -1; + PxVec3 p; + float u,v; + shdfnd::Array<SimpleVertexRef> refs; + SimpleVertexRef ref[maxVertsPerFace]; + + shdfnd::Array<PxVec3> vertices; + shdfnd::Array<PxVec3> normals; + shdfnd::Array<float> texCoords; + int numIndices = 0; + + mSubMeshes.resize(1); + mNames.resize(1); + mSubMeshes[0].init(); + mNames[0] = ""; + mSubMeshes[0].firstIndex = 0; + + FILE *f; + + if (fopen_s(&f, filename.c_str(), "r") != 0) { + std::cerr << "Could not load OBJ file: " << filename << std::endl; + return false; + } + + // first a vertex ref is generated for each v/n/t combination + while (!feof(f)) { + if (fgets(s, OBJ_STR_LEN, f) == NULL) break; + + if (strncmp(s, "usemtl", 6) == 0 || strncmp(s, "g ", 2) == 0) { // new group + bool isGroup = strncmp(s, "g ", 2) == 0; + if (isGroup) + strcpy(sub, &s[2]); + else + strcpy(sub, &s[6]); + int numSubs = mSubMeshes.size(); + if (mSubMeshes[numSubs-1].numIndices > 0) { + mSubMeshes.resize(numSubs+1); + mNames.resize(numSubs+1); + mSubMeshes[numSubs].init(); + mNames[numSubs] = ""; + mSubMeshes[numSubs].firstIndex = mIndices.size(); + } + int subNr = mSubMeshes.size() - 1; + if (mNames[subNr] == "" || isGroup) + mNames[subNr] = std::string(sub); + } + else if (strncmp(s, "v ", 2) == 0) { // vertex + sscanf_s(s, "v %f %f %f", &p.x, &p.y, &p.z); + vertices.pushBack(p); + } + else if (strncmp(s, "vn ", 3) == 0) { // normal + sscanf_s(s, "vn %f %f %f", &p.x, &p.y, &p.z); + normals.pushBack(p); + } + else if (strncmp(s, "vt ", 3) == 0) { // texture coords + sscanf_s(s, "vt %f %f", &u, &v); + texCoords.pushBack(u); + texCoords.pushBack(v); + } + else if (strncmp(s, "f ", 2) == 0) { // face, tri or quad + int nr; + nr = sscanf_s(s, "f %s %s %s %s %s %s", + ps[0], OBJ_STR_LEN, ps[1], OBJ_STR_LEN, ps[2], OBJ_STR_LEN, ps[3], OBJ_STR_LEN, + ps[4], OBJ_STR_LEN, ps[5], OBJ_STR_LEN, ps[6], OBJ_STR_LEN, ps[7], OBJ_STR_LEN); + + if (nr >= 3) { + for (int i = 0; i < nr; i++) + ref[i].parse(ps[i], 0); + for (int i = 1; i < nr-1; i++) { + ref[0].indexNr = numIndices++; refs.pushBack(ref[0]); mIndices.pushBack(0); + ref[i].indexNr = numIndices++; refs.pushBack(ref[i]); mIndices.pushBack(0); + ref[i+1].indexNr = numIndices++; refs.pushBack(ref[i+1]); mIndices.pushBack(0); + mSubMeshes[mSubMeshes.size()-1].numIndices += 3; + } + } + } + } + fclose(f); + + // now we merge multiple v/n/t triplets + std::sort(refs.begin(), refs.end()); + + int i = 0; + PxVec3 defNormal(1.0f, 0.0f, 0.0f); + bool normalsOK = true; + bool mTextured = true; + int numTexCoords = texCoords.size(); + + int baseVertNr = 0; + + while (i < (int)refs.size()) { + int vertNr = mVertices.size(); + SimpleVertexRef &r = refs[i]; + mVertices.pushBack(vertices[r.vert]); + + if (r.normal >= 0) mNormals.pushBack(normals[r.normal]); + else { mNormals.pushBack(defNormal); normalsOK = false; } + + if (r.texCoord >= 0 && r.texCoord < numTexCoords) { + //mTexCoords.pushBack(texCoords[2*r.texCoord]); + //mTexCoords.pushBack(texCoords[2*r.texCoord+1]); + mTexCoords.pushBack(PxVec2(texCoords[2*r.texCoord],texCoords[2*r.texCoord+1])); + } + else { + //mTexCoords.pushBack(0.0f); + //mTexCoords.pushBack(0.0f); + mTexCoords.pushBack(PxVec2(0.0f,0.0f)); + } + + mIndices[r.indexNr] = vertNr; + i++; + while (i < (int)refs.size() && r == refs[i]) { + mIndices[refs[i].indexNr] = vertNr; + i++; + } + } + + if (!normalsOK) + updateNormals(); + + return true; +}
\ No newline at end of file |