Source Code Cross Referenced for GeometryDecompressor.java in  » 6.0-JDK-Modules » java-3d » javax » media » j3d » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » java 3d » javax.media.j3d 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $RCSfile: GeometryDecompressor.java,v $
0003:         *
0004:         * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0006:         *
0007:         * This code is free software; you can redistribute it and/or modify it
0008:         * under the terms of the GNU General Public License version 2 only, as
0009:         * published by the Free Software Foundation.  Sun designates this
0010:         * particular file as subject to the "Classpath" exception as provided
0011:         * by Sun in the LICENSE file that accompanied this code.
0012:         *
0013:         * This code is distributed in the hope that it will be useful, but WITHOUT
0014:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0015:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0016:         * version 2 for more details (a copy is included in the LICENSE file that
0017:         * accompanied this code).
0018:         *
0019:         * You should have received a copy of the GNU General Public License version
0020:         * 2 along with this work; if not, write to the Free Software Foundation,
0021:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0022:         *
0023:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0024:         * CA 95054 USA or visit www.sun.com if you need additional information or
0025:         * have any questions.
0026:         *
0027:         * $Revision: 1.7 $
0028:         * $Date: 2008/02/28 20:17:22 $
0029:         * $State: Exp $
0030:         */
0031:
0032:        package javax.media.j3d;
0033:
0034:        import javax.vecmath.*;
0035:
0036:        /**
0037:         * This abstract class provides the base methods needed to create a geometry
0038:         * decompressor.  Subclasses must implement a backend to handle the output,
0039:         * consisting of a generalized triangle strip, line strip, or point array,
0040:         * along with possible global color and normal changes.
0041:         */
0042:        abstract class GeometryDecompressor {
0043:            private static final boolean debug = false;
0044:            private static final boolean benchmark = false;
0045:
0046:            /**
0047:             * Compressed geometry format version supported.
0048:             */
0049:            static final int majorVersionNumber = 1;
0050:            static final int minorVersionNumber = 0;
0051:            static final int minorMinorVersionNumber = 2;
0052:
0053:            /**
0054:             * This method is called when a SetState command is encountered in the
0055:             * decompression stream.  
0056:             *
0057:             * @param bundlingNorm true indicates normals are bundled with vertices
0058:             * @param bundlingColor true indicates colors are bundled with vertices
0059:             * @param doingAlpha true indicates alpha values are bundled with vertices
0060:             */
0061:            abstract void outputVertexFormat(boolean bundlingNorm,
0062:                    boolean bundlingColor, boolean doingAlpha);
0063:
0064:            /**
0065:             * This method captures the vertex output of the decompressor.  The normal
0066:             * or color references may be null if the corresponding data is not
0067:             * bundled with the vertices in the compressed geometry buffer.  Alpha
0068:             * values may be included in the color.  
0069:             * 
0070:             * @param position The coordinates of the vertex.
0071:             * @param normal The normal bundled with the vertex.  May be null.
0072:             * @param color The color bundled with the vertex.  May be null.  
0073:             * Alpha may be present.
0074:             * @param vertexReplaceCode Specifies the generalized strip flag
0075:             * that is bundled with each vertex.
0076:             * @see GeneralizedStripFlags
0077:             * @see CompressedGeometryHeader
0078:             */
0079:            abstract void outputVertex(Point3f position, Vector3f normal,
0080:                    Color4f color, int vertexReplaceCode);
0081:
0082:            /**
0083:             * This method captures the global color output of the decompressor.  It
0084:             * is only invoked if colors are not bundled with the vertex data.  The
0085:             * global color applies to all succeeding vertices until the next time the
0086:             * method is invoked.
0087:             *
0088:             * @param color The current global color.
0089:             */
0090:            abstract void outputColor(Color4f color);
0091:
0092:            /**
0093:             * This method captures the global normal output of the decompressor.  It
0094:             * is only invoked if normals are not bundled with the vertex data.  The
0095:             * global normal applies to all succeeding vertices until the next time the
0096:             * method is invoked.
0097:             *
0098:             * @param normal The current global normal.
0099:             */
0100:            abstract void outputNormal(Vector3f normal);
0101:
0102:            // Geometry compression opcodes.
0103:            private static final int GC_VERTEX = 0x40;
0104:            private static final int GC_SET_NORM = 0xC0;
0105:            private static final int GC_SET_COLOR = 0x80;
0106:            private static final int GC_MESH_B_R = 0x20;
0107:            private static final int GC_SET_STATE = 0x18;
0108:            private static final int GC_SET_TABLE = 0x10;
0109:            private static final int GC_PASS_THROUGH = 0x08;
0110:            private static final int GC_EOS = 0x00;
0111:            private static final int GC_V_NO_OP = 0x01;
0112:            private static final int GC_SKIP_8 = 0x07;
0113:
0114:            // Three 64-entry decompression tables are used: gctables[0] for
0115:            // positions, gctables[1] for colors, and gctables[2] for normals.
0116:            private HuffmanTableEntry gctables[][];
0117:
0118:            /**
0119:             * Decompression table entry.
0120:             */
0121:            static class HuffmanTableEntry {
0122:                int tagLength, dataLength;
0123:                int rightShift, absolute;
0124:
0125:                public String toString() {
0126:                    return " tag length: " + tagLength + " data length: "
0127:                            + dataLength + " shift: " + rightShift
0128:                            + " abs/rel: " + absolute;
0129:                }
0130:            }
0131:
0132:            // A 16-entry mesh buffer is used.
0133:            private MeshBufferEntry meshBuffer[];
0134:            private int meshIndex = 15;
0135:            private int meshState;
0136:
0137:            // meshState values.  These are needed to determine if colors and/or
0138:            // normals should come from meshBuffer or from SetColor or SetNormal.
0139:            private static final int USE_MESH_NORMAL = 0x1;
0140:            private static final int USE_MESH_COLOR = 0x2;
0141:
0142:            /**
0143:             * Mesh buffer entry containing position, normal, and color.
0144:             */
0145:            static class MeshBufferEntry {
0146:                short x, y, z;
0147:                short octant, sextant, u, v;
0148:                short r, g, b, a;
0149:            }
0150:
0151:            // Geometry compression state variables.
0152:            private short curX, curY, curZ;
0153:            private short curR, curG, curB, curA;
0154:            private int curSex, curOct, curU, curV;
0155:
0156:            // Current vertex data.
0157:            private Point3f curPos;
0158:            private Vector3f curNorm;
0159:            private Color4f curColor;
0160:            private int repCode;
0161:
0162:            // Flags indicating what data is bundled with the vertex.
0163:            private boolean bundlingNorm;
0164:            private boolean bundlingColor;
0165:            private boolean doingAlpha;
0166:
0167:            // Internal decompression buffering variables.
0168:            private int currentHeader = 0;
0169:            private int nextHeader = 0;
0170:            private int bitBuffer = 0;
0171:            private int bitBufferCount = 32;
0172:
0173:            // Used for benchmarking if so configured.
0174:            private long startTime;
0175:            private int vertexCount;
0176:
0177:            // Bit-field masks: BMASK[i] = (1<<i)-1
0178:            private static final int BMASK[] = { 0x0, 0x1, 0x3, 0x7, 0xF, 0x1F,
0179:                    0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF,
0180:                    0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF,
0181:                    0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, 0x1FFFFFF,
0182:                    0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF,
0183:                    0x7FFFFFFF, 0xFFFFFFFF, };
0184:
0185:            // A reference to the compressed data and the current offset.
0186:            private byte gcData[];
0187:            private int gcIndex;
0188:
0189:            // The normals table for decoding 6-bit [u,v] spherical sextant coordinates.
0190:            private static final double gcNormals[][][];
0191:            private static final double NORMAL_MAX_Y_ANG = 0.615479709;
0192:            private static final boolean printNormalTable = false;
0193:
0194:            /**
0195:             * Initialize the normals table.
0196:             */
0197:            static {
0198:                int i, j, inx, iny, inz;
0199:                double th, psi, qnx, qny, qnz;
0200:
0201:                gcNormals = new double[65][65][3];
0202:
0203:                for (i = 0; i < 65; i++) {
0204:                    for (j = 0; j < 65; j++) {
0205:                        if (i + j > 64)
0206:                            continue;
0207:
0208:                        psi = NORMAL_MAX_Y_ANG * (i / 64.0);
0209:                        th = Math.asin(Math.tan(NORMAL_MAX_Y_ANG
0210:                                * ((64 - j) / 64.0)));
0211:
0212:                        qnx = Math.cos(th) * Math.cos(psi);
0213:                        qny = Math.sin(psi);
0214:                        qnz = Math.sin(th) * Math.cos(psi);
0215:
0216:                        //  Convert the floating point normal to s1.14 bit notation,
0217:                        //  then back again.
0218:                        qnx = qnx * 16384.0;
0219:                        inx = (int) qnx;
0220:                        qnx = (double) inx;
0221:                        qnx = qnx / 16384.0;
0222:
0223:                        qny = qny * 16384.0;
0224:                        iny = (int) qny;
0225:                        qny = (double) iny;
0226:                        qny = qny / 16384.0;
0227:
0228:                        qnz = qnz * 16384.0;
0229:                        inz = (int) qnz;
0230:                        qnz = (double) inz;
0231:                        qnz = qnz / 16384.0;
0232:
0233:                        gcNormals[i][j][0] = qnx;
0234:                        gcNormals[i][j][1] = qny;
0235:                        gcNormals[i][j][2] = qnz;
0236:                    }
0237:                }
0238:
0239:                if (printNormalTable) {
0240:                    System.err.println("struct {");
0241:                    System.err.println("    double nx, ny, nz ;");
0242:                    System.err.println("} gcNormals[65][65] = {");
0243:                    for (i = 0; i <= 64; i++) {
0244:                        System.err.println("{");
0245:                        for (j = 0; j <= 64; j++) {
0246:                            if (j + i > 64)
0247:                                continue;
0248:                            System.err.println("{ " + gcNormals[i][j][0] + ", "
0249:                                    + gcNormals[i][j][1] + ", "
0250:                                    + gcNormals[i][j][2] + " }");
0251:                        }
0252:                        System.err.println("},");
0253:                    }
0254:                    System.err.println("}");
0255:                }
0256:            }
0257:
0258:            //
0259:            // The constructor.
0260:            //
0261:            GeometryDecompressor() {
0262:                curPos = new Point3f();
0263:                curNorm = new Vector3f();
0264:                curColor = new Color4f();
0265:                gctables = new HuffmanTableEntry[3][64];
0266:
0267:                for (int i = 0; i < 64; i++) {
0268:                    gctables[0][i] = new HuffmanTableEntry();
0269:                    gctables[1][i] = new HuffmanTableEntry();
0270:                    gctables[2][i] = new HuffmanTableEntry();
0271:                }
0272:
0273:                meshBuffer = new MeshBufferEntry[16];
0274:                for (int i = 0; i < 16; i++)
0275:                    meshBuffer[i] = new MeshBufferEntry();
0276:            }
0277:
0278:            /**
0279:             * Check version numbers and return true if compatible.
0280:             */
0281:            boolean checkVersion(int majorVersionNumber, int minorVersionNumber) {
0282:                return ((majorVersionNumber < this .majorVersionNumber) || ((majorVersionNumber == this .majorVersionNumber) && (minorVersionNumber <= this .minorVersionNumber)));
0283:            }
0284:
0285:            /**
0286:             * Decompress data and invoke abstract output methods.
0287:             *
0288:             * @param start byte offset to start of compressed geometry in data array
0289:             * @param length size of compressed geometry in bytes
0290:             * @param data array containing compressed geometry buffer of the
0291:             * specified length at the given offset from the start of the array
0292:             * @exception ArrayIndexOutOfBoundsException if start+length > data size
0293:             */
0294:            void decompress(int start, int length, byte data[]) {
0295:                if (debug)
0296:                    System.err.println("GeometryDecompressor.decompress\n"
0297:                            + " start: " + start + " length: " + length
0298:                            + " data array size: " + data.length);
0299:                if (benchmark)
0300:                    benchmarkStart(length);
0301:
0302:                if (start + length > data.length)
0303:                    throw new ArrayIndexOutOfBoundsException(J3dI18N
0304:                            .getString("GeometryDecompressor0"));
0305:
0306:                // Set reference to compressed data and skip to start of data.
0307:                gcData = data;
0308:                gcIndex = start;
0309:
0310:                // Initialize state.
0311:                bitBufferCount = 0;
0312:                meshState = 0;
0313:                bundlingNorm = false;
0314:                bundlingColor = false;
0315:                doingAlpha = false;
0316:                repCode = 0;
0317:
0318:                // Headers are interleaved for hardware implementations, so the
0319:                // first is always a nullop.
0320:                nextHeader = GC_V_NO_OP;
0321:
0322:                // Enter decompression loop.
0323:                while (gcIndex < start + length)
0324:                    processDecompression();
0325:
0326:                // Finish out any bits left in bitBuffer.
0327:                while (bitBufferCount > 0)
0328:                    processDecompression();
0329:
0330:                if (benchmark)
0331:                    benchmarkPrint(length);
0332:            }
0333:
0334:            //
0335:            // Return the next bitCount bits of compressed data.
0336:            //
0337:            private int getBits(int bitCount, String d) {
0338:                int bits;
0339:
0340:                if (debug)
0341:                    System.err.print(" getBits(" + bitCount + ") " + d + ", "
0342:                            + bitBufferCount + " available at gcIndex "
0343:                            + gcIndex);
0344:
0345:                if (bitCount == 0) {
0346:                    if (debug)
0347:                        System.err.println(": got 0x0");
0348:                    return 0;
0349:                }
0350:
0351:                if (bitBufferCount == 0) {
0352:                    bitBuffer = (((gcData[gcIndex++] & 0xff) << 24)
0353:                            | ((gcData[gcIndex++] & 0xff) << 16)
0354:                            | ((gcData[gcIndex++] & 0xff) << 8) | ((gcData[gcIndex++] & 0xff)));
0355:
0356:                    bitBufferCount = 32;
0357:                }
0358:
0359:                if (bitBufferCount >= bitCount) {
0360:                    bits = (bitBuffer >>> (32 - bitCount)) & BMASK[bitCount];
0361:                    bitBuffer = bitBuffer << bitCount;
0362:                    bitBufferCount -= bitCount;
0363:                } else {
0364:                    bits = (bitBuffer >>> (32 - bitCount)) & BMASK[bitCount];
0365:                    bits = bits >>> (bitCount - bitBufferCount);
0366:                    bits = bits << (bitCount - bitBufferCount);
0367:
0368:                    bitBuffer = (((gcData[gcIndex++] & 0xff) << 24)
0369:                            | ((gcData[gcIndex++] & 0xff) << 16)
0370:                            | ((gcData[gcIndex++] & 0xff) << 8) | ((gcData[gcIndex++] & 0xff)));
0371:
0372:                    bits = bits
0373:                            | ((bitBuffer >>> (32 - (bitCount - bitBufferCount))) & BMASK[bitCount
0374:                                    - bitBufferCount]);
0375:
0376:                    bitBuffer = bitBuffer << (bitCount - bitBufferCount);
0377:                    bitBufferCount = 32 - (bitCount - bitBufferCount);
0378:                }
0379:
0380:                if (debug)
0381:                    System.err.println(": got 0x" + Integer.toHexString(bits));
0382:
0383:                return bits;
0384:            }
0385:
0386:            //
0387:            // Shuffle interleaved headers and opcodes.
0388:            //
0389:            private void processDecompression() {
0390:                int mbp;
0391:                currentHeader = nextHeader;
0392:
0393:                if ((currentHeader & 0xC0) == GC_VERTEX) {
0394:                    // Process a vertex.
0395:                    if (!bundlingNorm && !bundlingColor) {
0396:                        // get next opcode, process current position opcode
0397:                        nextHeader = getBits(8, "header");
0398:                        mbp = processDecompressionOpcode(0);
0399:
0400:                    } else if (bundlingNorm && !bundlingColor) {
0401:                        // get normal header, process current position opcode
0402:                        nextHeader = getBits(6, "normal");
0403:                        mbp = processDecompressionOpcode(0);
0404:                        currentHeader = nextHeader | GC_SET_NORM;
0405:
0406:                        // get next opcode, process current normal opcode
0407:                        nextHeader = getBits(8, "header");
0408:                        processDecompressionOpcode(mbp);
0409:
0410:                    } else if (!bundlingNorm && bundlingColor) {
0411:                        // get color header, process current position opcode
0412:                        nextHeader = getBits(6, "color");
0413:                        mbp = processDecompressionOpcode(0);
0414:                        currentHeader = nextHeader | GC_SET_COLOR;
0415:
0416:                        // get next opcode, process current color opcode
0417:                        nextHeader = getBits(8, "header");
0418:                        processDecompressionOpcode(mbp);
0419:
0420:                    } else {
0421:                        // get normal header, process current position opcode
0422:                        nextHeader = getBits(6, "normal");
0423:                        mbp = processDecompressionOpcode(0);
0424:                        currentHeader = nextHeader | GC_SET_NORM;
0425:
0426:                        // get color header, process current normal opcode
0427:                        nextHeader = getBits(6, "color");
0428:                        processDecompressionOpcode(mbp);
0429:                        currentHeader = nextHeader | GC_SET_COLOR;
0430:
0431:                        // get next opcode, process current color opcode
0432:                        nextHeader = getBits(8, "header");
0433:                        processDecompressionOpcode(mbp);
0434:                    }
0435:
0436:                    // Send out the complete vertex.
0437:                    outputVertex(curPos, curNorm, curColor, repCode);
0438:                    if (benchmark)
0439:                        vertexCount++;
0440:
0441:                    // meshState bits get turned off in the setColor and setNormal
0442:                    // routines in order to keep track of what data a mesh buffer
0443:                    // reference should use.
0444:                    meshState |= USE_MESH_NORMAL;
0445:                    meshState |= USE_MESH_COLOR;
0446:
0447:                } else {
0448:                    // Non-vertex case: get next opcode, then process current opcode.
0449:                    nextHeader = getBits(8, "header");
0450:                    processDecompressionOpcode(0);
0451:                }
0452:            }
0453:
0454:            //
0455:            // Decode the opcode in currentHeader, and dispatch to the appropriate
0456:            // processing method.  
0457:            //
0458:            private int processDecompressionOpcode(int mbp) {
0459:                if ((currentHeader & 0xC0) == GC_SET_NORM)
0460:                    processSetNormal(mbp);
0461:                else if ((currentHeader & 0xC0) == GC_SET_COLOR)
0462:                    processSetColor(mbp);
0463:                else if ((currentHeader & 0xC0) == GC_VERTEX)
0464:                    // Return the state of the mesh buffer push bit
0465:                    // when processing a vertex.
0466:                    return processVertex();
0467:                else if ((currentHeader & 0xE0) == GC_MESH_B_R) {
0468:                    processMeshBR();
0469:
0470:                    // Send out the complete vertex.
0471:                    outputVertex(curPos, curNorm, curColor, repCode);
0472:                    if (benchmark)
0473:                        vertexCount++;
0474:
0475:                    // meshState bits get turned off in the setColor and setNormal
0476:                    // routines in order to keep track of what data a mesh buffer
0477:                    // reference should use.
0478:                    meshState |= USE_MESH_NORMAL;
0479:                    meshState |= USE_MESH_COLOR;
0480:                } else if ((currentHeader & 0xF8) == GC_SET_STATE)
0481:                    processSetState();
0482:                else if ((currentHeader & 0xF8) == GC_SET_TABLE)
0483:                    processSetTable();
0484:                else if ((currentHeader & 0xFF) == GC_EOS)
0485:                    processEos();
0486:                else if ((currentHeader & 0xFF) == GC_V_NO_OP)
0487:                    processVNoop();
0488:                else if ((currentHeader & 0xFF) == GC_PASS_THROUGH)
0489:                    processPassThrough();
0490:                else if ((currentHeader & 0xFF) == GC_SKIP_8)
0491:                    processSkip8();
0492:
0493:                return 0;
0494:            }
0495:
0496:            //
0497:            //  Process a set state opcode.
0498:            //
0499:            private void processSetState() {
0500:                int ii;
0501:                if (debug)
0502:                    System.err.println("GeometryDecompressor.processSetState");
0503:
0504:                ii = getBits(3, "bundling");
0505:
0506:                bundlingNorm = ((currentHeader & 0x1) != 0);
0507:                bundlingColor = (((ii >>> 2) & 0x1) != 0);
0508:                doingAlpha = (((ii >>> 1) & 0x1) != 0);
0509:
0510:                if (debug)
0511:                    System.err.println(" bundling normal: " + bundlingNorm
0512:                            + " bundling color: " + bundlingColor
0513:                            + " alpha present: " + doingAlpha);
0514:
0515:                // Call the abstract output implementation.
0516:                outputVertexFormat(bundlingNorm, bundlingColor, doingAlpha);
0517:            }
0518:
0519:            //
0520:            // Process a set decompression table opcode.
0521:            //
0522:            // Extract the parameters of the table set command,
0523:            // and set the approprate table entries.
0524:            //
0525:            private void processSetTable() {
0526:                HuffmanTableEntry gct[];
0527:                int i, adr, tagLength, dataLength, rightShift, absolute;
0528:                int ii, index;
0529:
0530:                if (debug)
0531:                    System.err.println("GeometryDecompressor.processSetTable");
0532:
0533:                // Get reference to approprate 64 entry table.
0534:                index = (currentHeader & 0x6) >>> 1;
0535:                gct = gctables[index];
0536:
0537:                // Get the remaining bits of the set table command.
0538:                ii = getBits(15, "set table");
0539:
0540:                // Extract the individual fields from the two bit strings.
0541:                adr = ((currentHeader & 0x1) << 6) | ((ii >>> 9) & 0x3F);
0542:
0543:                // Get data length.  For positions and colors, 0 really means 16, as 0
0544:                // lengths are meaningless for them.  Normal components are allowed to
0545:                // have lengths of 0.
0546:                dataLength = (ii >>> 5) & 0x0F;
0547:                if (dataLength == 0 && index != 2)
0548:                    dataLength = 16;
0549:
0550:                rightShift = ii & 0x0F;
0551:                absolute = (ii >>> 4) & 0x1;
0552:
0553:                //
0554:                // Decode the tag length from the address field by finding the
0555:                // first set 1 from the left in the bitfield.
0556:                //
0557:                for (tagLength = 6; tagLength > 0; tagLength--) {
0558:                    if ((adr >> tagLength) != 0)
0559:                        break;
0560:                }
0561:
0562:                // Shift the address bits up into place, and off the leading 1.
0563:                adr = (adr << (6 - tagLength)) & 0x3F;
0564:
0565:                if (debug)
0566:                    System.err.println(" table "
0567:                            + ((currentHeader & 0x6) >>> 1) + " address " + adr
0568:                            + " tag length " + tagLength + " data length "
0569:                            + dataLength + " shift " + rightShift
0570:                            + " absolute " + absolute);
0571:
0572:                // Fill in the table fields with the specified values.
0573:                for (i = 0; i < (1 << (6 - tagLength)); i++) {
0574:                    gct[adr + i].tagLength = tagLength;
0575:                    gct[adr + i].dataLength = dataLength;
0576:                    gct[adr + i].rightShift = rightShift;
0577:                    gct[adr + i].absolute = absolute;
0578:                }
0579:            }
0580:
0581:            //
0582:            // Process a vertex opcode.  Any bundled normal and/or color will be
0583:            // processed by separate methods.  Return the mesh buffer push indicator.
0584:            //
0585:            private int processVertex() {
0586:                HuffmanTableEntry gct;
0587:                float fX, fY, fZ;
0588:                short dx, dy, dz;
0589:                int mbp, x, y, z, dataLen;
0590:                int ii;
0591:
0592:                // If the next command is a mesh buffer reference
0593:                // then use colors and normals from the mesh buffer.
0594:                meshState = 0;
0595:
0596:                // Get a reference to the approprate tag table entry.
0597:                gct = gctables[0][currentHeader & 0x3F];
0598:
0599:                if (debug)
0600:                    System.err.println("GeometryDecompressor.processVertex\n"
0601:                            + gct.toString());
0602:
0603:                // Get the true length of the data.
0604:                dataLen = gct.dataLength - gct.rightShift;
0605:
0606:                // Read in the replace code and mesh buffer push bits,
0607:                // if they're not in the current header.
0608:                if (6 - (3 * dataLen) - gct.tagLength > 0) {
0609:                    int numBits = 6 - (3 * dataLen) - gct.tagLength;
0610:                    int jj;
0611:
0612:                    jj = currentHeader & BMASK[numBits];
0613:                    ii = getBits(3 - numBits, "repcode/mbp");
0614:                    ii |= (jj << (3 - numBits));
0615:                } else
0616:                    ii = getBits(3, "repcode/mbp");
0617:
0618:                repCode = ii >>> 1;
0619:                mbp = ii & 0x1;
0620:
0621:                // Read in x, y, and z components.
0622:                x = currentHeader & BMASK[6 - gct.tagLength];
0623:
0624:                if (gct.tagLength + dataLen == 6) {
0625:                    y = getBits(dataLen, "y");
0626:                    z = getBits(dataLen, "z");
0627:                } else if (gct.tagLength + dataLen < 6) {
0628:                    x = x >> (6 - gct.tagLength - dataLen);
0629:
0630:                    y = currentHeader & BMASK[6 - gct.tagLength - dataLen];
0631:                    if (gct.tagLength + 2 * dataLen == 6) {
0632:                        z = getBits(dataLen, "z");
0633:                    } else if (gct.tagLength + 2 * dataLen < 6) {
0634:                        y = y >> (6 - gct.tagLength - 2 * dataLen);
0635:
0636:                        z = currentHeader
0637:                                & BMASK[6 - gct.tagLength - 2 * dataLen];
0638:                        if (gct.tagLength + 3 * dataLen < 6) {
0639:                            z = z >> (6 - gct.tagLength - 3 * dataLen);
0640:                        } else if (gct.tagLength + 3 * dataLen > 6) {
0641:                            ii = getBits(dataLen
0642:                                    - (6 - gct.tagLength - 2 * dataLen), "z");
0643:                            z = (z << (dataLen - (6 - gct.tagLength - 2 * dataLen)))
0644:                                    | ii;
0645:                        }
0646:                    } else {
0647:                        ii = getBits(dataLen - (6 - gct.tagLength - dataLen),
0648:                                "y");
0649:                        y = (y << (dataLen - (6 - gct.tagLength - dataLen)))
0650:                                | ii;
0651:                        z = getBits(dataLen, "z");
0652:                    }
0653:                } else {
0654:                    ii = getBits(dataLen - (6 - gct.tagLength), "x");
0655:                    x = (x << (dataLen - (6 - gct.tagLength))) | ii;
0656:                    y = getBits(dataLen, "y");
0657:                    z = getBits(dataLen, "z");
0658:                }
0659:
0660:                // Sign extend delta x y z components.
0661:                x = x << (32 - dataLen);
0662:                x = x >> (32 - dataLen);
0663:                y = y << (32 - dataLen);
0664:                y = y >> (32 - dataLen);
0665:                z = z << (32 - dataLen);
0666:                z = z >> (32 - dataLen);
0667:
0668:                // Normalize values.
0669:                dx = (short) (x << gct.rightShift);
0670:                dy = (short) (y << gct.rightShift);
0671:                dz = (short) (z << gct.rightShift);
0672:
0673:                // Update current position, first adding deltas if in relative mode.
0674:                if (gct.absolute != 0) {
0675:                    curX = dx;
0676:                    curY = dy;
0677:                    curZ = dz;
0678:                    if (debug)
0679:                        System.err.println(" absolute position: " + curX + " "
0680:                                + curY + " " + curZ);
0681:                } else {
0682:                    curX += dx;
0683:                    curY += dy;
0684:                    curZ += dz;
0685:                    if (debug)
0686:                        System.err.println(" delta position: " + dx + " " + dy
0687:                                + " " + dz);
0688:                }
0689:
0690:                // Do optional mesh buffer push.
0691:                if (mbp != 0) {
0692:                    // Increment to next position (meshIndex is initialized to 15).
0693:                    meshIndex = (meshIndex + 1) & 0xF;
0694:                    meshBuffer[meshIndex].x = curX;
0695:                    meshBuffer[meshIndex].y = curY;
0696:                    meshBuffer[meshIndex].z = curZ;
0697:                    if (debug)
0698:                        System.err
0699:                                .println(" pushed position into mesh buffer at "
0700:                                        + meshIndex);
0701:                }
0702:
0703:                // Convert point back to [-1..1] floating point.
0704:                fX = curX;
0705:                fX /= 32768.0;
0706:                fY = curY;
0707:                fY /= 32768.0;
0708:                fZ = curZ;
0709:                fZ /= 32768.0;
0710:                if (debug)
0711:                    System.err.println(" result position " + fX + " " + fY
0712:                            + " " + fZ);
0713:
0714:                curPos.set(fX, fY, fZ);
0715:                return mbp;
0716:            }
0717:
0718:            //
0719:            // Process a set current normal opcode.
0720:            //
0721:            private void processSetNormal(int mbp) {
0722:                HuffmanTableEntry gct;
0723:                int index, du, dv, n, dataLength;
0724:                int ii;
0725:
0726:                // if next command is a mesh buffer reference, use this normal
0727:                meshState &= ~USE_MESH_NORMAL;
0728:
0729:                // use table 2 for normals
0730:                gct = gctables[2][currentHeader & 0x3F];
0731:
0732:                if (debug)
0733:                    System.err
0734:                            .println("GeometryDecompressor.processSetNormal\n"
0735:                                    + gct.toString());
0736:
0737:                // subtract up-shift amount to get true data (u, v) length
0738:                dataLength = gct.dataLength - gct.rightShift;
0739:
0740:                if (gct.absolute != 0) {
0741:                    //
0742:                    // Absolute normal case.  Extract index from 6-bit tag.
0743:                    //
0744:                    index = currentHeader & BMASK[6 - gct.tagLength];
0745:
0746:                    if (gct.tagLength != 0) {
0747:                        // read in the rest of the 6-bit sex/oct pair (index)
0748:                        ii = getBits(6 - (6 - gct.tagLength), "sex/oct");
0749:                        index = (index << (6 - (6 - gct.tagLength))) | ii;
0750:                    }
0751:
0752:                    // read in u and v data
0753:                    curU = getBits(dataLength, "u");
0754:                    curV = getBits(dataLength, "v");
0755:
0756:                    // normalize u, v, sextant, and octant
0757:                    curU = curU << gct.rightShift;
0758:                    curV = curV << gct.rightShift;
0759:
0760:                    curSex = (index >> 3) & 0x7;
0761:                    curOct = index & 0x7;
0762:
0763:                    if (debug) {
0764:                        if (curSex < 6)
0765:                            System.err.println(" absolute normal: sex "
0766:                                    + curSex + " oct " + curOct + " u " + curU
0767:                                    + " v " + curV);
0768:                        else
0769:                            System.err.println(" special normal: sex " + curSex
0770:                                    + " oct " + curOct);
0771:                    }
0772:                } else {
0773:                    //
0774:                    // Relative normal case.  Extract du from 6-bit tag.
0775:                    //
0776:                    du = currentHeader & BMASK[6 - gct.tagLength];
0777:
0778:                    if (gct.tagLength + dataLength < 6) {
0779:                        // normalize du, get dv
0780:                        du = du >> (6 - gct.tagLength - dataLength);
0781:                        dv = currentHeader
0782:                                & BMASK[6 - gct.tagLength - dataLength];
0783:
0784:                        if (gct.tagLength + 2 * dataLength < 6) {
0785:                            // normalize dv
0786:                            dv = dv >> (6 - gct.tagLength - 2 * dataLength);
0787:                        } else if (gct.tagLength + 2 * dataLength > 6) {
0788:                            // read in rest of dv and normalize it
0789:                            ii = getBits(dataLength
0790:                                    - (6 - gct.tagLength - dataLength), "dv");
0791:                            dv = (dv << (dataLength - (6 - gct.tagLength - dataLength)))
0792:                                    | ii;
0793:                        }
0794:                    } else if (gct.tagLength + dataLength > 6) {
0795:                        // read in rest of du and normalize it
0796:                        ii = getBits(dataLength - (6 - gct.tagLength), "du");
0797:                        du = (du << (dataLength - (6 - gct.tagLength))) | ii;
0798:                        // read in dv
0799:                        dv = getBits(dataLength, "dv");
0800:                    } else {
0801:                        // read in dv
0802:                        dv = getBits(dataLength, "dv");
0803:                    }
0804:
0805:                    // Sign extend delta uv components.
0806:                    du = du << (32 - dataLength);
0807:                    du = du >> (32 - dataLength);
0808:                    dv = dv << (32 - dataLength);
0809:                    dv = dv >> (32 - dataLength);
0810:
0811:                    // normalize values
0812:                    du = du << gct.rightShift;
0813:                    dv = dv << gct.rightShift;
0814:
0815:                    // un-delta
0816:                    curU += du;
0817:                    curV += dv;
0818:
0819:                    if (debug)
0820:                        System.err.println(" delta normal: du " + du + " dv "
0821:                                + dv);
0822:
0823:                    //
0824:                    // Check for normal wrap.
0825:                    //
0826:                    if (!((curU >= 0) && (curV >= 0) && (curU + curV <= 64)))
0827:                        if ((curU < 0) && (curV >= 0)) {
0828:                            // wrap on u, same octant, different sextant
0829:                            curU = -curU;
0830:                            switch (curSex) {
0831:                            case 0:
0832:                                curSex = 4;
0833:                                break;
0834:                            case 1:
0835:                                curSex = 5;
0836:                                break;
0837:                            case 2:
0838:                                curSex = 3;
0839:                                break;
0840:                            case 3:
0841:                                curSex = 2;
0842:                                break;
0843:                            case 4:
0844:                                curSex = 0;
0845:                                break;
0846:                            case 5:
0847:                                curSex = 1;
0848:                                break;
0849:                            }
0850:                        } else if ((curU >= 0) && (curV < 0)) {
0851:                            // wrap on v, same sextant, different octant
0852:                            curV = -curV;
0853:                            switch (curSex) {
0854:                            case 1:
0855:                            case 5:
0856:                                curOct = curOct ^ 4; // invert x axis
0857:                                break;
0858:                            case 0:
0859:                            case 4:
0860:                                curOct = curOct ^ 2; // invert y axis
0861:                                break;
0862:                            case 2:
0863:                            case 3:
0864:                                curOct = curOct ^ 1; // invert z axis
0865:                                break;
0866:                            }
0867:                        } else if (curU + curV > 64) {
0868:                            // wrap on uv, same octant, different sextant
0869:                            curU = 64 - curU;
0870:                            curV = 64 - curV;
0871:                            switch (curSex) {
0872:                            case 0:
0873:                                curSex = 2;
0874:                                break;
0875:                            case 1:
0876:                                curSex = 3;
0877:                                break;
0878:                            case 2:
0879:                                curSex = 0;
0880:                                break;
0881:                            case 3:
0882:                                curSex = 1;
0883:                                break;
0884:                            case 4:
0885:                                curSex = 5;
0886:                                break;
0887:                            case 5:
0888:                                curSex = 4;
0889:                                break;
0890:                            }
0891:                        } else {
0892:                            throw new IllegalArgumentException(J3dI18N
0893:                                    .getString("GeometryDecompressor1"));
0894:                        }
0895:                }
0896:
0897:                // do optional mesh buffer push
0898:                if (mbp != 0) {
0899:                    if (debug)
0900:                        System.err
0901:                                .println(" pushing normal into mesh buffer at "
0902:                                        + meshIndex);
0903:
0904:                    meshBuffer[meshIndex].sextant = (short) curSex;
0905:                    meshBuffer[meshIndex].octant = (short) curOct;
0906:                    meshBuffer[meshIndex].u = (short) curU;
0907:                    meshBuffer[meshIndex].v = (short) curV;
0908:                }
0909:
0910:                // convert normal back to [-1..1] floating point
0911:                indexNormal(curSex, curOct, curU, curV, curNorm);
0912:
0913:                // a set normal opcode when normals aren't bundled with the vertices
0914:                // is a global normal change.
0915:                if (!bundlingNorm)
0916:                    outputNormal(curNorm);
0917:            }
0918:
0919:            //
0920:            // Get the floating point normal from its sextant, octant, u, and v.
0921:            //
0922:            private void indexNormal(int sex, int oct, int u, int v, Vector3f n) {
0923:                float nx, ny, nz, t;
0924:
0925:                if (debug)
0926:                    System.err.println(" sextant " + sex + " octant " + oct
0927:                            + " u " + u + " v " + v);
0928:                if (sex > 5) {
0929:                    // special normals
0930:                    switch (oct & 0x1) {
0931:                    case 0: // six coordinate axes
0932:                        switch (((sex & 0x1) << 1) | ((oct & 0x4) >> 2)) {
0933:                        case 0:
0934:                            nx = 1.0f;
0935:                            ny = nz = 0.0f;
0936:                            break;
0937:                        case 1:
0938:                            ny = 1.0f;
0939:                            nx = nz = 0.0f;
0940:                            break;
0941:                        default:
0942:                        case 2:
0943:                            nz = 1.0f;
0944:                            nx = ny = 0.0f;
0945:                            break;
0946:                        }
0947:                        sex = 0;
0948:                        oct = (oct & 0x2) >> 1;
0949:                        oct = (oct << 2) | (oct << 1) | oct;
0950:                        break;
0951:                    case 1: // eight mid
0952:                    default:
0953:                        oct = ((sex & 0x1) << 2) | (oct >> 1);
0954:                        sex = 0;
0955:                        nx = ny = nz = (float) (1.0 / Math.sqrt(3.0));
0956:                        break;
0957:                    }
0958:                    if ((oct & 0x1) != 0)
0959:                        nz = -nz;
0960:                    if ((oct & 0x2) != 0)
0961:                        ny = -ny;
0962:                    if ((oct & 0x4) != 0)
0963:                        nx = -nx;
0964:
0965:                } else {
0966:                    // regular normals
0967:                    nx = (float) gcNormals[v][u][0];
0968:                    ny = (float) gcNormals[v][u][1];
0969:                    nz = (float) gcNormals[v][u][2];
0970:
0971:                    // reverse the swap 
0972:                    if ((sex & 0x4) != 0) {
0973:                        t = nx;
0974:                        nx = nz;
0975:                        nz = t;
0976:                    }
0977:                    if ((sex & 0x2) != 0) {
0978:                        t = ny;
0979:                        ny = nz;
0980:                        nz = t;
0981:                    }
0982:                    if ((sex & 0x1) != 0) {
0983:                        t = nx;
0984:                        nx = ny;
0985:                        ny = t;
0986:                    }
0987:
0988:                    // reverse the sign flip 
0989:                    if ((oct & 0x1) != 0)
0990:                        nz = -nz;
0991:                    if ((oct & 0x2) != 0)
0992:                        ny = -ny;
0993:                    if ((oct & 0x4) != 0)
0994:                        nx = -nx;
0995:                }
0996:
0997:                // return resulting normal
0998:                n.set(nx, ny, nz);
0999:                if (debug)
1000:                    System.err.println(" result normal: " + nx + " " + ny + " "
1001:                            + nz);
1002:            }
1003:
1004:            //
1005:            // Process a set current color command.
1006:            //
1007:            private void processSetColor(int mbp) {
1008:                HuffmanTableEntry gct;
1009:                short dr, dg, db, da;
1010:                float fR, fG, fB, fA;
1011:                int r, g, b, a, index, dataLength;
1012:                int ii;
1013:
1014:                // If the next command is a mesh buffer reference, use this color.
1015:                meshState &= ~USE_MESH_COLOR;
1016:
1017:                // Get the huffman table entry.
1018:                gct = gctables[1][currentHeader & 0x3F];
1019:
1020:                if (debug)
1021:                    System.err.println("GeometryDecompressor.processSetColor\n"
1022:                            + gct.toString());
1023:
1024:                // Get the true length of the data.
1025:                dataLength = gct.dataLength - gct.rightShift;
1026:
1027:                // Read in red, green, blue, and possibly alpha.
1028:                r = currentHeader & BMASK[6 - gct.tagLength];
1029:                a = 0;
1030:
1031:                if (gct.tagLength + dataLength == 6) {
1032:                    g = getBits(dataLength, "g");
1033:                    b = getBits(dataLength, "b");
1034:                    if (doingAlpha)
1035:                        a = getBits(dataLength, "a");
1036:                } else if (gct.tagLength + dataLength < 6) {
1037:                    r = r >> (6 - gct.tagLength - dataLength);
1038:
1039:                    g = currentHeader & BMASK[6 - gct.tagLength - dataLength];
1040:                    if (gct.tagLength + 2 * dataLength == 6) {
1041:                        b = getBits(dataLength, "b");
1042:                        if (doingAlpha)
1043:                            a = getBits(dataLength, "a");
1044:                    } else if (gct.tagLength + 2 * dataLength < 6) {
1045:                        g = g >> (6 - gct.tagLength - 2 * dataLength);
1046:
1047:                        b = currentHeader
1048:                                & BMASK[6 - gct.tagLength - 2 * dataLength];
1049:                        if (gct.tagLength + 3 * dataLength == 6) {
1050:                            if (doingAlpha)
1051:                                a = getBits(dataLength, "a");
1052:                        } else if (gct.tagLength + 3 * dataLength < 6) {
1053:                            b = b >> (6 - gct.tagLength - 3 * dataLength);
1054:
1055:                            if (doingAlpha) {
1056:                                a = currentHeader
1057:                                        & BMASK[6 - gct.tagLength - 4
1058:                                                * dataLength];
1059:                                if (gct.tagLength + 4 * dataLength < 6) {
1060:                                    a = a >> (6 - gct.tagLength - 3 * dataLength);
1061:                                } else if (gct.tagLength + 4 * dataLength > 6) {
1062:                                    ii = getBits(
1063:                                            dataLength
1064:                                                    - (6 - gct.tagLength - 3 * dataLength),
1065:                                            "a");
1066:                                    a = (a << (dataLength - (6 - gct.tagLength - 3 * dataLength)))
1067:                                            | ii;
1068:                                }
1069:                            }
1070:                        } else {
1071:                            ii = getBits(dataLength
1072:                                    - (6 - gct.tagLength - 2 * dataLength), "b");
1073:                            b = (b << (dataLength - (6 - gct.tagLength - 2 * dataLength)))
1074:                                    | ii;
1075:                            if (doingAlpha)
1076:                                a = getBits(dataLength, "a");
1077:                        }
1078:                    } else {
1079:                        ii = getBits(dataLength
1080:                                - (6 - gct.tagLength - dataLength), "g");
1081:                        g = (g << (dataLength - (6 - gct.tagLength - dataLength)))
1082:                                | ii;
1083:                        b = getBits(dataLength, "b");
1084:                        if (doingAlpha)
1085:                            a = getBits(dataLength, "a");
1086:                    }
1087:                } else {
1088:                    ii = getBits(dataLength - (6 - gct.tagLength), "r");
1089:                    r = (r << (dataLength - (6 - gct.tagLength))) | ii;
1090:                    g = getBits(dataLength, "g");
1091:                    b = getBits(dataLength, "b");
1092:                    if (doingAlpha)
1093:                        a = getBits(dataLength, "a");
1094:                }
1095:
1096:                // Sign extend delta x y z components.
1097:                r <<= (32 - dataLength);
1098:                r >>= (32 - dataLength);
1099:                g <<= (32 - dataLength);
1100:                g >>= (32 - dataLength);
1101:                b <<= (32 - dataLength);
1102:                b >>= (32 - dataLength);
1103:                a <<= (32 - dataLength);
1104:                a >>= (32 - dataLength);
1105:
1106:                // Normalize values.
1107:                dr = (short) (r << gct.rightShift);
1108:                dg = (short) (g << gct.rightShift);
1109:                db = (short) (b << gct.rightShift);
1110:                da = (short) (a << gct.rightShift);
1111:
1112:                // Update current position, first adding deltas if in relative mode.
1113:                if (gct.absolute != 0) {
1114:                    curR = dr;
1115:                    curG = dg;
1116:                    curB = db;
1117:                    if (doingAlpha)
1118:                        curA = da;
1119:                    if (debug)
1120:                        System.err.println(" absolute color: r " + curR + " g "
1121:                                + curG + " b " + curB + " a " + curA);
1122:                } else {
1123:                    curR += dr;
1124:                    curG += dg;
1125:                    curB += db;
1126:                    if (doingAlpha)
1127:                        curA += da;
1128:                    if (debug)
1129:                        System.err.println(" delta color: dr " + dr + " dg "
1130:                                + dg + " db " + db + " da " + da);
1131:                }
1132:
1133:                // Do optional mesh buffer push.
1134:                if (mbp != 0) {
1135:                    if (debug)
1136:                        System.err
1137:                                .println(" pushing color into mesh buffer at "
1138:                                        + meshIndex);
1139:
1140:                    meshBuffer[meshIndex].r = curR;
1141:                    meshBuffer[meshIndex].g = curG;
1142:                    meshBuffer[meshIndex].b = curB;
1143:                    meshBuffer[meshIndex].a = curA;
1144:                }
1145:
1146:                // Convert point back to [-1..1] floating point.
1147:                fR = curR;
1148:                fR /= 32768.0;
1149:                fG = curG;
1150:                fG /= 32768.0;
1151:                fB = curB;
1152:                fB /= 32768.0;
1153:                fA = curA;
1154:                fA /= 32768.0;
1155:
1156:                curColor.set(fR, fG, fB, fA);
1157:                if (debug)
1158:                    System.err.println(" result color: " + fR + " " + fG + " "
1159:                            + fB + " " + fA);
1160:
1161:                // A set color opcode when colors aren't bundled with the vertices
1162:                // is a global color change.
1163:                if (!bundlingColor)
1164:                    outputColor(curColor);
1165:            }
1166:
1167:            //
1168:            // Process a mesh buffer reference command.
1169:            //
1170:            private void processMeshBR() {
1171:                MeshBufferEntry entry;
1172:                int index, normal;
1173:                int ii;
1174:
1175:                if (debug)
1176:                    System.err.println("GeometryDecompressor.processMeshBR");
1177:
1178:                ii = getBits(1, "mbr");
1179:
1180:                index = (currentHeader >>> 1) & 0xF;
1181:                repCode = ((currentHeader & 0x1) << 1) | ii;
1182:
1183:                // Adjust index to proper place in fifo.
1184:                index = (meshIndex - index) & 0xf;
1185:                if (debug)
1186:                    System.err.println(" using index " + index);
1187:
1188:                // Get reference to mesh buffer entry.
1189:                entry = meshBuffer[index];
1190:                curX = entry.x;
1191:                curY = entry.y;
1192:                curZ = entry.z;
1193:
1194:                // Convert point back to [-1..1] floating point.
1195:                curPos.set(((float) curX) / 32768.0f,
1196:                        ((float) curY) / 32768.0f, ((float) curZ) / 32768.0f);
1197:
1198:                if (debug)
1199:                    System.err.println(" retrieved position " + curPos.x + " "
1200:                            + curPos.y + " " + curPos.z + " replace code "
1201:                            + repCode);
1202:
1203:                // Get mesh buffer normal if previous opcode was not a setNormal.
1204:                if (bundlingNorm && ((meshState & USE_MESH_NORMAL) != 0)) {
1205:                    curSex = entry.sextant;
1206:                    curOct = entry.octant;
1207:                    curU = entry.u;
1208:                    curV = entry.v;
1209:
1210:                    // Convert normal back to -1.0 - 1.0 floating point from index.
1211:                    normal = (curSex << 15) | (curOct << 12) | (curU << 6)
1212:                            | curV;
1213:
1214:                    if (debug)
1215:                        System.err.println(" retrieving normal");
1216:                    indexNormal(curSex, curOct, curU, curV, curNorm);
1217:                }
1218:
1219:                // Get mesh buffer color if previous opcode was not a setColor.
1220:                if (bundlingColor && ((meshState & USE_MESH_COLOR) != 0)) {
1221:                    curR = entry.r;
1222:                    curG = entry.g;
1223:                    curB = entry.b;
1224:
1225:                    // Convert point back to -1.0 - 1.0 floating point.
1226:                    curColor.x = curR;
1227:                    curColor.x /= 32768.0;
1228:                    curColor.y = curG;
1229:                    curColor.y /= 32768.0;
1230:                    curColor.z = curB;
1231:                    curColor.z /= 32768.0;
1232:
1233:                    if (doingAlpha) {
1234:                        curA = entry.a;
1235:                        curColor.w = curA;
1236:                        curColor.w /= 32768.0;
1237:                    }
1238:                    if (debug)
1239:                        System.err.println(" retrieved color " + curColor.x
1240:                                + " " + curColor.y + " " + curColor.z + " "
1241:                                + curColor.w);
1242:                }
1243:
1244:                // Reset meshState.
1245:                meshState = 0;
1246:            }
1247:
1248:            // Process a end-of-stream opcode.
1249:            private void processEos() {
1250:                if (debug)
1251:                    System.err.println("GeometryDecompressor.processEos");
1252:            }
1253:
1254:            // Process a variable length no-op opcode.
1255:            private void processVNoop() {
1256:                int ii, ct;
1257:                if (debug)
1258:                    System.err.println("GeometryDecompressor.processVNoop");
1259:
1260:                ct = getBits(5, "noop count");
1261:                ii = getBits(ct, "noop bits");
1262:            }
1263:
1264:            // Process a pass-through opcode.
1265:            private void processPassThrough() {
1266:                int ignore;
1267:                if (debug)
1268:                    System.err
1269:                            .println("GeometryDecompressor.processPassThrough");
1270:
1271:                ignore = getBits(24, "passthrough");
1272:                ignore = getBits(32, "passthrough");
1273:            }
1274:
1275:            // Process a skip-8 opcode.
1276:            private void processSkip8() {
1277:                int skip;
1278:                if (debug)
1279:                    System.err.println("GeometryDecompressor.processSkip8");
1280:
1281:                skip = getBits(8, "skip8");
1282:            }
1283:
1284:            private void benchmarkStart(int length) {
1285:                vertexCount = 0;
1286:                System.err.println(" GeometryDecompressor: decompressing "
1287:                        + length + " bytes...");
1288:                startTime = J3dClock.currentTimeMillis();
1289:            }
1290:
1291:            private void benchmarkPrint(int length) {
1292:                float t = (J3dClock.currentTimeMillis() - startTime) / 1000.0f;
1293:                System.err.println("  done in " + t + " sec." + "\n"
1294:                        + "  decompressed " + vertexCount + " vertices at "
1295:                        + (vertexCount / t) + " vertices/sec\n");
1296:
1297:                System.err.print("  vertex data present: coords");
1298:                int floatVertexSize = 12;
1299:                if (bundlingNorm) {
1300:                    System.err.print(" normals");
1301:                    floatVertexSize += 12;
1302:                }
1303:                if (bundlingColor) {
1304:                    System.err.println(" colors");
1305:                    floatVertexSize += 12;
1306:                }
1307:                if (doingAlpha) {
1308:                    System.err.println(" alpha");
1309:                    floatVertexSize += 4;
1310:                }
1311:                System.err.println();
1312:
1313:                System.err
1314:                        .println("  bytes of data in generalized strip output: "
1315:                                + (vertexCount * floatVertexSize)
1316:                                + "\n"
1317:                                + "  compression ratio: "
1318:                                + (length / (float) (vertexCount * floatVertexSize))
1319:                                + "\n");
1320:            }
1321:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.