📄 compressionstreamnormal.java
字号:
(stream.normalQuant < 0? 0 : (stream.normalQuant > 6? 6 : stream.normalQuant)) ; nx = normalX ; ny = normalY ; nz = normalZ ; octant = 0 ; sextant = 0 ; u = 0 ; v = 0 ; // Normalize the fixed point normal to the positive signed octant. if (nx < 0.0) { octant |= 4 ; nx = -nx ; } if (ny < 0.0) { octant |= 2 ; ny = -ny ; } if (nz < 0.0) { octant |= 1 ; nz = -nz ; } // Normalize the fixed point normal to the proper sextant of the octant. if (nx < ny) { sextant |= 1 ; t = nx ; nx = ny ; ny = t ; } if (nz < ny) { sextant |= 2 ; t = ny ; ny = nz ; nz = t ; } if (nx < nz) { sextant |= 4 ; t = nx ; nx = nz ; nz = t ; } // Convert the floating point y component to s1.14 fixed point. int yInt = (int)(ny * UNITY_14) ; // The y component of the normal is the sine of the y angle. Quantize // the y angle by using the fixed point y component as an index into // the inverse sine table of the correct size for the quantization // level. (12 - quant) bits of the s1.14 y normal component are // rolled off with a right shift; the remaining bits then match the // number of bits used to represent the delta sine of the table. int yIndex = inverseSine[quant][yInt >> (12-quant)] ; // Search the two xz rows near y for the best match. int ii = 0 ; int jj = 0 ; int n = 1 << quant ; double dot, bestDot = -1 ; for (int j = yIndex-1 ; j < yIndex+1 && j <= n ; j++) { if (j < 0) continue ; for (int i = 0 ; i <= n ; i++) { if (i+j > n) continue ; dot = nx * cgNormals[quant][j][i][0] + ny * cgNormals[quant][j][i][1] + nz * cgNormals[quant][j][i][2] ; if (dot > bestDot) { bestDot = dot ; ii = i ; jj = j ; } } } // Convert u and v to standard grid form. u = ii << (6 - quant) ; v = jj << (6 - quant) ; // Check for special normals and specially encode them. specialNormal = false ; if (u == 64 && v == 0) { // six coordinate axes case if (sextant == 0 || sextant == 2) { // +/- x-axis specialSextant = 0x6 ; specialOctant = ((octant & 4) != 0)? 0x2 : 0 ; } else if (sextant == 3 || sextant == 1) { // +/- y-axis specialSextant = 0x6 ; specialOctant = 4 | (((octant & 2) != 0)? 0x2 : 0) ; } else if (sextant == 5 || sextant == 4) { // +/- z-axis specialSextant = 0x7 ; specialOctant = ((octant & 1) != 0)? 0x2 : 0 ; } specialNormal = true ; u = v = 0 ; } else if (u == 0 && v == 64) { // eight mid point case specialSextant = 6 | (octant >> 2) ; specialOctant = ((octant & 0x3) << 1) | 1 ; specialNormal = true ; u = v = 0 ; } // Compute deltas if possible. // Use the non-normalized ii and jj indices. int du = 0 ; int dv = 0 ; int uv64 = 64 >> (6 - quant) ; absolute = false ; if (stream.firstNormal || stream.normalQuantChanged || stream.lastSpecialNormal || specialNormal) { // The first normal by definition is absolute, and normals cannot // be represented as deltas to or from special normals, nor from // normals with a different quantization. absolute = true ; stream.firstNormal = false ; stream.normalQuantChanged = false ; } else if (stream.lastOctant == octant && stream.lastSextant == sextant) { // Deltas are always allowed within the same sextant/octant. du = ii - stream.lastU ; dv = jj - stream.lastV ; } else if (stream.lastOctant != octant && stream.lastSextant == sextant && (((sextant == 1 || sextant == 5) && (stream.lastOctant & 3) == (octant & 3)) || ((sextant == 0 || sextant == 4) && (stream.lastOctant & 5) == (octant & 5)) || ((sextant == 2 || sextant == 3) && (stream.lastOctant & 6) == (octant & 6)))) { // If the sextants are the same, the octants can differ only when // they are bordering each other on the same edge that the // sextant has. du = ii - stream.lastU ; dv = -jj - stream.lastV ; // Can't delta by less than -64. if (dv < -uv64) absolute = true ; // Can't delta doubly defined points. if (jj == 0) absolute = true ; } else if (stream.lastOctant == octant && stream.lastSextant != sextant && ((sextant == 0 && stream.lastSextant == 4) || (sextant == 4 && stream.lastSextant == 0) || (sextant == 1 && stream.lastSextant == 5) || (sextant == 5 && stream.lastSextant == 1) || (sextant == 2 && stream.lastSextant == 3) || (sextant == 3 && stream.lastSextant == 2))) { // If the octants are the same, the sextants must border on // the i side (this case) or the j side (next case). du = -ii - stream.lastU ; dv = jj - stream.lastV ; // Can't delta by less than -64. if (du < -uv64) absolute = true ; // Can't delta doubly defined points. if (ii == 0) absolute = true ; } else if (stream.lastOctant == octant && stream.lastSextant != sextant && ((sextant == 0 && stream.lastSextant == 2) || (sextant == 2 && stream.lastSextant == 0) || (sextant == 1 && stream.lastSextant == 3) || (sextant == 3 && stream.lastSextant == 1) || (sextant == 4 && stream.lastSextant == 5) || (sextant == 5 && stream.lastSextant == 4))) { // If the octants are the same, the sextants must border on // the j side (this case) or the i side (previous case). if (((ii + jj ) != uv64) && (ii != 0) && (jj != 0)) { du = uv64 - ii - stream.lastU ; dv = uv64 - jj - stream.lastV ; // Can't delta by greater than +63. if ((du >= uv64) || (dv >= uv64)) absolute = true ; } else // Can't delta doubly defined points. absolute = true ; } else // Can't delta this normal. absolute = true ; if (absolute == false) { // Convert du and dv to standard grid form. u = du << (6 - quant) ; v = dv << (6 - quant) ; } // Compute length and shift common to all components. computeLengthShift(u, v) ; if (absolute && length > 6) { // Absolute normal u, v components are unsigned 6-bit integers, so // truncate the 0 sign bit for values > 0x001f. length = 6 ; } // Add this element to the Huffman table associated with this stream. huffmanTable.addNormalEntry(length, shift, absolute) ; // Save current normal as last. stream.lastSextant = sextant ; stream.lastOctant = octant ; stream.lastU = ii ; stream.lastV = jj ; stream.lastSpecialNormal = specialNormal ; // Copy and retain absolute normal for mesh buffer lookup. uAbsolute = ii ; vAbsolute = jj ; } /** * Output a setNormal command. * * @param table HuffmanTable mapping quantized representations to * compressed encodings * @param output CommandStream for collecting compressed output */ void outputCommand(HuffmanTable table, CommandStream output) { outputNormal(table, output, CommandStream.SET_NORM, 8) ; } /** * Output a normal subcommand. * * @param table HuffmanTable mapping quantized representations to * compressed encodings * @param output CommandStream for collecting compressed output */ void outputSubcommand(HuffmanTable table, CommandStream output) { outputNormal(table, output, 0, 6) ; } // // Output the final compressed bits to the output command stream. // private void outputNormal(HuffmanTable table, CommandStream output, int header, int headerLength) { HuffmanNode t ; // Look up the Huffman token for this compression stream element. t = table.getNormalEntry(length, shift, absolute) ; // Construct the normal subcommand. int componentLength = t.dataLength - t.shift ; int subcommandLength = 0 ; long normalSubcommand = 0 ; if (absolute) { // A 3-bit sextant and a 3-bit octant are always present. subcommandLength = t.tagLength + 6 ; if (specialNormal) // Use the specially-encoded sextant and octant. normalSubcommand = (t.tag << 6) | (specialSextant << 3) | specialOctant ; else // Use the general encoding rule. normalSubcommand = (t.tag << 6) | (sextant << 3) | octant ; } else { // The tag is immediately followed by the u and v delta components. subcommandLength = t.tagLength ; normalSubcommand = t.tag ; } // Add the u and v values to the subcommand. subcommandLength += (2 * componentLength) ; u = (u >> t.shift) & (int)lengthMask[componentLength] ; v = (v >> t.shift) & (int)lengthMask[componentLength] ; normalSubcommand = (normalSubcommand << (2 * componentLength)) | (u << (1 * componentLength)) | (v << (0 * componentLength)) ; if (subcommandLength < 6) { // The header will have some empty bits. The Huffman tag // computation will prevent this if necessary. header |= (int)(normalSubcommand << (6 - subcommandLength)) ; subcommandLength = 0 ; } else { // Move the 1st 6 bits of the subcommand into the header. header |= (int)(normalSubcommand >>> (subcommandLength - 6)) ; subcommandLength -= 6 ; } // Add the header and body to the output buffer. output.addCommand(header, headerLength, normalSubcommand, subcommandLength) ; } public String toString() { String fixed ; if (specialNormal) fixed = " special normal, sextant " + specialSextant + " octant " + specialOctant ; else if (absolute) fixed = " sextant " + sextant + " octant " + octant + " u " + u + " v " + v ; else fixed = " du " + u + " dv " + v ; return "normal: " + normalX + " " + normalY + " " + normalZ + "\n" + fixed + "\n" + " length " + length + " shift " + shift + (absolute? " absolute" : " relative") ; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -