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) 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.scene.plugins.blender.math.Matrix in project jmonkeyengine by jMonkeyEngine.
the class AbstractShadowRenderer method renderShadowMap.
protected void renderShadowMap(int shadowMapIndex) {
shadowMapOccluders = getOccludersToRender(shadowMapIndex, shadowMapOccluders);
Camera shadowCam = getShadowCam(shadowMapIndex);
//saving light view projection matrix for this split
lightViewProjectionsMatrices[shadowMapIndex].set(shadowCam.getViewProjectionMatrix());
renderManager.setCamera(shadowCam, false);
renderManager.getRenderer().setFrameBuffer(shadowFB[shadowMapIndex]);
renderManager.getRenderer().clearBuffers(true, true, true);
renderManager.setForcedRenderState(forcedRenderState);
// render shadow casters to shadow map
viewPort.getQueue().renderShadowQueue(shadowMapOccluders, renderManager, shadowCam, true);
renderManager.setForcedRenderState(null);
}
use of com.jme3.scene.plugins.blender.math.Matrix in project jmonkeyengine by jMonkeyEngine.
the class Geometry method computeWorldMatrix.
/**
* Indicate that the transform of this spatial has changed and that
* a refresh is required.
*/
// NOTE: Spatial has an identical implementation of this method,
// thus it was commented out.
// @Override
// protected void setTransformRefresh() {
// refreshFlags |= RF_TRANSFORM;
// setBoundRefresh();
// }
/**
* 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();
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();
}
use of com.jme3.scene.plugins.blender.math.Matrix in project jmonkeyengine by jMonkeyEngine.
the class SimpleBatchNode method getTransformMatrix.
@Override
protected Matrix4f getTransformMatrix(Geometry g) {
// Compute the Local matrix for the geometry
cachedLocalMat.loadIdentity();
cachedLocalMat.setRotationQuaternion(g.localTransform.getRotation());
cachedLocalMat.setTranslation(g.localTransform.getTranslation());
TempVars vars = TempVars.get();
Matrix4f scaleMat = vars.tempMat4;
scaleMat.loadIdentity();
scaleMat.scale(g.localTransform.getScale());
cachedLocalMat.multLocal(scaleMat);
vars.release();
return cachedLocalMat;
}
use of com.jme3.scene.plugins.blender.math.Matrix in project jmonkeyengine by jMonkeyEngine.
the class Material method resetUniformsNotSetByCurrent.
private void resetUniformsNotSetByCurrent(Shader shader) {
ListMap<String, Uniform> uniforms = shader.getUniformMap();
int size = uniforms.size();
for (int i = 0; i < size; i++) {
Uniform u = uniforms.getValue(i);
if (!u.isSetByCurrentMaterial()) {
if (u.getName().charAt(0) != 'g') {
// Don't reset world globals!
// The benefits gained from this are very minimal
// and cause lots of matrix -> FloatBuffer conversions.
u.clearValue();
}
}
}
}
Aggregations