Search in sources :

Example 6 with DynamicArray

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

the class ObjectHelper method getMatrix.

/**
     * This method returns the matrix of a given name for the given structure.
     * It takes up axis into consideration.
     * 
     * The method that moves the matrix from Z-up axis to Y-up axis space is as follows:
     * - load the matrix directly from blender (it has the Z-up axis orientation)
     * - switch the second and third rows in the matrix
     * - switch the second and third column in the matrix
     * - multiply the values in the third row by -1
     * - multiply the values in the third column by -1
     * 
     * The result matrix is now in Y-up axis orientation.
     * The procedure was discovered by experimenting but it looks like it's working :)
     * The previous procedure transformet the loaded matrix into component (loc, rot, scale),
     * switched several values and pu the back into the matrix.
     * It worked fine until models with negative scale are used.
     * The current method is not touched by that flaw.
     * 
     * @param structure
     *            the structure with matrix data
     * @param matrixName
     *            the name of the matrix
     * @param fixUpAxis
     *            tells if the Y axis is a UP axis
     * @param store
     *            the matrix where the result will pe placed
     * @return the required matrix
     */
@SuppressWarnings("unchecked")
private Matrix4f getMatrix(Structure structure, String matrixName, boolean fixUpAxis, Matrix4f store) {
    DynamicArray<Number> obmat = (DynamicArray<Number>) structure.getFieldValue(matrixName);
    // the matrix must be square
    int rowAndColumnSize = Math.abs((int) Math.sqrt(obmat.getTotalSize()));
    for (int i = 0; i < rowAndColumnSize; ++i) {
        for (int j = 0; j < rowAndColumnSize; ++j) {
            float value = obmat.get(j, i).floatValue();
            if (Math.abs(value) <= FastMath.FLT_EPSILON) {
                value = 0;
            }
            store.set(i, j, value);
        }
    }
    if (fixUpAxis) {
        // first switch the second and third row
        for (int i = 0; i < 4; ++i) {
            float temp = store.get(1, i);
            store.set(1, i, store.get(2, i));
            store.set(2, i, temp);
        }
        // then switch the second and third column
        for (int i = 0; i < 4; ++i) {
            float temp = store.get(i, 1);
            store.set(i, 1, store.get(i, 2));
            store.set(i, 2, temp);
        }
        // multiply the values in the third row by -1
        store.m20 *= -1;
        store.m21 *= -1;
        store.m22 *= -1;
        store.m23 *= -1;
        // multiply the values in the third column by -1
        store.m02 *= -1;
        store.m12 *= -1;
        store.m22 *= -1;
        store.m32 *= -1;
    }
    return store;
}
Also used : DynamicArray(com.jme3.scene.plugins.blender.file.DynamicArray) CullHint(com.jme3.scene.Spatial.CullHint)

Example 7 with DynamicArray

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

the class CurvesTemporalMesh method loadBevelObject.

/**
     * The method loads the bevel object that sould be applied to curve. It can either be another curve or a generated one
     * based on the bevel generating parameters in blender.
     * @param curveStructure
     *            the structure with the curve's data (the curve being loaded, NOT the bevel curve)
     * @return the curve's bevel object
     * @throws BlenderFileException
     *             an exception is thrown when problems with reading occur
     */
@SuppressWarnings("unchecked")
private CurvesTemporalMesh loadBevelObject(Structure curveStructure) throws BlenderFileException {
    CurvesTemporalMesh bevelObject = null;
    Pointer pBevelObject = (Pointer) curveStructure.getFieldValue("bevobj");
    boolean cyclic = false;
    if (pBevelObject.isNotNull()) {
        Structure bevelObjectStructure = pBevelObject.fetchData().get(0);
        DynamicArray<Number> scaleArray = (DynamicArray<Number>) bevelObjectStructure.getFieldValue("size");
        Vector3f scale = blenderContext.getBlenderKey().isFixUpAxis() ? new Vector3f(scaleArray.get(0).floatValue(), scaleArray.get(1).floatValue(), scaleArray.get(2).floatValue()) : new Vector3f(scaleArray.get(0).floatValue(), scaleArray.get(2).floatValue(), scaleArray.get(1).floatValue());
        Pointer pBevelStructure = (Pointer) bevelObjectStructure.getFieldValue("data");
        Structure bevelStructure = pBevelStructure.fetchData().get(0);
        bevelObject = new CurvesTemporalMesh(bevelStructure, scale, false, blenderContext);
        // transforming the bezier lines from plane XZ to plane YZ
        for (BezierLine bl : bevelObject.beziers) {
            for (Vector3f v : bl.vertices) {
                // casting the bezier curve orthogonally on the plane XZ (making Y = 0) and then moving the plane XZ to ZY in a way that:
                // -Z => +Y and +X => +Z and +Y => +X (but because casting would make Y = 0, then we simply set X = 0)
                v.y = -v.z;
                v.z = v.x;
                v.x = 0;
            }
            // bevel curves should not have repeated the first vertex at the end when they are cyclic (this is handled differently)
            if (bl.isCyclic()) {
                bl.removeLastVertex();
            }
        }
    } else {
        // this option is inactive in blender when there is no bevel object applied
        fillCaps = false;
        int bevResol = ((Number) curveStructure.getFieldValue("bevresol")).intValue();
        float extrude = ((Number) curveStructure.getFieldValue("ext1")).floatValue();
        float bevelDepth = ((Number) curveStructure.getFieldValue("ext2")).floatValue();
        float offset = ((Number) curveStructure.getFieldValue("offset", 0)).floatValue();
        if (offset != 0) {
            // TODO: add support for offset parameter
            LOGGER.warning("Offset parameter not yet supported.");
        }
        Curve bevelCurve = null;
        if (bevelDepth > 0.0f) {
            float handlerLength = bevelDepth / 2.0f;
            cyclic = !isFront && !isBack;
            List<Vector3f> conrtolPoints = new ArrayList<Vector3f>();
            // when neither fron and back face is selected all version behave the same and draw full bevel around the curve
            if (cyclic || blenderContext.getBlenderVersion() < 253) {
                conrtolPoints.add(new Vector3f(0, -extrude - bevelDepth, 0));
                conrtolPoints.add(new Vector3f(0, -extrude - bevelDepth, -handlerLength));
                conrtolPoints.add(new Vector3f(0, -extrude - handlerLength, -bevelDepth));
                conrtolPoints.add(new Vector3f(0, -extrude, -bevelDepth));
                conrtolPoints.add(new Vector3f(0, -extrude + handlerLength, -bevelDepth));
                if (extrude > 0) {
                    conrtolPoints.add(new Vector3f(0, extrude - handlerLength, -bevelDepth));
                    conrtolPoints.add(new Vector3f(0, extrude, -bevelDepth));
                    conrtolPoints.add(new Vector3f(0, extrude + handlerLength, -bevelDepth));
                }
                conrtolPoints.add(new Vector3f(0, extrude + bevelDepth, -handlerLength));
                conrtolPoints.add(new Vector3f(0, extrude + bevelDepth, 0));
                if (cyclic) {
                    conrtolPoints.add(new Vector3f(0, extrude + bevelDepth, handlerLength));
                    conrtolPoints.add(new Vector3f(0, extrude + handlerLength, bevelDepth));
                    conrtolPoints.add(new Vector3f(0, extrude, bevelDepth));
                    conrtolPoints.add(new Vector3f(0, extrude - handlerLength, bevelDepth));
                    if (extrude > 0) {
                        conrtolPoints.add(new Vector3f(0, -extrude + handlerLength, bevelDepth));
                        conrtolPoints.add(new Vector3f(0, -extrude, bevelDepth));
                        conrtolPoints.add(new Vector3f(0, -extrude - handlerLength, bevelDepth));
                    }
                    conrtolPoints.add(new Vector3f(0, -extrude - bevelDepth, handlerLength));
                    conrtolPoints.add(new Vector3f(0, -extrude - bevelDepth, 0));
                }
            } else {
                if (extrude > 0) {
                    if (isBack) {
                        conrtolPoints.add(new Vector3f(0, -extrude - bevelDepth, 0));
                        conrtolPoints.add(new Vector3f(0, -extrude - bevelDepth, -handlerLength));
                        conrtolPoints.add(new Vector3f(0, -extrude - handlerLength, -bevelDepth));
                    }
                    conrtolPoints.add(new Vector3f(0, -extrude, -bevelDepth));
                    conrtolPoints.add(new Vector3f(0, -extrude + handlerLength, -bevelDepth));
                    conrtolPoints.add(new Vector3f(0, extrude - handlerLength, -bevelDepth));
                    conrtolPoints.add(new Vector3f(0, extrude, -bevelDepth));
                    if (isFront) {
                        conrtolPoints.add(new Vector3f(0, extrude + handlerLength, -bevelDepth));
                        conrtolPoints.add(new Vector3f(0, extrude + bevelDepth, -handlerLength));
                        conrtolPoints.add(new Vector3f(0, extrude + bevelDepth, 0));
                    }
                } else {
                    if (isFront && isBack) {
                        conrtolPoints.add(new Vector3f(0, -bevelDepth, 0));
                        conrtolPoints.add(new Vector3f(0, -bevelDepth, -handlerLength));
                        conrtolPoints.add(new Vector3f(0, -handlerLength, -bevelDepth));
                        conrtolPoints.add(new Vector3f(0, 0, -bevelDepth));
                        conrtolPoints.add(new Vector3f(0, handlerLength, -bevelDepth));
                        conrtolPoints.add(new Vector3f(0, bevelDepth, -handlerLength));
                        conrtolPoints.add(new Vector3f(0, bevelDepth, 0));
                    } else {
                        if (isBack) {
                            conrtolPoints.add(new Vector3f(0, -bevelDepth, 0));
                            conrtolPoints.add(new Vector3f(0, -bevelDepth, -handlerLength));
                            conrtolPoints.add(new Vector3f(0, -handlerLength, -bevelDepth));
                            conrtolPoints.add(new Vector3f(0, 0, -bevelDepth));
                        } else {
                            conrtolPoints.add(new Vector3f(0, 0, -bevelDepth));
                            conrtolPoints.add(new Vector3f(0, handlerLength, -bevelDepth));
                            conrtolPoints.add(new Vector3f(0, bevelDepth, -handlerLength));
                            conrtolPoints.add(new Vector3f(0, bevelDepth, 0));
                        }
                    }
                }
            }
            bevelCurve = new Curve(new Spline(SplineType.Bezier, conrtolPoints, 0, false), bevResol);
        } else if (extrude > 0.0f) {
            Spline bevelSpline = new Spline(SplineType.Linear, new Vector3f[] { new Vector3f(0, extrude, 0), new Vector3f(0, -extrude, 0) }, 1, false);
            bevelCurve = new Curve(bevelSpline, bevResol);
        }
        if (bevelCurve != null) {
            bevelObject = new CurvesTemporalMesh(blenderContext);
            FloatBuffer vertsBuffer = (FloatBuffer) bevelCurve.getBuffer(Type.Position).getData();
            Vector3f[] verts = BufferUtils.getVector3Array(vertsBuffer);
            if (cyclic) {
                // get rid of the last vertex which is identical to the first one
                verts = Arrays.copyOf(verts, verts.length - 1);
            }
            bevelObject.beziers.add(new BezierLine(verts, 0, false, cyclic));
        }
    }
    return bevelObject;
}
Also used : Curve(com.jme3.scene.shape.Curve) ArrayList(java.util.ArrayList) Pointer(com.jme3.scene.plugins.blender.file.Pointer) FloatBuffer(java.nio.FloatBuffer) Spline(com.jme3.math.Spline) DynamicArray(com.jme3.scene.plugins.blender.file.DynamicArray) Vector3f(com.jme3.math.Vector3f) Structure(com.jme3.scene.plugins.blender.file.Structure)

Example 8 with DynamicArray

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

the class TextureHelper method readTextureData.

/**
     * Reads the texture data from the given material or sky structure.
     * @param structure
     *            the structure of material or sky
     * @param diffuseColorArray
     *            array of diffuse colors
     * @param skyTexture
     *            indicates it we're going to read sky texture or not
     * @return a list of combined textures
     * @throws BlenderFileException
     *             an exception is thrown when problems with reading the blend file occur
     */
@SuppressWarnings("unchecked")
public List<CombinedTexture> readTextureData(Structure structure, float[] diffuseColorArray, boolean skyTexture) throws BlenderFileException {
    DynamicArray<Pointer> mtexsArray = (DynamicArray<Pointer>) structure.getFieldValue("mtex");
    int separatedTextures = skyTexture ? 0 : ((Number) structure.getFieldValue("septex")).intValue();
    List<TextureData> texturesList = new ArrayList<TextureData>();
    for (int i = 0; i < mtexsArray.getTotalSize(); ++i) {
        Pointer p = mtexsArray.get(i);
        if (p.isNotNull() && (separatedTextures & 1 << i) == 0) {
            TextureData textureData = new TextureData();
            textureData.mtex = p.fetchData().get(0);
            textureData.uvCoordinatesType = skyTexture ? UVCoordinatesType.TEXCO_ORCO.blenderValue : ((Number) textureData.mtex.getFieldValue("texco")).intValue();
            textureData.projectionType = ((Number) textureData.mtex.getFieldValue("mapping")).intValue();
            textureData.uvCoordinatesName = textureData.mtex.getFieldValue("uvName").toString();
            if (textureData.uvCoordinatesName != null && textureData.uvCoordinatesName.trim().length() == 0) {
                textureData.uvCoordinatesName = null;
            }
            Pointer pTex = (Pointer) textureData.mtex.getFieldValue("tex");
            if (pTex.isNotNull()) {
                Structure tex = pTex.fetchData().get(0);
                textureData.textureStructure = tex;
                texturesList.add(textureData);
            }
        }
    }
    LOGGER.info("Loading model's textures.");
    List<CombinedTexture> loadedTextures = new ArrayList<CombinedTexture>();
    if (blenderContext.getBlenderKey().isOptimiseTextures()) {
        LOGGER.fine("Optimising the useage of model's textures.");
        Map<Number, List<TextureData>> textureDataMap = this.sortTextures(texturesList);
        for (Entry<Number, List<TextureData>> entry : textureDataMap.entrySet()) {
            if (entry.getValue().size() > 0) {
                CombinedTexture combinedTexture = new CombinedTexture(entry.getKey().intValue(), !skyTexture);
                for (TextureData textureData : entry.getValue()) {
                    int texflag = ((Number) textureData.mtex.getFieldValue("texflag")).intValue();
                    boolean negateTexture = (texflag & 0x04) != 0;
                    Texture texture = this.getTexture(textureData.textureStructure, textureData.mtex, blenderContext);
                    if (texture != null) {
                        int blendType = ((Number) textureData.mtex.getFieldValue("blendtype")).intValue();
                        float[] color = new float[] { ((Number) textureData.mtex.getFieldValue("r")).floatValue(), ((Number) textureData.mtex.getFieldValue("g")).floatValue(), ((Number) textureData.mtex.getFieldValue("b")).floatValue() };
                        float colfac = ((Number) textureData.mtex.getFieldValue("colfac")).floatValue();
                        TextureBlender textureBlender = TextureBlenderFactory.createTextureBlender(texture.getImage().getFormat(), texflag, negateTexture, blendType, diffuseColorArray, color, colfac);
                        combinedTexture.add(texture, textureBlender, textureData.uvCoordinatesType, textureData.projectionType, textureData.textureStructure, textureData.uvCoordinatesName, blenderContext);
                    }
                }
                if (combinedTexture.getTexturesCount() > 0) {
                    loadedTextures.add(combinedTexture);
                }
            }
        }
    } else {
        LOGGER.fine("No textures optimisation applied.");
        int[] mappings = new int[] { MaterialContext.MTEX_COL, MaterialContext.MTEX_NOR, MaterialContext.MTEX_EMIT, MaterialContext.MTEX_SPEC, MaterialContext.MTEX_ALPHA, MaterialContext.MTEX_AMB };
        for (TextureData textureData : texturesList) {
            Texture texture = this.getTexture(textureData.textureStructure, textureData.mtex, blenderContext);
            if (texture != null) {
                Number mapto = (Number) textureData.mtex.getFieldValue("mapto");
                int texflag = ((Number) textureData.mtex.getFieldValue("texflag")).intValue();
                boolean negateTexture = (texflag & 0x04) != 0;
                for (int i = 0; i < mappings.length; ++i) {
                    if ((mappings[i] & mapto.intValue()) != 0) {
                        CombinedTexture combinedTexture = new CombinedTexture(mappings[i], !skyTexture);
                        int blendType = ((Number) textureData.mtex.getFieldValue("blendtype")).intValue();
                        float[] color = new float[] { ((Number) textureData.mtex.getFieldValue("r")).floatValue(), ((Number) textureData.mtex.getFieldValue("g")).floatValue(), ((Number) textureData.mtex.getFieldValue("b")).floatValue() };
                        float colfac = ((Number) textureData.mtex.getFieldValue("colfac")).floatValue();
                        TextureBlender textureBlender = TextureBlenderFactory.createTextureBlender(texture.getImage().getFormat(), texflag, negateTexture, blendType, diffuseColorArray, color, colfac);
                        combinedTexture.add(texture, textureBlender, textureData.uvCoordinatesType, textureData.projectionType, textureData.textureStructure, textureData.uvCoordinatesName, blenderContext);
                        if (combinedTexture.getTexturesCount() > 0) {
                            // the added texture might not have been accepted (if for example loading generated textures is disabled)
                            loadedTextures.add(combinedTexture);
                        }
                    }
                }
            }
        }
    }
    return loadedTextures;
}
Also used : ArrayList(java.util.ArrayList) Pointer(com.jme3.scene.plugins.blender.file.Pointer) TextureBlender(com.jme3.scene.plugins.blender.textures.blending.TextureBlender) Texture(com.jme3.texture.Texture) DynamicArray(com.jme3.scene.plugins.blender.file.DynamicArray) ArrayList(java.util.ArrayList) List(java.util.List) Structure(com.jme3.scene.plugins.blender.file.Structure)

