Search in sources :

Example 16 with Matrix

use of com.jme3.scene.plugins.blender.math.Matrix 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 17 with Matrix

use of com.jme3.scene.plugins.blender.math.Matrix in project jmonkeyengine by jMonkeyEngine.

the class ShadowUtil method updateShadowCamera.

/**
     * Updates the shadow camera to properly contain the given points (which
     * contain the eye camera frustum corners)
     *
     * @param shadowCam
     * @param points
     */
public static void updateShadowCamera(Camera shadowCam, Vector3f[] points) {
    boolean ortho = shadowCam.isParallelProjection();
    shadowCam.setProjectionMatrix(null);
    if (ortho) {
        shadowCam.setFrustum(-1, 1, -1, 1, 1, -1);
    } else {
        shadowCam.setFrustumPerspective(45, 1, 1, 150);
    }
    Matrix4f viewProjMatrix = shadowCam.getViewProjectionMatrix();
    Matrix4f projMatrix = shadowCam.getProjectionMatrix();
    BoundingBox splitBB = computeBoundForPoints(points, viewProjMatrix);
    TempVars vars = TempVars.get();
    Vector3f splitMin = splitBB.getMin(vars.vect1);
    Vector3f splitMax = splitBB.getMax(vars.vect2);
    //        splitMin.z = 0;
    // Create the crop matrix.
    float scaleX, scaleY, scaleZ;
    float offsetX, offsetY, offsetZ;
    scaleX = 2.0f / (splitMax.x - splitMin.x);
    scaleY = 2.0f / (splitMax.y - splitMin.y);
    offsetX = -0.5f * (splitMax.x + splitMin.x) * scaleX;
    offsetY = -0.5f * (splitMax.y + splitMin.y) * scaleY;
    scaleZ = 1.0f / (splitMax.z - splitMin.z);
    offsetZ = -splitMin.z * scaleZ;
    Matrix4f cropMatrix = vars.tempMat4;
    cropMatrix.set(scaleX, 0f, 0f, offsetX, 0f, scaleY, 0f, offsetY, 0f, 0f, scaleZ, offsetZ, 0f, 0f, 0f, 1f);
    Matrix4f result = new Matrix4f();
    result.set(cropMatrix);
    result.multLocal(projMatrix);
    vars.release();
    shadowCam.setProjectionMatrix(result);
}
Also used : Matrix4f(com.jme3.math.Matrix4f) BoundingBox(com.jme3.bounding.BoundingBox) Vector3f(com.jme3.math.Vector3f) TempVars(com.jme3.util.TempVars)

Example 18 with Matrix

use of com.jme3.scene.plugins.blender.math.Matrix in project jmonkeyengine by jMonkeyEngine.

the class BillboardControl method rotateCameraAligned.

/**
     * Aligns this Billboard so that it points to the camera position.
     *
     * @param camera
     *            Camera
     */
private void rotateCameraAligned(Camera camera) {
    look.set(camera.getLocation()).subtractLocal(spatial.getWorldTranslation());
    // coopt left for our own purposes.
    Vector3f xzp = left;
    // The xzp vector is the projection of the look vector on the xz plane
    xzp.set(look.x, 0, look.z);
    // check for undefined rotation...
    if (xzp.equals(Vector3f.ZERO)) {
        return;
    }
    look.normalizeLocal();
    xzp.normalizeLocal();
    float cosp = look.dot(xzp);
    // compute the local orientation matrix for the billboard
    orient.set(0, 0, xzp.z);
    orient.set(0, 1, xzp.x * -look.y);
    orient.set(0, 2, xzp.x * cosp);
    orient.set(1, 0, 0);
    orient.set(1, 1, cosp);
    orient.set(1, 2, look.y);
    orient.set(2, 0, -xzp.x);
    orient.set(2, 1, xzp.z * -look.y);
    orient.set(2, 2, xzp.z * cosp);
    // The billboard must be oriented to face the camera before it is
    // transformed into the world.
    spatial.setLocalRotation(orient);
    fixRefreshFlags();
}
Also used : Vector3f(com.jme3.math.Vector3f)

Example 19 with Matrix

use of com.jme3.scene.plugins.blender.math.Matrix in project jmonkeyengine by jMonkeyEngine.

the class AndroidBufferImageLoader method load.

