⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compressionstreamnormal.java

📁 JAVA3D矩陈的相关类
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * $RCSfile: CompressionStreamNormal.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistribution of source code must retain the above copyright *   notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright *   notice, this list of conditions and the following disclaimer in *   the documentation and/or other materials provided with the *   distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. * * $Revision: 1.5 $ * $Date: 2007/02/09 17:20:16 $ * $State: Exp $ */package com.sun.j3d.utils.compression;import javax.vecmath.Vector3f;/** * This class represents a normal in a compression stream. It maintains both * floating-point and quantized representations.  This normal may be bundled * with a vertex or exist separately as a global normal. */class CompressionStreamNormal extends CompressionStreamElement {    private int u, v ;    private int specialOctant, specialSextant ;    private float normalX, normalY, normalZ ;    int octant, sextant ;    boolean specialNormal ;    int uAbsolute, vAbsolute ;	        /**     * Create a CompressionStreamNormal.     *     * @param stream CompressionStream associated with this element     * @param normal floating-point representation to be encoded     */    CompressionStreamNormal(CompressionStream stream, Vector3f normal) {	this.normalX = normal.x ;	this.normalY = normal.y ;	this.normalZ = normal.z ;	stream.byteCount += 12 ;    }    //    // Normal Encoding Parameterization    //     // A floating point normal is quantized to a desired number of bits by    // comparing it to candidate entries in a table of every possible normal    // at that quantization and finding the closest match.  This table of    // normals is indexed by the following encoding:    //    // First, points on a unit radius sphere are parameterized by two angles,    // th and psi, using usual spherical coordinates. th is the angle about    // the y axis, psi is the inclination to the plane containing the point.    // The mapping between rectangular and spherical coordinates is:    //     // x = cos(th)*cos(psi)    // y = sin(psi)    // z = sin(th)*cos(psi)    //     // Points on sphere are folded first by octant, and then by sort order    // of xyz into one of six sextants. All the table encoding takes place in    // the positive octant, in the region bounded by the half spaces:    //     // x >= z    // z >= y    // y >= 0    //     // This triangular shaped patch runs from 0 to 45 degrees in th, and    // from 0 to as much as 0.615479709 (MAX_Y_ANG) in psi. The xyz bounds    // of the patch is:    //     // (1, 0, 0)  (1/sqrt(2), 0, 1/sqrt(2))  (1/sqrt(3), 1/sqrt(3), 1/sqrt(3))    //     // When dicing this space up into discrete points, the choice for y is    // linear quantization in psi.  This means that if the y range is to be    // divided up into n segments, the angle of segment j is:    //     // psi(j) = MAX_Y_ANG*(j/n)    //     // The y height of the patch (in arc length) is *not* the same as the xz    // dimension. However, the subdivision quantization needs to treat xz and    // y equally. To achieve this, the th angles are re-parameterized as    // reflected psi angles.  That is, the i-th point's th is:    //     // th(i) = asin(tan(psi(i))) = asin(tan(MAX_Y_ANG*(i/n)))    //     // To go the other direction, the angle th corresponds to the real index r    // (in the same 0-n range as i):    //     // r(th) = n*atan(sin(th))/MAX_Y_ANG    //     // Rounded to the nearest integer, this gives the closest integer index i    // to the xz angle th. Because the triangle has a straight edge on the    // line x=z, it is more intuitive to index the xz angles in reverse    // order.  Thus the two equations above are replaced by:    //     // th(i) = asin(tan(psi(i))) = asin(tan(MAX_Y_ANG*((n-i)/n)))    //     // r(th) = n*(1 - atan(sin(th))/MAX_Y_ANG)    //     // Each level of quantization subdivides the triangular patch twice as    // densely.  The case in which only the three vertices of the triangle are    // present is the first logical stage of representation, but because of    // how the table is encoded the first usable case starts one level of    // sub-division later.  This three point level has an n of 2 by the above    // conventions.    //    private static final int MAX_UV_BITS = 6 ;    private static final int MAX_UV_ENTRIES = 64 ;    private static final double cgNormals[][][][] =	new double[MAX_UV_BITS+1][MAX_UV_ENTRIES+1][MAX_UV_ENTRIES+1][3] ;    private static final double MAX_Y_ANG = 0.615479709 ;    private static final double UNITY_14 = 16384.0 ;    private static void computeNormals() {	int inx, iny, inz, n ;	double th, psi, qnx, qny, qnz ;	for (int quant = 0 ; quant <= MAX_UV_BITS ; quant++) {	    n = 1 << quant ;	    for (int j = 0 ; j <= n ; j++) {		for (int i = 0 ; i <= n ; i++) {		    if (i+j > n) continue ;		    psi = MAX_Y_ANG*(j/((double) n)) ;		    th = Math.asin(Math.tan(MAX_Y_ANG*((n-i)/((double) n)))) ;		    qnx = Math.cos(th)*Math.cos(psi) ;		    qny = Math.sin(psi) ;		    qnz = Math.sin(th)*Math.cos(psi) ;		    // The normal table uses 16-bit components and must be		    // able to represent both +1.0 and -1.0, so convert the		    // floating point normal components to fixed point with 14		    // fractional bits, a unity bit, and a sign bit (s1.14).		    // Set them back to get the float equivalent.		    qnx = qnx*UNITY_14 ; inx = (int)qnx ;		    qnx = inx ; qnx = qnx/UNITY_14 ;		    qny = qny*UNITY_14 ; iny = (int)qny ;		    qny = iny ; qny = qny/UNITY_14 ;		    qnz = qnz*UNITY_14 ; inz = (int)qnz ;		    qnz = inz ; qnz = qnz/UNITY_14 ;		    cgNormals[quant][j][i][0] = qnx ;		    cgNormals[quant][j][i][1] = qny ;		    cgNormals[quant][j][i][2] = qnz ;		}	    }	}    }    //    // An inverse sine table is used for each quantization level to take the Y    // component of a normal (which is the sine of the inclination angle) and    // obtain the closest quantized Y angle.    //     // At any level of compression, there are a fixed number of different Y    // angles (between 0 and MAX_Y_ANG).  The inverse table is built to have    // slightly more than twice as many entries as y angles at any particular    // level; this ensures that the inverse look-up will get within one angle    // of the right one.  The size of the table should be as small as    // possible, but with its delta sine still smaller than the delta sine    // between the last two angles to be encoded.    //     // Example: the inverse sine table has a maximum angle of 0.615479709.  At    // the maximum resolution of 6 bits there are 65 discrete angles used,    // but twice as many are needed for thresholding between angles, so the    // delta angle is 0.615479709/128. The difference then between the last    // two angles to be encoded is:    // sin(0.615479709*128.0/128.0) - sin(0.615479709*127.0/128.0) = 0.003932730    //     // Using 8 significent bits below the binary point, fixed point can    // represent sines in increments of 0.003906250, just slightly smaller.    // However, because the maximum Y angle sine is 0.577350269, only 148    // instead of 256 table entries are needed.    //     private static final short inverseSine[][] = new short[MAX_UV_BITS+1][] ;    // UNITY_14 * sin(MAX_Y_ANGLE)    private static final short MAX_SIN_14BIT = 9459 ;    private static void computeInverseSineTables() {	int intSin, deltaSin, intAngle ;	double floatSin, floatAngle ;	short sin14[] = new short[MAX_UV_ENTRIES+1] ;	// Build table of sines in s1.14 fixed point for each of the	// discrete angles used at maximum resolution.	for (int i = 0 ; i <= MAX_UV_ENTRIES ; i++) {	    sin14[i] = (short)(UNITY_14*Math.sin(i*MAX_Y_ANG/MAX_UV_ENTRIES)) ;	}	for (int quant = 0 ; quant <= MAX_UV_BITS ; quant++) {	    switch (quant) {	    default:	    case 6:		// Delta angle: MAX_Y_ANGLE/128.0		// Bits below binary point for fixed point delta sine: 8		// Integer delta sine: 64		// Inverse sine table size: 148 entries		deltaSin = 1 << (14 - 8) ; 		break ;	    case 5:		// Delta angle: MAX_Y_ANGLE/64.0		// Bits below binary point for fixed point delta sine: 7		// Integer delta sine: 128		// Inverse sine table size: 74 entries		deltaSin = 1 << (14 - 7) ; 		break ;	    case 4:		// Delta angle: MAX_Y_ANGLE/32.0		// Bits below binary point for fixed point delta sine: 6		// Integer delta sine: 256		// Inverse sine table size: 37 entries		deltaSin = 1 << (14 - 6) ; 		break ;	    case 3:		// Delta angle: MAX_Y_ANGLE/16.0		// Bits below binary point for fixed point delta sine: 5		// Integer delta sine: 512		// Inverse sine table size: 19 entries		deltaSin = 1 << (14 - 5) ; 		break ;	    case 2:		// Delta angle: MAX_Y_ANGLE/8.0		// Bits below binary point for fixed point delta sine: 4		// Integer delta sine: 1024		// Inverse sine table size: 10 entries		deltaSin = 1 << (14 - 4) ; 		break ;	    case 1:		// Delta angle: MAX_Y_ANGLE/4.0		// Bits below binary point for fixed point delta sine: 3		// Integer delta sine: 2048		// Inverse sine table size: 5 entries		deltaSin = 1 << (14 - 3) ; 		break ;	    case 0:		// Delta angle: MAX_Y_ANGLE/2.0		// Bits below binary point for fixed point delta sine: 2		// Integer delta sine: 4096		// Inverse sine table size: 3 entries		deltaSin = 1 << (14 - 2) ; 		break ;	    }	    inverseSine[quant] = new short[(MAX_SIN_14BIT/deltaSin) + 1] ;	    	    intSin = 0 ;	    for (int i = 0 ; i < inverseSine[quant].length ; i++) {		// Compute float representation of integer sine with desired		// number of fractional bits by effectively right shifting 14.		floatSin = intSin/UNITY_14 ;		// Compute the angle with this sine value and quantize it.		floatAngle = Math.asin(floatSin) ;		intAngle = (int)((floatAngle/MAX_Y_ANG) * (1 << quant)) ;		// Choose the closest of the three nearest quantized values		// intAngle-1, intAngle, and intAngle+1.		if (intAngle > 0) {		    if (Math.abs(sin14[intAngle << (6-quant)] - intSin) >			Math.abs(sin14[(intAngle-1) << (6-quant)] - intSin))			intAngle = intAngle-1 ;		}		if (intAngle < (1 << quant)) {		    if (Math.abs(sin14[intAngle << (6-quant)] - intSin) >			Math.abs(sin14[(intAngle+1) << (6-quant)] - intSin))			intAngle = intAngle+1 ;		}		inverseSine[quant][i] = (short)intAngle ;		intSin += deltaSin ;	    }	}    }    /**     * Compute static tables needed for normal quantization.     */    static {	computeNormals() ;	computeInverseSineTables() ;    }    /**     * Quantize the floating point normal to a 6-bit octant/sextant plus u,v     * components of [0..6] bits.  Full resolution is 18 bits and the minimum     * is 6 bits.     *     * @param stream CompressionStream associated with this element     * @param table HuffmanTable for collecting data about the quantized     * representation of this element     */    void quantize(CompressionStream stream, HuffmanTable huffmanTable) {	double nx, ny, nz, t ;	// Clamp UV quantization.	int quant = 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -