short* generateLookup(){ short *table = (short*) malloc(sizeof(short)*256); for(long i = 0; i < 255; i++){ table[i] = calculateParity(i); } return table; }
//--------------------------------------------------------------------- void TangentSpaceCalc::addFaceTangentSpaceToVertices( size_t indexSet, size_t faceIndex, size_t *localVertInd, const Vector3& faceTsU, const Vector3& faceTsV, const Vector3& faceNorm, Result& result) { // Calculate parity for this triangle int faceParity = calculateParity(faceTsU, faceTsV, faceNorm); // Now add these to each vertex referenced by the face for (int v = 0; v < 3; ++v) { // index 0 is vertex we're calculating, 1 and 2 are the others // We want to re-weight these by the angle the face makes with the vertex // in order to obtain tesselation-independent results Real angleWeight = calculateAngleWeight(localVertInd[v], localVertInd[(v+1)%3], localVertInd[(v+2)%3]); VertexInfo* vertex = &(mVertexArray[localVertInd[v]]); // check parity (0 means not set) // Locate parity-version of vertex index, or create if doesn't exist // If parity-version of vertex index was different, record alteration // in triangle remap // in vertex split list bool splitVertex = false; size_t reusedOppositeParity = 0; bool splitBecauseOfParity = false; bool newVertex = false; if (!vertex->parity) { // init vertex->parity = faceParity; newVertex = true; } if (mSplitMirrored) { if (!newVertex && faceParity != calculateParity(vertex->tangent, vertex->binormal, vertex->norm))//vertex->parity != faceParity) { // Check for existing alternative parity if (vertex->oppositeParityIndex) { // Ok, have already split this vertex because of parity // Use the same one again reusedOppositeParity = vertex->oppositeParityIndex; vertex = &(mVertexArray[reusedOppositeParity]); } else { splitVertex = true; splitBecauseOfParity = true; LogManager::getSingleton().stream(LML_TRIVIAL) << "TSC parity split - Vpar: " << vertex->parity << " Fpar: " << faceParity << " faceTsU: " << faceTsU << " faceTsV: " << faceTsV << " faceNorm: " << faceNorm << " vertTsU:" << vertex->tangent << " vertTsV:" << vertex->binormal << " vertNorm:" << vertex->norm; } } } if (mSplitRotated) { // deal with excessive tangent space rotations as well as mirroring // same kind of split behaviour appropriate if (!newVertex && !splitVertex) { // If more than 90 degrees, split Vector3 uvCurrent = vertex->tangent + vertex->binormal; // project down to the plane (plane normal = face normal) Vector3 vRotHalf = uvCurrent - faceNorm; vRotHalf *= faceNorm.dotProduct(uvCurrent); if ((faceTsU + faceTsV).dotProduct(vRotHalf) < 0.0f) { splitVertex = true; } } } if (splitVertex) { size_t newVertexIndex = mVertexArray.size(); VertexSplit splitInfo(localVertInd[v], newVertexIndex); result.vertexSplits.push_back(splitInfo); // re-point opposite parity if (splitBecauseOfParity) { vertex->oppositeParityIndex = newVertexIndex; } // copy old values but reset tangent space VertexInfo locVertex = *vertex; locVertex.tangent = Vector3::ZERO; locVertex.binormal = Vector3::ZERO; locVertex.parity = faceParity; mVertexArray.push_back(locVertex); result.indexesRemapped.push_back(IndexRemap(indexSet, faceIndex, splitInfo)); vertex = &(mVertexArray[newVertexIndex]); } else if (reusedOppositeParity) { // didn't split again, but we do need to record the re-used remapping VertexSplit splitInfo(localVertInd[v], reusedOppositeParity); result.indexesRemapped.push_back(IndexRemap(indexSet, faceIndex, splitInfo)); } // Add weighted tangent & binormal vertex->tangent += (faceTsU * angleWeight); vertex->binormal += (faceTsV * angleWeight); } }
int main(){ long test = ((long)1) << 63; short parity = calculateParity(test); printf("%d\n",parity); return 0; }