Search in sources :

Example 6 with Type

use of com.jme3.effect.ParticleMesh.Type in project jmonkeyengine by jMonkeyEngine.

the class ModifierHelper method readModifiers.

/**
     * This method reads the given object's modifiers.
     * 
     * @param objectStructure
     *            the object structure
     * @param blenderContext
     *            the blender context
     * @throws BlenderFileException
     *             this exception is thrown when the blender file is somehow
     *             corrupted
     */
public Collection<Modifier> readModifiers(Structure objectStructure, BlenderContext blenderContext) throws BlenderFileException {
    Set<String> alreadyReadModifiers = new HashSet<String>();
    Collection<Modifier> result = new ArrayList<Modifier>();
    Structure modifiersListBase = (Structure) objectStructure.getFieldValue("modifiers");
    List<Structure> modifiers = modifiersListBase.evaluateListBase();
    for (Structure modifierStructure : modifiers) {
        String modifierType = modifierStructure.getType();
        if (!Modifier.canBeAppliedMultipleTimes(modifierType) && alreadyReadModifiers.contains(modifierType)) {
            LOGGER.log(Level.WARNING, "Modifier {0} can only be applied once to object: {1}", new Object[] { modifierType, objectStructure.getName() });
        } else {
            Modifier modifier = null;
            if (Modifier.ARRAY_MODIFIER_DATA.equals(modifierStructure.getType())) {
                modifier = new ArrayModifier(modifierStructure, blenderContext);
            } else if (Modifier.MIRROR_MODIFIER_DATA.equals(modifierStructure.getType())) {
                modifier = new MirrorModifier(modifierStructure, blenderContext);
            } else if (Modifier.ARMATURE_MODIFIER_DATA.equals(modifierStructure.getType())) {
                modifier = new ArmatureModifier(objectStructure, modifierStructure, blenderContext);
            } else if (Modifier.PARTICLE_MODIFIER_DATA.equals(modifierStructure.getType())) {
                modifier = new ParticlesModifier(modifierStructure, blenderContext);
            } else if (Modifier.SUBSURF_MODIFIER_DATA.equals(modifierStructure.getType())) {
                modifier = new SubdivisionSurfaceModifier(modifierStructure, blenderContext);
            }
            if (modifier != null) {
                if (modifier.isModifying()) {
                    result.add(modifier);
                    alreadyReadModifiers.add(modifierType);
                } else {
                    LOGGER.log(Level.WARNING, "The modifier {0} will cause no changes in the model. It will be ignored!", modifierStructure.getName());
                }
            } else {
                LOGGER.log(Level.WARNING, "Unsupported modifier type: {0}", modifierStructure.getType());
            }
        }
    }
    return result;
}
Also used : ArrayList(java.util.ArrayList) Structure(com.jme3.scene.plugins.blender.file.Structure) HashSet(java.util.HashSet)

Example 7 with Type

use of com.jme3.effect.ParticleMesh.Type in project jmonkeyengine by jMonkeyEngine.

the class ParticlesModifier method postMeshCreationApply.

@Override
public void postMeshCreationApply(Node node, BlenderContext blenderContext) {
    LOGGER.log(Level.FINE, "Applying particles modifier to: {0}", node);
    MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class);
    ParticleEmitter emitter = particleEmitter.clone();
    // veryfying the alpha function for particles' texture
    Integer alphaFunction = MaterialHelper.ALPHA_MASK_HYPERBOLE;
    char nameSuffix = emitter.getName().charAt(emitter.getName().length() - 1);
    if (nameSuffix == 'B' || nameSuffix == 'N') {
        alphaFunction = MaterialHelper.ALPHA_MASK_NONE;
    }
    // removing the type suffix from the name
    emitter.setName(emitter.getName().substring(0, emitter.getName().length() - 1));
    // applying emitter shape
    EmitterShape emitterShape = emitter.getShape();
    List<Mesh> meshes = new ArrayList<Mesh>();
    for (Spatial spatial : node.getChildren()) {
        if (spatial instanceof Geometry) {
            Mesh mesh = ((Geometry) spatial).getMesh();
            if (mesh != null) {
                meshes.add(mesh);
                Material material = materialHelper.getParticlesMaterial(((Geometry) spatial).getMaterial(), alphaFunction, blenderContext);
                // TODO: divide into several pieces
                emitter.setMaterial(material);
            }
        }
    }
    if (meshes.size() > 0 && emitterShape instanceof EmitterMeshVertexShape) {
        ((EmitterMeshVertexShape) emitterShape).setMeshes(meshes);
    }
    node.attachChild(emitter);
}
Also used : ParticleEmitter(com.jme3.effect.ParticleEmitter) Geometry(com.jme3.scene.Geometry) Spatial(com.jme3.scene.Spatial) EmitterShape(com.jme3.effect.shapes.EmitterShape) ArrayList(java.util.ArrayList) MaterialHelper(com.jme3.scene.plugins.blender.materials.MaterialHelper) TemporalMesh(com.jme3.scene.plugins.blender.meshes.TemporalMesh) Mesh(com.jme3.scene.Mesh) Material(com.jme3.material.Material) EmitterMeshVertexShape(com.jme3.effect.shapes.EmitterMeshVertexShape)