Aggregations

DynamicArray (com.jme3.scene.plugins.blender.file.DynamicArray)7 Pointer (com.jme3.scene.plugins.blender.file.Pointer)6 Structure (com.jme3.scene.plugins.blender.file.Structure)6 ArrayList (java.util.ArrayList)4 List (java.util.List)3 Spline (com.jme3.math.Spline)2 Vector3f (com.jme3.math.Vector3f)2 Curve (com.jme3.scene.shape.Curve)2 FloatBuffer (java.nio.FloatBuffer)2 ParticleEmitter (com.jme3.effect.ParticleEmitter)1 EmptyParticleInfluencer (com.jme3.effect.influencers.EmptyParticleInfluencer)1 NewtonianParticleInfluencer (com.jme3.effect.influencers.NewtonianParticleInfluencer)1 ParticleInfluencer (com.jme3.effect.influencers.ParticleInfluencer)1 EmitterMeshConvexHullShape (com.jme3.effect.shapes.EmitterMeshConvexHullShape)1 EmitterMeshFaceShape (com.jme3.effect.shapes.EmitterMeshFaceShape)1 EmitterMeshVertexShape (com.jme3.effect.shapes.EmitterMeshVertexShape)1 ColorRGBA (com.jme3.math.ColorRGBA)1 Vector2f (com.jme3.math.Vector2f)1 Vector4f (com.jme3.math.Vector4f)1 CullHint (com.jme3.scene.Spatial.CullHint)1