/**
* Second material tutorial.
* <p/>
* Adapted from tutorial: http://jerome.jouvie.free.fr/OpenGl/Tutorials/Tutorial14.php
* <p/>
* This tutorial will deals with material transitioning using a Controller object.
* Inspired from http://www.jmonkeyengine.com/jmeforum/index.php?topic=7214.0
*
* @author <a href="mailto:loic.lefevre@gmail.com">Lo
/**
* The material transition controller handles material transition control over time.
* It needs a changing material that will change (i.e. <b>it is mutable</b>) in order
* to meet the caracteristics of a "target" material starting from a "source" material.
* This transition is controlled to last a given amount of milli-seconds.
*/
public class MaterialTransitionController extends Controller {
/**
* Flag to denote that the transition has not started yet.
*/
private static final long TRANSITION_NOT_STARTED = -1;
/**
* The changing material (mutable).
*/
private MaterialState changingMaterial;
/**
* The source material (immutable).
*/
private MaterialState sourceMaterial;
/**
* The target material (immutable).
*/
private MaterialState targetMaterial;
/**
* The transition duration in milli-seconds.
*/
private long transitionDuration;
/**
* Time at which the transition effect started.
*/
private long start;
/**
* Keep track of the change amount for optimization.
*/
private float oldChangeAmount;
/**
* Instanciate a material transition controller.
*
* @param changingMaterial changing material, this one will be modified!
* @param sourceMaterial starting material, this one will <b>not</b> be modified!
* @param targetMaterial target material, this one will <b>not</b> be modified!
* @param transitionDuration duration of the transition in milli-seconds
* @param active tells if this controller is active at instanciation time
*/
public MaterialTransitionController(final MaterialState changingMaterial,
final MaterialState sourceMaterial,
final MaterialState targetMaterial,
final long transitionDuration,
final boolean active) {
// do not start unless setup is complete!
setActive(false);
if (transitionDuration <= 0) {
throw new IllegalArgumentException("transitionDuration must be a positive integer!");
}
if (changingMaterial == null) {
throw new IllegalArgumentException("changingMaterial must be not null!");
}
if (sourceMaterial == null) {
throw new IllegalArgumentException("sourceMaterial must be not null!");
}
if (targetMaterial == null) {
throw new IllegalArgumentException("targetMaterial must be not null!");
}
/**
* Apply the transition.
*
* @param time time since last frame in second
*/
@Override
public void update(final float time) {
if (isActive()) {
if (start == TRANSITION_NOT_STARTED) {
// note the starting time
start = System.currentTimeMillis();
}
// note the amount of time since start
final long amount = System.currentTimeMillis() - start;
// if not yet finished...
if (amount < transitionDuration) {
final float changeAmount = (float)amount / (float)transitionDuration;
/**
* Public method to initiate a transition.
*
* @param sourceMaterial the new source material
* @param targetMaterial the new target material
* @param transitionDuration the new transition duration in milli-seconds
*/
public void setNewMaterialTransition(final MaterialState sourceMaterial, final MaterialState targetMaterial, final long transitionDuration) {
setNewMaterialTransition(sourceMaterial, targetMaterial, transitionDuration, true);
}
/**
* Internal method that initialize the local variables for efficient transition.
*
* @param sourceMaterial the new source material
* @param targetMaterial the new target material
* @param transitionDuration the new transition duration in milli-seconds
* @param active is it active right now?
*/
private void setNewMaterialTransition(final MaterialState sourceMaterial, final MaterialState targetMaterial, final long transitionDuration, final boolean active) {