Search in sources :

Example 21 with Entry

use of com.jme3.util.IntMap.Entry in project jmonkeyengine by jMonkeyEngine.

the class SubdivisionSurfaceModifier method computeFaceUVs.

/**
     * The method computes the UV coordinates of the face middle point.
     * @param face
     *            the face of the mesh
     * @return a map whose key is the name of the UV set and value is the UV coordinate of the face's middle point
     */
private Map<String, Vector2f> computeFaceUVs(Face face) {
    Map<String, Vector2f> result = null;
    Map<String, List<Vector2f>> uvSets = face.getUvSets();
    if (uvSets != null && uvSets.size() > 0) {
        result = new HashMap<String, Vector2f>(uvSets.size());
        for (Entry<String, List<Vector2f>> entry : uvSets.entrySet()) {
            Vector2f faceUV = new Vector2f();
            for (Vector2f uv : entry.getValue()) {
                faceUV.addLocal(uv);
            }
            faceUV.divideLocal(entry.getValue().size());
            result.put(entry.getKey(), faceUV);
        }
    }
    return result;
}
Also used : Vector2f(com.jme3.math.Vector2f) ArrayList(java.util.ArrayList) List(java.util.List)

Example 22 with Entry

use of com.jme3.util.IntMap.Entry in project jmonkeyengine by jMonkeyEngine.

the class EmitterMeshVertexShape method setMeshes.

/**
     * This method sets the meshes that will form the emiter's shape.
     * @param meshes
     *        a list of meshes that will form the emitter's shape
     */
public void setMeshes(List<Mesh> meshes) {
    Map<Vector3f, Vector3f> vertToNormalMap = new HashMap<Vector3f, Vector3f>();
    this.vertices = new ArrayList<List<Vector3f>>(meshes.size());
    this.normals = new ArrayList<List<Vector3f>>(meshes.size());
    for (Mesh mesh : meshes) {
        // fetching the data
        float[] vertexTable = BufferUtils.getFloatArray(mesh.getFloatBuffer(Type.Position));
        float[] normalTable = BufferUtils.getFloatArray(mesh.getFloatBuffer(Type.Normal));
        // unifying normals
        for (int i = 0; i < vertexTable.length; i += 3) {
            // the tables should have the same size and be dividable by 3
            Vector3f vert = new Vector3f(vertexTable[i], vertexTable[i + 1], vertexTable[i + 2]);
            Vector3f norm = vertToNormalMap.get(vert);
            if (norm == null) {
                norm = new Vector3f(normalTable[i], normalTable[i + 1], normalTable[i + 2]);
                vertToNormalMap.put(vert, norm);
            } else {
                norm.addLocal(normalTable[i], normalTable[i + 1], normalTable[i + 2]);
            }
        }
        // adding data to vertices and normals
        List<Vector3f> vertices = new ArrayList<Vector3f>(vertToNormalMap.size());
        List<Vector3f> normals = new ArrayList<Vector3f>(vertToNormalMap.size());
        for (Entry<Vector3f, Vector3f> entry : vertToNormalMap.entrySet()) {
            vertices.add(entry.getKey());
            normals.add(entry.getValue().normalizeLocal());
        }
        this.vertices.add(vertices);
        this.normals.add(normals);
    }
}
Also used : HashMap(java.util.HashMap) Vector3f(com.jme3.math.Vector3f) ArrayList(java.util.ArrayList) Mesh(com.jme3.scene.Mesh) ArrayList(java.util.ArrayList) List(java.util.List)

Example 23 with Entry

use of com.jme3.util.IntMap.Entry in project jmonkeyengine by jMonkeyEngine.

the class TGALoader method load.

/**
     * <code>loadImage</code> is a manual image loader which is entirely
     * independent of AWT. OUT: RGB888 or RGBA8888 Image object
     * 
     * 
    
     * @param in
     *            InputStream of an uncompressed 24b RGB or 32b RGBA TGA
     * @param flip
     *            Flip the image vertically
     * @return <code>Image</code> object that contains the
     *         image, either as a RGB888 or RGBA8888
     * @throws java.io.IOException
     */
public static Image load(InputStream in, boolean flip) throws IOException {
    boolean flipH = false;
    // open a stream to the file
    DataInputStream dis = new DataInputStream(new BufferedInputStream(in));
    // ---------- Start Reading the TGA header ---------- //
    // length of the image id (1 byte)
    int idLength = dis.readUnsignedByte();
    // Type of color map (if any) included with the image
    // 0 - no color map data is included
    // 1 - a color map is included
    int colorMapType = dis.readUnsignedByte();
    // Type of image being read:
    int imageType = dis.readUnsignedByte();
    // Read Color Map Specification (5 bytes)
    // Index of first color map entry (if we want to use it, uncomment and remove extra read.)
    //        short cMapStart = flipEndian(dis.readShort());
    dis.readShort();
    // number of entries in the color map
    short cMapLength = flipEndian(dis.readShort());
    // number of bits per color map entry
    int cMapDepth = dis.readUnsignedByte();
    // Read Image Specification (10 bytes)
    // horizontal coordinate of lower left corner of image. (if we want to use it, uncomment and remove extra read.)
    //        int xOffset = flipEndian(dis.readShort());
    dis.readShort();
    // vertical coordinate of lower left corner of image. (if we want to use it, uncomment and remove extra read.)
    //        int yOffset = flipEndian(dis.readShort());
    dis.readShort();
    // width of image - in pixels
    int width = flipEndian(dis.readShort());
    // height of image - in pixels
    int height = flipEndian(dis.readShort());
    // bits per pixel in image.
    int pixelDepth = dis.readUnsignedByte();
    int imageDescriptor = dis.readUnsignedByte();
    if (// bit 5 : if 1, flip top/bottom ordering
    (imageDescriptor & 32) != 0) {
        flip = !flip;
    }
    if (// bit 4 : if 1, flip left/right ordering
    (imageDescriptor & 16) != 0) {
        flipH = !flipH;
    }
    // Skip image ID
    if (idLength > 0) {
        dis.skip(idLength);
    }
    ColorMapEntry[] cMapEntries = null;
    if (colorMapType != 0) {
        // read the color map.
        int bytesInColorMap = (cMapDepth * cMapLength) >> 3;
        int bitsPerColor = Math.min(cMapDepth / 3, 8);
        byte[] cMapData = new byte[bytesInColorMap];
        dis.read(cMapData);
        // table if this is declared a color mapped image.
        if (imageType == TYPE_COLORMAPPED || imageType == TYPE_COLORMAPPED_RLE) {
            cMapEntries = new ColorMapEntry[cMapLength];
            int alphaSize = cMapDepth - (3 * bitsPerColor);
            float scalar = 255f / (FastMath.pow(2, bitsPerColor) - 1);
            float alphaScalar = 255f / (FastMath.pow(2, alphaSize) - 1);
            for (int i = 0; i < cMapLength; i++) {
                ColorMapEntry entry = new ColorMapEntry();
                int offset = cMapDepth * i;
                entry.red = (byte) (int) (getBitsAsByte(cMapData, offset, bitsPerColor) * scalar);
                entry.green = (byte) (int) (getBitsAsByte(cMapData, offset + bitsPerColor, bitsPerColor) * scalar);
                entry.blue = (byte) (int) (getBitsAsByte(cMapData, offset + (2 * bitsPerColor), bitsPerColor) * scalar);
                if (alphaSize <= 0) {
                    entry.alpha = (byte) 255;
                } else {
                    entry.alpha = (byte) (int) (getBitsAsByte(cMapData, offset + (3 * bitsPerColor), alphaSize) * alphaScalar);
                }
                cMapEntries[i] = entry;
            }
        }
    }
    // Allocate image data array
    Format format;
    byte[] rawData = null;
    int dl;
    if (pixelDepth == 32) {
        rawData = new byte[width * height * 4];
        dl = 4;
    } else {
        rawData = new byte[width * height * 3];
        dl = 3;
    }
    int rawDataIndex = 0;
    if (imageType == TYPE_TRUECOLOR) {
        byte red = 0;
        byte green = 0;
        byte blue = 0;
        byte alpha = 0;
        // just make a seperate loop for each.
        if (pixelDepth == 16) {
            byte[] data = new byte[2];
            float scalar = 255f / 31f;
            for (int i = 0; i <= (height - 1); i++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; j++) {
                    data[1] = dis.readByte();
                    data[0] = dis.readByte();
                    rawData[rawDataIndex++] = (byte) (int) (getBitsAsByte(data, 1, 5) * scalar);
                    rawData[rawDataIndex++] = (byte) (int) (getBitsAsByte(data, 6, 5) * scalar);
                    rawData[rawDataIndex++] = (byte) (int) (getBitsAsByte(data, 11, 5) * scalar);
                    if (dl == 4) {
                        // create an alpha channel
                        alpha = getBitsAsByte(data, 0, 1);
                        if (alpha == 1) {
                            alpha = (byte) 255;
                        }
                        rawData[rawDataIndex++] = alpha;
                    }
                }
            }
            format = dl == 4 ? Format.RGBA8 : Format.RGB8;
        } else if (pixelDepth == 24) {
            for (int y = 0; y < height; y++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - y) * width * dl;
                } else {
                    rawDataIndex = y * width * dl;
                }
                dis.readFully(rawData, rawDataIndex, width * dl);
            //                    for (int x = 0; x < width; x++) {
            //read scanline
            //                        blue = dis.readByte();
            //                        green = dis.readByte();
            //                        red = dis.readByte();
            //                        rawData[rawDataIndex++] = red;
            //                        rawData[rawDataIndex++] = green;
            //                        rawData[rawDataIndex++] = blue;
            //                    }
            }
            format = Format.BGR8;
        } else if (pixelDepth == 32) {
            for (int i = 0; i <= (height - 1); i++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; j++) {
                    blue = dis.readByte();
                    green = dis.readByte();
                    red = dis.readByte();
                    alpha = dis.readByte();
                    rawData[rawDataIndex++] = red;
                    rawData[rawDataIndex++] = green;
                    rawData[rawDataIndex++] = blue;
                    rawData[rawDataIndex++] = alpha;
                }
            }
            format = Format.RGBA8;
        } else {
            throw new IOException("Unsupported TGA true color depth: " + pixelDepth);
        }
    } else if (imageType == TYPE_TRUECOLOR_RLE) {
        byte red = 0;
        byte green = 0;
        byte blue = 0;
        byte alpha = 0;
        // just make a seperate loop for each.
        if (pixelDepth == 32) {
            for (int i = 0; i <= (height - 1); ++i) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; ++j) {
                    // Get the number of pixels the next chunk covers (either packed or unpacked)
                    int count = dis.readByte();
                    if ((count & 0x80) != 0) {
                        // Its an RLE packed block - use the following 1 pixel for the next <count> pixels
                        count &= 0x07f;
                        j += count;
                        blue = dis.readByte();
                        green = dis.readByte();
                        red = dis.readByte();
                        alpha = dis.readByte();
                        while (count-- >= 0) {
                            rawData[rawDataIndex++] = red;
                            rawData[rawDataIndex++] = green;
                            rawData[rawDataIndex++] = blue;
                            rawData[rawDataIndex++] = alpha;
                        }
                    } else {
                        // Its not RLE packed, but the next <count> pixels are raw.
                        j += count;
                        while (count-- >= 0) {
                            blue = dis.readByte();
                            green = dis.readByte();
                            red = dis.readByte();
                            alpha = dis.readByte();
                            rawData[rawDataIndex++] = red;
                            rawData[rawDataIndex++] = green;
                            rawData[rawDataIndex++] = blue;
                            rawData[rawDataIndex++] = alpha;
                        }
                    }
                }
            }
            format = Format.RGBA8;
        } else if (pixelDepth == 24) {
            for (int i = 0; i <= (height - 1); i++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; ++j) {
                    // Get the number of pixels the next chunk covers (either packed or unpacked)
                    int count = dis.readByte();
                    if ((count & 0x80) != 0) {
                        // Its an RLE packed block - use the following 1 pixel for the next <count> pixels
                        count &= 0x07f;
                        j += count;
                        blue = dis.readByte();
                        green = dis.readByte();
                        red = dis.readByte();
                        while (count-- >= 0) {
                            rawData[rawDataIndex++] = red;
                            rawData[rawDataIndex++] = green;
                            rawData[rawDataIndex++] = blue;
                        }
                    } else {
                        // Its not RLE packed, but the next <count> pixels are raw.
                        j += count;
                        while (count-- >= 0) {
                            blue = dis.readByte();
                            green = dis.readByte();
                            red = dis.readByte();
                            rawData[rawDataIndex++] = red;
                            rawData[rawDataIndex++] = green;
                            rawData[rawDataIndex++] = blue;
                        }
                    }
                }
            }
            format = Format.RGB8;
        } else if (pixelDepth == 16) {
            byte[] data = new byte[2];
            float scalar = 255f / 31f;
            for (int i = 0; i <= (height - 1); i++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; j++) {
                    // Get the number of pixels the next chunk covers (either packed or unpacked)
                    int count = dis.readByte();
                    if ((count & 0x80) != 0) {
                        // Its an RLE packed block - use the following 1 pixel for the next <count> pixels
                        count &= 0x07f;
                        j += count;
                        data[1] = dis.readByte();
                        data[0] = dis.readByte();
                        blue = (byte) (int) (getBitsAsByte(data, 1, 5) * scalar);
                        green = (byte) (int) (getBitsAsByte(data, 6, 5) * scalar);
                        red = (byte) (int) (getBitsAsByte(data, 11, 5) * scalar);
                        while (count-- >= 0) {
                            rawData[rawDataIndex++] = red;
                            rawData[rawDataIndex++] = green;
                            rawData[rawDataIndex++] = blue;
                        }
                    } else {
                        // Its not RLE packed, but the next <count> pixels are raw.
                        j += count;
                        while (count-- >= 0) {
                            data[1] = dis.readByte();
                            data[0] = dis.readByte();
                            blue = (byte) (int) (getBitsAsByte(data, 1, 5) * scalar);
                            green = (byte) (int) (getBitsAsByte(data, 6, 5) * scalar);
                            red = (byte) (int) (getBitsAsByte(data, 11, 5) * scalar);
                            rawData[rawDataIndex++] = red;
                            rawData[rawDataIndex++] = green;
                            rawData[rawDataIndex++] = blue;
                        }
                    }
                }
            }
            format = Format.RGB8;
        } else {
            throw new IOException("Unsupported TGA true color depth: " + pixelDepth);
        }
    } else if (imageType == TYPE_COLORMAPPED) {
        int bytesPerIndex = pixelDepth / 8;
        if (bytesPerIndex == 1) {
            for (int i = 0; i <= (height - 1); i++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; j++) {
                    int index = dis.readUnsignedByte();
                    if (index >= cMapEntries.length || index < 0) {
                        throw new IOException("TGA: Invalid color map entry referenced: " + index);
                    }
                    ColorMapEntry entry = cMapEntries[index];
                    rawData[rawDataIndex++] = entry.blue;
                    rawData[rawDataIndex++] = entry.green;
                    rawData[rawDataIndex++] = entry.red;
                    if (dl == 4) {
                        rawData[rawDataIndex++] = entry.alpha;
                    }
                }
            }
        } else if (bytesPerIndex == 2) {
            for (int i = 0; i <= (height - 1); i++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; j++) {
                    int index = flipEndian(dis.readShort());
                    if (index >= cMapEntries.length || index < 0) {
                        throw new IOException("TGA: Invalid color map entry referenced: " + index);
                    }
                    ColorMapEntry entry = cMapEntries[index];
                    rawData[rawDataIndex++] = entry.blue;
                    rawData[rawDataIndex++] = entry.green;
                    rawData[rawDataIndex++] = entry.red;
                    if (dl == 4) {
                        rawData[rawDataIndex++] = entry.alpha;
                    }
                }
            }
        } else {
            throw new IOException("TGA: unknown colormap indexing size used: " + bytesPerIndex);
        }
        format = dl == 4 ? Format.RGBA8 : Format.RGB8;
    } else {
        throw new IOException("Monochrome and RLE colormapped images are not supported");
    }
    in.close();
    // Get a pointer to the image memory
    ByteBuffer scratch = BufferUtils.createByteBuffer(rawData.length);
    scratch.clear();
    scratch.put(rawData);
    scratch.rewind();
    // Create the Image object
    Image textureImage = new Image();
    textureImage.setFormat(format);
    textureImage.setWidth(width);
    textureImage.setHeight(height);
    textureImage.setData(scratch);
    return textureImage;
}
Also used : IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) Image(com.jme3.texture.Image) ByteBuffer(java.nio.ByteBuffer) Format(com.jme3.texture.Image.Format) BufferedInputStream(java.io.BufferedInputStream)

