use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.
the class Quaternion method lookAt.
/**
* <code>lookAt</code> is a convienence method for auto-setting the
* quaternion based on a direction and an up vector. It computes
* the rotation to transform the z-axis to point into 'direction'
* and the y-axis to 'up'.
*
* @param direction
* where to look at in terms of local coordinates
* @param up
* a vector indicating the local up direction.
* (typically {0, 1, 0} in jME.)
*/
public void lookAt(Vector3f direction, Vector3f up) {
TempVars vars = TempVars.get();
vars.vect3.set(direction).normalizeLocal();
vars.vect1.set(up).crossLocal(direction).normalizeLocal();
vars.vect2.set(direction).crossLocal(vars.vect1).normalizeLocal();
fromAxes(vars.vect1, vars.vect2, vars.vect3);
vars.release();
}
use of com.jme3.util.TempVars 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;
}
use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.
the class Ray method intersects.
/**
* <code>intersects</code> does the actual intersection work.
*
* @param v0
* first point of the triangle.
* @param v1
* second point of the triangle.
* @param v2
* third point of the triangle.
* @param store
* storage vector - if null, no intersection is calc'd
* @param doPlanar
* true if we are calcing planar results.
* @param quad
* @return true if ray intersects triangle
*/
private boolean intersects(Vector3f v0, Vector3f v1, Vector3f v2, Vector3f store, boolean doPlanar, boolean quad) {
TempVars vars = TempVars.get();
Vector3f tempVa = vars.vect1, tempVb = vars.vect2, tempVc = vars.vect3, tempVd = vars.vect4;
Vector3f diff = origin.subtract(v0, tempVa);
Vector3f edge1 = v1.subtract(v0, tempVb);
Vector3f edge2 = v2.subtract(v0, tempVc);
Vector3f norm = edge1.cross(edge2, tempVd);
float dirDotNorm = direction.dot(norm);
float sign;
if (dirDotNorm > FastMath.FLT_EPSILON) {
sign = 1;
} else if (dirDotNorm < -FastMath.FLT_EPSILON) {
sign = -1f;
dirDotNorm = -dirDotNorm;
} else {
// ray and triangle/quad are parallel
vars.release();
return false;
}
float dirDotDiffxEdge2 = sign * direction.dot(diff.cross(edge2, edge2));
if (dirDotDiffxEdge2 >= 0.0f) {
float dirDotEdge1xDiff = sign * direction.dot(edge1.crossLocal(diff));
if (dirDotEdge1xDiff >= 0.0f) {
if (!quad ? dirDotDiffxEdge2 + dirDotEdge1xDiff <= dirDotNorm : dirDotEdge1xDiff <= dirDotNorm) {
float diffDotNorm = -sign * diff.dot(norm);
if (diffDotNorm >= 0.0f) {
// this method always returns
vars.release();
// if storage vector is null, just return true,
if (store == null) {
return true;
}
// else fill in.
float inv = 1f / dirDotNorm;
float t = diffDotNorm * inv;
if (!doPlanar) {
store.set(origin).addLocal(direction.x * t, direction.y * t, direction.z * t);
} else {
// these weights can be used to determine
// interpolated values, such as texture coord.
// eg. texcoord s,t at intersection point:
// s = w0*s0 + w1*s1 + w2*s2;
// t = w0*t0 + w1*t1 + w2*t2;
float w1 = dirDotDiffxEdge2 * inv;
float w2 = dirDotEdge1xDiff * inv;
//float w0 = 1.0f - w1 - w2;
store.set(t, w1, w2);
}
return true;
}
}
}
}
vars.release();
return false;
}
use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.
the class Ray method distanceSquared.
public float distanceSquared(Vector3f point) {
TempVars vars = TempVars.get();
Vector3f tempVa = vars.vect1, tempVb = vars.vect2;
point.subtract(origin, tempVa);
float rayParam = direction.dot(tempVa);
if (rayParam > 0) {
origin.add(direction.mult(rayParam, tempVb), tempVb);
} else {
tempVb.set(origin);
rayParam = 0.0f;
}
tempVb.subtract(point, tempVa);
float len = tempVa.lengthSquared();
vars.release();
return len;
}
use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.
the class LightFilterTest method testSpotFiltering.
@Test
public void testSpotFiltering() {
SpotLight sl = new SpotLight(Vector3f.ZERO, Vector3f.UNIT_Z);
sl.setSpotRange(0);
geom.addLight(sl);
// Infinite spot lights are only filtered
checkFilteredLights(1);
// if the geometry is outside the infinite cone.
TempVars vars = TempVars.get();
try {
// The spot is not touching the near plane of the camera yet,
// should still be culled.
sl.setSpotRange(1f - FastMath.ZERO_TOLERANCE);
assert !sl.intersectsFrustum(cam, vars);
// should be culled from the geometry's PoV
checkFilteredLights(0);
// Now it touches the near plane.
sl.setSpotRange(1f);
// still culled from the geometry's PoV
checkFilteredLights(0);
assert sl.intersectsFrustum(cam, vars);
} finally {
vars.release();
}
// make it barely reach the geometry
sl.setSpotRange(9f);
checkFilteredLights(0);
// make it reach the geometry (touching its bound)
sl.setSpotRange(9f + FastMath.ZERO_TOLERANCE);
checkFilteredLights(1);
// rotate the cone a bit so it no longer faces the geom
sl.setDirection(new Vector3f(0.316f, 0, 0.948f).normalizeLocal());
checkFilteredLights(0);
// extent the range much farther
sl.setSpotRange(20);
checkFilteredLights(0);
// Create box of size X=10 (double the extent)
// now, the spot will touch the box.
geom.setMesh(new Box(5, 1, 1));
checkFilteredLights(1);
// ==================================
// Tests for bounding sphere, with a radius of 1f (in the box geom)
sl.setPosition(Vector3f.ZERO);
sl.setDirection(Vector3f.UNIT_Z);
geom.setLocalTranslation(Vector3f.ZERO);
geom.setModelBound(new BoundingSphere(1f, Vector3f.ZERO));
// Infinit spot lights are only filtered
// if the geometry is outside the infinite cone.
sl.setSpotRange(0);
checkFilteredLights(1);
//the geommetry is outside the infinit cone (cone direction going away from the geom)
sl.setPosition(Vector3f.UNIT_Z.mult(1 + FastMath.ZERO_TOLERANCE));
checkFilteredLights(0);
//place the spote ligth in the corner of the box geom, (in order to test bounding sphere)
sl.setDirection(new Vector3f(1, 1, 0).normalizeLocal());
geom.setLocalTranslation(0, 0, 10);
sl.setPosition(sl.getDirection().mult(-2f).add(geom.getLocalTranslation()));
// make it barely reach the sphere, incorect with a box
sl.setSpotRange(1f - FastMath.ZERO_TOLERANCE);
checkFilteredLights(0);
// make it reach the sphere
sl.setSpotRange(1f + FastMath.ZERO_TOLERANCE);
checkFilteredLights(1);
// extent the range
sl.setPosition(Vector3f.ZERO);
sl.setDirection(Vector3f.UNIT_Z);
sl.setSpotRange(20);
checkFilteredLights(1);
// rotate the cone a bit so it no longer faces the geom
sl.setDirection(new Vector3f(0, 0.3f, 0.7f).normalizeLocal());
checkFilteredLights(0);
// Create sphere of size X=10 (double the radius)
// now, the spot will touch the sphere.
geom.setModelBound(new BoundingSphere(5f, Vector3f.ZERO));
checkFilteredLights(1);
}
Aggregations