Search in sources :

Example 1 with BlenderFileException

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

the class ParticlesHelper method toParticleEmitter.

@SuppressWarnings("unchecked")
public ParticleEmitter toParticleEmitter(Structure particleSystem) throws BlenderFileException {
    ParticleEmitter result = null;
    Pointer pParticleSettings = (Pointer) particleSystem.getFieldValue("part");
    if (pParticleSettings.isNotNull()) {
        Structure particleSettings = pParticleSettings.fetchData().get(0);
        int totPart = ((Number) particleSettings.getFieldValue("totpart")).intValue();
        // draw type will be stored temporarily in the name (it is used during modifier applying operation)
        int drawAs = ((Number) particleSettings.getFieldValue("draw_as")).intValue();
        // P - point, L - line, N - None, B - Bilboard
        char nameSuffix;
        switch(drawAs) {
            case PART_DRAW_NOT:
                nameSuffix = 'N';
                // no need to generate particles in this case
                totPart = 0;
                break;
            case PART_DRAW_BB:
                nameSuffix = 'B';
                break;
            case PART_DRAW_OB:
            case PART_DRAW_GR:
                nameSuffix = 'P';
                // TODO: support groups and aobjects
                LOGGER.warning("Neither object nor group particles supported yet! Using point representation instead!");
                break;
            case PART_DRAW_LINE:
                nameSuffix = 'L';
                // TODO: support lines
                LOGGER.warning("Lines not yet supported! Using point representation instead!");
            default:
                // all others are rendered as points in blender
                nameSuffix = 'P';
        }
        result = new ParticleEmitter(particleSettings.getName() + nameSuffix, Type.Triangle, totPart);
        if (nameSuffix == 'N') {
            // no need to set anything else
            return result;
        }
        // setting the emitters shape (the shapes meshes will be set later during modifier applying operation)
        int from = ((Number) particleSettings.getFieldValue("from")).intValue();
        switch(from) {
            case PART_FROM_VERT:
                result.setShape(new EmitterMeshVertexShape());
                break;
            case PART_FROM_FACE:
                result.setShape(new EmitterMeshFaceShape());
                break;
            case PART_FROM_VOLUME:
                result.setShape(new EmitterMeshConvexHullShape());
                break;
            default:
                LOGGER.warning("Default shape used! Unknown emitter shape value ('from' parameter: " + from + ')');
        }
        // reading acceleration
        DynamicArray<Number> acc = (DynamicArray<Number>) particleSettings.getFieldValue("acc");
        result.setGravity(-acc.get(0).floatValue(), -acc.get(1).floatValue(), -acc.get(2).floatValue());
        // setting the colors
        result.setEndColor(new ColorRGBA(1f, 1f, 1f, 1f));
        result.setStartColor(new ColorRGBA(1f, 1f, 1f, 1f));
        // reading size
        float sizeFactor = nameSuffix == 'B' ? 1.0f : 0.3f;
        float size = ((Number) particleSettings.getFieldValue("size")).floatValue() * sizeFactor;
        result.setStartSize(size);
        result.setEndSize(size);
        // reading lifetime
        int fps = blenderContext.getBlenderKey().getFps();
        float lifetime = ((Number) particleSettings.getFieldValue("lifetime")).floatValue() / fps;
        float randlife = ((Number) particleSettings.getFieldValue("randlife")).floatValue() / fps;
        result.setLowLife(lifetime * (1.0f - randlife));
        result.setHighLife(lifetime);
        // preparing influencer
        ParticleInfluencer influencer;
        int phystype = ((Number) particleSettings.getFieldValue("phystype")).intValue();
        switch(phystype) {
            case PART_PHYS_NEWTON:
                influencer = new NewtonianParticleInfluencer();
                ((NewtonianParticleInfluencer) influencer).setNormalVelocity(((Number) particleSettings.getFieldValue("normfac")).floatValue());
                ((NewtonianParticleInfluencer) influencer).setVelocityVariation(((Number) particleSettings.getFieldValue("randfac")).floatValue());
                ((NewtonianParticleInfluencer) influencer).setSurfaceTangentFactor(((Number) particleSettings.getFieldValue("tanfac")).floatValue());
                ((NewtonianParticleInfluencer) influencer).setSurfaceTangentRotation(((Number) particleSettings.getFieldValue("tanphase")).floatValue());
                break;
            case PART_PHYS_BOIDS:
            case // TODO: support other influencers
            PART_PHYS_KEYED:
                LOGGER.warning("Boids and Keyed particles physic not yet supported! Empty influencer used!");
            case PART_PHYS_NO:
            default:
                influencer = new EmptyParticleInfluencer();
        }
        result.setParticleInfluencer(influencer);
    }
    return result;
}
Also used : ParticleEmitter(com.jme3.effect.ParticleEmitter) EmptyParticleInfluencer(com.jme3.effect.influencers.EmptyParticleInfluencer) Pointer(com.jme3.scene.plugins.blender.file.Pointer) EmitterMeshVertexShape(com.jme3.effect.shapes.EmitterMeshVertexShape) EmitterMeshFaceShape(com.jme3.effect.shapes.EmitterMeshFaceShape) NewtonianParticleInfluencer(com.jme3.effect.influencers.NewtonianParticleInfluencer) ColorRGBA(com.jme3.math.ColorRGBA) EmitterMeshConvexHullShape(com.jme3.effect.shapes.EmitterMeshConvexHullShape) DynamicArray(com.jme3.scene.plugins.blender.file.DynamicArray) Structure(com.jme3.scene.plugins.blender.file.Structure) EmptyParticleInfluencer(com.jme3.effect.influencers.EmptyParticleInfluencer) ParticleInfluencer(com.jme3.effect.influencers.ParticleInfluencer) NewtonianParticleInfluencer(com.jme3.effect.influencers.NewtonianParticleInfluencer)

Example 2 with BlenderFileException

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

the class TextureHelper method getTexture.

/**
     * This class returns a texture read from the file or from packed blender
     * data. The returned texture has the name set to the value of its blender
     * type.
     * 
     * @param textureStructure
     *            texture structure filled with data
     * @param blenderContext
     *            the blender context
     * @return the texture that can be used by JME engine
     * @throws BlenderFileException
     *             this exception is thrown when the blend file structure is
     *             somehow invalid or corrupted
     */
public Texture getTexture(Structure textureStructure, Structure mTex, BlenderContext blenderContext) throws BlenderFileException {
    Texture result = (Texture) blenderContext.getLoadedFeature(textureStructure.getOldMemoryAddress(), LoadedDataType.FEATURE);
    if (result != null) {
        return result;
    }
    if ("ID".equals(textureStructure.getType())) {
        LOGGER.fine("Loading texture from external blend file.");
        return (Texture) this.loadLibrary(textureStructure);
    }
    int type = ((Number) textureStructure.getFieldValue("type")).intValue();
    int imaflag = ((Number) textureStructure.getFieldValue("imaflag")).intValue();
    switch(type) {
        case // (it is first because probably this will be most commonly used)
        TEX_IMAGE:
            Pointer pImage = (Pointer) textureStructure.getFieldValue("ima");
            if (pImage.isNotNull()) {
                Structure image = pImage.fetchData().get(0);
                Texture loadedTexture = this.loadImageAsTexture(image, imaflag, blenderContext);
                if (loadedTexture != null) {
                    result = loadedTexture;
                    this.applyColorbandAndColorFactors(textureStructure, result.getImage(), blenderContext);
                }
            }
            break;
        case TEX_CLOUDS:
        case TEX_WOOD:
        case TEX_MARBLE:
        case TEX_MAGIC:
        case TEX_BLEND:
        case TEX_STUCCI:
        case TEX_NOISE:
        case TEX_MUSGRAVE:
        case TEX_VORONOI:
        case TEX_DISTNOISE:
            result = new GeneratedTexture(textureStructure, mTex, textureGeneratorFactory.createTextureGenerator(type), blenderContext);
            break;
        case // No texture, do nothing
        TEX_NONE:
            break;
        case TEX_POINTDENSITY:
        case TEX_VOXELDATA:
        case TEX_PLUGIN:
        case TEX_ENVMAP:
        case TEX_OCEAN:
            LOGGER.log(Level.WARNING, "Unsupported texture type: {0} for texture: {1}", new Object[] { type, textureStructure.getName() });
            break;
        default:
            throw new BlenderFileException("Unknown texture type: " + type + " for texture: " + textureStructure.getName());
    }
    if (result != null) {
        result.setName(textureStructure.getName());
        result.setWrap(WrapMode.Repeat);
        // decide if the mipmaps will be generated
        switch(blenderContext.getBlenderKey().getMipmapGenerationMethod()) {
            case ALWAYS_GENERATE:
                result.setMinFilter(MinFilter.Trilinear);
                break;
            case NEVER_GENERATE:
                break;
            case GENERATE_WHEN_NEEDED:
                if ((imaflag & 0x04) != 0) {
                    result.setMinFilter(MinFilter.Trilinear);
                }
                break;
            default:
                throw new IllegalStateException("Unknown mipmap generation method: " + blenderContext.getBlenderKey().getMipmapGenerationMethod());
        }
        if (type != TEX_IMAGE) {
            // only generated textures should have this key
            result.setKey(new GeneratedTextureKey(textureStructure.getName()));
        }
        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.log(Level.FINE, "Adding texture {0} to the loaded features with OMA = {1}", new Object[] { result.getName(), textureStructure.getOldMemoryAddress() });
        }
        blenderContext.addLoadedFeatures(textureStructure.getOldMemoryAddress(), LoadedDataType.STRUCTURE, textureStructure);
        blenderContext.addLoadedFeatures(textureStructure.getOldMemoryAddress(), LoadedDataType.FEATURE, result);
    }
    return result;
}
Also used : BlenderFileException(com.jme3.scene.plugins.blender.file.BlenderFileException) Pointer(com.jme3.scene.plugins.blender.file.Pointer) GeneratedTextureKey(com.jme3.asset.GeneratedTextureKey) Structure(com.jme3.scene.plugins.blender.file.Structure) Texture(com.jme3.texture.Texture)

