void COORD::UnitTest() { assert(COORD(3, 3) + COORD(2, 2) == COORD(5, 5)); COORD coord(5, 2); coord += COORD(2, 5); assert(coord == COORD(7, 7)); assert(COORD(2, 2) + North == COORD(2, 3)); assert(COORD(2, 2) + East == COORD(3, 2)); assert(COORD(2, 2) + South == COORD(2, 1)); assert(COORD(2, 2) + West == COORD(1, 2)); assert(Compass[E_NORTH] == North); assert(Compass[E_EAST] == East); assert(Compass[E_WEST] == West); assert(Compass[E_SOUTH] == South); assert(Clockwise(E_NORTH) == E_EAST); assert(Clockwise(E_EAST) == E_SOUTH); assert(Clockwise(E_SOUTH) == E_WEST); assert(Clockwise(E_WEST) == E_NORTH); assert(Opposite(E_NORTH) == E_SOUTH); assert(Opposite(E_EAST) == E_WEST); assert(Opposite(E_SOUTH) == E_NORTH); assert(Opposite(E_WEST) == E_EAST); assert(Anticlockwise(E_NORTH) == E_WEST); assert(Anticlockwise(E_EAST) == E_NORTH); assert(Anticlockwise(E_SOUTH) == E_EAST); assert(Anticlockwise(E_WEST) == E_SOUTH); assert(ManhattanDistance(COORD(3, 2), COORD(-4, -7)) == 16); assert(DirectionalDistance(COORD(3, 2), COORD(-4, -7), E_NORTH) == -9); assert(DirectionalDistance(COORD(3, 2), COORD(-4, -7), E_EAST) == -7); assert(DirectionalDistance(COORD(3, 2), COORD(-4, -7), E_SOUTH) == 9); assert(DirectionalDistance(COORD(3, 2), COORD(-4, -7), E_WEST) == 7); }
void Mutate2(Poly* PolyList) { // Mutate2: Iterate through the list and for each triangle, attempt to mutate 10 times in a row before continuing static int Iterator = 0; static int IterCount = -1; IterCount++; if (IterCount >= 10) { IterCount = 0; Iterator += 1; if (Iterator >= POLYGON_COUNT) Iterator = 0; } unsigned int MutationCount = rand() % 10; if (MutationCount < 3) MutationCount = 1; else if (MutationCount < 5) MutationCount = 2; else if (MutationCount < 7) MutationCount = 3; else if (MutationCount < 9) MutationCount = 4; else MutationCount = 5; unsigned int RandomMutator; for (unsigned int i = 0; i < MutationCount; i++) { TempPolygon = PolyList[Iterator]; RandomMutator = rand() % (4 + VERTEX_COUNT * 2); switch (RandomMutator) { case 0: case 1: case 2: PolyList[Iterator].Color[RandomMutator] = rand() % 256; if (~PolyList[Iterator].BitFlag & DEFINED_BIT) PolyList[Iterator].Color[3] = rand() % 256; break; case 3: PolyList[Iterator].Color[RandomMutator] = rand() % 256; break; default: if (RandomMutator - 4 < VERTEX_COUNT) PolyList[Iterator].X[RandomMutator - 4] = rand() % Target->w; else PolyList[Iterator].Y[RandomMutator - 4 - VERTEX_COUNT] = rand() % Target->h; Clockwise(&PolyList[ListIterator]); break; } PolyList[Iterator].BitFlag |= DEFINED_BIT; // Test to see if the evolution was successful. If not, place the temporary polygon back in the list. if (TestEvolution() == false) PolyList[Iterator] = TempPolygon; } }
void Mutate1(Poly* PolyList) { // Mutate1: Choose a random triangle and commit X random mutations, where X is // a partially random number between 1 and 5. unsigned int MutationCount = rand() % 10; if (MutationCount < 3) MutationCount = 1; else if (MutationCount < 5) MutationCount = 2; else if (MutationCount < 7) MutationCount = 3; else if (MutationCount < 9) MutationCount = 4; else MutationCount = 5; unsigned int RandomMutator; for (unsigned int i = 0; i < MutationCount; i++) { ListIterator = rand() % POLYGON_COUNT; TempPolygon = PolyList[ListIterator]; RandomMutator = rand() % (4 + VERTEX_COUNT * 2); switch (RandomMutator) { case 0: case 1: case 2: PolyList[ListIterator].Color[RandomMutator] = rand() % 256; if (~PolyList[ListIterator].BitFlag & DEFINED_BIT) PolyList[ListIterator].Color[3] = rand() % 256; break; case 3: PolyList[ListIterator].Color[RandomMutator] = rand() % 256; break; default: if (RandomMutator - 4 < VERTEX_COUNT) PolyList[ListIterator].X[RandomMutator - 4] = rand() % Target->w; else PolyList[ListIterator].Y[RandomMutator - 4 - VERTEX_COUNT] = rand() % Target->h; Clockwise(&PolyList[ListIterator]); break; } PolyList[ListIterator].BitFlag |= DEFINED_BIT; // Test to see if the evolution was successful. If not, place the temporary polygon back in the list. if (TestEvolution() == false) PolyList[ListIterator] = TempPolygon; } }
void IFXNeighborResController::UpdateEdgesInMap(U32 meshIndex) { ResolutionState* state = &(m_pMeshStates[meshIndex]); IFXUpdates* pUpdates = m_pUpdatesGroup->GetUpdates(meshIndex); IFXResolutionChange* rc = &(pUpdates->pResChanges[state->resolutionChangeIndex - 1]); IFXMesh* pMesh = 0; m_pMeshGroup->GetMesh(meshIndex, pMesh); IFXFaceIter faceIter; pMesh->GetFaceIter(faceIter); // Update modified edges U32 endUpdate = state->faceUpdateIndex; U32 update; for ( update = endUpdate - rc->numFaceUpdates; update < endUpdate; ++update) { IFXFaceUpdate* pFaceUpdate = &(pUpdates->pFaceUpdates[update]); U32 p = m_pVertexMap->Convert(meshIndex, pFaceUpdate->newDown); U32 q = m_pVertexMap->Convert(meshIndex, pFaceUpdate->newUp); if (p == q) { // This is a face update for a non-position attribute change. // Example: better normals at corners of cube. // We are only concerned with updates that affect geometry. continue; } U32 faceIndex = pFaceUpdate->face; IFXFace* pFace = faceIter.Index(faceIndex); U32 childCorner = pFaceUpdate->corner; U32 cwCorner = Clockwise(childCorner); U32 ccwCorner = CounterClockwise(childCorner); U32 c = m_pVertexMap->Convert(meshIndex, pFace->Vertex(childCorner)); U32 x = m_pVertexMap->Convert(meshIndex, pFace->Vertex(cwCorner)); U32 y = m_pVertexMap->Convert(meshIndex, pFace->Vertex(ccwCorner)); // AddOrReplaceEdge does one of two things: // In the case of vertex merge, it will add any new edges. // In the case of a manifold merge, it will replace the // reference of a potentially deleted neighbor face with // a valid reference. m_pEdgeMap->AddOrReplaceEdge(x, p, meshIndex, faceIndex, ccwCorner); m_pEdgeMap->AddOrReplaceEdge(y, p, meshIndex, faceIndex, cwCorner); m_pEdgeMap->RemoveEdge(x, c); m_pEdgeMap->RemoveEdge(y, c); } // Remove deleted edges U32 prevNumFaces = state->prevNumFaces; U32 faceIndex; for ( faceIndex = state->numFaces; faceIndex < prevNumFaces; ++faceIndex) { IFXFace* pFace = faceIter.Index(faceIndex); U32 a = m_pVertexMap->Convert(meshIndex, pFace->Vertex(0)); U32 b = m_pVertexMap->Convert(meshIndex, pFace->Vertex(1)); U32 c = m_pVertexMap->Convert(meshIndex, pFace->Vertex(2)); FindNonDeletedFaceForEdge(a, b); FindNonDeletedFaceForEdge(b, c); FindNonDeletedFaceForEdge(c, a); } IFXRELEASE(pMesh); }
void IFXNeighborResController::AnalyzeMergingEdges(U32 meshIndex, U32 resolution) { ResolutionState* state = &(m_pMeshStates[meshIndex]); IFXUpdates* pUpdates = m_pUpdatesGroup->GetUpdates(meshIndex); IFXResolutionChange* rc = &(pUpdates->pResChanges[state->resolutionChangeIndex - 1]); IFXMesh* pMesh = 0; m_pMeshGroup->GetMesh(meshIndex, pMesh); IFXFaceIter faceIter; pMesh->GetFaceIter(faceIter); U32 endUpdate = state->faceUpdateIndex; U32 update; for ( update = endUpdate - rc->numFaceUpdates; update < endUpdate; ++update) { IFXFaceUpdate* pFaceUpdate = &pUpdates->pFaceUpdates[update]; U32 p = m_pVertexMap->Convert(meshIndex, pFaceUpdate->newDown); U32 q = m_pVertexMap->Convert(meshIndex, pFaceUpdate->newUp); if (p == q) { // This is a face update for a non-position attribute change. // Example: better normals at corners of cube. // We are only concerned with updates that affect geometry. continue; } IFXFace* pFace = faceIter.Index(pFaceUpdate->face); U32 childCorner = pFaceUpdate->corner; U32 cwCorner = Clockwise(childCorner); U32 ccwCorner = CounterClockwise(childCorner); IFXASSERT(pFaceUpdate->newUp == pFace->Vertex(childCorner)); U32 c = m_pVertexMap->Convert(meshIndex, pFace->Vertex(childCorner)); U32 x = m_pVertexMap->Convert(meshIndex, pFace->Vertex(cwCorner)); U32 y = m_pVertexMap->Convert(meshIndex, pFace->Vertex(ccwCorner)); // Let c = child vertex // Let p = parent vertex // Let x = cw of child // Let y = ccw of child // // If the xp edge exists: Look for a face that is common // to the lists around edge xp and xc. If a face exists, // it is assumed that this face is a deleted face and // the disparate lists will be joined when the face removed. // If a common face is not found, then this is a distal // edge merge. // // If the xp edge does not exist: A merge does not exist // because there is only one list. // // The check can be accomplished by walking the faces // around the first edge and setting a visited flag. Then // we walk around the second edge looking for a visited flag. BOOL distalMerge = CheckForDistalMerge(x, c, p); // xc and xp edge if (distalMerge) { AddDistalMergeRecord(resolution, x, c, p); // xc and xp edge } distalMerge = CheckForDistalMerge(y, c, p); // yc and yp edge if (distalMerge) { AddDistalMergeRecord(resolution, y, c, p); // xc and xp edge } } IFXRELEASE(pMesh); }