Search in sources :

Example 11 with Structure

use of com.jme3.scene.plugins.blender.file.Structure in project jmonkeyengine by jMonkeyEngine.

the class MeshHelper method loadVerticesColors.

/**
     * This method returns the vertices colors. Each vertex is stored in byte[4] array.
     * 
     * @param meshStructure
     *            the structure containing the mesh data
     * @param blenderContext
     *            the blender context
     * @return a list of vertices colors, each color belongs to a single vertex or empty list of colors are not specified
     * @throws BlenderFileException
     *             this exception is thrown when the blend file structure is somehow invalid or corrupted
     */
public List<byte[]> loadVerticesColors(Structure meshStructure, BlenderContext blenderContext) throws BlenderFileException {
    LOGGER.log(Level.FINE, "Loading vertices colors from mesh: {0}.", meshStructure.getName());
    MeshHelper meshHelper = blenderContext.getHelper(MeshHelper.class);
    Pointer pMCol = (Pointer) meshStructure.getFieldValue(meshHelper.isBMeshCompatible(meshStructure) ? "mloopcol" : "mcol");
    List<byte[]> verticesColors = new ArrayList<byte[]>();
    // it was likely a bug in blender untill version 2.63 (the blue and red factors were misplaced in their structure)
    // so we need to put them right
    boolean useBGRA = blenderContext.getBlenderVersion() < 263;
    if (pMCol.isNotNull()) {
        List<Structure> mCol = pMCol.fetchData();
        for (Structure color : mCol) {
            byte r = ((Number) color.getFieldValue("r")).byteValue();
            byte g = ((Number) color.getFieldValue("g")).byteValue();
            byte b = ((Number) color.getFieldValue("b")).byteValue();
            byte a = ((Number) color.getFieldValue("a")).byteValue();
            verticesColors.add(useBGRA ? new byte[] { b, g, r, a } : new byte[] { r, g, b, a });
        }
    }
    return verticesColors;
}
Also used : ArrayList(java.util.ArrayList) Pointer(com.jme3.scene.plugins.blender.file.Pointer) Structure(com.jme3.scene.plugins.blender.file.Structure)

Example 12 with Structure

use of com.jme3.scene.plugins.blender.file.Structure in project jmonkeyengine by jMonkeyEngine.

the class MeshHelper method toTemporalMesh.

/**
     * Converts the mesh structure into temporal mesh.
     * The temporal mesh is stored in blender context and here always a clone is being returned because the mesh might
     * be modified by modifiers.
     * 
     * @param meshStructure
     *            the mesh structure
     * @param blenderContext
     *            the blender context
     * @return temporal mesh read from the given structure
     * @throws BlenderFileException
     *             an exception is thrown when problems with reading blend file occur
     */
public TemporalMesh toTemporalMesh(Structure meshStructure, BlenderContext blenderContext) throws BlenderFileException {
    LOGGER.log(Level.FINE, "Loading temporal mesh named: {0}.", meshStructure.getName());
    TemporalMesh temporalMesh = (TemporalMesh) blenderContext.getLoadedFeature(meshStructure.getOldMemoryAddress(), LoadedDataType.TEMPORAL_MESH);
    if (temporalMesh != null) {
        LOGGER.fine("The mesh is already loaded. Returning its clone.");
        return temporalMesh.clone();
    }
    if ("ID".equals(meshStructure.getType())) {
        LOGGER.fine("Loading mesh from external blend file.");
        return (TemporalMesh) this.loadLibrary(meshStructure);
    }
    String name = meshStructure.getName();
    LOGGER.log(Level.FINE, "Reading mesh: {0}.", name);
    temporalMesh = new TemporalMesh(meshStructure, blenderContext);
    LOGGER.fine("Loading materials.");
    MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class);
    temporalMesh.setMaterials(materialHelper.getMaterials(meshStructure, blenderContext));
    LOGGER.fine("Reading custom properties.");
    Properties properties = this.loadProperties(meshStructure, blenderContext);
    temporalMesh.setProperties(properties);
    blenderContext.addLoadedFeatures(meshStructure.getOldMemoryAddress(), LoadedDataType.STRUCTURE, meshStructure);
    blenderContext.addLoadedFeatures(meshStructure.getOldMemoryAddress(), LoadedDataType.TEMPORAL_MESH, temporalMesh);
    return temporalMesh.clone();
}
Also used : MaterialHelper(com.jme3.scene.plugins.blender.materials.MaterialHelper) Properties(com.jme3.scene.plugins.blender.objects.Properties)

Example 13 with Structure

use of com.jme3.scene.plugins.blender.file.Structure in project jmonkeyengine by jMonkeyEngine.

the class MeshHelper method loadVerticesAndNormals.

/**
     * This method returns the vertices.
     * 
     * @param meshStructure
     *            the structure containing the mesh data
     * @return a list of two - element arrays, the first element is the vertex and the second - its normal
     * @throws BlenderFileException
     *             this exception is thrown when the blend file structure is somehow invalid or corrupted
     */
@SuppressWarnings("unchecked")
public void loadVerticesAndNormals(Structure meshStructure, List<Vector3f> vertices, List<Vector3f> normals) throws BlenderFileException {
    LOGGER.log(Level.FINE, "Loading vertices and normals from mesh: {0}.", meshStructure.getName());
    int count = ((Number) meshStructure.getFieldValue("totvert")).intValue();
    if (count > 0) {
        Pointer pMVert = (Pointer) meshStructure.getFieldValue("mvert");
        List<Structure> mVerts = pMVert.fetchData();
        Vector3f co = null, no = null;
        if (fixUpAxis) {
            for (int i = 0; i < count; ++i) {
                DynamicArray<Number> coordinates = (DynamicArray<Number>) mVerts.get(i).getFieldValue("co");
                co = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(2).floatValue(), -coordinates.get(1).floatValue());
                vertices.add(co);
                DynamicArray<Number> norm = (DynamicArray<Number>) mVerts.get(i).getFieldValue("no");
                no = new Vector3f(norm.get(0).shortValue() / 32767.0f, norm.get(2).shortValue() / 32767.0f, -norm.get(1).shortValue() / 32767.0f);
                normals.add(no);
            }
        } else {
            for (int i = 0; i < count; ++i) {
                DynamicArray<Number> coordinates = (DynamicArray<Number>) mVerts.get(i).getFieldValue("co");
                co = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(1).floatValue(), coordinates.get(2).floatValue());
                vertices.add(co);
                DynamicArray<Number> norm = (DynamicArray<Number>) mVerts.get(i).getFieldValue("no");
                no = new Vector3f(norm.get(0).shortValue() / 32767.0f, norm.get(1).shortValue() / 32767.0f, norm.get(2).shortValue() / 32767.0f);
                normals.add(no);
            }
        }
    }
    LOGGER.log(Level.FINE, "Loaded {0} vertices and normals.", vertices.size());
}
Also used : DynamicArray(com.jme3.scene.plugins.blender.file.DynamicArray) Vector3f(com.jme3.math.Vector3f) Pointer(com.jme3.scene.plugins.blender.file.Pointer) Structure(com.jme3.scene.plugins.blender.file.Structure)

Example 14 with Structure

use of com.jme3.scene.plugins.blender.file.Structure in project jmonkeyengine by jMonkeyEngine.

the class ArrayModifier method apply.

@Override
public void apply(Node node, BlenderContext blenderContext) {
    if (invalid) {
        LOGGER.log(Level.WARNING, "Array modifier is invalid! Cannot be applied to: {0}", node.getName());
    } else {
        TemporalMesh temporalMesh = this.getTemporalMesh(node);
        if (temporalMesh != null) {
            LOGGER.log(Level.FINE, "Applying array modifier to: {0}", temporalMesh);
            if (offset == null) {
                // the node will be repeated several times in the same place
                offset = new float[] { 0.0f, 0.0f, 0.0f };
            }
            if (scale == null) {
                // the node will be repeated several times in the same place
                scale = new float[] { 0.0f, 0.0f, 0.0f };
            } else {
                // getting bounding box
                temporalMesh.updateModelBound();
                BoundingVolume boundingVolume = temporalMesh.getWorldBound();
                if (boundingVolume instanceof BoundingBox) {
                    scale[0] *= ((BoundingBox) boundingVolume).getXExtent() * 2.0f;
                    scale[1] *= ((BoundingBox) boundingVolume).getYExtent() * 2.0f;
                    scale[2] *= ((BoundingBox) boundingVolume).getZExtent() * 2.0f;
                } else if (boundingVolume instanceof BoundingSphere) {
                    float radius = ((BoundingSphere) boundingVolume).getRadius();
                    scale[0] *= radius * 2.0f;
                    scale[1] *= radius * 2.0f;
                    scale[2] *= radius * 2.0f;
                } else {
                    throw new IllegalStateException("Unknown bounding volume type: " + boundingVolume.getClass().getName());
                }
            }
            // adding object's offset
            float[] objectOffset = new float[] { 0.0f, 0.0f, 0.0f };
            if (pOffsetObject != null && pOffsetObject.isNotNull()) {
                FileBlockHeader offsetObjectBlock = blenderContext.getFileBlock(pOffsetObject.getOldMemoryAddress());
                ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
                try {
                    // we take the structure in case the object was not yet loaded
                    Structure offsetStructure = offsetObjectBlock.getStructure(blenderContext);
                    Vector3f translation = objectHelper.getTransformation(offsetStructure, blenderContext).getTranslation();
                    objectOffset[0] = translation.x;
                    objectOffset[1] = translation.y;
                    objectOffset[2] = translation.z;
                } catch (BlenderFileException e) {
                    LOGGER.log(Level.WARNING, "Problems in blender file structure! Object offset cannot be applied! The problem: {0}", e.getMessage());
                }
            }
            // getting start and end caps
            MeshHelper meshHelper = blenderContext.getHelper(MeshHelper.class);
            TemporalMesh[] caps = new TemporalMesh[] { null, null };
            Pointer[] pCaps = new Pointer[] { pStartCap, pEndCap };
            for (int i = 0; i < pCaps.length; ++i) {
                if (pCaps[i].isNotNull()) {
                    FileBlockHeader capBlock = blenderContext.getFileBlock(pCaps[i].getOldMemoryAddress());
                    try {
                        // we take the structure in case the object was not yet loaded
                        Structure capStructure = capBlock.getStructure(blenderContext);
                        Pointer pMesh = (Pointer) capStructure.getFieldValue("data");
                        List<Structure> meshesArray = pMesh.fetchData();
                        caps[i] = meshHelper.toTemporalMesh(meshesArray.get(0), blenderContext);
                    } catch (BlenderFileException e) {
                        LOGGER.log(Level.WARNING, "Problems in blender file structure! Cap object cannot be applied! The problem: {0}", e.getMessage());
                    }
                }
            }
            Vector3f translationVector = new Vector3f(offset[0] + scale[0] + objectOffset[0], offset[1] + scale[1] + objectOffset[1], offset[2] + scale[2] + objectOffset[2]);
            if (blenderContext.getBlenderKey().isFixUpAxis()) {
                float y = translationVector.y;
                translationVector.y = translationVector.z;
                translationVector.z = y == 0 ? 0 : -y;
            }
            // getting/calculating repeats amount
            int count = 0;
            if (fittype == 0) {
                // Fixed count
                count = this.count - 1;
            } else if (fittype == 1) {
                // Fixed length
                float length = this.length;
                if (translationVector.length() > 0.0f) {
                    count = (int) (length / translationVector.length()) - 1;
                }
            } else if (fittype == 2) {
                // Fit curve
                throw new IllegalStateException("Fit curve should be transformed to Fixed Length array type!");
            } else {
                throw new IllegalStateException("Unknown fit type: " + fittype);
            }
            // adding translated nodes and caps
            Vector3f totalTranslation = new Vector3f(translationVector);
            if (count > 0) {
                TemporalMesh originalMesh = temporalMesh.clone();
                for (int i = 0; i < count; ++i) {
                    TemporalMesh clone = originalMesh.clone();
                    for (Vector3f v : clone.getVertices()) {
                        v.addLocal(totalTranslation);
                    }
                    temporalMesh.append(clone);
                    totalTranslation.addLocal(translationVector);
                }
            }
            if (caps[0] != null) {
                translationVector.multLocal(-1);
                TemporalMesh capsClone = caps[0].clone();
                for (Vector3f v : capsClone.getVertices()) {
                    v.addLocal(translationVector);
                }
                temporalMesh.append(capsClone);
            }
            if (caps[1] != null) {
                TemporalMesh capsClone = caps[1].clone();
                for (Vector3f v : capsClone.getVertices()) {
                    v.addLocal(totalTranslation);
                }
                temporalMesh.append(capsClone);
            }
        } else {
            LOGGER.log(Level.WARNING, "Cannot find temporal mesh for node: {0}. The modifier will NOT be applied!", node);
        }
    }
}
Also used : ObjectHelper(com.jme3.scene.plugins.blender.objects.ObjectHelper) BoundingSphere(com.jme3.bounding.BoundingSphere) FileBlockHeader(com.jme3.scene.plugins.blender.file.FileBlockHeader) BlenderFileException(com.jme3.scene.plugins.blender.file.BlenderFileException) Pointer(com.jme3.scene.plugins.blender.file.Pointer) TemporalMesh(com.jme3.scene.plugins.blender.meshes.TemporalMesh) BoundingBox(com.jme3.bounding.BoundingBox) Vector3f(com.jme3.math.Vector3f) BoundingVolume(com.jme3.bounding.BoundingVolume) Structure(com.jme3.scene.plugins.blender.file.Structure) MeshHelper(com.jme3.scene.plugins.blender.meshes.MeshHelper)

