Search in sources :

Example 16 with BlenderFileException

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

the class CameraHelper method toCamera249.

/**
     * This method converts the given structure to jme camera. Should be used form blender 2.49.
     * 
     * @param structure
     *            camera structure
     * @return jme camera object
     * @throws BlenderFileException
     *             an exception is thrown when there are problems with the
     *             blender file
     */
private Camera toCamera249(Structure structure) throws BlenderFileException {
    Camera camera = new Camera(DEFAULT_CAM_WIDTH, DEFAULT_CAM_HEIGHT);
    int type = ((Number) structure.getFieldValue("type")).intValue();
    if (type != 0 && type != 1) {
        LOGGER.log(Level.WARNING, "Unknown camera type: {0}. Perspective camera is being used!", type);
        type = 0;
    }
    // type==0 - perspective; type==1 - orthographic; perspective is used as default
    camera.setParallelProjection(type == 1);
    float aspect = 0;
    float clipsta = ((Number) structure.getFieldValue("clipsta")).floatValue();
    float clipend = ((Number) structure.getFieldValue("clipend")).floatValue();
    if (type == 0) {
        aspect = ((Number) structure.getFieldValue("lens")).floatValue();
    } else {
        aspect = ((Number) structure.getFieldValue("ortho_scale")).floatValue();
    }
    camera.setFrustumPerspective(aspect, camera.getWidth() / camera.getHeight(), clipsta, clipend);
    camera.setName(structure.getName());
    return camera;
}
Also used : Camera(com.jme3.renderer.Camera)

Example 17 with BlenderFileException

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

the class CurvesTemporalMesh method loadNurbSurface.

/**
     * This method loads the NURBS curve or surface.
     * @param nurb
     *            the NURBS data structure
     * @throws BlenderFileException
     *             an exception is thrown when problems with reading occur
     */
@SuppressWarnings("unchecked")
private void loadNurbSurface(Structure nurb, int materialIndex) throws BlenderFileException {
    // loading the knots
    List<Float>[] knots = new List[2];
    Pointer[] pKnots = new Pointer[] { (Pointer) nurb.getFieldValue("knotsu"), (Pointer) nurb.getFieldValue("knotsv") };
    for (int i = 0; i < knots.length; ++i) {
        if (pKnots[i].isNotNull()) {
            FileBlockHeader fileBlockHeader = blenderContext.getFileBlock(pKnots[i].getOldMemoryAddress());
            BlenderInputStream blenderInputStream = blenderContext.getInputStream();
            blenderInputStream.setPosition(fileBlockHeader.getBlockPosition());
            int knotsAmount = fileBlockHeader.getCount() * fileBlockHeader.getSize() / 4;
            knots[i] = new ArrayList<Float>(knotsAmount);
            for (int j = 0; j < knotsAmount; ++j) {
                knots[i].add(Float.valueOf(blenderInputStream.readFloat()));
            }
        }
    }
    // loading the flags and orders (basis functions degrees)
    int flag = ((Number) nurb.getFieldValue("flag")).intValue();
    boolean smooth = (flag & FLAG_SMOOTH) != 0;
    int flagU = ((Number) nurb.getFieldValue("flagu")).intValue();
    int flagV = ((Number) nurb.getFieldValue("flagv")).intValue();
    int orderU = ((Number) nurb.getFieldValue("orderu")).intValue();
    int orderV = ((Number) nurb.getFieldValue("orderv")).intValue();
    // loading control points and their weights
    int pntsU = ((Number) nurb.getFieldValue("pntsu")).intValue();
    int pntsV = ((Number) nurb.getFieldValue("pntsv")).intValue();
    List<Structure> bPoints = ((Pointer) nurb.getFieldValue("bp")).fetchData();
    List<List<Vector4f>> controlPoints = new ArrayList<List<Vector4f>>(pntsV);
    for (int i = 0; i < pntsV; ++i) {
        List<Vector4f> uControlPoints = new ArrayList<Vector4f>(pntsU);
        for (int j = 0; j < pntsU; ++j) {
            DynamicArray<Float> vec = (DynamicArray<Float>) bPoints.get(j + i * pntsU).getFieldValue("vec");
            if (blenderContext.getBlenderKey().isFixUpAxis()) {
                uControlPoints.add(new Vector4f(vec.get(0).floatValue(), vec.get(2).floatValue(), -vec.get(1).floatValue(), vec.get(3).floatValue()));
            } else {
                uControlPoints.add(new Vector4f(vec.get(0).floatValue(), vec.get(1).floatValue(), vec.get(2).floatValue(), vec.get(3).floatValue()));
            }
        }
        if ((flagU & 0x01) != 0) {
            for (int k = 0; k < orderU - 1; ++k) {
                uControlPoints.add(uControlPoints.get(k));
            }
        }
        controlPoints.add(uControlPoints);
    }
    if ((flagV & 0x01) != 0) {
        for (int k = 0; k < orderV - 1; ++k) {
            controlPoints.add(controlPoints.get(k));
        }
    }
    int originalVerticesAmount = vertices.size();
    int resolu = ((Number) nurb.getFieldValue("resolu")).intValue();
    if (knots[1] == null) {
        // creating the NURB curve
        Curve curve = new Curve(new Spline(controlPoints.get(0), knots[0]), resolu);
        FloatBuffer vertsBuffer = (FloatBuffer) curve.getBuffer(Type.Position).getData();
        beziers.add(new BezierLine(BufferUtils.getVector3Array(vertsBuffer), materialIndex, smooth, false));
    } else {
        // creating the NURB surface
        int resolv = ((Number) nurb.getFieldValue("resolv")).intValue();
        int uSegments = resolu * controlPoints.get(0).size() - 1;
        int vSegments = resolv * controlPoints.size() - 1;
        Surface nurbSurface = Surface.createNurbsSurface(controlPoints, knots, uSegments, vSegments, orderU, orderV, smooth);
        FloatBuffer vertsBuffer = (FloatBuffer) nurbSurface.getBuffer(Type.Position).getData();
        vertices.addAll(Arrays.asList(BufferUtils.getVector3Array(vertsBuffer)));
        FloatBuffer normalsBuffer = (FloatBuffer) nurbSurface.getBuffer(Type.Normal).getData();
        normals.addAll(Arrays.asList(BufferUtils.getVector3Array(normalsBuffer)));
        IndexBuffer indexBuffer = nurbSurface.getIndexBuffer();
        for (int i = 0; i < indexBuffer.size(); i += 3) {
            int index1 = indexBuffer.get(i) + originalVerticesAmount;
            int index2 = indexBuffer.get(i + 1) + originalVerticesAmount;
            int index3 = indexBuffer.get(i + 2) + originalVerticesAmount;
            faces.add(new Face(new Integer[] { index1, index2, index3 }, smooth, materialIndex, null, null, this));
        }
    }
}
Also used : ArrayList(java.util.ArrayList) Pointer(com.jme3.scene.plugins.blender.file.Pointer) FloatBuffer(java.nio.FloatBuffer) Spline(com.jme3.math.Spline) Surface(com.jme3.scene.shape.Surface) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) Vector4f(com.jme3.math.Vector4f) ArrayList(java.util.ArrayList) List(java.util.List) BlenderInputStream(com.jme3.scene.plugins.blender.file.BlenderInputStream) Structure(com.jme3.scene.plugins.blender.file.Structure) Face(com.jme3.scene.plugins.blender.meshes.Face) FileBlockHeader(com.jme3.scene.plugins.blender.file.FileBlockHeader) Curve(com.jme3.scene.shape.Curve) DynamicArray(com.jme3.scene.plugins.blender.file.DynamicArray)

Example 18 with BlenderFileException

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

the class Field method fill.

/**
     * This method fills the field wth data read from the input stream.
     * @param blenderInputStream
     *            the stream we read data from
     * @throws BlenderFileException
     *             an exception is thrown when the blend file is somehow invalid or corrupted
     */