Example 24 with Entry

use of com.jme3.util.IntMap.Entry in project jmonkeyengine by jMonkeyEngine.

the class GeometryBatchFactory method makeBatches.

/**
     * Batches a collection of Geometries so that all with the same material get combined.
     * @param geometries The Geometries to combine
     * @return A List of newly created Geometries, each with a  distinct material
     */
public static List<Geometry> makeBatches(Collection<Geometry> geometries, boolean useLods) {
    ArrayList<Geometry> retVal = new ArrayList<Geometry>();
    HashMap<Material, List<Geometry>> matToGeom = new HashMap<Material, List<Geometry>>();
    for (Geometry geom : geometries) {
        List<Geometry> outList = matToGeom.get(geom.getMaterial());
        if (outList == null) {
            //trying to compare materials with the contentEquals method 
            for (Material mat : matToGeom.keySet()) {
                if (geom.getMaterial().contentEquals(mat)) {
                    outList = matToGeom.get(mat);
                }
            }
        }
        if (outList == null) {
            outList = new ArrayList<Geometry>();
            matToGeom.put(geom.getMaterial(), outList);
        }
        outList.add(geom);
    }
    int batchNum = 0;
    for (Map.Entry<Material, List<Geometry>> entry : matToGeom.entrySet()) {
        Material mat = entry.getKey();
        List<Geometry> geomsForMat = entry.getValue();
        Mesh mesh = new Mesh();
        mergeGeometries(geomsForMat, mesh);
        // lods
        if (useLods) {
            makeLods(geomsForMat, mesh);
        }
        mesh.updateCounts();
        Geometry out = new Geometry("batch[" + (batchNum++) + "]", mesh);
        out.setMaterial(mat);
        out.updateModelBound();
        retVal.add(out);
    }
    return retVal;
}
Also used : Material(com.jme3.material.Material)