Example 3 with BlenderFileException

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

the class MaskModifier method readBoneNames.

/**
     * Reads the names of the bones from the given bone base.
     * @param boneBase
     *            the list of bone base structures
     * @return a list of bones' names
     * @throws BlenderFileException
     *             is thrown if problems with reading the child bones' bases occur
     */
private List<String> readBoneNames(List<Structure> boneBase) throws BlenderFileException {
    List<String> result = new ArrayList<String>();
    for (Structure boneStructure : boneBase) {
        int flag = ((Number) boneStructure.getFieldValue("flag")).intValue();
        if ((flag & BoneContext.SELECTED) != 0) {
            result.add(boneStructure.getFieldValue("name").toString());
        }
        List<Structure> childbase = ((Structure) boneStructure.getFieldValue("childbase")).evaluateListBase();
        result.addAll(this.readBoneNames(childbase));
    }
    return result;
}
Also used : ArrayList(java.util.ArrayList) Structure(com.jme3.scene.plugins.blender.file.Structure) Point(com.jme3.scene.plugins.blender.meshes.Point)

Example 4 with BlenderFileException

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

the class MirrorModifier method apply.

@Override
public void apply(Node node, BlenderContext blenderContext) {
    if (invalid) {
        LOGGER.log(Level.WARNING, "Mirror modifier is invalid! Cannot be applied to: {0}", node.getName());
    } else {
        TemporalMesh temporalMesh = this.getTemporalMesh(node);
        if (temporalMesh != null) {
            LOGGER.log(Level.FINE, "Applying mirror modifier to: {0}", temporalMesh);
            Vector3f mirrorPlaneCenter = new Vector3f();
            if (pMirrorObject.isNotNull()) {
                Structure objectStructure;
                try {
                    objectStructure = pMirrorObject.fetchData().get(0);
                    ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
                    Node object = (Node) objectHelper.toObject(objectStructure, blenderContext);
                    if (object != null) {
                        // compute the mirror object coordinates in node's local space
                        mirrorPlaneCenter = this.getWorldMatrix(node).invertLocal().mult(object.getWorldTranslation());
                    }
                } catch (BlenderFileException e) {
                    LOGGER.log(Level.SEVERE, "Cannot load mirror''s reference object. Cause: {0}", e.getLocalizedMessage());
                    LOGGER.log(Level.SEVERE, "Mirror modifier will not be applied to node named: {0}", node.getName());
                    return;
                }
            }
            LOGGER.finest("Allocating temporal variables.");
            float d;
            Vector3f mirrorPlaneNormal = new Vector3f();
            Vector3f shiftVector = new Vector3f();
            LOGGER.fine("Mirroring mesh.");
            for (int mirrorIndex = 0; mirrorIndex < 3; ++mirrorIndex) {
                if (isMirrored[mirrorIndex]) {
                    boolean mirrorAtPoint0 = mirrorPlaneCenter.get(mirrorIndex) == 0;
                    if (!mirrorAtPoint0) {
                        // compute mirror's plane normal vector in node's space
                        mirrorPlaneNormal.set(0, 0, 0).set(mirrorIndex, Math.signum(mirrorPlaneCenter.get(mirrorIndex)));
                    }
                    TemporalMesh mirror = temporalMesh.clone();
                    for (int i = 0; i < mirror.getVertexCount(); ++i) {
                        Vector3f vertex = mirror.getVertices().get(i);
                        Vector3f normal = mirror.getNormals().get(i);
                        if (mirrorAtPoint0) {
                            d = Math.abs(vertex.get(mirrorIndex));
                            shiftVector.set(0, 0, 0).set(mirrorIndex, -vertex.get(mirrorIndex));
                        } else {
                            d = this.computeDistanceFromPlane(vertex, mirrorPlaneCenter, mirrorPlaneNormal);
                            mirrorPlaneNormal.mult(d, shiftVector);
                        }
                        if (merge && d <= tolerance) {
                            vertex.addLocal(shiftVector);
                            normal.set(mirrorIndex, 0);
                            temporalMesh.getVertices().get(i).addLocal(shiftVector);
                            temporalMesh.getNormals().get(i).set(mirrorIndex, 0);
                        } else {
                            vertex.addLocal(shiftVector.multLocal(2));
                            normal.set(mirrorIndex, -normal.get(mirrorIndex));
                        }
                    }
                    // flipping the indexes
                    for (Face face : mirror.getFaces()) {
                        face.flipIndexes();
                    }
                    for (Edge edge : mirror.getEdges()) {
                        edge.flipIndexes();
                    }
                    Collections.reverse(mirror.getPoints());
                    if (mirrorU || mirrorV) {
                        for (Face face : mirror.getFaces()) {
                            face.flipUV(mirrorU, mirrorV);
                        }
                    }
                    temporalMesh.append(mirror);
                }
            }
        } else {
            LOGGER.log(Level.WARNING, "Cannot find temporal mesh for node: {0}. The modifier will NOT be applied!", node);
        }
    }
}
Also used : TemporalMesh(com.jme3.scene.plugins.blender.meshes.TemporalMesh) ObjectHelper(com.jme3.scene.plugins.blender.objects.ObjectHelper) Vector3f(com.jme3.math.Vector3f) Node(com.jme3.scene.Node) BlenderFileException(com.jme3.scene.plugins.blender.file.BlenderFileException) Structure(com.jme3.scene.plugins.blender.file.Structure) Face(com.jme3.scene.plugins.blender.meshes.Face) Edge(com.jme3.scene.plugins.blender.meshes.Edge)