public void fill(BlenderInputStream blenderInputStream) throws BlenderFileException {
    int dataToRead = 1;
    if (tableSizes != null && tableSizes.length > 0) {
        for (int size : tableSizes) {
            if (size <= 0) {
                throw new BlenderFileException("The field " + name + " has invalid table size: " + size);
            }
            dataToRead *= size;
        }
    }
    DataType dataType = pointerLevel == 0 ? DataType.getDataType(type, blenderContext) : DataType.POINTER;
    switch(dataType) {
        case POINTER:
            if (dataToRead == 1) {
                Pointer pointer = new Pointer(pointerLevel, function, blenderContext);
                pointer.fill(blenderInputStream);
                value = pointer;
            } else {
                Pointer[] data = new Pointer[dataToRead];
                for (int i = 0; i < dataToRead; ++i) {
                    Pointer pointer = new Pointer(pointerLevel, function, blenderContext);
                    pointer.fill(blenderInputStream);
                    data[i] = pointer;
                }
                value = new DynamicArray<Pointer>(tableSizes, data);
            }
            break;
        case CHARACTER:
            // and characters are very often used as byte number stores instead of real chars
            if (dataToRead == 1) {
                value = Byte.valueOf((byte) blenderInputStream.readByte());
            } else {
                Character[] data = new Character[dataToRead];
                for (int i = 0; i < dataToRead; ++i) {
                    data[i] = Character.valueOf((char) blenderInputStream.readByte());
                }
                value = new DynamicArray<Character>(tableSizes, data);
            }
            break;
        case SHORT:
            if (dataToRead == 1) {
                value = Integer.valueOf(blenderInputStream.readShort());
            } else {
                Number[] data = new Number[dataToRead];
                for (int i = 0; i < dataToRead; ++i) {
                    data[i] = Integer.valueOf(blenderInputStream.readShort());
                }
                value = new DynamicArray<Number>(tableSizes, data);
            }
            break;
        case INTEGER:
            if (dataToRead == 1) {
                value = Integer.valueOf(blenderInputStream.readInt());
            } else {
                Number[] data = new Number[dataToRead];
                for (int i = 0; i < dataToRead; ++i) {
                    data[i] = Integer.valueOf(blenderInputStream.readInt());
                }
                value = new DynamicArray<Number>(tableSizes, data);
            }
            break;
        case LONG:
            if (dataToRead == 1) {
                value = Long.valueOf(blenderInputStream.readLong());
            } else {
                Number[] data = new Number[dataToRead];
                for (int i = 0; i < dataToRead; ++i) {
                    data[i] = Long.valueOf(blenderInputStream.readLong());
                }
                value = new DynamicArray<Number>(tableSizes, data);
            }
            break;
        case FLOAT:
            if (dataToRead == 1) {
                value = Float.valueOf(blenderInputStream.readFloat());
            } else {
                Number[] data = new Number[dataToRead];
                for (int i = 0; i < dataToRead; ++i) {
                    data[i] = Float.valueOf(blenderInputStream.readFloat());
                }
                value = new DynamicArray<Number>(tableSizes, data);
            }
            break;
        case DOUBLE:
            if (dataToRead == 1) {
                value = Double.valueOf(blenderInputStream.readDouble());
            } else {
                Number[] data = new Number[dataToRead];
                for (int i = 0; i < dataToRead; ++i) {
                    data[i] = Double.valueOf(blenderInputStream.readDouble());
                }
                value = new DynamicArray<Number>(tableSizes, data);
            }
            break;
        case VOID:
            break;
        case STRUCTURE:
            if (dataToRead == 1) {
                Structure structure = blenderContext.getDnaBlockData().getStructure(type);
                structure.fill(blenderContext.getInputStream());
                value = structure;
            } else {
                Structure[] data = new Structure[dataToRead];
                for (int i = 0; i < dataToRead; ++i) {
                    Structure structure = blenderContext.getDnaBlockData().getStructure(type);
                    structure.fill(blenderContext.getInputStream());
                    data[i] = structure;
                }
                value = new DynamicArray<Structure>(tableSizes, data);
            }
            break;
        default:
            throw new IllegalStateException("Unimplemented filling of type: " + type);
    }
}
Also used : DataType(com.jme3.scene.plugins.blender.file.Structure.DataType)

Example 19 with BlenderFileException

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

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

the class ConstraintHelper method loadConstraints.

/**
     * This method reads constraints for for the given structure. The
     * constraints are loaded only once for object/bone.
     * 
     * @param objectStructure
     *            the structure we read constraint's for
     * @param blenderContext
     *            the blender context
     * @throws BlenderFileException
     */