public Object load(AssetInfo assetInfo) throws IOException {
    Bitmap bitmap = null;
    Image.Format format;
    InputStream in = null;
    int bpp;
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferQualityOverSpeed = false;
    options.inPreferredConfig = Bitmap.Config.RGB_565;
    options.inTempStorage = tempData;
    options.inScaled = false;
    options.inDither = false;
    options.inInputShareable = true;
    options.inPurgeable = true;
    options.inSampleSize = 1;
    try {
        in = assetInfo.openStream();
        bitmap = BitmapFactory.decodeStream(in, null, options);
        if (bitmap == null) {
            throw new IOException("Failed to load image: " + assetInfo.getKey().getName());
        }
    } finally {
        if (in != null) {
            in.close();
        }
    }
    switch(bitmap.getConfig()) {
        case ALPHA_8:
            format = Image.Format.Alpha8;
            bpp = 1;
            break;
        case ARGB_8888:
            format = Image.Format.RGBA8;
            bpp = 4;
            break;
        case RGB_565:
            format = Image.Format.RGB565;
            bpp = 2;
            break;
        default:
            throw new UnsupportedOperationException("Unrecognized Android bitmap format: " + bitmap.getConfig());
    }
    TextureKey texKey = (TextureKey) assetInfo.getKey();
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    ByteBuffer data = BufferUtils.createByteBuffer(bitmap.getWidth() * bitmap.getHeight() * bpp);
    if (format == Image.Format.RGBA8) {
        int[] pixelData = new int[width * height];
        bitmap.getPixels(pixelData, 0, width, 0, 0, width, height);
        if (texKey.isFlipY()) {
            int[] sln = new int[width];
            int y2;
            for (int y1 = 0; y1 < height / 2; y1++) {
                y2 = height - y1 - 1;
                convertARGBtoABGR(pixelData, y1 * width, sln, 0, width);
                convertARGBtoABGR(pixelData, y2 * width, pixelData, y1 * width, width);
                System.arraycopy(sln, 0, pixelData, y2 * width, width);
            }
        } else {
            convertARGBtoABGR(pixelData, 0, pixelData, 0, pixelData.length);
        }
        data.asIntBuffer().put(pixelData);
    } else {
        if (texKey.isFlipY()) {
            // Flip the image, then delete the old one.
            Matrix flipMat = new Matrix();
            flipMat.preScale(1.0f, -1.0f);
            Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), flipMat, false);
            bitmap.recycle();
            bitmap = newBitmap;
            if (bitmap == null) {
                throw new IOException("Failed to flip image: " + texKey);
            }
        }
        bitmap.copyPixelsToBuffer(data);
    }
    data.flip();
    bitmap.recycle();
    Image image = new Image(format, width, height, data, ColorSpace.sRGB);
    return image;
}
Also used : InputStream(java.io.InputStream) IOException(java.io.IOException) Image(com.jme3.texture.Image) ByteBuffer(java.nio.ByteBuffer) TextureKey(com.jme3.asset.TextureKey) Bitmap(android.graphics.Bitmap) Matrix(android.graphics.Matrix) BitmapFactory(android.graphics.BitmapFactory)

Example 20 with Matrix

use of com.jme3.scene.plugins.blender.math.Matrix in project jmonkeyengine by jMonkeyEngine.

the class ConstraintDefinitionIK method bake.

