Search in sources :

Example 1 with UVCoordinatesType

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

the class GeneratedTexture method triangulate.

/**
     * This method triangulates the texture. In the result we get a set of small
     * flat textures for each face of the given mesh. This can be later merged
     * into one flat texture.
     * 
     * @param mesh
     *            the mesh we create the texture for
     * @param geometriesOMA
     *            the old memory address of the geometries group that the given
     *            mesh belongs to (required for bounding box calculations)
     * @param coordinatesType
     *            the types of UV coordinates
     * @param blenderContext
     *            the blender context
     * @return triangulated texture
     */
public TriangulatedTexture triangulate(Mesh mesh, Long geometriesOMA, UVCoordinatesType coordinatesType, BlenderContext blenderContext) {
    TemporalMesh geometries = (TemporalMesh) blenderContext.getLoadedFeature(geometriesOMA, LoadedDataType.TEMPORAL_MESH);
    int[] coordinatesSwappingIndexes = new int[] { ((Number) mTex.getFieldValue("projx")).intValue(), ((Number) mTex.getFieldValue("projy")).intValue(), ((Number) mTex.getFieldValue("projz")).intValue() };
    List<Vector3f> uvs = UVCoordinatesGenerator.generateUVCoordinatesFor3DTexture(mesh, coordinatesType, coordinatesSwappingIndexes, geometries);
    Vector3f[] uvsArray = uvs.toArray(new Vector3f[uvs.size()]);
    BoundingBox boundingBox = UVCoordinatesGenerator.getBoundingBox(geometries);
    Set<TriangleTextureElement> triangleTextureElements = new TreeSet<TriangleTextureElement>(new Comparator<TriangleTextureElement>() {

        public int compare(TriangleTextureElement o1, TriangleTextureElement o2) {
            return o1.faceIndex - o2.faceIndex;
        }
    });
    int[] indices = new int[3];
    for (int i = 0; i < mesh.getTriangleCount(); ++i) {
        mesh.getTriangle(i, indices);
        triangleTextureElements.add(new TriangleTextureElement(i, boundingBox, this, uvsArray, indices, blenderContext));
    }
    return new TriangulatedTexture(triangleTextureElements, blenderContext);
}
Also used : TriangleTextureElement(com.jme3.scene.plugins.blender.textures.TriangulatedTexture.TriangleTextureElement) TemporalMesh(com.jme3.scene.plugins.blender.meshes.TemporalMesh) TreeSet(java.util.TreeSet) Vector3f(com.jme3.math.Vector3f) BoundingBox(com.jme3.bounding.BoundingBox)

Example 2 with UVCoordinatesType

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

the class CombinedTexture method flatten.

/**
	 * This method flattens the texture and creates a single result of Texture2D
	 * type.
	 * 
	 * @param geometry
	 *            the geometry the texture is created for
	 * @param geometriesOMA
	 *            the old memory address of the geometries list that the given
	 *            geometry belongs to (needed for bounding box creation)
	 * @param userDefinedUVCoordinates
	 *            the UV's defined by user (null or zero length table if none
	 *            were defined)
	 * @param blenderContext
	 *            the blender context
	 * @return the name of the user UV coordinates used (null if the UV's were
	 *         generated)
	 */
