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 /APEX_1.4/common/src/ApexGeneralizedCubeTemplates.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 'APEX_1.4/common/src/ApexGeneralizedCubeTemplates.cpp')
| -rw-r--r-- | APEX_1.4/common/src/ApexGeneralizedCubeTemplates.cpp | 677 |
1 files changed, 677 insertions, 0 deletions
diff --git a/APEX_1.4/common/src/ApexGeneralizedCubeTemplates.cpp b/APEX_1.4/common/src/ApexGeneralizedCubeTemplates.cpp new file mode 100644 index 00000000..87a9d6ea --- /dev/null +++ b/APEX_1.4/common/src/ApexGeneralizedCubeTemplates.cpp @@ -0,0 +1,677 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, related documentation + * and any modifications thereto. Any use, reproduction, disclosure or + * distribution of this software and related documentation without an express + * license agreement from NVIDIA CORPORATION is strictly prohibited. + */ + + +#include "ApexGeneralizedCubeTemplates.h" + +namespace nvidia +{ +namespace apex +{ + +ApexGeneralizedCubeTemplates::ApexGeneralizedCubeTemplates() +{ + // init basis + uint32_t p = 0; + const float d = 1.0f / (SUB_GRID_LEN - 1); + for (uint32_t xi = 0; xi < SUB_GRID_LEN; xi++) + { + const float wx = d * xi; + const float mx = 1.0f - wx; + for (uint32_t yi = 0; yi < SUB_GRID_LEN; yi++) + { + const float wy = d * yi; + const float my = 1.0f - wy; + for (uint32_t zi = 0; zi < SUB_GRID_LEN; zi++) + { + const float wz = d * zi; + const float mz = 1.0f - wz; + mBasis[p][0] = mx * my * mz; + mBasis[p][1] = wx * my * mz; + mBasis[p][2] = wx * wy * mz; + mBasis[p][3] = mx * wy * mz; + mBasis[p][4] = mx * my * wz; + mBasis[p][5] = wx * my * wz; + mBasis[p][6] = wx * wy * wz; + mBasis[p][7] = mx * wy * wz; + p++; + } + } + } + + // default vertex positions + mVertPos[ 0] = PxVec3(0.5f, 0.0f, 0.0f); // on edges + mVertPos[ 1] = PxVec3(1.0f, 0.5f, 0.0f); + mVertPos[ 2] = PxVec3(0.5f, 1.0f, 0.0f); + mVertPos[ 3] = PxVec3(0.0f, 0.5f, 0.0f); + mVertPos[ 4] = PxVec3(0.5f, 0.0f, 1.0f); + mVertPos[ 5] = PxVec3(1.0f, 0.5f, 1.0f); + mVertPos[ 6] = PxVec3(0.5f, 1.0f, 1.0f); + mVertPos[ 7] = PxVec3(0.0f, 0.5f, 1.0f); + mVertPos[ 8] = PxVec3(0.0f, 0.0f, 0.5f); + mVertPos[ 9] = PxVec3(1.0f, 0.0f, 0.5f); + mVertPos[10] = PxVec3(1.0f, 1.0f, 0.5f); + mVertPos[11] = PxVec3(0.0f, 1.0f, 0.5f); + mVertPos[12] = PxVec3(0.0f, 0.5f, 0.5f); // on faces + mVertPos[13] = PxVec3(1.0f, 0.5f, 0.5f); + mVertPos[14] = PxVec3(0.5f, 0.0f, 0.5f); + mVertPos[15] = PxVec3(0.5f, 1.0f, 0.5f); + mVertPos[16] = PxVec3(0.5f, 0.5f, 0.0f); + mVertPos[17] = PxVec3(0.5f, 0.5f, 1.0f); + mVertPos[18] = PxVec3(0.5f, 0.5f, 0.5f); // in center + + // init other data structures + for (int i = 0; i < NUM_SUB_CELLS; i++) + { + mSubGrid[i].init(); + } + + for (int i = 0; i < NUM_CASES_3; i++) + { + mFirst3[i] = -1; + } + + mLookupIndices3.clear(); + + createLookupTable3(); +} + + + + +void ApexGeneralizedCubeTemplates::getTriangles(const int groups[8], physx::Array<int32_t> &indices) +{ + int32_t maxGroup = 0; + for (uint32_t i = 0; i < 8; i++) + { + if (groups[i] > maxGroup) + { + maxGroup = groups[i]; + } + } + + //physx::Array<int32_t> currentIndices; + + indices.clear(); + PX_ASSERT(maxGroup < 8); + if (maxGroup <= 2 && !mLookupIndices3.empty()) + { + uint32_t code = 0; + for (int32_t i = 7; i >= 0; i--) + { + code = code * 3 + groups[i]; + } + + int32_t first = mFirst3[code]; + if (first >= 0) + { + for (uint32_t i = (uint32_t)first; mLookupIndices3[i] >= 0; i++) + { + indices.pushBack(mLookupIndices3[i]); + //currentIndices.pushBack(mLookupIndices3[i]); + } + return; + } + } + + setCellGroups(groups); + splitDisconnectedGroups(); + findVertices(); + createTriangles(indices); +} + + + + +void ApexGeneralizedCubeTemplates::createLookupTable3() +{ + if (!mLookupIndices3.empty()) + { + return; + } + + int32_t groups[8]; + physx::Array<int32_t> indices; + indices.reserve(32); + + mLookupIndices3.clear(); + mLookupIndices3.reserve(169200); // otherwise it crashes in release mode! + + for (uint32_t i = 0; i < NUM_CASES_3; i++) + { + int32_t c = (int32_t)i; + for (uint32_t j = 0; j < 8; j++) + { + groups[j] = c % 3; + c /= 3; + } + + getTriangles(groups, indices); + + mFirst3[i] = (int32_t)mLookupIndices3.size(); + for (uint32_t j = 0; j < indices.size(); j++) + { + mLookupIndices3.pushBack(indices[j]); + } + + mLookupIndices3.pushBack(-1); // marks end + } +} + + + +void ApexGeneralizedCubeTemplates::setCellGroups(const int32_t groups[8]) +{ + float groupWeights[8]; + uint32_t p = 0; + + for (uint32_t xi = 0; xi < SUB_GRID_LEN; xi++) + { + for (uint32_t yi = 0; yi < SUB_GRID_LEN; yi++) + { + for (uint32_t zi = 0; zi < SUB_GRID_LEN; zi++) + { + GenSubCell& c = mSubGrid[p]; + + float* basis = mBasis[p]; + p++; + c.init(); + + memset(groupWeights, 0, sizeof(float) * 8); + + for (uint32_t corner = 0; corner < 8; corner++) + { + groupWeights[groups[corner]] += basis[corner]; + } + + c.group = 0; + float maxWeight = groupWeights[0]; + for (int32_t group = 1; group < 8; group++) + { + if (groupWeights[group] > maxWeight) + { + maxWeight = groupWeights[group]; + c.group = group; + } + } + } + } + } +} + + + +void ApexGeneralizedCubeTemplates::splitDisconnectedGroups() +{ + // in certain cases groups are not connected sub spaces + // in that case we want to create (more) new connected groups + + physx::Array<GenCoord> queue; + //GenCoord c; + + const int n[6][3] = + { + { -1, 0, 0}, + { 1, 0, 0}, + { 0, -1, 0}, + { 0, 1, 0}, + { 0, 0, -1}, + { 0, 0, 1} + }; + + int newGroup = -1; + for (int32_t xi = 0; xi < SUB_GRID_LEN; xi++) + { + for (int32_t yi = 0; yi < SUB_GRID_LEN; yi++) + { + for (int32_t zi = 0; zi < SUB_GRID_LEN; zi++) + { + GenSubCell& start = mSubGrid[cellNr((uint32_t)xi, (uint32_t)yi, (uint32_t)zi)]; + + if (start.group < 0 || start.marked) + { + continue; + } + + newGroup++; + int32_t oldGroup = start.group; + + GenCoord c; + c.xi = xi; + c.yi = yi; + c.zi = zi; + + queue.pushBack(c); + while (!queue.empty()) + { + c = queue[queue.size() - 1]; + queue.popBack(); + + GenSubCell& cell = mSubGrid[cellNr((uint32_t)c.xi, (uint32_t)c.yi, (uint32_t)c.zi)]; + + if (cell.marked) + { + continue; + } + + cell.marked = true; + cell.group = newGroup; + + for (uint32_t i = 0; i < 6; i++) + { + GenCoord ci = c; + ci.xi = c.xi + n[i][0]; + ci.yi = c.yi + n[i][1]; + ci.zi = c.zi + n[i][2]; + if (ci.xi < 0 || ci.xi >= SUB_GRID_LEN || + ci.yi < 0 || ci.yi >= SUB_GRID_LEN || + ci.zi < 0 || ci.zi >= SUB_GRID_LEN) + { + continue; + } + + GenSubCell& celli = mSubGrid[cellNr((uint32_t)ci.xi, (uint32_t)ci.yi, (uint32_t)ci.zi)]; + + if (celli.marked || celli.group != oldGroup) + { + continue; + } + + queue.pushBack(ci); + } + } + } + } + } +} + + + +void ApexGeneralizedCubeTemplates::findVertices() +{ + //int i,j,xi,yi,zi; + + for (uint32_t i = 0; i < 8; i++) + for (uint32_t j = 0; j < 8; j++) + { + mFirstPairVertex[i][j] = -1; + } + + const int faces[6][4] = + { + {0, 4, 7, 3}, + {1, 2, 6, 5}, + {0, 1, 5, 4}, + {2, 3, 7, 6}, + {0, 3, 2, 1}, + {4, 5, 6, 7}, + }; + const int edges[12][6] = + { + {0, 1, 2, 3, 4, 5}, + {0, 1, 2, 3, 5, 6}, + {0, 1, 2, 3, 6, 7}, + {0, 1, 2, 3, 7, 4}, + {4, 5, 6, 7, 0, 1}, + {4, 5, 6, 7, 1, 2}, + {4, 5, 6, 7, 2, 3}, + {4, 5, 6, 7, 3, 0}, + {0, 1, 4, 5, 3, 7}, + {0, 1, 4, 5, 2, 6}, + {3, 2, 7, 6, 1, 5}, + {3, 2, 7, 6, 0, 4}, + }; + + for (int32_t xi = 0; xi <= SUB_GRID_LEN; xi++) + { + for (int32_t yi = 0; yi <= SUB_GRID_LEN; yi++) + { + for (int32_t zi = 0; zi <= SUB_GRID_LEN; zi++) + { + int32_t groups[8]; + groups[0] = groupAt(xi - 1, yi - 1, zi - 1); + groups[1] = groupAt(xi , yi - 1, zi - 1); + groups[2] = groupAt(xi , yi , zi - 1); + groups[3] = groupAt(xi - 1, yi, zi - 1); + groups[4] = groupAt(xi - 1, yi - 1, zi); + groups[5] = groupAt(xi , yi - 1, zi); + groups[6] = groupAt(xi , yi, zi); + groups[7] = groupAt(xi - 1, yi, zi); + + // edges test + uint32_t numEdges = 0; + for (uint32_t i = 0; i < 6; i++) + { + int32_t g0 = groups[faces[i][0]]; + int32_t g1 = groups[faces[i][1]]; + int32_t g2 = groups[faces[i][2]]; + int32_t g3 = groups[faces[i][3]]; + uint32_t flips = 0; + if (g0 != g1) + { + flips++; + } + if (g1 != g2) + { + flips++; + } + if (g2 != g3) + { + flips++; + } + if (g3 != g0) + { + flips++; + } + if (flips > 2) + { + numEdges++; + } + } + + int32_t vertexNr = -1; + + // edge vertex? + if (numEdges > 1) + { + for (uint32_t i = 0; i < 12; i++) + { + if (groups[edges[i][0]] < 0 && + groups[edges[i][1]] < 0 && + groups[edges[i][2]] < 0 && + groups[edges[i][3]] < 0 && + groups[edges[i][4]] < 0 && + groups[edges[i][5]] < 0) + { + vertexNr = (int32_t)i; + } + } + } + + // face vertex? + if (vertexNr < 0 && numEdges > 2) + { + for (uint32_t i = 0; i < 6; i++) + { + if (groups[faces[i][0]] < 0 && + groups[faces[i][1]] < 0 && + groups[faces[i][2]] < 0 && + groups[faces[i][3]] < 0) + { + vertexNr = (int32_t)i + 12; + } + } + } + + // inner vertex + if (vertexNr < 0 && numEdges > 2) + { + vertexNr = 18; + } + + mVertexAt[xi][yi][zi] = vertexNr; + + if (vertexNr < 0) + { + continue; + } + + for (uint32_t i = 0; i < 8; i++) + { + if (groups[i] < 0) + { + continue; + } + + for (uint32_t j = 0; j < 8; j++) + { + if (groups[j] < 0) + { + continue; + } + + if (vertexNr > mFirstPairVertex[groups[i]][groups[j]]) + { + mFirstPairVertex[groups[i]][groups[j]] = vertexNr; + mFirstPairCoord[groups[i]][groups[j]].init(xi, yi, zi); + } + } + } + } + } + } +} + + +void ApexGeneralizedCubeTemplates::createTriangles(physx::Array<int32_t>& currentIndices) +{ + physx::Array<int32_t> verts; + physx::Array<GenCoord> queue; + + currentIndices.clear(); + + for (int32_t group0 = 0; group0 < 8; group0++) + { + for (int32_t group1 = group0 + 1; group1 < 8; group1++) + { + int32_t first = mFirstPairVertex[group0][group1]; + + if (first < 0) + { + continue; + } + + // walk around the edge of the surface between group 0 and group 1 + verts.clear(); + + GenCoord c; + for (c.xi = 0; c.xi <= SUB_GRID_LEN; c.xi++) + for (c.yi = 0; c.yi <= SUB_GRID_LEN; c.yi++) + for (c.zi = 0; c.zi <= SUB_GRID_LEN; c.zi++) + { + mVertexMarked[c.xi][c.yi][c.zi] = false; + } + + c = mFirstPairCoord[group0][group1]; + queue.pushBack(c); + while (!queue.empty()) + { + c = queue[queue.size() - 1]; + queue.popBack(); + + if (vertexMarked(c)) + { + continue; + } + + markVertex(c); + + int vert = mVertexAt[c.xi][c.yi][c.zi]; + if (vert >= 0) + { + if (verts.size() == 1) + { + queue.clear(); // otherwise the search goes both ways around the border + } + if (verts.empty() || verts[verts.size() - 1] != vert) + { + verts.pushBack(vert); + } + } + + GenCoord next; + next = c; + next.xi--; + if (!vertexMarked(next) && isEdge(next, 0, group0, group1)) + { + queue.pushBack(next); + } + next = c; + next.yi--; + if (!vertexMarked(next) && isEdge(next, 1, group0, group1)) + { + queue.pushBack(next); + } + next = c; + next.zi--; + if (!vertexMarked(next) && isEdge(next, 2, group0, group1)) + { + queue.pushBack(next); + } + next = c; + next.xi++; + if (!vertexMarked(next) && isEdge(c, 0, group0, group1)) + { + queue.pushBack(next); + } + next = c; + next.yi++; + if (!vertexMarked(next) && isEdge(c, 1, group0, group1)) + { + queue.pushBack(next); + } + next = c; + next.zi++; + if (!vertexMarked(next) && isEdge(c, 2, group0, group1)) + { + queue.pushBack(next); + } + } + + if (verts.size() < 3) + { + continue; + } + + // create triangle fan + if (verts[0] == verts[verts.size() - 1]) + { + verts.popBack(); + } + + for (uint32_t i = 1; i + 1 < verts.size(); i++) + { + // PH: Attemt to fix: This is a double fan where the initial value also appears somewhere in the middle + if (verts[0] == verts[i] || verts[0] == verts[i + 1]) + { + continue; + } + + PX_ASSERT(verts[0] != verts[i]); + PX_ASSERT(verts[0] != verts[i + 1]); + PX_ASSERT(verts[i] != verts[i + 1]); + currentIndices.pushBack(verts[0]); + currentIndices.pushBack(verts[i]); + currentIndices.pushBack(verts[i + 1]); + } + } + } +} + + + +bool ApexGeneralizedCubeTemplates::isEdge(const GenCoord& c, int32_t dim, int32_t group0, int32_t group1) +{ + if (dim < 0 || dim >= 3) + { + return false; + } + + int g0, g1, g2, g3; + if (dim == 0) + { + g0 = groupAt(c.xi, c.yi, c.zi); + g1 = groupAt(c.xi, c.yi - 1, c.zi); + g2 = groupAt(c.xi, c.yi - 1, c.zi - 1); + g3 = groupAt(c.xi, c.yi, c.zi - 1); + } + else if (dim == 1) + { + g0 = groupAt(c.xi, c.yi, c.zi); + g1 = groupAt(c.xi, c.yi, c.zi - 1); + g2 = groupAt(c.xi - 1, c.yi, c.zi - 1); + g3 = groupAt(c.xi - 1, c.yi, c.zi); + } + else + { + g0 = groupAt(c.xi, c.yi, c.zi); + g1 = groupAt(c.xi - 1, c.yi, c.zi); + g2 = groupAt(c.xi - 1, c.yi - 1, c.zi); + g3 = groupAt(c.xi, c.yi - 1, c.zi); + } + + uint32_t flips = 0; + if (g0 != g1) + { + flips++; + } + if (g1 != g2) + { + flips++; + } + if (g2 != g3) + { + flips++; + } + if (g3 != g0) + { + flips++; + } + + if (flips <= 2) + { + return false; + } + + if (group0 < 0 || group1 < 0) + { + return true; + } + + if (g0 == group0 && g1 == group1) + { + return true; + } + if (g1 == group0 && g2 == group1) + { + return true; + } + if (g2 == group0 && g3 == group1) + { + return true; + } + if (g3 == group0 && g0 == group1) + { + return true; + } + + if (g0 == group1 && g1 == group0) + { + return true; + } + if (g1 == group1 && g2 == group0) + { + return true; + } + if (g2 == group1 && g3 == group0) + { + return true; + } + if (g3 == group1 && g0 == group0) + { + return true; + } + + return false; +} + +} +} // end namespace nvidia::apex + |