public void loadConstraints(Structure objectStructure, BlenderContext blenderContext) throws BlenderFileException {
    LOGGER.fine("Loading constraints.");
    // reading influence ipos for the constraints
    AnimationHelper animationHelper = blenderContext.getHelper(AnimationHelper.class);
    Map<String, Map<String, Ipo>> constraintsIpos = new HashMap<String, Map<String, Ipo>>();
    Pointer pActions = (Pointer) objectStructure.getFieldValue("action");
    if (pActions.isNotNull()) {
        List<Structure> actions = pActions.fetchData();
        for (Structure action : actions) {
            Structure chanbase = (Structure) action.getFieldValue("chanbase");
            List<Structure> actionChannels = chanbase.evaluateListBase();
            for (Structure actionChannel : actionChannels) {
                Map<String, Ipo> ipos = new HashMap<String, Ipo>();
                Structure constChannels = (Structure) actionChannel.getFieldValue("constraintChannels");
                List<Structure> constraintChannels = constChannels.evaluateListBase();
                for (Structure constraintChannel : constraintChannels) {
                    Pointer pIpo = (Pointer) constraintChannel.getFieldValue("ipo");
                    if (pIpo.isNotNull()) {
                        String constraintName = constraintChannel.getFieldValue("name").toString();
                        Ipo ipo = animationHelper.fromIpoStructure(pIpo.fetchData().get(0), blenderContext);
                        ipos.put(constraintName, ipo);
                    }
                }
                String actionName = actionChannel.getFieldValue("name").toString();
                constraintsIpos.put(actionName, ipos);
            }
        }
    }
    // loading constraints connected with the object's bones
    Pointer pPose = (Pointer) objectStructure.getFieldValue("pose");
    if (pPose.isNotNull()) {
        List<Structure> poseChannels = ((Structure) pPose.fetchData().get(0).getFieldValue("chanbase")).evaluateListBase();
        for (Structure poseChannel : poseChannels) {
            List<Constraint> constraintsList = new ArrayList<Constraint>();
            Long boneOMA = Long.valueOf(((Pointer) poseChannel.getFieldValue("bone")).getOldMemoryAddress());
            // the name is read directly from structure because bone might
            // not yet be loaded
            String name = blenderContext.getFileBlock(boneOMA).getStructure(blenderContext).getFieldValue("name").toString();
            List<Structure> constraints = ((Structure) poseChannel.getFieldValue("constraints")).evaluateListBase();
            for (Structure constraint : constraints) {
                String constraintName = constraint.getFieldValue("name").toString();
                Map<String, Ipo> ipoMap = constraintsIpos.get(name);
                Ipo ipo = ipoMap == null ? null : ipoMap.get(constraintName);
                if (ipo == null) {
                    float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue();
                    ipo = animationHelper.fromValue(enforce);
                }
                constraintsList.add(new BoneConstraint(constraint, boneOMA, ipo, blenderContext));
            }
            blenderContext.addConstraints(boneOMA, constraintsList);
        }
    }
    // loading constraints connected with the object itself
    List<Structure> constraints = ((Structure) objectStructure.getFieldValue("constraints")).evaluateListBase();
    if (constraints != null && constraints.size() > 0) {
        Pointer pData = (Pointer) objectStructure.getFieldValue("data");
        String dataType = pData.isNotNull() ? pData.fetchData().get(0).getType() : null;
        List<Constraint> constraintsList = new ArrayList<Constraint>(constraints.size());
        for (Structure constraint : constraints) {
            String constraintName = constraint.getFieldValue("name").toString();
            String objectName = objectStructure.getName();
            Map<String, Ipo> objectConstraintsIpos = constraintsIpos.get(objectName);
            Ipo ipo = objectConstraintsIpos != null ? objectConstraintsIpos.get(constraintName) : null;
            if (ipo == null) {
                float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue();
                ipo = animationHelper.fromValue(enforce);
            }
            constraintsList.add(this.createConstraint(dataType, constraint, objectStructure.getOldMemoryAddress(), ipo, blenderContext));
        }
        blenderContext.addConstraints(objectStructure.getOldMemoryAddress(), constraintsList);
    }
}
Also used : AnimationHelper(com.jme3.scene.plugins.blender.animations.AnimationHelper) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Ipo(com.jme3.scene.plugins.blender.animations.Ipo) Pointer(com.jme3.scene.plugins.blender.file.Pointer) Structure(com.jme3.scene.plugins.blender.file.Structure) HashMap(java.util.HashMap) Map(java.util.Map)

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