Search in sources :

Example 1 with CombinedTexture

use of com.jme3.scene.plugins.blender.textures.CombinedTexture in project jmonkeyengine by jMonkeyEngine.

the class MaterialContext method applyMaterial.

/**
     * Applies material to a given geometry.
     * 
     * @param geometry
     *            the geometry
     * @param geometriesOMA
     *            the geometries OMA
     * @param userDefinedUVCoordinates
     *            UV coords defined by user
     * @param blenderContext
     *            the blender context
     */
public void applyMaterial(Geometry geometry, Long geometriesOMA, Map<String, List<Vector2f>> userDefinedUVCoordinates, BlenderContext blenderContext) {
    Material material = null;
    if (shadeless) {
        material = new Material(blenderContext.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
        if (!transparent) {
            diffuseColor.a = 1;
        }
        material.setColor("Color", diffuseColor);
    } else {
        material = new Material(blenderContext.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
        material.setBoolean("UseMaterialColors", Boolean.TRUE);
        // setting the colors
        if (!transparent) {
            diffuseColor.a = 1;
        }
        material.setColor("Diffuse", diffuseColor);
        material.setColor("Specular", specularColor);
        material.setFloat("Shininess", shininess);
        material.setColor("Ambient", new ColorRGBA(ambientFactor, ambientFactor, ambientFactor, 1f));
    }
    // applying textures
    int textureIndex = 0;
    if (loadedTextures != null && loadedTextures.size() > 0) {
        if (loadedTextures.size() > TextureHelper.TEXCOORD_TYPES.length) {
            LOGGER.log(Level.WARNING, "The blender file has defined more than {0} different textures. JME supports only {0} UV mappings.", TextureHelper.TEXCOORD_TYPES.length);
        }
        for (CombinedTexture combinedTexture : loadedTextures) {
            if (textureIndex < TextureHelper.TEXCOORD_TYPES.length) {
                String usedUserUVSet = combinedTexture.flatten(geometry, geometriesOMA, userDefinedUVCoordinates, blenderContext);
                this.setTexture(material, combinedTexture.getMappingType(), combinedTexture.getResultTexture());
                List<Vector2f> uvs = combinedTexture.getResultUVS();
                if (uvs != null && uvs.size() > 0) {
                    VertexBuffer uvCoordsBuffer = new VertexBuffer(TextureHelper.TEXCOORD_TYPES[textureIndex++]);
                    uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(uvs.toArray(new Vector2f[uvs.size()])));
                    geometry.getMesh().setBuffer(uvCoordsBuffer);
                }
                if (usedUserUVSet != null) {
                    userDefinedUVCoordinates = new HashMap<>(userDefinedUVCoordinates);
                    userDefinedUVCoordinates.remove(usedUserUVSet);
                }
            } else {
                LOGGER.log(Level.WARNING, "The texture could not be applied because JME only supports up to {0} different UV's.", TextureHelper.TEXCOORD_TYPES.length);
            }
        }
    }
    if (userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
        LOGGER.fine("Storing unused, user defined UV coordinates sets.");
        if (userDefinedUVCoordinates.size() > TextureHelper.TEXCOORD_TYPES.length) {
            LOGGER.log(Level.WARNING, "The blender file has defined more than {0} different UV coordinates for the mesh. JME supports only {0} UV coordinates buffers.", TextureHelper.TEXCOORD_TYPES.length);
        }
        for (Entry<String, List<Vector2f>> entry : userDefinedUVCoordinates.entrySet()) {
            if (textureIndex < TextureHelper.TEXCOORD_TYPES.length) {
                List<Vector2f> uvs = entry.getValue();
                VertexBuffer uvCoordsBuffer = new VertexBuffer(TextureHelper.TEXCOORD_TYPES[textureIndex++]);
                uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(uvs.toArray(new Vector2f[uvs.size()])));
                geometry.getMesh().setBuffer(uvCoordsBuffer);
            } else {
                LOGGER.log(Level.WARNING, "The user's UV set named: '{0}' could not be stored because JME only supports up to {1} different UV's.", new Object[] { entry.getKey(), TextureHelper.TEXCOORD_TYPES.length });
            }
        }
    }
    // applying additional data
    material.setName(name);
    if (vertexColor) {
        material.setBoolean(shadeless ? "VertexColor" : "UseVertexColor", true);
    }
    material.getAdditionalRenderState().setFaceCullMode(faceCullMode != null ? faceCullMode : blenderContext.getBlenderKey().getFaceCullMode());
    if (transparent) {
        material.setTransparent(true);
        material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
        geometry.setQueueBucket(Bucket.Transparent);
    }
    geometry.setMaterial(material);
}
Also used : ColorRGBA(com.jme3.math.ColorRGBA) VertexBuffer(com.jme3.scene.VertexBuffer) Vector2f(com.jme3.math.Vector2f) Material(com.jme3.material.Material) List(java.util.List) CombinedTexture(com.jme3.scene.plugins.blender.textures.CombinedTexture)