Example 25 with Entry

use of com.jme3.util.IntMap.Entry in project jmonkeyengine by jMonkeyEngine.

the class TestAndroidSensors method onAction.

public void onAction(String string, boolean pressed, float tpf) {
    if (string.equalsIgnoreCase("MouseClick") && pressed) {
        // is a sensor joystick axis
        for (IntMap.Entry<Joystick> entry : joystickMap) {
            for (JoystickAxis axis : entry.getValue().getAxes()) {
                if (axis instanceof SensorJoystickAxis) {
                    logger.log(Level.INFO, "Calibrating Axis: {0}", axis.toString());
                    ((SensorJoystickAxis) axis).calibrateCenter();
                }
            }
        }
        if (enableRumble) {
            // manipulate joystick rumble
            for (IntMap.Entry<Joystick> entry : joystickMap) {
                rumbleAmount += 0.1f;
                if (rumbleAmount > 1f + FastMath.ZERO_TOLERANCE) {
                    rumbleAmount = 0f;
                }
                logger.log(Level.INFO, "rumbling with amount: {0}", rumbleAmount);
                entry.getValue().rumble(rumbleAmount);
            }
        }
    }
}
Also used : Joystick(com.jme3.input.Joystick) SensorJoystickAxis(com.jme3.input.SensorJoystickAxis) IntMap(com.jme3.util.IntMap) SensorJoystickAxis(com.jme3.input.SensorJoystickAxis) JoystickAxis(com.jme3.input.JoystickAxis)

Aggregations

HashMap (java.util.HashMap)17 Map (java.util.Map)13 ArrayList (java.util.ArrayList)11 List (java.util.List)11 Vector2f (com.jme3.math.Vector2f)8 Vector3f (com.jme3.math.Vector3f)7 Node (com.jme3.scene.Node)6 Spatial (com.jme3.scene.Spatial)6 VertexBuffer (com.jme3.scene.VertexBuffer)5 Material (com.jme3.material.Material)4 FloatBuffer (java.nio.FloatBuffer)4 Bone (com.jme3.animation.Bone)3 Geometry (com.jme3.scene.Geometry)3 Mesh (com.jme3.scene.Mesh)3 Pointer (com.jme3.scene.plugins.blender.file.Pointer)3 Structure (com.jme3.scene.plugins.blender.file.Structure)3 Face (com.jme3.scene.plugins.blender.meshes.Face)3 Image (com.jme3.texture.Image)3 IntMap (com.jme3.util.IntMap)3 ByteBuffer (java.nio.ByteBuffer)3