fr.def.iss.vd2.lib_v3d.v3draw.V3DrawReader.java Source code

Java tutorial

Introduction

Here is the source code for fr.def.iss.vd2.lib_v3d.v3draw.V3DrawReader.java

Source

// Copyright 2010 DEF
//
// This file is part of V3dScene.
//
// V3dScene is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// V3dScene is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with V3dScene.  If not, see <http://www.gnu.org/licenses/>.
package fr.def.iss.vd2.lib_v3d.v3draw;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.CRC32;

import javax.imageio.ImageIO;

import org.lwjgl.opengl.GL11;

import com.spaceagencies.i3d.scene.I3dCamera;

/**
 *
 * @author fberto
 */
public class V3DrawReader {

    final private ByteBuffer buffer;
    private float maxX;
    private float maxY;
    private float maxZ;
    private float minX;
    private float minY;
    private float minZ;
    private String version = "";
    private List<String> metadataList = new ArrayList<String>();
    private int commandListOffset;
    private int initCommandListOffset;
    private I3dCamera camera;
    private List<Tesselation> concavePolygonList = new ArrayList<Tesselation>();
    //    private List<TextureHandler> textureList = new ArrayList<TextureHandler>();

    public V3DrawReader(ByteBuffer buffer) throws V3DrawBadFormatError {
        this.buffer = buffer;
        checkIntegrity();
        load();
    }

    private void checkIntegrity() throws V3DrawBadFormatError {
        // Prepare the buffer for reading
        buffer.clear();

        String magicNumber = "";
        for (int i = 0; i < 8; i++) {
            byte c = buffer.get();
            magicNumber += Character.valueOf((char) c);
        }
        if (!magicNumber.equals("V3Draw  ")) {
            throw new V3DrawBadFormatError("Magic number is '" + magicNumber + "' but 'V3Draw' is expected.");
        }
        int crc = buffer.getInt();

        byte[] digest = new byte[buffer.remaining()];
        buffer.get(digest);
        int computedCRC = computeCRC(digest);

        if (computedCRC != crc) {
            throw new V3DrawBadFormatError("CRC in file is '" + Integer.toHexString(crc) + "' but computed CRC is "
                    + Integer.toHexString(computedCRC) + ".");
        }
    }

    private int computeCRC(byte[] digest) {
        CRC32 crc = new CRC32();
        crc.update(digest);
        return (int) crc.getValue();
    }

    private void load() {

        // Prepare the buffer for reading
        buffer.clear();

        // Skip Magic number and CRC
        buffer.position(buffer.position() + 12);

        int headerLenght = buffer.getInt();

        // Read version
        version = readString(buffer);

        // Read metadata
        int metadataCount = buffer.getInt();

        for (int i = 0; i < metadataCount; i++) {
            metadataList.add(readString(buffer));
        }
        // Read bound
        minX = buffer.getFloat();
        maxX = buffer.getFloat();
        minY = buffer.getFloat();
        maxY = buffer.getFloat();
        minZ = buffer.getFloat();
        maxZ = buffer.getFloat();

        int bodyLenght = buffer.getInt();
        int commandListLenght = buffer.getInt();

        buffer.position(buffer.position() + commandListLenght);

        // 24 = 12 + headerSize size + body size size + commandListSize
        commandListOffset = 24 + headerLenght;

        // 4 = size of init command list
        initCommandListOffset = commandListOffset + commandListLenght + 4;
    }

    public void init() {
        // Skip header and command list
        buffer.position(initCommandListOffset);

        int commandCount = buffer.getInt();

        for (int i = 0; i < commandCount; i++) {

            int commandCode = buffer.getInt();
            int commandSize = buffer.getInt();

            switch (commandCode) {
            case V3DrawSpec.REGISTER_3D__CONCAVE_POLYGON:
                register3dConcavePolygon();
                break;
            case V3DrawSpec.REGISTER_TEXTURE:
                registerTexture();
                break;
            default:
                System.err.println("Warning: Unimplemented init command code '" + commandCode + "'");
                // Consume command
                buffer.position(buffer.position() + commandSize);
            }
        }
    }

    public float getMaxX() {
        return maxX;
    }

    public float getMaxY() {
        return maxY;
    }

    public float getMinX() {
        return minX;
    }

    public float getMinY() {
        return minY;
    }

    public float getMinZ() {
        return minZ;
    }

    public float getMaxZ() {
        return maxZ;
    }

    public static class V3DrawBadFormatError extends Exception {

        public V3DrawBadFormatError(String message) {
            super(message);
        }
    }

    private String readString(ByteBuffer buffer) {
        int lenght = buffer.getInt();
        byte[] bytes = new byte[lenght];

        buffer.get(bytes);

        return new String(bytes);
    }

    public List<String> getMetadataList() {
        return metadataList;
    }

    public String getVersion() {
        return version;
    }

    public void draw(I3dCamera camera) {
        this.camera = camera;

        // Prepare the buffer for reading
        buffer.clear();

        // Skip header
        buffer.position(commandListOffset);

        int commandCount = buffer.getInt();

        for (int i = 0; i < commandCount; i++) {

            int commandCode = buffer.getInt();
            int commandSize = buffer.getInt();

            switch (commandCode) {
            case V3DrawSpec.DRAW_2D_LINE_STRIP_LIST:
                draw2dLineStripList();
                break;
            case V3DrawSpec.DRAW_3D_QUAD_LIST:
                draw3dQuadList();
                break;
            case V3DrawSpec.DRAW_3D_TRIANGLE_LIST:
                draw3dTriangleList();
                break;
            case V3DrawSpec.DRAW_3D_POLYGON_LIST:
                draw3dPolygonList();
                break;
            case V3DrawSpec.DRAW_REGISTRATED_3D_CONCAVE_POLYGON:
                drawRegistrated3dConcavePolygon();
                break;
            case V3DrawSpec.ENABLE_TEXTURE:
                enableTexture();
                break;
            case V3DrawSpec.DISABLE_TEXTURE:
                disableTexture();
                break;
            case V3DrawSpec.SET_LINE_THICKNESS:
                setLineThickness();
                break;
            case V3DrawSpec.SET_POINT_THICKNESS:
                setPointThickness();
                break;
            default:
                System.err.println("Warning: Unimplemented command code '" + commandCode + "'");

                // Consume command
                buffer.position(buffer.position() + commandSize);
            }
        }
    }

