}
float [] sunDirection = getSunDirection(this.compass, Camera.convertTimeToTimeZone(camera.getTime(), this.compass.getTimeZone()));
// Update Sun direction during daytime
if (sunDirection [1] > -0.075f) {
if (this.useSunSky) {
this.sunflow.parameter("up", new Vector3(0, 1, 0));
this.sunflow.parameter("east",
new Vector3((float)Math.sin(compass.getNorthDirection()), 0, (float)Math.cos(compass.getNorthDirection())));
this.sunflow.parameter("sundir", new Vector3(sunDirection [0], sunDirection [1], sunDirection [2]));
this.sunflow.parameter("turbidity", 6f);
this.sunflow.parameter("samples", this.useAmbientOcclusion ? 0 : 12);
this.sunSkyLightName = UUID.randomUUID().toString();
this.sunflow.light(this.sunSkyLightName, "sunsky");
}
// Retrieve sun color
SunSkyLight sunSkyLight = new SunSkyLight();
ParameterList parameterList = new ParameterList();
parameterList.addVectors("up", InterpolationType.NONE, new float [] {0, 1, 0});
parameterList.addVectors("east", InterpolationType.NONE,
new float [] {(float)Math.sin(compass.getNorthDirection()), 0, (float)Math.cos(compass.getNorthDirection())});
parameterList.addVectors("sundir", InterpolationType.NONE,
new float [] {sunDirection [0], sunDirection [1], sunDirection [2]});
sunSkyLight.update(parameterList, this.sunflow);
float [] sunColor = sunSkyLight.getSunColor().getRGB();
// Simulate additional Sun with a faraway sphere light of a color depending of the hour of the day
int sunPower = this.useAmbientOcclusion ? 40 : 10;
this.sunflow.parameter("radiance", null,
(this.homeLightColor >> 16) * sunPower * (float)Math.sqrt(sunColor [0]),
((this.homeLightColor >> 8) & 0xFF) * sunPower * (float)Math.sqrt(sunColor [1]),
(this.homeLightColor & 0xFF) * sunPower * (float)Math.sqrt(sunColor [2]));
this.sunflow.parameter("center", new Point3(1000000 * sunDirection [0], 1000000 * sunDirection [1], 1000000 * sunDirection [2]));
this.sunflow.parameter("radius", 10000f);
this.sunflow.parameter("samples", 4);
this.sunLightName = UUID.randomUUID().toString();
this.sunflow.light(this.sunLightName, "sphere");
if (this.useAmbientOcclusion) {
this.sunflow.parameter("gi.engine", "ambocc");
this.sunflow.parameter("gi.ambocc.bright", null, new float [] {1, 1, 1});
// Use complementary color
this.sunflow.parameter("gi.ambocc.dark", null,
new float [] {(sunColor [1] + sunColor [2]) / 200,
(sunColor [0] + sunColor [2]) / 200,
(sunColor [0] + sunColor [1]) / 200});
this.sunflow.parameter("gi.ambocc.samples", 1);
this.sunflow.options(SunflowAPI.DEFAULT_OPTIONS);
}
}
// Update camera lens
final String CAMERA_NAME = "camera";
switch (camera.getLens()) {
case SPHERICAL:
this.sunflow.camera(CAMERA_NAME, "spherical");
break;
case FISHEYE:
this.sunflow.camera(CAMERA_NAME, "fisheye");
break;
case NORMAL:
this.sunflow.parameter("focus.distance", 250f);
this.sunflow.parameter("lens.radius", 1f);
this.sunflow.camera(CAMERA_NAME, "thinlens");
break;
case PINHOLE:
default:
this.sunflow.camera(CAMERA_NAME, "pinhole");
break;
}
// Update camera location
Point3 eye = new Point3(camera.getX(), camera.getZ(), camera.getY());
Matrix4 transform;
float yaw = camera.getYaw();
float pitch;
if (camera.getLens() == Camera.Lens.SPHERICAL) {
pitch = 0;
} else {
pitch = camera.getPitch();
}
double pitchCos = Math.cos(pitch);
if (Math.abs(pitchCos) > 1E-6) {
// Set the point the camera is pointed to
Point3 target = new Point3(
camera.getX() - (float)(Math.sin(yaw) * pitchCos),
camera.getZ() - (float)Math.sin(pitch),
camera.getY() + (float)(Math.cos(yaw) * pitchCos));
Vector3 up = new Vector3(0, 1, 0);
transform = Matrix4.lookAt(eye, target, up);
} else {
// Compute matrix directly when the camera points is at top
transform = new Matrix4((float)-Math.cos(yaw), (float)-Math.sin(yaw), 0, camera.getX(),
0, 0, 1, camera.getZ(),