Example 15 with Structure

use of com.jme3.scene.plugins.blender.file.Structure in project jmonkeyengine by jMonkeyEngine.

the class MaterialHelper method getMaterials.

/**
     * This method returns the table of materials connected to the specified structure. The given structure can be of any type (ie. mesh or
     * curve) but needs to have 'mat' field/
     * 
     * @param structureWithMaterials
     *            the structure containing the mesh data
     * @param blenderContext
     *            the blender context
     * @return a list of vertices colors, each color belongs to a single vertex
     * @throws BlenderFileException
     *             this exception is thrown when the blend file structure is somehow invalid or corrupted
     */
public MaterialContext[] getMaterials(Structure structureWithMaterials, BlenderContext blenderContext) throws BlenderFileException {
    Pointer ppMaterials = (Pointer) structureWithMaterials.getFieldValue("mat");
    MaterialContext[] materials = null;
    if (ppMaterials.isNotNull()) {
        List<Structure> materialStructures = ppMaterials.fetchData();
        if (materialStructures != null && materialStructures.size() > 0) {
            MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class);
            materials = new MaterialContext[materialStructures.size()];
            int i = 0;
            for (Structure s : materialStructures) {
                materials[i++] = s == null ? null : materialHelper.toMaterialContext(s, blenderContext);
            }
        }
    }
    return materials;
}
Also used : Pointer(com.jme3.scene.plugins.blender.file.Pointer) Structure(com.jme3.scene.plugins.blender.file.Structure)

Aggregations

Structure (com.jme3.scene.plugins.blender.file.Structure)34 Pointer (com.jme3.scene.plugins.blender.file.Pointer)30 ArrayList (java.util.ArrayList)16 Vector3f (com.jme3.math.Vector3f)8 BlenderFileException (com.jme3.scene.plugins.blender.file.BlenderFileException)7 DynamicArray (com.jme3.scene.plugins.blender.file.DynamicArray)7 FileBlockHeader (com.jme3.scene.plugins.blender.file.FileBlockHeader)7 List (java.util.List)6 Map (java.util.Map)6 TemporalMesh (com.jme3.scene.plugins.blender.meshes.TemporalMesh)5 ObjectHelper (com.jme3.scene.plugins.blender.objects.ObjectHelper)5 HashMap (java.util.HashMap)5 ColorRGBA (com.jme3.math.ColorRGBA)4 Node (com.jme3.scene.Node)4 Texture (com.jme3.texture.Texture)4 CameraNode (com.jme3.scene.CameraNode)3 LightNode (com.jme3.scene.LightNode)3 Spatial (com.jme3.scene.Spatial)3 AnimationHelper (com.jme3.scene.plugins.blender.animations.AnimationHelper)3 ConstIpo (com.jme3.scene.plugins.blender.animations.Ipo.ConstIpo)3