    private void draw2dLineStripList() {
        int lineCount = buffer.getInt();

        for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) {
            int lineLenght = buffer.getInt();
            GL11.glBegin(GL11.GL_LINE_STRIP); // Draw line
            for (int j = 0; j < lineLenght; j++) {
                GL11.glVertex3f(buffer.getFloat(), buffer.getFloat(), 0.0f);
            }
            GL11.glEnd();
        }
    }

    private void draw3dQuadList() {
        int quadCount = buffer.getInt();
        GL11.glBegin(GL11.GL_QUADS);

        for (int quadIndex = 0; quadIndex < quadCount; quadIndex++) {
            for (int i = 0; i < 4; i++) {
                GL11.glTexCoord2f(buffer.getFloat(), buffer.getFloat());
                GL11.glNormal3f(buffer.getFloat(), buffer.getFloat(), buffer.getFloat());
                GL11.glVertex3f(buffer.getFloat(), buffer.getFloat(), buffer.getFloat());

            }
        }
        GL11.glEnd();
    }

    private void draw3dTriangleList() {
        int triangleCount = buffer.getInt();

        GL11.glBegin(GL11.GL_TRIANGLES);
        for (int triangleIndex = 0; triangleIndex < triangleCount; triangleIndex++) {

            for (int i = 0; i < 3; i++) {
                GL11.glTexCoord2f(buffer.getFloat(), buffer.getFloat());
                GL11.glNormal3f(buffer.getFloat(), buffer.getFloat(), buffer.getFloat());
                GL11.glVertex3f(buffer.getFloat(), buffer.getFloat(), buffer.getFloat());
            }
        }
        GL11.glEnd();
    }

    private void draw3dPolygonList() {
        int polygonCount = buffer.getInt();

        for (int polygonIndex = 0; polygonIndex < polygonCount; polygonIndex++) {
            GL11.glBegin(GL11.GL_POLYGON);
            int vertexCount = buffer.getInt();
            for (int i = 0; i < vertexCount; i++) {
                GL11.glTexCoord2f(buffer.getFloat(), buffer.getFloat());
                GL11.glNormal3f(buffer.getFloat(), buffer.getFloat(), buffer.getFloat());
                GL11.glVertex3f(buffer.getFloat(), buffer.getFloat(), buffer.getFloat());
            }
            GL11.glEnd();
        }
    }

    private void register3dConcavePolygon() {
        Tesselator tesselator = new Tesselator();

        tesselator.begin();

        int vertexCount = buffer.getInt();
        for (int i = 0; i < vertexCount; i++) {
            tesselator.addVertex(new V3DrawVertex(buffer));
        }
        tesselator.end();

        concavePolygonList.add(tesselator.getResult());

        tesselator.delete();
    }

    private void registerTexture() {
        int dataLenght = buffer.getInt();

        byte[] imageBuffer = new byte[dataLenght];
        buffer.get(imageBuffer);

        BufferedImage image = null;
        try {
            image = ImageIO.read(new ByteArrayInputStream(imageBuffer));
        } catch (IOException e) {
            return;
        }
        //        TextureHandler texture = new TextureHandler(image);

        //        textureList.add(texture);
    }

    private void drawRegistrated3dConcavePolygon() {
        int polygonIndex = buffer.getInt();
        Tesselation tesselation = concavePolygonList.get(polygonIndex);

        List<Integer> vertexTypeList = tesselation.getVertexTypeList();

        for (int i = 0; i < vertexTypeList.size(); i++) {

            List<V3DrawVertex> vertexList = tesselation.getVertexListList().get(i);

            GL11.glBegin(vertexTypeList.get(i));
            for (V3DrawVertex vertex : vertexList) {
                GL11.glTexCoord2f(vertex.texture.x, vertex.texture.y);
                GL11.glNormal3f(vertex.normal.x, vertex.normal.y, vertex.normal.z);
                GL11.glVertex3f(vertex.position.x, vertex.position.y, vertex.position.z);
            }
            GL11.glEnd();
        }
    }

    private void enableTexture() {
        int textureIndex = buffer.getInt();

        GL11.glEnable(GL11.GL_TEXTURE_2D);

        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
        GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);

        GL11.glAlphaFunc(GL11.GL_GREATER, 0.1f);
        GL11.glEnable(GL11.GL_ALPHA_TEST);

        //        GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureList.get(textureIndex).getID());
    }

    private void disableTexture() {
        GL11.glDisable(GL11.GL_ALPHA_TEST);
        GL11.glDisable(GL11.GL_TEXTURE_2D);
    }

    private void setLineThickness() {
        float thickness = buffer.getFloat();
        GL11.glLineWidth(thickness);
        // System.err.println("glLineWidth " + thickness);
    }

    private void setPointThickness() {
        float thickness = buffer.getFloat();
        GL11.glPointSize(thickness);
        // System.err.println("glPointSize " + thickness);
    }
}