Example 2 with CombinedTexture

use of com.jme3.scene.plugins.blender.textures.CombinedTexture in project jmonkeyengine by jMonkeyEngine.

the class LandscapeHelper method toSky.

/**
     * Loads scene's sky. Sky can be plain or textured.
     * If no sky type is selected in blender then no sky is loaded.
     * @param worldStructure
     *            the world's structure
     * @return the scene's sky
     * @throws BlenderFileException
     *             blender exception is thrown when problems with blender file occur
     */
public Spatial toSky(Structure worldStructure) throws BlenderFileException {
    int skytype = ((Number) worldStructure.getFieldValue("skytype")).intValue();
    if (skytype == 0) {
        return null;
    }
    LOGGER.fine("Loading sky.");
    ColorRGBA horizontalColor = this.toBackgroundColor(worldStructure);
    float zenr = ((Number) worldStructure.getFieldValue("zenr")).floatValue();
    float zeng = ((Number) worldStructure.getFieldValue("zeng")).floatValue();
    float zenb = ((Number) worldStructure.getFieldValue("zenb")).floatValue();
    ColorRGBA zenithColor = new ColorRGBA(zenr, zeng, zenb, 1);
    // jutr for this case load generated textures wheather user had set it or not because those might be needed to properly load the sky
    boolean loadGeneratedTextures = blenderContext.getBlenderKey().isLoadGeneratedTextures();
    blenderContext.getBlenderKey().setLoadGeneratedTextures(true);
    TextureHelper textureHelper = blenderContext.getHelper(TextureHelper.class);
    List<CombinedTexture> loadedTextures = null;
    try {
        loadedTextures = textureHelper.readTextureData(worldStructure, new float[] { horizontalColor.r, horizontalColor.g, horizontalColor.b, horizontalColor.a }, true);
    } finally {
        blenderContext.getBlenderKey().setLoadGeneratedTextures(loadGeneratedTextures);
    }
    TextureCubeMap texture = null;
    if (loadedTextures != null && loadedTextures.size() > 0) {
        if (loadedTextures.size() > 1) {
            throw new IllegalStateException("There should be only one combined texture for sky!");
        }
        CombinedTexture combinedTexture = loadedTextures.get(0);
        texture = combinedTexture.generateSkyTexture(horizontalColor, zenithColor, blenderContext);
    } else {
        LOGGER.fine("Preparing colors for colorband.");
        int colorbandType = ColorBand.IPO_CARDINAL;
        List<ColorRGBA> colorbandColors = new ArrayList<ColorRGBA>(3);
        colorbandColors.add(horizontalColor);
        if ((skytype & SKYTYPE_BLEND) != 0) {
            if ((skytype & SKYTYPE_PAPER) != 0) {
                colorbandType = ColorBand.IPO_LINEAR;
            }
            if ((skytype & SKYTYPE_REAL) != 0) {
                colorbandColors.add(0, zenithColor);
            }
            colorbandColors.add(zenithColor);
        }
        int size = blenderContext.getBlenderKey().getSkyGeneratedTextureSize();
        List<Integer> positions = new ArrayList<Integer>(colorbandColors.size());
        positions.add(0);
        if (colorbandColors.size() == 2) {
            positions.add(size - 1);
        } else if (colorbandColors.size() == 3) {
            positions.add(size / 2);
            positions.add(size - 1);
        }
        LOGGER.fine("Generating sky texture.");
        float[][] values = new ColorBand(colorbandType, colorbandColors, positions, size).computeValues();
        Image image = ImageUtils.createEmptyImage(Format.RGB8, size, size, 6);
        PixelInputOutput pixelIO = PixelIOFactory.getPixelIO(image.getFormat());
        TexturePixel pixel = new TexturePixel();
        LOGGER.fine("Creating side textures.");
        int[] sideImagesIndexes = new int[] { 0, 1, 4, 5 };
        for (int i : sideImagesIndexes) {
            for (int y = 0; y < size; ++y) {
                pixel.red = values[y][0];
                pixel.green = values[y][1];
                pixel.blue = values[y][2];
                for (int x = 0; x < size; ++x) {
                    pixelIO.write(image, i, pixel, x, y);
                }
            }
        }
        LOGGER.fine("Creating top texture.");
        pixelIO.read(image, 0, pixel, 0, image.getHeight() - 1);
        for (int y = 0; y < size; ++y) {
            for (int x = 0; x < size; ++x) {
                pixelIO.write(image, 3, pixel, x, y);
            }
        }
        LOGGER.fine("Creating bottom texture.");
        pixelIO.read(image, 0, pixel, 0, 0);
        for (int y = 0; y < size; ++y) {
            for (int x = 0; x < size; ++x) {
                pixelIO.write(image, 2, pixel, x, y);
            }
        }
        texture = new TextureCubeMap(image);
    }
    LOGGER.fine("Sky texture created. Creating sky.");
    return SkyFactory.createSky(blenderContext.getAssetManager(), texture, SkyFactory.EnvMapType.CubeMap);
}
Also used : ColorBand(com.jme3.scene.plugins.blender.textures.ColorBand) ArrayList(java.util.ArrayList) Image(com.jme3.texture.Image) PixelInputOutput(com.jme3.scene.plugins.blender.textures.io.PixelInputOutput) ColorRGBA(com.jme3.math.ColorRGBA) TextureCubeMap(com.jme3.texture.TextureCubeMap) TextureHelper(com.jme3.scene.plugins.blender.textures.TextureHelper) TexturePixel(com.jme3.scene.plugins.blender.textures.TexturePixel) CombinedTexture(com.jme3.scene.plugins.blender.textures.CombinedTexture)

