double fMinZ = Double.POSITIVE_INFINITY;
double fMaxZ = Double.NEGATIVE_INFINITY;
final ReadOnlyMatrix4 lightviewproj = shadowCam.getModelViewProjectionMatrix();
final Vector4 position = Vector4.fetchTempInstance();
for (final Vector3 frustumCorner : frustumCorners) {
position.set(frustumCorner.getX(), frustumCorner.getY(), frustumCorner.getZ(), 1);
lightviewproj.applyPre(position, position);
position.setX(position.getX() / position.getW());
position.setY(position.getY() / position.getW());
position.setZ(position.getZ());
fMinX = Math.min(position.getX(), fMinX);
fMaxX = Math.max(position.getX(), fMaxX);
fMinY = Math.min(position.getY(), fMinY);
fMaxY = Math.max(position.getY(), fMaxY);
fMinZ = Math.min(position.getZ(), fMinZ);
fMaxZ = Math.max(position.getZ(), fMaxZ);
}
double width = 0;
double height = 0;
fMinX = clamp(fMinX, -1.0, 1.0);
fMaxX = clamp(fMaxX, -1.0, 1.0);
fMinY = clamp(fMinY, -1.0, 1.0);
fMaxY = clamp(fMaxY, -1.0, 1.0);
// Make sure the minimum z is at least a specified distance from
// the target.
fMinZ = Math.min(fMinZ, distance - _minimumLightDistance);
fMinZ = Math.max(10.0, fMinZ);
width = fMinZ * (fMaxX - fMinX) * 0.5;
height = fMinZ * (fMaxY - fMinY) * 0.5;
final Vector3 newCenter = Vector3.fetchTempInstance();
position.set((fMinX + fMaxX) * 0.5, (fMinY + fMaxY) * 0.5, 1.0, 1);
shadowCam.getModelViewProjectionInverseMatrix().applyPre(position, position);
position.divideLocal(position.getW());
newCenter.set(position.getX(), position.getY(), position.getZ());
shadowCam.lookAt(newCenter, Vector3.UNIT_Y);
Vector3.releaseTempInstance(newCenter);
Vector4.releaseTempInstance(position);