Example 8 with Type

use of com.jme3.effect.ParticleMesh.Type in project jmonkeyengine by jMonkeyEngine.

the class MeshHelper method loadUVCoordinates.

/**
     * The method loads the UV coordinates. The result is a map where the key is the user's UV set name and the values are UV coordinates.
     * But depending on the mesh type (triangle/quads or bmesh) the lists in the map have different meaning.
     * For bmesh they are enlisted just like they are stored in the blend file (in loops).
     * For traditional faces every 4 UV's should be assigned for a single face.
     * @param meshStructure
     *            the mesh structure
     * @return a map that sorts UV coordinates between different UV sets
     * @throws BlenderFileException
     *             an exception is thrown when problems with blend file occur
     */
@SuppressWarnings("unchecked")
public LinkedHashMap<String, List<Vector2f>> loadUVCoordinates(Structure meshStructure) throws BlenderFileException {
    LOGGER.log(Level.FINE, "Loading UV coordinates from mesh: {0}.", meshStructure.getName());
    LinkedHashMap<String, List<Vector2f>> result = new LinkedHashMap<String, List<Vector2f>>();
    if (this.isBMeshCompatible(meshStructure)) {
        // in this case the UV's are assigned to vertices (an array is the same length as the vertex array)
        Structure loopData = (Structure) meshStructure.getFieldValue("ldata");
        Pointer pLoopDataLayers = (Pointer) loopData.getFieldValue("layers");
        List<Structure> loopDataLayers = pLoopDataLayers.fetchData();
        for (Structure structure : loopDataLayers) {
            Pointer p = (Pointer) structure.getFieldValue("data");
            if (p.isNotNull() && ((Number) structure.getFieldValue("type")).intValue() == MeshHelper.UV_DATA_LAYER_TYPE_BMESH) {
                String uvSetName = structure.getFieldValue("name").toString();
                List<Structure> uvsStructures = p.fetchData();
                List<Vector2f> uvs = new ArrayList<Vector2f>(uvsStructures.size());
                for (Structure uvStructure : uvsStructures) {
                    DynamicArray<Number> loopUVS = (DynamicArray<Number>) uvStructure.getFieldValue("uv");
                    uvs.add(new Vector2f(loopUVS.get(0).floatValue(), loopUVS.get(1).floatValue()));
                }
                result.put(uvSetName, uvs);
            }
        }
    } else {
        // in this case UV's are assigned to faces (the array has the same legnth as the faces count)
        Structure facesData = (Structure) meshStructure.getFieldValue("fdata");
        Pointer pFacesDataLayers = (Pointer) facesData.getFieldValue("layers");
        if (pFacesDataLayers.isNotNull()) {
            List<Structure> facesDataLayers = pFacesDataLayers.fetchData();
            for (Structure structure : facesDataLayers) {
                Pointer p = (Pointer) structure.getFieldValue("data");
                if (p.isNotNull() && ((Number) structure.getFieldValue("type")).intValue() == MeshHelper.UV_DATA_LAYER_TYPE_FMESH) {
                    String uvSetName = structure.getFieldValue("name").toString();
                    List<Structure> uvsStructures = p.fetchData();
                    List<Vector2f> uvs = new ArrayList<Vector2f>(uvsStructures.size());
                    for (Structure uvStructure : uvsStructures) {
                        DynamicArray<Number> mFaceUVs = (DynamicArray<Number>) uvStructure.getFieldValue("uv");
                        uvs.add(new Vector2f(mFaceUVs.get(0).floatValue(), mFaceUVs.get(1).floatValue()));
                        uvs.add(new Vector2f(mFaceUVs.get(2).floatValue(), mFaceUVs.get(3).floatValue()));
                        uvs.add(new Vector2f(mFaceUVs.get(4).floatValue(), mFaceUVs.get(5).floatValue()));
                        uvs.add(new Vector2f(mFaceUVs.get(6).floatValue(), mFaceUVs.get(7).floatValue()));
                    }
                    result.put(uvSetName, uvs);
                }
            }
        }
    }
    return result;
}
Also used : ArrayList(java.util.ArrayList) Pointer(com.jme3.scene.plugins.blender.file.Pointer) LinkedHashMap(java.util.LinkedHashMap) Vector2f(com.jme3.math.Vector2f) DynamicArray(com.jme3.scene.plugins.blender.file.DynamicArray) ArrayList(java.util.ArrayList) List(java.util.List) Structure(com.jme3.scene.plugins.blender.file.Structure)