@Override
public void bake(Space ownerSpace, Space targetSpace, Transform targetTransform, float influence) {
    if (influence == 0 || !trackToBeChanged || targetTransform == null || bonesCount == 0) {
        // no need to do anything
        return;
    }
    if (bones == null) {
        bones = new BonesChain((Bone) this.getOwner(), useTail, bonesAffected, alteredOmas, blenderContext);
    }
    if (bones.size() == 0) {
        bonesCount = 0;
        // no need to do anything
        return;
    }
    double distanceFromTarget = Double.MAX_VALUE;
    target.set(targetTransform.getTranslation().x, targetTransform.getTranslation().y, targetTransform.getTranslation().z);
    if (bonesCount < 0) {
        bonesCount = bones.size();
        rotationVectors = new Vector3d[bonesCount];
        for (int i = 0; i < bonesCount; ++i) {
            rotationVectors[i] = new Vector3d();
        }
        J = new Matrix(3, bonesCount);
    }
    BoneContext topBone = bones.get(0);
    for (int i = 0; i < iterations; ++i) {
        DTransform topBoneTransform = bones.getWorldTransform(topBone);
        // effector
        Vector3d e = topBoneTransform.getTranslation().add(topBoneTransform.getRotation().mult(Vector3d.UNIT_Y).multLocal(topBone.getLength()));
        distanceFromTarget = e.distance(target);
        if (distanceFromTarget <= MIN_DISTANCE) {
            break;
        }
        deltaP.setColumn(0, 0, target.x - e.x, target.y - e.y, target.z - e.z);
        int column = 0;
        for (BoneContext boneContext : bones) {
            DTransform boneWorldTransform = bones.getWorldTransform(boneContext);
            // current join position
            Vector3d j = boneWorldTransform.getTranslation();
            Vector3d vectorFromJointToEffector = e.subtract(j);
            vectorFromJointToEffector.cross(target.subtract(j), rotationVectors[column]).normalizeLocal();
            rotationVectors[column].cross(vectorFromJointToEffector, col);
            J.setColumn(col, column++);
        }
        Matrix J_1 = J.pseudoinverse();
        SimpleMatrix deltaThetas = J_1.mult(deltaP);
        if (deltaThetas.elementMaxAbs() < MIN_ANGLE_CHANGE) {
            break;
        }
        for (int j = 0; j < deltaThetas.numRows(); ++j) {
            double angle = deltaThetas.get(j, 0);
            Vector3d rotationVector = rotationVectors[j];
            tempDQuaternion.fromAngleAxis(angle, rotationVector);
            BoneContext boneContext = bones.get(j);
            Bone bone = boneContext.getBone();
            if (bone.equals(this.getOwner())) {
                if (boneContext.isLockX()) {
                    tempDQuaternion.set(0, tempDQuaternion.getY(), tempDQuaternion.getZ(), tempDQuaternion.getW());
                }
                if (boneContext.isLockY()) {
                    tempDQuaternion.set(tempDQuaternion.getX(), 0, tempDQuaternion.getZ(), tempDQuaternion.getW());
                }
                if (boneContext.isLockZ()) {
                    tempDQuaternion.set(tempDQuaternion.getX(), tempDQuaternion.getY(), 0, tempDQuaternion.getW());
                }
            }
            DTransform boneTransform = bones.getWorldTransform(boneContext);
            boneTransform.getRotation().set(tempDQuaternion.mult(boneTransform.getRotation()));
            bones.setWorldTransform(boneContext, boneTransform);
        }
    }
    // applying the results
    for (int i = bonesCount - 1; i >= 0; --i) {
        BoneContext boneContext = bones.get(i);
        DTransform transform = bones.getWorldTransform(boneContext);
        constraintHelper.applyTransform(boneContext.getArmatureObjectOMA(), boneContext.getBone().getName(), Space.CONSTRAINT_SPACE_WORLD, transform.toTransform());
    }
    // need to reload them again
    bones = null;
}
Also used : SimpleMatrix(org.ejml.simple.SimpleMatrix) Matrix(com.jme3.scene.plugins.blender.math.Matrix) SimpleMatrix(org.ejml.simple.SimpleMatrix) Vector3d(com.jme3.scene.plugins.blender.math.Vector3d) BoneContext(com.jme3.scene.plugins.blender.animations.BoneContext) DTransform(com.jme3.scene.plugins.blender.math.DTransform) Bone(com.jme3.animation.Bone)

Aggregations

TempVars (com.jme3.util.TempVars)12 Matrix4f (com.jme3.math.Matrix4f)10 Vector3f (com.jme3.math.Vector3f)5 Bone (com.jme3.animation.Bone)3 Camera (com.jme3.renderer.Camera)3 Spatial (com.jme3.scene.Spatial)3 BoundingBox (com.jme3.bounding.BoundingBox)2 com.jme3.opencl (com.jme3.opencl)2 BoneContext (com.jme3.scene.plugins.blender.animations.BoneContext)2 Uniform (com.jme3.shader.Uniform)2 Bitmap (android.graphics.Bitmap)1 BitmapFactory (android.graphics.BitmapFactory)1 Matrix (android.graphics.Matrix)1 Skeleton (com.jme3.animation.Skeleton)1 TextureKey (com.jme3.asset.TextureKey)1 BoundingSphere (com.jme3.bounding.BoundingSphere)1 BoundingVolume (com.jme3.bounding.BoundingVolume)1 JoyAxisEvent (com.jme3.input.event.JoyAxisEvent)1 DirectionalLight (com.jme3.light.DirectionalLight)1 Light (com.jme3.light.Light)1