//------------------------------------------------------------- // encode.C // // Implements functions in the PolygonNormalMask class // // Hansong Zhang // Department of Computer Science // UNC-Chapel Hill // 1996 //------------------------------------------------------------- #include #include #include "nmask.h" #define ABS(x) (((x)<0)?(-(x)):(x)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MAXMAX(a,b,c) ((a) > (b) ? MAX (a,c) : MAX (b,c)) // // Given a normal and number of subdivisions, compute the // byteOffset and bitMask of the normal. Normally this is // done once for each polygon as a preprocess, with the // polygon's normal as input. // // The order of faces on the cube : -x, x, -y, y, -z, z; // i.e. Face # for -x is 0, 1 for x, 2 for -y, 3 for y, // 4 for -z, 5 for z; // Each face is subdivided into nSubdiv * nSubdiv sub-faces. // void PolygonNormalMask::Encode(Vec3 &_normal, int nSubdiv) { int nSubFacesPerFace = nSubdiv * nSubdiv; float coordOnFacex, coordOnFacey; int faceNo; Vec3 normal = _normal; // To resize the normal so that its end is on one of the 6 faces // of the cube... by divide the normal by its largest component float max = MAXMAX(ABS(normal.x), ABS(normal.y), ABS(normal.z)); normal /= max; // Decide which face the vector is on if (normal.x == 1 || normal.x == -1) { // normal vector end on |X| = 1 faceNo = normal.x == -1 ? 0 : 1; coordOnFacex = normal.y; coordOnFacey = normal.z; } else if (normal.y == 1 || normal.y == -1) { // normal vector end on |Y| = 1 faceNo = normal.y == -1 ? 2 : 3; coordOnFacex = normal.z; coordOnFacey = normal.x; } else if (normal.z == 1 || normal.z == -1) { // normal vector end on |Z| = 1 faceNo = normal.z == -1 ? 4 : 5; coordOnFacex = normal.x; coordOnFacey = normal.y; } else fprintf(stderr, "Numerical error.\n"); int intOffsetX = (int)floor((coordOnFacex+1)/2 * nSubdiv), intOffsetY = (int)floor((coordOnFacey+1)/2 * nSubdiv); if (intOffsetX == nSubdiv) intOffsetX --; if (intOffsetY == nSubdiv) intOffsetY --; int offsetOnFace = intOffsetX + nSubdiv * intOffsetY; // Bit offset of the normal cluster's corresponding bit in the // (virtual) full normal mask. int bitOffsetInMask = faceNo * nSubFacesPerFace + offsetOnFace; byteOffset = bitOffsetInMask / 8; bitMask = Masks[(bitOffsetInMask & 0x7)]; bitOffset = bitOffsetInMask; //fprintf(stderr, "%d ------ %x\n", (int)byteOffset , (int)bitMask); }