Example 3 with CombinedTexture

use of com.jme3.scene.plugins.blender.textures.CombinedTexture in project jmonkeyengine by jMonkeyEngine.

the class TextureHelper method readTextureData.

/**
     * Reads the texture data from the given material or sky structure.
     * @param structure
     *            the structure of material or sky
     * @param diffuseColorArray
     *            array of diffuse colors
     * @param skyTexture
     *            indicates it we're going to read sky texture or not
     * @return a list of combined textures
     * @throws BlenderFileException
     *             an exception is thrown when problems with reading the blend file occur
     */
@SuppressWarnings("unchecked")
public List<CombinedTexture> readTextureData(Structure structure, float[] diffuseColorArray, boolean skyTexture) throws BlenderFileException {
    DynamicArray<Pointer> mtexsArray = (DynamicArray<Pointer>) structure.getFieldValue("mtex");
    int separatedTextures = skyTexture ? 0 : ((Number) structure.getFieldValue("septex")).intValue();
    List<TextureData> texturesList = new ArrayList<TextureData>();
    for (int i = 0; i < mtexsArray.getTotalSize(); ++i) {
        Pointer p = mtexsArray.get(i);
        if (p.isNotNull() && (separatedTextures & 1 << i) == 0) {
            TextureData textureData = new TextureData();
            textureData.mtex = p.fetchData().get(0);
            textureData.uvCoordinatesType = skyTexture ? UVCoordinatesType.TEXCO_ORCO.blenderValue : ((Number) textureData.mtex.getFieldValue("texco")).intValue();
            textureData.projectionType = ((Number) textureData.mtex.getFieldValue("mapping")).intValue();
            textureData.uvCoordinatesName = textureData.mtex.getFieldValue("uvName").toString();
            if (textureData.uvCoordinatesName != null && textureData.uvCoordinatesName.trim().length() == 0) {
                textureData.uvCoordinatesName = null;
            }
            Pointer pTex = (Pointer) textureData.mtex.getFieldValue("tex");
            if (pTex.isNotNull()) {
                Structure tex = pTex.fetchData().get(0);
                textureData.textureStructure = tex;
                texturesList.add(textureData);
            }
        }
    }
    LOGGER.info("Loading model's textures.");
    List<CombinedTexture> loadedTextures = new ArrayList<CombinedTexture>();
    if (blenderContext.getBlenderKey().isOptimiseTextures()) {
        LOGGER.fine("Optimising the useage of model's textures.");
        Map<Number, List<TextureData>> textureDataMap = this.sortTextures(texturesList);
        for (Entry<Number, List<TextureData>> entry : textureDataMap.entrySet()) {
            if (entry.getValue().size() > 0) {
                CombinedTexture combinedTexture = new CombinedTexture(entry.getKey().intValue(), !skyTexture);
                for (TextureData textureData : entry.getValue()) {
                    int texflag = ((Number) textureData.mtex.getFieldValue("texflag")).intValue();
                    boolean negateTexture = (texflag & 0x04) != 0;
                    Texture texture = this.getTexture(textureData.textureStructure, textureData.mtex, blenderContext);
                    if (texture != null) {
                        int blendType = ((Number) textureData.mtex.getFieldValue("blendtype")).intValue();
                        float[] color = new float[] { ((Number) textureData.mtex.getFieldValue("r")).floatValue(), ((Number) textureData.mtex.getFieldValue("g")).floatValue(), ((Number) textureData.mtex.getFieldValue("b")).floatValue() };
                        float colfac = ((Number) textureData.mtex.getFieldValue("colfac")).floatValue();
                        TextureBlender textureBlender = TextureBlenderFactory.createTextureBlender(texture.getImage().getFormat(), texflag, negateTexture, blendType, diffuseColorArray, color, colfac);
                        combinedTexture.add(texture, textureBlender, textureData.uvCoordinatesType, textureData.projectionType, textureData.textureStructure, textureData.uvCoordinatesName, blenderContext);
                    }
                }
                if (combinedTexture.getTexturesCount() > 0) {
                    loadedTextures.add(combinedTexture);
                }
            }
        }
    } else {
        LOGGER.fine("No textures optimisation applied.");
        int[] mappings = new int[] { MaterialContext.MTEX_COL, MaterialContext.MTEX_NOR, MaterialContext.MTEX_EMIT, MaterialContext.MTEX_SPEC, MaterialContext.MTEX_ALPHA, MaterialContext.MTEX_AMB };
        for (TextureData textureData : texturesList) {
            Texture texture = this.getTexture(textureData.textureStructure, textureData.mtex, blenderContext);
            if (texture != null) {
                Number mapto = (Number) textureData.mtex.getFieldValue("mapto");
                int texflag = ((Number) textureData.mtex.getFieldValue("texflag")).intValue();
                boolean negateTexture = (texflag & 0x04) != 0;
                for (int i = 0; i < mappings.length; ++i) {
                    if ((mappings[i] & mapto.intValue()) != 0) {
                        CombinedTexture combinedTexture = new CombinedTexture(mappings[i], !skyTexture);
                        int blendType = ((Number) textureData.mtex.getFieldValue("blendtype")).intValue();
                        float[] color = new float[] { ((Number) textureData.mtex.getFieldValue("r")).floatValue(), ((Number) textureData.mtex.getFieldValue("g")).floatValue(), ((Number) textureData.mtex.getFieldValue("b")).floatValue() };
                        float colfac = ((Number) textureData.mtex.getFieldValue("colfac")).floatValue();
                        TextureBlender textureBlender = TextureBlenderFactory.createTextureBlender(texture.getImage().getFormat(), texflag, negateTexture, blendType, diffuseColorArray, color, colfac);
                        combinedTexture.add(texture, textureBlender, textureData.uvCoordinatesType, textureData.projectionType, textureData.textureStructure, textureData.uvCoordinatesName, blenderContext);
                        if (combinedTexture.getTexturesCount() > 0) {
                            // the added texture might not have been accepted (if for example loading generated textures is disabled)
                            loadedTextures.add(combinedTexture);
                        }
                    }
                }
            }
        }
    }
    return loadedTextures;
}
Also used : ArrayList(java.util.ArrayList) Pointer(com.jme3.scene.plugins.blender.file.Pointer) TextureBlender(com.jme3.scene.plugins.blender.textures.blending.TextureBlender) Texture(com.jme3.texture.Texture) DynamicArray(com.jme3.scene.plugins.blender.file.DynamicArray) ArrayList(java.util.ArrayList) List(java.util.List) Structure(com.jme3.scene.plugins.blender.file.Structure)

Aggregations

ColorRGBA (com.jme3.math.ColorRGBA)2 CombinedTexture (com.jme3.scene.plugins.blender.textures.CombinedTexture)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Material (com.jme3.material.Material)1 Vector2f (com.jme3.math.Vector2f)1 VertexBuffer (com.jme3.scene.VertexBuffer)1 DynamicArray (com.jme3.scene.plugins.blender.file.DynamicArray)1 Pointer (com.jme3.scene.plugins.blender.file.Pointer)1 Structure (com.jme3.scene.plugins.blender.file.Structure)1 ColorBand (com.jme3.scene.plugins.blender.textures.ColorBand)1 TextureHelper (com.jme3.scene.plugins.blender.textures.TextureHelper)1 TexturePixel (com.jme3.scene.plugins.blender.textures.TexturePixel)1 TextureBlender (com.jme3.scene.plugins.blender.textures.blending.TextureBlender)1 PixelInputOutput (com.jme3.scene.plugins.blender.textures.io.PixelInputOutput)1 Image (com.jme3.texture.Image)1 Texture (com.jme3.texture.Texture)1 TextureCubeMap (com.jme3.texture.TextureCubeMap)1