public String flatten(Geometry geometry, Long geometriesOMA, Map<String, List<Vector2f>> userDefinedUVCoordinates, BlenderContext blenderContext) {
    Mesh mesh = geometry.getMesh();
    Texture previousTexture = null;
    UVCoordinatesType masterUVCoordinatesType = null;
    String masterUserUVSetName = null;
    for (TextureData textureData : textureDatas) {
        // decompress compressed textures (all will be merged into one texture anyway)
        if (textureDatas.size() > 1 && textureData.texture.getImage().getFormat().isCompressed()) {
            textureData.texture.setImage(ImageUtils.decompress(textureData.texture.getImage()));
            textureData.textureBlender = TextureBlenderFactory.alterTextureType(textureData.texture.getImage().getFormat(), textureData.textureBlender);
        }
        if (previousTexture == null) {
            // the first texture will lead the others to its shape
            if (textureData.texture instanceof GeneratedTexture) {
                resultTexture = ((GeneratedTexture) textureData.texture).triangulate(mesh, geometriesOMA, textureData.uvCoordinatesType, blenderContext);
            } else if (textureData.texture instanceof Texture2D) {
                resultTexture = textureData.texture;
                if (textureData.uvCoordinatesType == UVCoordinatesType.TEXCO_UV && userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
                    if (textureData.uvCoordinatesName == null) {
                        // get the first UV available
                        resultUVS = userDefinedUVCoordinates.values().iterator().next();
                    } else {
                        resultUVS = userDefinedUVCoordinates.get(textureData.uvCoordinatesName);
                    }
                    if (resultUVS == null && LOGGER.isLoggable(Level.WARNING)) {
                        LOGGER.warning("The texture " + textureData.texture.getName() + " has assigned non existing UV coordinates group: " + textureData.uvCoordinatesName + ".");
                    }
                    masterUserUVSetName = textureData.uvCoordinatesName;
                } else {
                    TemporalMesh temporalMesh = (TemporalMesh) blenderContext.getLoadedFeature(geometriesOMA, LoadedDataType.TEMPORAL_MESH);
                    resultUVS = UVCoordinatesGenerator.generateUVCoordinatesFor2DTexture(mesh, textureData.uvCoordinatesType, textureData.projectionType, temporalMesh);
                }
            }
            this.blend(resultTexture, textureData.textureBlender, blenderContext);
            previousTexture = resultTexture;
            masterUVCoordinatesType = textureData.uvCoordinatesType;
        } else {
            if (textureData.texture instanceof GeneratedTexture) {
                if (!(resultTexture instanceof TriangulatedTexture)) {
                    resultTexture = new TriangulatedTexture((Texture2D) resultTexture, resultUVS, blenderContext);
                    resultUVS = null;
                    previousTexture = resultTexture;
                }
                TriangulatedTexture triangulatedTexture = ((GeneratedTexture) textureData.texture).triangulate(mesh, geometriesOMA, textureData.uvCoordinatesType, blenderContext);
                triangulatedTexture.castToUVS((TriangulatedTexture) resultTexture, blenderContext);
                triangulatedTexture.blend(textureData.textureBlender, (TriangulatedTexture) resultTexture, blenderContext);
                resultTexture = previousTexture = triangulatedTexture;
            } else if (textureData.texture instanceof Texture2D) {
                if (this.isUVTypesMatch(masterUVCoordinatesType, masterUserUVSetName, textureData.uvCoordinatesType, textureData.uvCoordinatesName) && resultTexture instanceof Texture2D) {
                    this.scale((Texture2D) textureData.texture, resultTexture.getImage().getWidth(), resultTexture.getImage().getHeight());
                    ImageUtils.merge(resultTexture.getImage(), textureData.texture.getImage());
                    previousTexture = resultTexture;
                } else {
                    if (!(resultTexture instanceof TriangulatedTexture)) {
                        resultTexture = new TriangulatedTexture((Texture2D) resultTexture, resultUVS, blenderContext);
                        resultUVS = null;
                    }
                    // first triangulate the current texture
                    List<Vector2f> textureUVS = null;
                    if (textureData.uvCoordinatesType == UVCoordinatesType.TEXCO_UV && userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
                        if (textureData.uvCoordinatesName == null) {
                            // get the first UV available
                            textureUVS = userDefinedUVCoordinates.values().iterator().next();
                        } else {
                            textureUVS = userDefinedUVCoordinates.get(textureData.uvCoordinatesName);
                        }
                    } else {
                        TemporalMesh geometries = (TemporalMesh) blenderContext.getLoadedFeature(geometriesOMA, LoadedDataType.TEMPORAL_MESH);
                        textureUVS = UVCoordinatesGenerator.generateUVCoordinatesFor2DTexture(mesh, textureData.uvCoordinatesType, textureData.projectionType, geometries);
                    }
                    TriangulatedTexture triangulatedTexture = new TriangulatedTexture((Texture2D) textureData.texture, textureUVS, blenderContext);
                    // then move the texture to different UV's
                    triangulatedTexture.castToUVS((TriangulatedTexture) resultTexture, blenderContext);
                    // merge triangulated textures
                    for (int i = 0; i < ((TriangulatedTexture) resultTexture).getFaceTextureCount(); ++i) {
                        ImageUtils.merge(((TriangulatedTexture) resultTexture).getFaceTextureElement(i).image, triangulatedTexture.getFaceTextureElement(i).image);
                    }
                }
            }
        }
    }
    if (resultTexture instanceof TriangulatedTexture) {
        if (mappingType == MaterialContext.MTEX_NOR) {
            for (int i = 0; i < ((TriangulatedTexture) resultTexture).getFaceTextureCount(); ++i) {
                TriangleTextureElement triangleTextureElement = ((TriangulatedTexture) resultTexture).getFaceTextureElement(i);
                // TODO: get proper strength factor
                triangleTextureElement.image = ImageUtils.convertToNormalMapTexture(triangleTextureElement.image, 1);
            }
        }
        resultUVS = ((TriangulatedTexture) resultTexture).getResultUVS();
        resultTexture = ((TriangulatedTexture) resultTexture).getResultTexture();
        masterUserUVSetName = null;
    }
    // setting additional data
    resultTexture.setWrap(WrapMode.Repeat);
    // the filters are required if generated textures are used because
    // otherwise ugly lines appear between the mesh faces
    resultTexture.setMagFilter(MagFilter.Nearest);
    resultTexture.setMinFilter(MinFilter.NearestNoMipMaps);
    return masterUserUVSetName;
}
Also used : TemporalMesh(com.jme3.scene.plugins.blender.meshes.TemporalMesh) Texture2D(com.jme3.texture.Texture2D) TriangleTextureElement(com.jme3.scene.plugins.blender.textures.TriangulatedTexture.TriangleTextureElement) UVCoordinatesType(com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.UVCoordinatesType) TemporalMesh(com.jme3.scene.plugins.blender.meshes.TemporalMesh) Mesh(com.jme3.scene.Mesh) ArrayList(java.util.ArrayList) List(java.util.List) Texture(com.jme3.texture.Texture)

