/* * Copyright 2016 Nathan Howard * * This file is part of OpenGrave * * OpenGrave is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenGrave is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenGrave. If not, see <http://www.gnu.org/licenses/>. */ package com.opengrave.og.light; import java.util.ArrayList; import com.opengrave.og.Util; import com.opengrave.og.util.Matrix4f; import com.opengrave.og.util.Vector3f; import com.opengrave.og.util.Vector4f; public class DayCycleSkyLight extends Shadow2D { float dayCycle = 0f; int dayLength = 24; float seasonCycle = 0f; int seasonLength = 365; // Ditto on seasons ArrayList<Vector4f> sunLocation = new ArrayList<Vector4f>(); ArrayList<Vector4f> moonLocation = new ArrayList<Vector4f>(); private float intensity; public DayCycleSkyLight(int size) { super(size); Vector3f skyLightDirection = new Vector3f(0f, .5f, 1f); Vector3f lookAt = new Vector3f(0, 0, 0); Vector3f up = new Vector3f(0, 1, 0); View = Matrix4f.lookAt(skyLightDirection, lookAt, up); float lowestAngle = 25f; float angle = lowestAngle; float angleincr = (180f - (lowestAngle * 2f)) / 10f; addSunLocation(angle, 5f); for (int i = 1; i < 11; i++) { float intensity = 6f * (1f - (Math.abs(6 - i) / 6f)) + 9f; addSunLocation(angle, intensity); angle += angleincr; } angle = 180f - lowestAngle; addSunLocation(angle, 5f); addSunLocation(angle, 5f); for (int i = 1; i < 11; i++) { addSunLocation(angle, 5f); angle -= angleincr; } addSunLocation(angle, 5f); } private void addSunLocation(float angle, float f) { double x, y; x = Math.cos(Util.degreesToRadians(angle)); y = Math.sin(Util.degreesToRadians(angle)); sunLocation.add(new Vector4f((float) x, 0.1f, (float) y, f)); } @Override public void update(float delta) { dayCycle += delta * 0.001f; while (dayCycle >= dayLength) { dayCycle -= dayLength; seasonCycle++; } if (seasonCycle >= seasonLength) { seasonCycle -= seasonLength; } Vector3f skyLightDirection = getDirection(); Vector3f lookAt = new Vector3f(0f, 0f, 0f); Vector3f up = new Vector3f(0, 1, 0); View = Matrix4f.lookAt(skyLightDirection, lookAt, up); } public Vector3f getDirection() { int sun1 = (int) dayCycle, sun2 = sun1 + 1; if (sun2 >= sunLocation.size()) { sun2 = 0; } Vector4f sunPos1 = sunLocation.get(sun1), sunPos2 = sunLocation.get(sun2); float interp = dayCycle - sun1; intensity = getIntensity(interp, sunPos1, sunPos2); return getVector(interp, sunPos1, sunPos2); } private float getIntensity(float interp, Vector4f sunPos1, Vector4f sunPos2) { return sunPos1.w * (1f - interp) + sunPos2.w * interp; } private Vector3f getVector(float interp, Vector4f sunPos1, Vector4f sunPos2) { return new Vector3f(sunPos1.x * (1f - interp) + sunPos2.x * interp, sunPos1.y * (1f - interp) + sunPos2.y * interp, sunPos1.z * (1f - interp) + sunPos2.z * interp); } @Override public float getIntensity() { return intensity; } }