Java Code Examples for com.jme3.util.TempVars#get()

The following examples show how to use com.jme3.util.TempVars#get() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Geometry.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/**
 * Recomputes the matrix returned by {@link Geometry#getWorldMatrix() }.
 * This will require a localized transform update for this geometry.
 */
public void computeWorldMatrix() {
    // Force a local update of the geometry's transform
    checkDoTransformUpdate();

    // Compute the cached world matrix
    cachedWorldMat.loadIdentity();
    if (ignoreTransform) {
        return;
    }
    cachedWorldMat.setRotationQuaternion(worldTransform.getRotation());
    cachedWorldMat.setTranslation(worldTransform.getTranslation());

    TempVars vars = TempVars.get();
    Matrix4f scaleMat = vars.tempMat4;
    scaleMat.loadIdentity();
    scaleMat.scale(worldTransform.getScale());
    cachedWorldMat.multLocal(scaleMat);
    vars.release();
}
 
Example 2
Source File: Matrix4f.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/**
     * <code>fillFloatBuffer</code> fills a FloatBuffer object with the matrix
     * data.
     *
     * @param fb
     *            the buffer to fill, starting at current position. Must have
     *            room for 16 more floats.
     * @param columnMajor
     *            if true, this buffer should be filled with column major data,
     *            otherwise it will be filled row major.
     * @return matrix data as a FloatBuffer. (position is advanced by 16 and any
     *         limit set is not changed).
     */
    public FloatBuffer fillFloatBuffer(FloatBuffer fb, boolean columnMajor) {
//        if (columnMajor) {
//            fb.put(m00).put(m10).put(m20).put(m30);
//            fb.put(m01).put(m11).put(m21).put(m31);
//            fb.put(m02).put(m12).put(m22).put(m32);
//            fb.put(m03).put(m13).put(m23).put(m33);
//        } else {
//            fb.put(m00).put(m01).put(m02).put(m03);
//            fb.put(m10).put(m11).put(m12).put(m13);
//            fb.put(m20).put(m21).put(m22).put(m23);
//            fb.put(m30).put(m31).put(m32).put(m33);
//        }

        TempVars vars = TempVars.get();

        fillFloatArray(vars.matrixWrite, columnMajor);
        fb.put(vars.matrixWrite, 0, 16);

        vars.release();

        return fb;
    }
 
Example 3
Source File: Matrix4f.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
public void fromFrame(Vector3f location, Vector3f direction, Vector3f up, Vector3f left) {
    TempVars vars = TempVars.get();
    try {
        Vector3f fwdVector = vars.vect1.set(direction);
        Vector3f leftVector = vars.vect2.set(fwdVector).crossLocal(up);
        Vector3f upVector = vars.vect3.set(leftVector).crossLocal(fwdVector);

        m00 = leftVector.x;
        m01 = leftVector.y;
        m02 = leftVector.z;
        m03 = -leftVector.dot(location);

        m10 = upVector.x;
        m11 = upVector.y;
        m12 = upVector.z;
        m13 = -upVector.dot(location);

        m20 = -fwdVector.x;
        m21 = -fwdVector.y;
        m22 = -fwdVector.z;
        m23 = fwdVector.dot(location);

        m30 = 0f;
        m31 = 0f;
        m32 = 0f;
        m33 = 1f;
    } finally {
        vars.release();
    }
}
 
Example 4
Source File: OrientedBoxProbeArea.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private void updateMatrix() {
    TempVars vars = TempVars.get();
    Matrix3f r = vars.tempMat3;
    Matrix4f u = uniformMatrix;
    transform.getRotation().toRotationMatrix(r);

    u.m00 = r.get(0,0);
    u.m10 = r.get(1,0);
    u.m20 = r.get(2,0);
    u.m01 = r.get(0,1);
    u.m11 = r.get(1,1);
    u.m21 = r.get(2,1);
    u.m02 = r.get(0,2);
    u.m12 = r.get(1,2);
    u.m22 = r.get(2,2);

    //scale
    u.m30 = transform.getScale().x;
    u.m31 = transform.getScale().y;
    u.m32 = transform.getScale().z;

    //position
    u.m03 = transform.getTranslation().x;
    u.m13 = transform.getTranslation().y;
    u.m23 = transform.getTranslation().z;

    vars.release();
}
 
Example 5
Source File: BoundingBox.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
@Override
public BoundingVolume transform(Matrix4f trans, BoundingVolume store) {
    BoundingBox box;
    if (store == null || store.getType() != Type.AABB) {
        box = new BoundingBox();
    } else {
        box = (BoundingBox) store;
    }
    TempVars vars = TempVars.get();

    float w = trans.multProj(center, box.center);
    box.center.divideLocal(w);

    Matrix3f transMatrix = vars.tempMat3;
    trans.toRotationMatrix(transMatrix);

    // Make the rotation matrix all positive to get the maximum x/y/z extent
    transMatrix.absoluteLocal();

    vars.vect1.set(xExtent, yExtent, zExtent);
    transMatrix.mult(vars.vect1, vars.vect1);

    // Assign the biggest rotations after scales.
    box.xExtent = FastMath.abs(vars.vect1.getX());
    box.yExtent = FastMath.abs(vars.vect1.getY());
    box.zExtent = FastMath.abs(vars.vect1.getZ());

    vars.release();

    return box;
}
 
Example 6
Source File: KinematicRagdollControl.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Update this control in IK mode, based on IK targets.
 *
 * @param tpf the time interval between frames (in seconds, &ge;0)
 */
private void ikUpdate(float tpf){
    TempVars vars = TempVars.get();

    Quaternion tmpRot1 = vars.quat1;
    Quaternion[] tmpRot2 = new Quaternion[]{vars.quat2, new Quaternion()};

    Iterator<String> it = ikTargets.keySet().iterator();
    float distance;
    Bone bone;
    String boneName;
    while (it.hasNext()) {
        
        boneName = it.next();
        bone = boneLinks.get(boneName).bone;
        if (!bone.hasUserControl()) {
            Logger.getLogger(KinematicRagdollControl.class.getSimpleName()).log(Level.FINE, "{0} doesn't have user control", boneName);
            continue;
        }
        distance = bone.getModelSpacePosition().distance(ikTargets.get(boneName));
        if (distance < IKThreshold) {
            Logger.getLogger(KinematicRagdollControl.class.getSimpleName()).log(Level.FINE, "Distance is close enough");
            continue;
        }
        int depth = 0;
        int maxDepth = ikChainDepth.get(bone.getName());
        updateBone(boneLinks.get(bone.getName()), tpf * FastMath.sqrt(distance), vars, tmpRot1, tmpRot2, bone, ikTargets.get(boneName), depth, maxDepth);

        Vector3f position = vars.vect1;
        
        for (PhysicsBoneLink link : boneLinks.values()) {
            matchPhysicObjectToBone(link, position, tmpRot1);
        }
    }
    vars.release();
}
 
Example 7
Source File: BoundingSphere.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private int collideWithRay(Ray ray) {
    TempVars vars = TempVars.get();

    Vector3f diff = vars.vect1.set(ray.getOrigin()).subtractLocal(
            center);
    float a = diff.dot(diff) - (getRadius() * getRadius());
    float a1, discr;
    if (a <= 0.0) {
        // inside sphere
        vars.release();
        return 1;
    }

    a1 = ray.direction.dot(diff);
    vars.release();
    if (a1 >= 0.0) {
        return 0;
    }

    discr = a1 * a1 - a;
    if (discr < 0.0) {
        return 0;
    } else if (discr >= FastMath.ZERO_TOLERANCE) {
        return 2;
    }
    return 1;
}
 
Example 8
Source File: ShadowUtil.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Compute bounds of a geomList
 * @param list
 * @param mat
 * @return a new instance
 */
public static BoundingBox computeUnionBound(GeometryList list, Matrix4f mat) {
    BoundingBox bbox = new BoundingBox();
    TempVars tempv = TempVars.get();
    for (int i = 0; i < list.size(); i++) {
        BoundingVolume vol = list.get(i).getWorldBound();
        BoundingVolume store = vol.transform(mat, tempv.bbox);
        //Nehon : prevent NaN and infinity values to screw the final bounding box
        if (!Float.isNaN(store.getCenter().x) && !Float.isInfinite(store.getCenter().x)) {
            bbox.mergeLocal(store);
        }
    }
    tempv.release();
    return bbox;
}
 
Example 9
Source File: BIHTree.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private int collideWithRay(Ray r,
        Matrix4f worldMatrix,
        BoundingVolume worldBound,
        CollisionResults results) {

    TempVars vars = TempVars.get();
    try {
        CollisionResults boundResults = vars.collisionResults;
        boundResults.clear();
        worldBound.collideWith(r, boundResults);
        if (boundResults.size() > 0) {
            float tMin = boundResults.getClosestCollision().getDistance();
            float tMax = boundResults.getFarthestCollision().getDistance();

            if (tMax <= 0) {
                tMax = Float.POSITIVE_INFINITY;
            } else if (tMin == tMax) {
                tMin = 0;
            }

            if (tMin <= 0) {
                tMin = 0;
            }

            if (r.getLimit() < Float.POSITIVE_INFINITY) {
                tMax = Math.min(tMax, r.getLimit());
                if (tMin > tMax){
                    return 0;
                }
            }

//            return root.intersectBrute(r, worldMatrix, this, tMin, tMax, results);
            return root.intersectWhere(r, worldMatrix, this, tMin, tMax, results);
        }
        return 0;
    } finally {
        vars.release();
    }
}
 
Example 10
Source File: BoundingVolume.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
public int collideWith(Collidable other) {
    TempVars tempVars = TempVars.get();
    try {
        CollisionResults tempResults = tempVars.collisionResults;
        tempResults.clear();
        return collideWith(other, tempResults);
    } finally {
        tempVars.release();
    }
}
 
Example 11
Source File: Spatial.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Computes the world transform of this Spatial in the most
 * efficient manner possible.
 */
void checkDoTransformUpdate() {
    if ((refreshFlags & RF_TRANSFORM) == 0) {
        return;
    }

    if (parent == null) {
        worldTransform.set(localTransform);
        refreshFlags &= ~RF_TRANSFORM;
    } else {
        TempVars vars = TempVars.get();

        Spatial[] stack = vars.spatialStack;
        Spatial rootNode = this;
        int i = 0;
        while (true) {
            Spatial hisParent = rootNode.parent;
            if (hisParent == null) {
                rootNode.worldTransform.set(rootNode.localTransform);
                rootNode.refreshFlags &= ~RF_TRANSFORM;
                i--;
                break;
            }

            stack[i] = rootNode;

            if ((hisParent.refreshFlags & RF_TRANSFORM) == 0) {
                break;
            }

            rootNode = hisParent;
            i++;
        }

        vars.release();

        for (int j = i; j >= 0; j--) {
            rootNode = stack[j];
            //rootNode.worldTransform.set(rootNode.localTransform);
            //rootNode.worldTransform.combineWithParent(rootNode.parent.worldTransform);
            //rootNode.refreshFlags &= ~RF_TRANSFORM;
            rootNode.updateWorldTransforms();
        }
    }
}
 
Example 12
Source File: Spatial.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * <code>lookAt</code> is a convenience method for auto-setting the local
 * rotation based on a position in world space and an up vector. It computes the rotation
 * to transform the z-axis to point onto 'position' and the y-axis to 'up'.
 * Unlike {@link Quaternion#lookAt(com.jme3.math.Vector3f, com.jme3.math.Vector3f) }
 * this method takes a world position to look at and not a relative direction.
 *
 * Note : 28/01/2013 this method has been fixed as it was not taking into account the parent rotation.
 * This was resulting in improper rotation when the spatial had rotated parent nodes.
 * This method is intended to work in world space, so no matter what parent graph the
 * spatial has, it will look at the given position in world space.
 *
 * @param position
 *            where to look at in terms of world coordinates
 * @param upVector
 *            a vector indicating the (local) up direction. (typically {0,
 *            1, 0} in jME.)
 */
public void lookAt(Vector3f position, Vector3f upVector) {
    Vector3f worldTranslation = getWorldTranslation();

    TempVars vars = TempVars.get();

    Vector3f compVecA = vars.vect4;
    compVecA.set(position).subtractLocal(worldTranslation);
    getLocalRotation().lookAt(compVecA, upVector);
    if (getParent() != null) {
        Quaternion rot = vars.quat1;
        rot = rot.set(parent.getWorldRotation()).inverseLocal().multLocal(getLocalRotation());
        rot.normalizeLocal();
        setLocalRotation(rot);
    }
    vars.release();
    setTransformRefresh();
}
 
Example 13
Source File: KinematicRagdollControl.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Update this control in Ragdoll mode, based on Bullet physics.
 *
 * @param tpf the time interval between frames (in seconds, &ge;0)
 */
protected void ragDollUpdate(float tpf) {
    TempVars vars = TempVars.get();
    Quaternion tmpRot1 = vars.quat1;
    Quaternion tmpRot2 = vars.quat2;

    for (PhysicsBoneLink link : boneLinks.values()) {

        Vector3f position = vars.vect1;

        //retrieving bone position in physics world space
        Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
        //transforming this position with inverse transforms of the model
        targetModel.getWorldTransform().transformInverseVector(p, position);

        //retrieving bone rotation in physics world space
        Quaternion q = link.rigidBody.getMotionState().getWorldRotationQuat();

        //multiplying this rotation by the initialWorld rotation of the bone,
        //then transforming it with the inverse world rotation of the model
        tmpRot1.set(q).multLocal(link.initalWorldRotation);
        tmpRot2.set(targetModel.getWorldRotation()).inverseLocal().mult(tmpRot1, tmpRot1);
        tmpRot1.normalizeLocal();

        //if the bone is the root bone, we apply the physic's transform to the model, so its position and rotation are correctly updated
        if (link.bone.getParent() == null) {

            //offsetting the physic's position/rotation by the root bone inverse model space position/rotaion
            modelPosition.set(p).subtractLocal(link.bone.getBindPosition());
            targetModel.getParent().getWorldTransform().transformInverseVector(modelPosition, modelPosition);
            modelRotation.set(q).multLocal(tmpRot2.set(link.bone.getBindRotation()).inverseLocal());


            //applying transforms to the model
            targetModel.setLocalTranslation(modelPosition);

            targetModel.setLocalRotation(modelRotation);

            //Applying computed transforms to the bone
            link.bone.setUserTransformsInModelSpace(position, tmpRot1);

        } else {
            //some bones of the skeleton might not be associated with a collision shape.
            //So we update them recusively
            RagdollUtils.setTransform(link.bone, position, tmpRot1, false, boneList);
        }
    }
    vars.release();
}
 
Example 14
Source File: MathUtils.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Returns the shortest distance between a Ray and a segment.
 * The segment is defined by a start position and an end position in world space
 * The distance returned will be in world space (world units).
 * If the camera parameter is not null the distance will be returned in screen space (pixels)
 *
 * @param ray      The ray
 * @param segStart The start position of the segment in world space
 * @param segEnd   The end position of the segment in world space
 * @param camera   The renderer camera if the distance is required in screen space. Null if the distance is required in world space
 * @return the shortest distance between the ray and the segment or -1 if no solution is found.
 */
public static float raySegmentShortestDistance(Ray ray, Vector3f segStart, Vector3f segEnd, Camera camera) {
    // Algorithm is ported from the C algorithm of
    // Paul Bourke at http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/
    TempVars vars = TempVars.get();
    Vector3f resultSegmentPoint1 = vars.vect1;
    Vector3f resultSegmentPoint2 = vars.vect2;

    Vector3f p1 = segStart;
    Vector3f p2 = segEnd;
    Vector3f p3 = ray.origin;
    Vector3f p4 = vars.vect3.set(ray.getDirection()).multLocal(Math.min(ray.getLimit(), 1000)).addLocal(ray.getOrigin());
    Vector3f p13 = vars.vect4.set(p1).subtractLocal(p3);
    Vector3f p43 = vars.vect5.set(p4).subtractLocal(p3);

    if (p43.lengthSquared() < 0.0001) {
        vars.release();
        return -1;
    }
    Vector3f p21 = vars.vect6.set(p2).subtractLocal(p1);
    if (p21.lengthSquared() < 0.0001) {
        vars.release();
        return -1;
    }

    double d1343 = p13.x * (double) p43.x + (double) p13.y * p43.y + (double) p13.z * p43.z;
    double d4321 = p43.x * (double) p21.x + (double) p43.y * p21.y + (double) p43.z * p21.z;
    double d1321 = p13.x * (double) p21.x + (double) p13.y * p21.y + (double) p13.z * p21.z;
    double d4343 = p43.x * (double) p43.x + (double) p43.y * p43.y + (double) p43.z * p43.z;
    double d2121 = p21.x * (double) p21.x + (double) p21.y * p21.y + (double) p21.z * p21.z;

    double denom = d2121 * d4343 - d4321 * d4321;
    if (Math.abs(denom) < 0.0001) {
        vars.release();
        return -1;
    }
    double numer = d1343 * d4321 - d1321 * d4343;

    double mua = numer / denom;
    double mub = (d1343 + d4321 * (mua)) / d4343;

    resultSegmentPoint1.x = (float) (p1.x + mua * p21.x);
    resultSegmentPoint1.y = (float) (p1.y + mua * p21.y);
    resultSegmentPoint1.z = (float) (p1.z + mua * p21.z);
    resultSegmentPoint2.x = (float) (p3.x + mub * p43.x);
    resultSegmentPoint2.y = (float) (p3.y + mub * p43.y);
    resultSegmentPoint2.z = (float) (p3.z + mub * p43.z);

    //check if result 1 is in the segment section.
    float startToPoint = vars.vect3.set(resultSegmentPoint1).subtractLocal(segStart).lengthSquared();
    float endToPoint = vars.vect3.set(resultSegmentPoint1).subtractLocal(segEnd).lengthSquared();
    float segLength = vars.vect3.set(segEnd).subtractLocal(segStart).lengthSquared();
    if (startToPoint > segLength || endToPoint > segLength) {
        vars.release();
        return -1;
    }

    if (camera != null) {
        //camera is not null let's convert the points in screen space
        camera.getScreenCoordinates(resultSegmentPoint1, resultSegmentPoint1);
        camera.getScreenCoordinates(resultSegmentPoint2, resultSegmentPoint2);
    }

    float length = resultSegmentPoint1.subtractLocal(resultSegmentPoint2).length();
    vars.release();
    return length;
}
 
Example 15
Source File: Bone.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Blends the given animation transform onto the bone's local transform.
 * <p>
 * Subsequent calls of this method stack up, with the final transformation
 * of the bone computed at {@link #updateModelTransforms() } which resets
 * the stack.
 * <p>
 * E.g. a single transform blend with weight = 0.5 followed by an
 * updateModelTransforms() call will result in final transform = transform * 0.5.
 * Two transform blends with weight = 0.5 each will result in the two
 * transforms blended together (nlerp) with blend = 0.5.
 * 
 * @param translation The translation to blend in
 * @param rotation The rotation to blend in
 * @param scale The scale to blend in
 * @param weight The weight of the transform to apply. Set to 1.0 to prevent
 * any other transform from being applied until updateModelTransforms().
 */
void blendAnimTransforms(Vector3f translation, Quaternion rotation, Vector3f scale, float weight) {
    if (userControl) {
        return;
    }
    
    if (weight == 0) {
        // Do not apply this transform at all.
        return;
    }

    if (currentWeightSum == 1){
        return; // More than 2 transforms are being blended
    } else if (currentWeightSum == -1 || currentWeightSum == 0) {
        // Set the transform fully
        localPos.set(bindPos).addLocal(translation);
        localRot.set(bindRot).multLocal(rotation);
        if (scale != null) {
            localScale.set(bindScale).multLocal(scale);
        }
        // Set the weight. It will be applied in updateModelTransforms().
        currentWeightSum = weight;
    } else {
        // The weight is already set. 
        // Blend in the new transform.
        TempVars vars = TempVars.get();

        Vector3f tmpV = vars.vect1;
        Vector3f tmpV2 = vars.vect2;
        Quaternion tmpQ = vars.quat1;
        
        tmpV.set(bindPos).addLocal(translation);
        localPos.interpolateLocal(tmpV, weight);

        tmpQ.set(bindRot).multLocal(rotation);
        localRot.nlerp(tmpQ, weight);

        if (scale != null) {
            tmpV2.set(bindScale).multLocal(scale);
            localScale.interpolateLocal(tmpV2, weight);
        }
    
        // Ensures no new weights will be blended in the future.
        currentWeightSum = 1;
        
        vars.release();
    }
}
 
Example 16
Source File: SkeletonControl.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Method to apply skinning transforms to a mesh's buffers
 *
 * @param mesh the mesh
 * @param offsetMatrices the offset matices to apply
 */
private void applySkinning(Mesh mesh, Matrix4f[] offsetMatrices) {
    int maxWeightsPerVert = mesh.getMaxNumWeights();
    if (maxWeightsPerVert <= 0) {
        throw new IllegalStateException("Max weights per vert is incorrectly set!");
    }
    int fourMinusMaxWeights = 4 - maxWeightsPerVert;

    // NOTE: This code assumes the vertex buffer is in bind pose
    // resetToBind() has been called this frame
    VertexBuffer vb = mesh.getBuffer(Type.Position);
    FloatBuffer fvb = (FloatBuffer) vb.getData();
    fvb.rewind();

    VertexBuffer nb = mesh.getBuffer(Type.Normal);
    FloatBuffer fnb = (FloatBuffer) nb.getData();
    fnb.rewind();

    // get boneIndexes and weights for mesh
    IndexBuffer ib = IndexBuffer.wrapIndexBuffer(mesh.getBuffer(Type.BoneIndex).getData());
    FloatBuffer wb = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData();

    wb.rewind();

    float[] weights = wb.array();
    int idxWeights = 0;

    TempVars vars = TempVars.get();

    float[] posBuf = vars.skinPositions;
    float[] normBuf = vars.skinNormals;

    int iterations = (int) FastMath.ceil(fvb.limit() / ((float) posBuf.length));
    int bufLength = posBuf.length;
    for (int i = iterations - 1; i >= 0; i--) {
        // read next set of positions and normals from native buffer
        bufLength = Math.min(posBuf.length, fvb.remaining());
        fvb.get(posBuf, 0, bufLength);
        fnb.get(normBuf, 0, bufLength);
        int verts = bufLength / 3;
        int idxPositions = 0;

        // iterate vertices and apply skinning transform for each effecting bone
        for (int vert = verts - 1; vert >= 0; vert--) {
            // Skip this vertex if the first weight is zero.
            if (weights[idxWeights] == 0) {
                idxPositions += 3;
                idxWeights += 4;
                continue;
            }

            float nmx = normBuf[idxPositions];
            float vtx = posBuf[idxPositions++];
            float nmy = normBuf[idxPositions];
            float vty = posBuf[idxPositions++];
            float nmz = normBuf[idxPositions];
            float vtz = posBuf[idxPositions++];

            float rx = 0, ry = 0, rz = 0, rnx = 0, rny = 0, rnz = 0;

            for (int w = maxWeightsPerVert - 1; w >= 0; w--) {
                float weight = weights[idxWeights];
                Matrix4f mat = offsetMatrices[ib.get(idxWeights++)];

                rx += (mat.m00 * vtx + mat.m01 * vty + mat.m02 * vtz + mat.m03) * weight;
                ry += (mat.m10 * vtx + mat.m11 * vty + mat.m12 * vtz + mat.m13) * weight;
                rz += (mat.m20 * vtx + mat.m21 * vty + mat.m22 * vtz + mat.m23) * weight;

                rnx += (nmx * mat.m00 + nmy * mat.m01 + nmz * mat.m02) * weight;
                rny += (nmx * mat.m10 + nmy * mat.m11 + nmz * mat.m12) * weight;
                rnz += (nmx * mat.m20 + nmy * mat.m21 + nmz * mat.m22) * weight;
            }

            idxWeights += fourMinusMaxWeights;

            idxPositions -= 3;
            normBuf[idxPositions] = rnx;
            posBuf[idxPositions++] = rx;
            normBuf[idxPositions] = rny;
            posBuf[idxPositions++] = ry;
            normBuf[idxPositions] = rnz;
            posBuf[idxPositions++] = rz;
        }

        fvb.position(fvb.position() - bufLength);
        fvb.put(posBuf, 0, bufLength);
        fnb.position(fnb.position() - bufLength);
        fnb.put(normBuf, 0, bufLength);
    }

    vars.release();

    vb.updateData(fvb);
    nb.updateData(fnb);

}
 
Example 17
Source File: BoundingBox.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
@Override
public float distanceToEdge(Vector3f point) {
    // compute coordinates of point in box coordinate system
    TempVars vars = TempVars.get();
    Vector3f closest = vars.vect1;

    point.subtract(center, closest);

    // project test point onto box
    float sqrDistance = 0.0f;
    float delta;

    if (closest.x < -xExtent) {
        delta = closest.x + xExtent;
        sqrDistance += delta * delta;
        closest.x = -xExtent;
    } else if (closest.x > xExtent) {
        delta = closest.x - xExtent;
        sqrDistance += delta * delta;
        closest.x = xExtent;
    }

    if (closest.y < -yExtent) {
        delta = closest.y + yExtent;
        sqrDistance += delta * delta;
        closest.y = -yExtent;
    } else if (closest.y > yExtent) {
        delta = closest.y - yExtent;
        sqrDistance += delta * delta;
        closest.y = yExtent;
    }

    if (closest.z < -zExtent) {
        delta = closest.z + zExtent;
        sqrDistance += delta * delta;
        closest.z = -zExtent;
    } else if (closest.z > zExtent) {
        delta = closest.z - zExtent;
        sqrDistance += delta * delta;
        closest.z = zExtent;
    }

    vars.release();
    return FastMath.sqrt(sqrDistance);
}
 
Example 18
Source File: BIHNode.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
public final int intersectWhere(Collidable col,
            BoundingBox box,
            Matrix4f worldMatrix,
            BIHTree tree,
            CollisionResults results) {

        TempVars vars = TempVars.get();
        ArrayList<BIHStackData> stack = vars.bihStack;
        stack.clear();

        float[] minExts = {box.getCenter().x - box.getXExtent(),
            box.getCenter().y - box.getYExtent(),
            box.getCenter().z - box.getZExtent()};

        float[] maxExts = {box.getCenter().x + box.getXExtent(),
            box.getCenter().y + box.getYExtent(),
            box.getCenter().z + box.getZExtent()};

        stack.add(new BIHStackData(this, 0, 0));

        Triangle t = new Triangle();
        int cols = 0;

        stackloop:
        while (stack.size() > 0) {
            BIHNode node = stack.remove(stack.size() - 1).node;

            while (node.axis != 3) {
                int a = node.axis;

                float maxExt = maxExts[a];
                float minExt = minExts[a];

                if (node.leftPlane < node.rightPlane) {
                    // means there's a gap in the middle
                    // if the box is in that gap, we stop there
                    if (minExt > node.leftPlane
                            && maxExt < node.rightPlane) {
                        continue stackloop;
                    }
                }

                if (maxExt < node.rightPlane) {
                    node = node.left;
                } else if (minExt > node.leftPlane) {
                    node = node.right;
                } else {
                    stack.add(new BIHStackData(node.right, 0, 0));
                    node = node.left;
                }
//                if (maxExt < node.leftPlane
//                 && maxExt < node.rightPlane){
//                    node = node.left;
//                }else if (minExt > node.leftPlane
//                       && minExt > node.rightPlane){
//                    node = node.right;
//                }else{

//                }
            }

            for (int i = node.leftIndex; i <= node.rightIndex; i++) {
                tree.getTriangle(i, t.get1(), t.get2(), t.get3());
                if (worldMatrix != null) {
                    worldMatrix.mult(t.get1(), t.get1());
                    worldMatrix.mult(t.get2(), t.get2());
                    worldMatrix.mult(t.get3(), t.get3());
                }

                int added = col.collideWith(t, results);

                if (added > 0) {
                    int index = tree.getTriangleIndex(i);
                    int start = results.size() - added;

                    for (int j = start; j < results.size(); j++) {
                        CollisionResult cr = results.getCollisionDirect(j);
                        cr.setTriangleIndex(index);
                    }

                    cols += added;
                }
            }
        }
        vars.release();
        return cols;
    }
 
Example 19
Source File: Line.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Fit this line to the specified points.
 *
 * @param points a buffer containing location vectors, or null
 */
public void orthogonalLineFit(FloatBuffer points) {
    if (points == null) {
        return;
    }

    TempVars vars = TempVars.get();

    Vector3f compVec1 = vars.vect1;
    Vector3f compVec2 = vars.vect2;
    Matrix3f compMat1 = vars.tempMat3;
    Eigen3f compEigen1 = vars.eigen;

    points.rewind();

    // compute average of points
    int length = points.remaining() / 3;

    BufferUtils.populateFromBuffer(origin, points, 0);
    for (int i = 1; i < length; i++) {
        BufferUtils.populateFromBuffer(compVec1, points, i);
        origin.addLocal(compVec1);
    }

    origin.multLocal(1f / length);

    // compute sums of products
    float sumXX = 0.0f, sumXY = 0.0f, sumXZ = 0.0f;
    float sumYY = 0.0f, sumYZ = 0.0f, sumZZ = 0.0f;

    points.rewind();
    for (int i = 0; i < length; i++) {
        BufferUtils.populateFromBuffer(compVec1, points, i);
        compVec1.subtract(origin, compVec2);
        sumXX += compVec2.x * compVec2.x;
        sumXY += compVec2.x * compVec2.y;
        sumXZ += compVec2.x * compVec2.z;
        sumYY += compVec2.y * compVec2.y;
        sumYZ += compVec2.y * compVec2.z;
        sumZZ += compVec2.z * compVec2.z;
    }

    //find the smallest eigen vector for the direction vector
    compMat1.m00 = sumYY + sumZZ;
    compMat1.m01 = -sumXY;
    compMat1.m02 = -sumXZ;
    compMat1.m10 = -sumXY;
    compMat1.m11 = sumXX + sumZZ;
    compMat1.m12 = -sumYZ;
    compMat1.m20 = -sumXZ;
    compMat1.m21 = -sumYZ;
    compMat1.m22 = sumXX + sumYY;

    compEigen1.calculateEigen(compMat1);
    direction = compEigen1.getEigenVector(0);

    vars.release();
}
 
Example 20
Source File: DefaultLightFilter.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
@Override
public void filterLights(Geometry geometry, LightList filteredLightList) {
    TempVars vars = TempVars.get();
    try {
        LightList worldLights = geometry.getWorldLightList();
       
        for (int i = 0; i < worldLights.size(); i++) {
            Light light = worldLights.get(i);

            // If this light is not enabled it will be ignored.
            if (!light.isEnabled()) {
                continue;
            }

            if (light.frustumCheckNeeded) {
                processedLights.add(light);
                light.frustumCheckNeeded = false;
                light.intersectsFrustum = light.intersectsFrustum(camera, vars);
            }

            if (!light.intersectsFrustum) {
                continue;
            }

            BoundingVolume bv = geometry.getWorldBound();
            
            if (bv instanceof BoundingBox) {
                if (!light.intersectsBox((BoundingBox)bv, vars)) {
                    continue;
                }
            } else if (bv instanceof BoundingSphere) {
                if (!Float.isInfinite( ((BoundingSphere)bv).getRadius() )) {
                    if (!light.intersectsSphere((BoundingSphere)bv, vars)) {
                        continue;
                    }
                }
            }
            
            if (light.getType() == Light.Type.Probe) {
                probeBlendStrat.registerProbe((LightProbe) light);
            } else {
                filteredLightList.add(light);
            }
            
        }
        
        probeBlendStrat.populateProbes(geometry, filteredLightList);

    } finally {
        vars.release();
    }
}