use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.
the class BetterCharacterControl method calculateNewForward.
/**
* This method works similar to Camera.lookAt but where lookAt sets the
* priority on the direction, this method sets the priority on the up vector
* so that the result direction vector and rotation is guaranteed to be
* perpendicular to the up vector.
*
* @param rotation The rotation to set the result on or null to create a new
* Quaternion, this will be set to the new "z-forward" rotation if not null
* @param direction The direction to base the new look direction on, will be
* set to the new direction
* @param worldUpVector The up vector to use, the result direction will be
* perpendicular to this
* @return
*/
protected final void calculateNewForward(Quaternion rotation, Vector3f direction, Vector3f worldUpVector) {
if (direction == null) {
return;
}
TempVars vars = TempVars.get();
Vector3f newLeft = vars.vect1;
Vector3f newLeftNegate = vars.vect2;
newLeft.set(worldUpVector).crossLocal(direction).normalizeLocal();
if (newLeft.equals(Vector3f.ZERO)) {
if (direction.x != 0) {
newLeft.set(direction.y, -direction.x, 0f).normalizeLocal();
} else {
newLeft.set(0f, direction.z, -direction.y).normalizeLocal();
}
logger.log(Level.INFO, "Zero left for direction {0}, up {1}", new Object[] { direction, worldUpVector });
}
newLeftNegate.set(newLeft).negateLocal();
direction.set(worldUpVector).crossLocal(newLeftNegate).normalizeLocal();
if (direction.equals(Vector3f.ZERO)) {
direction.set(Vector3f.UNIT_Z);
logger.log(Level.INFO, "Zero left for left {0}, up {1}", new Object[] { newLeft, worldUpVector });
}
if (rotation != null) {
rotation.fromAxes(newLeft, worldUpVector, direction);
}
vars.release();
}
use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.
the class KinematicRagdollControl method ikUpdate.
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 = (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 * (float) 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();
}
use of com.jme3.util.TempVars 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) and the shadow occluder objects
* collected through the traverse of the scene hierarchy
*/
public static void updateShadowCamera(ViewPort viewPort, GeometryList receivers, Camera shadowCam, Vector3f[] points, GeometryList splitOccluders, float shadowMapSize) {
boolean ortho = shadowCam.isParallelProjection();
shadowCam.setProjectionMatrix(null);
if (ortho) {
shadowCam.setFrustum(-shadowCam.getFrustumFar(), shadowCam.getFrustumFar(), -1, 1, 1, -1);
}
// create transform to rotate points to viewspace
Matrix4f viewProjMatrix = shadowCam.getViewProjectionMatrix();
BoundingBox splitBB = computeBoundForPoints(points, viewProjMatrix);
TempVars vars = TempVars.get();
BoundingBox casterBB = new BoundingBox();
BoundingBox receiverBB = new BoundingBox();
int casterCount = 0, receiverCount = 0;
for (int i = 0; i < receivers.size(); i++) {
// convert bounding box to light's viewproj space
Geometry receiver = receivers.get(i);
BoundingVolume bv = receiver.getWorldBound();
BoundingVolume recvBox = bv.transform(viewProjMatrix, vars.bbox);
if (splitBB.intersects(recvBox)) {
//Nehon : prevent NaN and infinity values to screw the final bounding box
if (!Float.isNaN(recvBox.getCenter().x) && !Float.isInfinite(recvBox.getCenter().x)) {
receiverBB.mergeLocal(recvBox);
receiverCount++;
}
}
}
// collect splitOccluders through scene recursive traverse
OccludersExtractor occExt = new OccludersExtractor(viewProjMatrix, casterCount, splitBB, casterBB, splitOccluders, vars);
for (Spatial scene : viewPort.getScenes()) {
occExt.addOccluders(scene);
}
casterCount = occExt.casterCount;
//Nehon 08/18/2010 this is to avoid shadow bleeding when the ground is set to only receive shadows
if (casterCount != receiverCount) {
casterBB.setXExtent(casterBB.getXExtent() + 2.0f);
casterBB.setYExtent(casterBB.getYExtent() + 2.0f);
casterBB.setZExtent(casterBB.getZExtent() + 2.0f);
}
Vector3f casterMin = casterBB.getMin(vars.vect1);
Vector3f casterMax = casterBB.getMax(vars.vect2);
Vector3f receiverMin = receiverBB.getMin(vars.vect3);
Vector3f receiverMax = receiverBB.getMax(vars.vect4);
Vector3f splitMin = splitBB.getMin(vars.vect5);
Vector3f splitMax = splitBB.getMax(vars.vect6);
splitMin.z = 0;
// if (!ortho) {
// shadowCam.setFrustumPerspective(45, 1, 1, splitMax.z);
// }
Matrix4f projMatrix = shadowCam.getProjectionMatrix();
Vector3f cropMin = vars.vect7;
Vector3f cropMax = vars.vect8;
// IMPORTANT: Special handling for Z values
cropMin.x = max(max(casterMin.x, receiverMin.x), splitMin.x);
cropMax.x = min(min(casterMax.x, receiverMax.x), splitMax.x);
cropMin.y = max(max(casterMin.y, receiverMin.y), splitMin.y);
cropMax.y = min(min(casterMax.y, receiverMax.y), splitMax.y);
cropMin.z = min(casterMin.z, splitMin.z);
cropMax.z = min(receiverMax.z, splitMax.z);
// Create the crop matrix.
float scaleX, scaleY, scaleZ;
float offsetX, offsetY, offsetZ;
scaleX = (2.0f) / (cropMax.x - cropMin.x);
scaleY = (2.0f) / (cropMax.y - cropMin.y);
//Shadow map stabilization approximation from shaderX 7
//from Practical Cascaded Shadow maps adapted to PSSM
//scale stabilization
float halfTextureSize = shadowMapSize * 0.5f;
if (halfTextureSize != 0 && scaleX > 0 && scaleY > 0) {
float scaleQuantizer = 0.1f;
scaleX = 1.0f / FastMath.ceil(1.0f / scaleX * scaleQuantizer) * scaleQuantizer;
scaleY = 1.0f / FastMath.ceil(1.0f / scaleY * scaleQuantizer) * scaleQuantizer;
}
offsetX = -0.5f * (cropMax.x + cropMin.x) * scaleX;
offsetY = -0.5f * (cropMax.y + cropMin.y) * scaleY;
//offset stabilization
if (halfTextureSize != 0 && scaleX > 0 && scaleY > 0) {
offsetX = FastMath.ceil(offsetX * halfTextureSize) / halfTextureSize;
offsetY = FastMath.ceil(offsetY * halfTextureSize) / halfTextureSize;
}
scaleZ = 1.0f / (cropMax.z - cropMin.z);
offsetZ = -cropMin.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);
}
use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.
the class PointLightShadowRenderer method checkCulling.
/**
*
* @param viewCam
* @return
*/
@Override
protected boolean checkCulling(Camera viewCam) {
if (light == null) {
return false;
}
Camera cam = viewCam;
if (frustumCam != null) {
cam = frustumCam;
cam.setLocation(viewCam.getLocation());
cam.setRotation(viewCam.getRotation());
}
TempVars vars = TempVars.get();
boolean intersects = light.intersectsFrustum(cam, vars);
vars.release();
return intersects;
}
use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.
the class Sphere method setGeometryData.
/**
* builds the vertices based on the radius, radial and zSamples.
*/
private void setGeometryData() {
// allocate vertices
vertCount = (zSamples - 2) * (radialSamples + 1) + 2;
FloatBuffer posBuf = BufferUtils.createVector3Buffer(vertCount);
// allocate normals if requested
FloatBuffer normBuf = BufferUtils.createVector3Buffer(vertCount);
// allocate texture coordinates
FloatBuffer texBuf = BufferUtils.createVector2Buffer(vertCount);
setBuffer(Type.Position, 3, posBuf);
setBuffer(Type.Normal, 3, normBuf);
setBuffer(Type.TexCoord, 2, texBuf);
// generate geometry
float fInvRS = 1.0f / radialSamples;
float fZFactor = 2.0f / (zSamples - 1);
// Generate points on the unit circle to be used in computing the mesh
// points on a sphere slice.
float[] afSin = new float[(radialSamples + 1)];
float[] afCos = new float[(radialSamples + 1)];
for (int iR = 0; iR < radialSamples; iR++) {
float fAngle = FastMath.TWO_PI * fInvRS * iR;
afCos[iR] = FastMath.cos(fAngle);
afSin[iR] = FastMath.sin(fAngle);
}
afSin[radialSamples] = afSin[0];
afCos[radialSamples] = afCos[0];
TempVars vars = TempVars.get();
Vector3f tempVa = vars.vect1;
Vector3f tempVb = vars.vect2;
Vector3f tempVc = vars.vect3;
// generate the sphere itself
int i = 0;
for (int iZ = 1; iZ < (zSamples - 1); iZ++) {
// in (-pi/2, pi/2)
float fAFraction = FastMath.HALF_PI * (-1.0f + fZFactor * iZ);
float fZFraction;
if (useEvenSlices) {
// in (-1, 1)
fZFraction = -1.0f + fZFactor * iZ;
} else {
// in (-1,1)
fZFraction = FastMath.sin(fAFraction);
}
float fZ = radius * fZFraction;
// compute center of slice
Vector3f kSliceCenter = tempVb.set(Vector3f.ZERO);
kSliceCenter.z += fZ;
// compute radius of slice
float fSliceRadius = FastMath.sqrt(FastMath.abs(radius * radius - fZ * fZ));
// compute slice vertices with duplication at end point
Vector3f kNormal;
int iSave = i;
for (int iR = 0; iR < radialSamples; iR++) {
// in [0,1)
float fRadialFraction = iR * fInvRS;
Vector3f kRadial = tempVc.set(afCos[iR], afSin[iR], 0);
kRadial.mult(fSliceRadius, tempVa);
posBuf.put(kSliceCenter.x + tempVa.x).put(kSliceCenter.y + tempVa.y).put(kSliceCenter.z + tempVa.z);
BufferUtils.populateFromBuffer(tempVa, posBuf, i);
kNormal = tempVa;
kNormal.normalizeLocal();
if (// allow interior texture vs. exterior
!interior) {
normBuf.put(kNormal.x).put(kNormal.y).put(kNormal.z);
} else {
normBuf.put(-kNormal.x).put(-kNormal.y).put(-kNormal.z);
}
if (textureMode == TextureMode.Original) {
texBuf.put(fRadialFraction).put(0.5f * (fZFraction + 1.0f));
} else if (textureMode == TextureMode.Projected) {
texBuf.put(fRadialFraction).put(FastMath.INV_PI * (FastMath.HALF_PI + FastMath.asin(fZFraction)));
} else if (textureMode == TextureMode.Polar) {
float r = (FastMath.HALF_PI - FastMath.abs(fAFraction)) / FastMath.PI;
float u = r * afCos[iR] + 0.5f;
float v = r * afSin[iR] + 0.5f;
texBuf.put(u).put(v);
}
i++;
}
BufferUtils.copyInternalVector3(posBuf, iSave, i);
BufferUtils.copyInternalVector3(normBuf, iSave, i);
if (textureMode == TextureMode.Original) {
texBuf.put(1.0f).put(0.5f * (fZFraction + 1.0f));
} else if (textureMode == TextureMode.Projected) {
texBuf.put(1.0f).put(FastMath.INV_PI * (FastMath.HALF_PI + FastMath.asin(fZFraction)));
} else if (textureMode == TextureMode.Polar) {
float r = (FastMath.HALF_PI - FastMath.abs(fAFraction)) / FastMath.PI;
texBuf.put(r + 0.5f).put(0.5f);
}
i++;
}
vars.release();
// south pole
posBuf.position(i * 3);
posBuf.put(0f).put(0f).put(-radius);
normBuf.position(i * 3);
if (!interior) {
// allow for inner
normBuf.put(0).put(0).put(-1);
} else // texture orientation
// later.
{
normBuf.put(0).put(0).put(1);
}
texBuf.position(i * 2);
if (textureMode == TextureMode.Polar) {
texBuf.put(0.5f).put(0.5f);
} else {
texBuf.put(0.5f).put(0.0f);
}
i++;
// north pole
posBuf.put(0).put(0).put(radius);
if (!interior) {
normBuf.put(0).put(0).put(1);
} else {
normBuf.put(0).put(0).put(-1);
}
if (textureMode == TextureMode.Polar) {
texBuf.put(0.5f).put(0.5f);
} else {
texBuf.put(0.5f).put(1.0f);
}
updateBound();
}
Aggregations