Example 9 with Type

use of com.jme3.effect.ParticleMesh.Type 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 10 with Type

use of com.jme3.effect.ParticleMesh.Type in project jmonkeyengine by jMonkeyEngine.

the class MaterialHelper method getParticlesMaterial.

/**
     * This method converts the given material into particles-usable material.
     * The texture and glow color are being copied.
     * The method assumes it receives the Lighting type of material.
     * @param material
     *            the source material
     * @param blenderContext
     *            the blender context
     * @return material converted into particles-usable material
     */
public Material getParticlesMaterial(Material material, Integer alphaMaskIndex, BlenderContext blenderContext) {
    Material result = new Material(blenderContext.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
    // copying texture
    MatParam diffuseMap = material.getParam("DiffuseMap");
    if (diffuseMap != null) {
        Texture texture = ((Texture) diffuseMap.getValue()).clone();
        // applying alpha mask to the texture
        Image image = texture.getImage();
        ByteBuffer sourceBB = image.getData(0);
        sourceBB.rewind();
        int w = image.getWidth();
        int h = image.getHeight();
        ByteBuffer bb = BufferUtils.createByteBuffer(w * h * 4);
        IAlphaMask iAlphaMask = alphaMasks.get(alphaMaskIndex);
        iAlphaMask.setImageSize(w, h);
        for (int x = 0; x < w; ++x) {
            for (int y = 0; y < h; ++y) {
                bb.put(sourceBB.get());
                bb.put(sourceBB.get());
                bb.put(sourceBB.get());
                bb.put(iAlphaMask.getAlpha(x, y));
            }
        }
        image = new Image(Format.RGBA8, w, h, bb, ColorSpace.Linear);
        texture.setImage(image);
        result.setTextureParam("Texture", VarType.Texture2D, texture);
    }
    // copying glow color
    MatParam glowColor = material.getParam("GlowColor");
    if (glowColor != null) {
        ColorRGBA color = (ColorRGBA) glowColor.getValue();
        result.setParam("GlowColor", VarType.Vector3, color);
    }
    return result;
}
Also used : MatParam(com.jme3.material.MatParam) ColorRGBA(com.jme3.math.ColorRGBA) Material(com.jme3.material.Material) Image(com.jme3.texture.Image) Texture(com.jme3.texture.Texture) ByteBuffer(java.nio.ByteBuffer)

Aggregations

ArrayList (java.util.ArrayList)18 Structure (com.jme3.scene.plugins.blender.file.Structure)12 Vector3f (com.jme3.math.Vector3f)11 Pointer (com.jme3.scene.plugins.blender.file.Pointer)10 IOException (java.io.IOException)10 List (java.util.List)9 ColorRGBA (com.jme3.math.ColorRGBA)8 Texture (com.jme3.texture.Texture)8 Geometry (com.jme3.scene.Geometry)6 Image (com.jme3.texture.Image)6 BoundingBox (com.jme3.bounding.BoundingBox)5 BoundingSphere (com.jme3.bounding.BoundingSphere)5 Light (com.jme3.light.Light)5 TemporalMesh (com.jme3.scene.plugins.blender.meshes.TemporalMesh)5 Uniform (com.jme3.shader.Uniform)5 Material (com.jme3.material.Material)4 Quaternion (com.jme3.math.Quaternion)4 Transform (com.jme3.math.Transform)4 Mesh (com.jme3.scene.Mesh)4 BlenderFileException (com.jme3.scene.plugins.blender.file.BlenderFileException)4