Example 3 with UVCoordinatesType

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

the class UVCoordinatesGenerator method generateUVCoordinatesFor2DTexture.

/**
     * Generates a UV coordinates for 2D texture.
     * 
     * @param mesh
     *            the mesh we generate UV's for
     * @param texco
     *            UV coordinates type
     * @param projection
     *            projection type
     * @param geometries
     *            the geometris the given mesh belongs to (required to compute
     *            bounding box)
     * @return UV coordinates for the given mesh
     */
public static List<Vector2f> generateUVCoordinatesFor2DTexture(Mesh mesh, UVCoordinatesType texco, UVProjectionType projection, Geometry geometries) {
    List<Vector2f> result = new ArrayList<Vector2f>();
    BoundingBox bb = UVCoordinatesGenerator.getBoundingBox(geometries);
    // positions, normals, reflection vectors, etc.
    float[] inputData = null;
    switch(texco) {
        case TEXCO_ORCO:
            inputData = BufferUtils.getFloatArray(mesh.getFloatBuffer(VertexBuffer.Type.Position));
            break;
        case // this should be used if not defined by user explicitly
        TEXCO_UV:
            Vector2f[] data = new Vector2f[] { new Vector2f(0, 1), new Vector2f(0, 0), new Vector2f(1, 0) };
            for (int i = 0; i < mesh.getVertexCount(); ++i) {
                result.add(data[i % 3]);
            }
            break;
        case TEXCO_NORM:
            inputData = BufferUtils.getFloatArray(mesh.getFloatBuffer(VertexBuffer.Type.Normal));
            break;
        case TEXCO_REFL:
        case TEXCO_GLOB:
        case TEXCO_TANGENT:
        case TEXCO_STRESS:
        case TEXCO_LAVECTOR:
        case TEXCO_OBJECT:
        case TEXCO_OSA:
        case TEXCO_PARTICLE_OR_STRAND:
        case TEXCO_SPEED:
        case TEXCO_STICKY:
        case TEXCO_VIEW:
        case TEXCO_WINDOW:
            LOGGER.warning("Texture coordinates type not currently supported: " + texco);
            break;
        default:
            throw new IllegalStateException("Unknown texture coordinates value: " + texco);
    }
    if (inputData != null) {
        // make projection calculations
        switch(projection) {
            case PROJECTION_FLAT:
                inputData = UVProjectionGenerator.flatProjection(inputData, bb);
                break;
            case PROJECTION_CUBE:
                inputData = UVProjectionGenerator.cubeProjection(inputData, bb);
                break;
            case PROJECTION_TUBE:
                BoundingTube bt = UVCoordinatesGenerator.getBoundingTube(geometries);
                inputData = UVProjectionGenerator.tubeProjection(inputData, bt);
                break;
            case PROJECTION_SPHERE:
                BoundingSphere bs = UVCoordinatesGenerator.getBoundingSphere(geometries);
                inputData = UVProjectionGenerator.sphereProjection(inputData, bs);
                break;
            default:
                throw new IllegalStateException("Unknown projection type: " + projection);
        }
        for (int i = 0; i < inputData.length; i += 2) {
            result.add(new Vector2f(inputData[i], inputData[i + 1]));
        }
    }
    return result;
}
Also used : BoundingSphere(com.jme3.bounding.BoundingSphere) Vector2f(com.jme3.math.Vector2f) BoundingBox(com.jme3.bounding.BoundingBox) ArrayList(java.util.ArrayList)

