Search in sources :

Example 11 with Matrix

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

the class Quaternion method toRotationMatrix.

/**
     * <code>toRotationMatrix</code> converts this quaternion to a rotational
     * matrix. The result is stored in result. 4th row and 4th column values are
     * untouched. Note: the result is created from a normalized version of this quat.
     * 
     * @param result
     *            The Matrix4f to store the result in.
     * @return the rotation matrix representation of this quaternion.
     */
public Matrix4f toRotationMatrix(Matrix4f result) {
    TempVars tempv = TempVars.get();
    Vector3f originalScale = tempv.vect1;
    result.toScaleVector(originalScale);
    result.setScale(1, 1, 1);
    float norm = norm();
    // we explicitly test norm against one here, saving a division
    // at the cost of a test and branch.  Is it worth it?
    float s = (norm == 1f) ? 2f : (norm > 0f) ? 2f / norm : 0;
    // compute xs/ys/zs first to save 6 multiplications, since xs/ys/zs
    // will be used 2-4 times each.
    float xs = x * s;
    float ys = y * s;
    float zs = z * s;
    float xx = x * xs;
    float xy = x * ys;
    float xz = x * zs;
    float xw = w * xs;
    float yy = y * ys;
    float yz = y * zs;
    float yw = w * ys;
    float zz = z * zs;
    float zw = w * zs;
    // using s=2/norm (instead of 1/norm) saves 9 multiplications by 2 here
    result.m00 = 1 - (yy + zz);
    result.m01 = (xy - zw);
    result.m02 = (xz + yw);
    result.m10 = (xy + zw);
    result.m11 = 1 - (xx + zz);
    result.m12 = (yz - xw);
    result.m20 = (xz - yw);
    result.m21 = (yz + xw);
    result.m22 = 1 - (xx + yy);
    result.setScale(originalScale);
    tempv.release();
    return result;
}
Also used : TempVars(com.jme3.util.TempVars)

Example 12 with Matrix

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

the class FbxBindPose method buildTransform.

private static Matrix4f buildTransform(double[] transform) {
    float[] m = new float[transform.length];
    for (int i = 0; i < transform.length; ++i) m[i] = (float) transform[i];
    Matrix4f matrix = new Matrix4f();
    matrix.set(m, false);
    return matrix;
}
Also used : Matrix4f(com.jme3.math.Matrix4f)

Example 13 with Matrix

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

the class BoneContext method buildBone.

/**
     * This method builds the bone. It recursively builds the bone's children.
     * 
     * @param bones
     *            a list of bones where the newly created bone will be added
     * @param skeletonOwnerOma
     *            the spatial of the object that will own the skeleton
     * @param blenderContext
     *            the blender context
     * @return newly created bone
     */
public Bone buildBone(List<Bone> bones, Long skeletonOwnerOma, BlenderContext blenderContext) {
    this.skeletonOwnerOma = skeletonOwnerOma;
    Long boneOMA = boneStructure.getOldMemoryAddress();
    bone = new Bone(boneName);
    bones.add(bone);
    blenderContext.addLoadedFeatures(boneOMA, LoadedDataType.STRUCTURE, boneStructure);
    blenderContext.addLoadedFeatures(boneOMA, LoadedDataType.FEATURE, bone);
    ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
    Structure skeletonOwnerObjectStructure = (Structure) blenderContext.getLoadedFeature(skeletonOwnerOma, LoadedDataType.STRUCTURE);
    // I could load 'imat' here, but apparently in some older blenders there were bugs or unfinished functionalities that stored ZERO matrix in imat field
    // loading 'obmat' and inverting it makes us avoid errors in such cases
    Matrix4f invertedObjectOwnerGlobalMatrix = objectHelper.getMatrix(skeletonOwnerObjectStructure, "obmat", blenderContext.getBlenderKey().isFixUpAxis()).invertLocal();
    if (objectHelper.isParent(skeletonOwnerOma, armatureObjectOMA)) {
        boneMatrixInModelSpace = globalBoneMatrix.mult(invertedObjectOwnerGlobalMatrix);
    } else {
        boneMatrixInModelSpace = invertedObjectOwnerGlobalMatrix.mult(globalBoneMatrix);
    }
    Matrix4f boneLocalMatrix = parent == null ? boneMatrixInModelSpace : parent.boneMatrixInModelSpace.invert().multLocal(boneMatrixInModelSpace);
    Vector3f poseLocation = parent == null || !this.is(CONNECTED_TO_PARENT) ? boneLocalMatrix.toTranslationVector() : new Vector3f(0, parent.length, 0);
    Quaternion rotation = boneLocalMatrix.toRotationQuat().normalizeLocal();
    Vector3f scale = boneLocalMatrix.toScaleVector();
    bone.setBindTransforms(poseLocation, rotation, scale);
    for (BoneContext child : children) {
        bone.addChild(child.buildBone(bones, skeletonOwnerOma, blenderContext));
    }
    return bone;
}
Also used : ObjectHelper(com.jme3.scene.plugins.blender.objects.ObjectHelper) Matrix4f(com.jme3.math.Matrix4f) Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f) Bone(com.jme3.animation.Bone) Structure(com.jme3.scene.plugins.blender.file.Structure)

Example 14 with Matrix

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

the class ConstraintHelper method applyTransform.

/**
     * Applies transform to a feature (bone or spatial). Computations transform
     * the given transformation from the given space to the feature's local
     * space.
     * 
     * @param oma
     *            the OMA of the feature we apply transformation to
     * @param subtargetName
     *            the name of the feature's subtarget (bone in case of armature)
     * @param space
     *            the space in which the given transform is to be applied
     * @param transform
     *            the transform we apply
     */
public void applyTransform(Long oma, String subtargetName, Space space, Transform transform) {
    Spatial feature = (Spatial) blenderContext.getLoadedFeature(oma, LoadedDataType.FEATURE);
    boolean isArmature = blenderContext.getMarkerValue(ObjectHelper.ARMATURE_NODE_MARKER, feature) != null;
    if (isArmature) {
        Skeleton skeleton = blenderContext.getSkeleton(oma);
        BoneContext targetBoneContext = blenderContext.getBoneByName(oma, subtargetName);
        Bone bone = targetBoneContext.getBone();
        if (bone.getParent() == null && (space == Space.CONSTRAINT_SPACE_LOCAL || space == Space.CONSTRAINT_SPACE_PARLOCAL)) {
            space = Space.CONSTRAINT_SPACE_POSE;
        }
        TempVars tempVars = TempVars.get();
        switch(space) {
            case CONSTRAINT_SPACE_LOCAL:
                assert bone.getParent() != null : "CONSTRAINT_SPACE_LOCAL should be evaluated as CONSTRAINT_SPACE_POSE if the bone has no parent!";
                bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
                break;
            case CONSTRAINT_SPACE_WORLD:
                {
                    Matrix4f boneMatrixInWorldSpace = this.toMatrix(transform, tempVars.tempMat4);
                    Matrix4f modelWorldMatrix = this.toMatrix(this.getTransform(targetBoneContext.getSkeletonOwnerOma(), null, Space.CONSTRAINT_SPACE_WORLD), tempVars.tempMat42);
                    Matrix4f boneMatrixInModelSpace = modelWorldMatrix.invertLocal().multLocal(boneMatrixInWorldSpace);
                    Bone parent = bone.getParent();
                    if (parent != null) {
                        Matrix4f parentMatrixInModelSpace = this.toMatrix(parent.getModelSpacePosition(), parent.getModelSpaceRotation(), parent.getModelSpaceScale(), tempVars.tempMat4);
                        boneMatrixInModelSpace = parentMatrixInModelSpace.invertLocal().multLocal(boneMatrixInModelSpace);
                    }
                    bone.setBindTransforms(boneMatrixInModelSpace.toTranslationVector(), boneMatrixInModelSpace.toRotationQuat(), boneMatrixInModelSpace.toScaleVector());
                    break;
                }
            case CONSTRAINT_SPACE_POSE:
                {
                    Matrix4f armatureWorldMatrix = this.toMatrix(feature.getWorldTransform(), tempVars.tempMat4);
                    Matrix4f boneMatrixInWorldSpace = armatureWorldMatrix.multLocal(this.toMatrix(transform, tempVars.tempMat42));
                    Matrix4f invertedModelMatrix = this.toMatrix(this.getTransform(targetBoneContext.getSkeletonOwnerOma(), null, Space.CONSTRAINT_SPACE_WORLD), tempVars.tempMat42).invertLocal();
                    Matrix4f boneMatrixInModelSpace = invertedModelMatrix.multLocal(boneMatrixInWorldSpace);
                    Bone parent = bone.getParent();
                    if (parent != null) {
                        Matrix4f parentMatrixInModelSpace = this.toMatrix(parent.getModelSpacePosition(), parent.getModelSpaceRotation(), parent.getModelSpaceScale(), tempVars.tempMat4);
                        boneMatrixInModelSpace = parentMatrixInModelSpace.invertLocal().multLocal(boneMatrixInModelSpace);
                    }
                    bone.setBindTransforms(boneMatrixInModelSpace.toTranslationVector(), boneMatrixInModelSpace.toRotationQuat(), boneMatrixInModelSpace.toScaleVector());
                    break;
                }
            case CONSTRAINT_SPACE_PARLOCAL:
                Matrix4f armatureWorldMatrix = this.toMatrix(feature.getWorldTransform(), tempVars.tempMat4);
                Matrix4f boneMatrixInWorldSpace = armatureWorldMatrix.multLocal(this.toMatrix(transform, tempVars.tempMat42));
                Matrix4f invertedModelMatrix = this.toMatrix(this.getTransform(targetBoneContext.getSkeletonOwnerOma(), null, Space.CONSTRAINT_SPACE_WORLD), tempVars.tempMat42).invertLocal();
                Matrix4f boneMatrixInModelSpace = invertedModelMatrix.multLocal(boneMatrixInWorldSpace);
                Bone parent = bone.getParent();
                if (parent != null) {
                    //first add the initial parent matrix to the bone's model matrix
                    BoneContext parentContext = blenderContext.getBoneContext(parent);
                    Matrix4f initialParentMatrixInModelSpace = parentContext.getBoneMatrixInModelSpace();
                    Matrix4f currentParentMatrixInModelSpace = this.toMatrix(parent.getModelSpacePosition(), parent.getModelSpaceRotation(), parent.getModelSpaceScale(), tempVars.tempMat4);
                    //the bone will now move with its parent in model space
                    //now we need to subtract the difference between current parent's model matrix and its initial model matrix
                    boneMatrixInModelSpace = initialParentMatrixInModelSpace.mult(boneMatrixInModelSpace);
                    Matrix4f diffMatrix = initialParentMatrixInModelSpace.mult(currentParentMatrixInModelSpace.invert());
                    boneMatrixInModelSpace.multLocal(diffMatrix);
                //now the bone will have its position in model space with initial parent's model matrix added
                }
                bone.setBindTransforms(boneMatrixInModelSpace.toTranslationVector(), boneMatrixInModelSpace.toRotationQuat(), boneMatrixInModelSpace.toScaleVector());
                break;
            default:
                tempVars.release();
                throw new IllegalStateException("Invalid space type for target object: " + space.toString());
        }
        tempVars.release();
        skeleton.updateWorldVectors();
    } else {
        switch(space) {
            case CONSTRAINT_SPACE_LOCAL:
                feature.getLocalTransform().set(transform);
                break;
            case CONSTRAINT_SPACE_WORLD:
                if (feature.getParent() == null) {
                    feature.setLocalTransform(transform);
                } else {
                    Transform parentWorldTransform = feature.getParent().getWorldTransform();
                    TempVars tempVars = TempVars.get();
                    Matrix4f parentInverseMatrix = this.toMatrix(parentWorldTransform, tempVars.tempMat4).invertLocal();
                    Matrix4f m = this.toMatrix(transform, tempVars.tempMat42);
                    m = m.multLocal(parentInverseMatrix);
                    tempVars.release();
                    transform.setTranslation(m.toTranslationVector());
                    transform.setRotation(m.toRotationQuat());
                    transform.setScale(m.toScaleVector());
                    feature.setLocalTransform(transform);
                }
                break;
            default:
                throw new IllegalStateException("Invalid space type for spatial object: " + space.toString());
        }
    }
}
Also used : Matrix4f(com.jme3.math.Matrix4f) Spatial(com.jme3.scene.Spatial) BoneContext(com.jme3.scene.plugins.blender.animations.BoneContext) Skeleton(com.jme3.animation.Skeleton) Bone(com.jme3.animation.Bone) TempVars(com.jme3.util.TempVars) Transform(com.jme3.math.Transform)

Example 15 with Matrix

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

the class AndroidSensorJoyInput method updateOrientation.

/**
     * Calculates the device orientation based off the data recieved from the
     * Acceleration Sensor and Mangetic Field sensor
     * Values are returned relative to the Earth.
     *
     * From the Android Doc
     *
     * Computes the device's orientation based on the rotation matrix. When it returns, the array values is filled with the result:
     *  values[0]: azimuth, rotation around the Z axis.
     *  values[1]: pitch, rotation around the X axis.
     *  values[2]: roll, rotation around the Y axis.
     *
     * The reference coordinate-system used is different from the world
     * coordinate-system defined for the rotation matrix:
     *  X is defined as the vector product Y.Z (It is tangential to the ground at the device's current location and roughly points West).
     *  Y is tangential to the ground at the device's current location and points towards the magnetic North Pole.
     *  Z points towards the center of the Earth and is perpendicular to the ground.
     *
     * @return True if Orientation was calculated
     */
private boolean updateOrientation() {
    SensorData sensorData;
    AndroidSensorJoystickAxis axis;
    final float[] curInclinationMat = new float[16];
    final float[] curRotationMat = new float[16];
    final float[] rotatedRotationMat = new float[16];
    final float[] accValues = new float[3];
    final float[] magValues = new float[3];
    final float[] orderedOrientation = new float[3];
    // if the Gravity Sensor is available, use it for orientation, if not
    // use the accelerometer
    // NOTE: Seemed to work worse, so just using accelerometer
    //        sensorData = sensors.get(Sensor.TYPE_GRAVITY);
    //        if (sensorData == null) {
    sensorData = sensors.get(Sensor.TYPE_ACCELEROMETER);
    if (sensorData == null || !sensorData.enabled || !sensorData.haveData) {
        return false;
    }
    if (sensorData.sensorAccuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
        return false;
    }
    synchronized (sensorData.valuesLock) {
        accValues[0] = sensorData.lastValues[0];
        accValues[1] = sensorData.lastValues[1];
        accValues[2] = sensorData.lastValues[2];
    }
    sensorData = sensors.get(Sensor.TYPE_MAGNETIC_FIELD);
    if (sensorData == null || !sensorData.enabled || !sensorData.haveData) {
        return false;
    }
    if (sensorData.sensorAccuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
        return false;
    }
    synchronized (sensorData.valuesLock) {
        magValues[0] = sensorData.lastValues[0];
        magValues[1] = sensorData.lastValues[1];
        magValues[2] = sensorData.lastValues[2];
    }
    if (SensorManager.getRotationMatrix(curRotationMat, curInclinationMat, accValues, magValues)) {
        final float[] orientValues = new float[3];
        if (remapCoordinates(curRotationMat, rotatedRotationMat)) {
            SensorManager.getOrientation(rotatedRotationMat, orientValues);
            //                logger.log(Level.FINE, "Orientation Values: {0}, {1}, {2}",
            //                        new Object[]{orientValues[0], orientValues[1], orientValues[2]});
            // need to reorder to make it x, y, z order instead of z, x, y order
            orderedOrientation[0] = orientValues[1];
            orderedOrientation[1] = orientValues[2];
            orderedOrientation[2] = orientValues[0];
            sensorData = sensors.get(Sensor.TYPE_ORIENTATION);
            if (sensorData != null && sensorData.axes.size() > 0) {
                for (int i = 0; i < orderedOrientation.length; i++) {
                    axis = sensorData.axes.get(i);
                    if (axis != null) {
                        axis.setCurRawValue(orderedOrientation[i]);
                        if (!sensorData.haveData) {
                            sensorData.haveData = true;
                        } else {
                            if (axis.isChanged()) {
                                joyInput.addEvent(new JoyAxisEvent(axis, axis.getJoystickAxisValue()));
                            }
                        }
                    }
                }
            } else if (sensorData != null) {
                if (!sensorData.haveData) {
                    sensorData.haveData = true;
                }
            }
            return true;
        } else {
            logger.log(Level.FINE, "remapCoordinateSystem failed");
        }
    } else {
        logger.log(Level.FINE, "getRotationMatrix returned false");
    }
    return false;
}
Also used : JoyAxisEvent(com.jme3.input.event.JoyAxisEvent)

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