Example 5 with BlenderFileException

use of com.jme3.scene.plugins.blender.file.BlenderFileException 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)

Aggregations

Structure (com.jme3.scene.plugins.blender.file.Structure)31 Pointer (com.jme3.scene.plugins.blender.file.Pointer)26 ArrayList (java.util.ArrayList)19 BlenderFileException (com.jme3.scene.plugins.blender.file.BlenderFileException)10 Vector3f (com.jme3.math.Vector3f)7 FileBlockHeader (com.jme3.scene.plugins.blender.file.FileBlockHeader)7 List (java.util.List)7 DynamicArray (com.jme3.scene.plugins.blender.file.DynamicArray)6 TemporalMesh (com.jme3.scene.plugins.blender.meshes.TemporalMesh)5 Map (java.util.Map)5 Node (com.jme3.scene.Node)4 AnimationHelper (com.jme3.scene.plugins.blender.animations.AnimationHelper)4 MeshHelper (com.jme3.scene.plugins.blender.meshes.MeshHelper)4 ObjectHelper (com.jme3.scene.plugins.blender.objects.ObjectHelper)4 Texture (com.jme3.texture.Texture)4 HashMap (java.util.HashMap)4 BlenderKey (com.jme3.asset.BlenderKey)3 Light (com.jme3.light.Light)3 ColorRGBA (com.jme3.math.ColorRGBA)3 Spline (com.jme3.math.Spline)3