Example 4 with UVCoordinatesType

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

the class UVCoordinatesGenerator method generateUVCoordinatesFor3DTexture.

/**
     * Generates a UV coordinates for 3D texture.
     * 
     * @param mesh
     *            the mesh we generate UV's for
     * @param texco
     *            UV coordinates type
     * @param coordinatesSwappingIndexes
     *            coordinates swapping indexes
     * @param geometries
     *            the geometris the given mesh belongs to (required to compute
     *            bounding box)
     * @return UV coordinates for the given mesh
     */
public static List<Vector3f> generateUVCoordinatesFor3DTexture(Mesh mesh, UVCoordinatesType texco, int[] coordinatesSwappingIndexes, Geometry... geometries) {
    List<Vector3f> result = new ArrayList<Vector3f>();
    BoundingBox bb = UVCoordinatesGenerator.getBoundingBox(geometries);
    // positions, normals, reflection vectors, etc.
    float[] inputData = null;
    switch(texco) {
        case TEXCO_ORCO:
            inputData = BufferUtils.getFloatArray(mesh.getFloatBuffer(VertexBuffer.Type.Position));
            break;
        case TEXCO_UV:
            Vector2f[] data = new Vector2f[] { new Vector2f(0, 1), new Vector2f(0, 0), new Vector2f(1, 0) };
            for (int i = 0; i < mesh.getVertexCount(); ++i) {
                Vector2f uv = data[i % 3];
                result.add(new Vector3f(uv.x, uv.y, 0));
            }
            break;
        case TEXCO_NORM:
            inputData = BufferUtils.getFloatArray(mesh.getFloatBuffer(VertexBuffer.Type.Normal));
            break;
        case TEXCO_REFL:
        case TEXCO_GLOB:
        case TEXCO_TANGENT:
        case TEXCO_STRESS:
        case TEXCO_LAVECTOR:
        case TEXCO_OBJECT:
        case TEXCO_OSA:
        case TEXCO_PARTICLE_OR_STRAND:
        case TEXCO_SPEED:
        case TEXCO_STICKY:
        case TEXCO_VIEW:
        case TEXCO_WINDOW:
            LOGGER.warning("Texture coordinates type not currently supported: " + texco);
            break;
        default:
            throw new IllegalStateException("Unknown texture coordinates value: " + texco);
    }
    if (inputData != null) {
        // make calculations
        Vector3f min = bb.getMin(null);
        // used for coordinates swapping
        float[] uvCoordsResults = new float[4];
        float[] ext = new float[] { bb.getXExtent() * 2, bb.getYExtent() * 2, bb.getZExtent() * 2 };
        for (int i = 0; i < ext.length; ++i) {
            if (ext[i] == 0) {
                ext[i] = 1;
            }
        }
        // <0; 1>
        for (int i = 0; i < inputData.length; i += 3) {
            uvCoordsResults[1] = (inputData[i] - min.x) / ext[0];
            uvCoordsResults[2] = (inputData[i + 1] - min.y) / ext[1];
            uvCoordsResults[3] = (inputData[i + 2] - min.z) / ext[2];
            result.add(new Vector3f(uvCoordsResults[coordinatesSwappingIndexes[0]], uvCoordsResults[coordinatesSwappingIndexes[1]], uvCoordsResults[coordinatesSwappingIndexes[2]]));
        }
    }
    return result;
}
Also used : Vector2f(com.jme3.math.Vector2f) Vector3f(com.jme3.math.Vector3f) BoundingBox(com.jme3.bounding.BoundingBox) ArrayList(java.util.ArrayList)

Aggregations

BoundingBox (com.jme3.bounding.BoundingBox)3 ArrayList (java.util.ArrayList)3 Vector2f (com.jme3.math.Vector2f)2 Vector3f (com.jme3.math.Vector3f)2 TemporalMesh (com.jme3.scene.plugins.blender.meshes.TemporalMesh)2 TriangleTextureElement (com.jme3.scene.plugins.blender.textures.TriangulatedTexture.TriangleTextureElement)2 BoundingSphere (com.jme3.bounding.BoundingSphere)1 Mesh (com.jme3.scene.Mesh)1 UVCoordinatesType (com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.UVCoordinatesType)1 Texture (com.jme3.texture.Texture)1 Texture2D (com.jme3.texture.Texture2D)1 List (java.util.List)1 TreeSet (java.util.TreeSet)1