Renderer/src/main/java/electrosphere/renderer/anim/AnimChannel.java
2024-07-13 16:00:48 -04:00

285 lines
12 KiB
Java

package electrosphere.renderer.anim;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import org.joml.Quaterniond;
import org.joml.Vector3f;
/**
* A single channel of keyframes in an animation
*/
public class AnimChannel {
double timeCurrent;
double timeTotal;
double ticksPerSecond;
String nodeID;
Vector3f startingPosition;
TreeMap<Double,Keyframe> positionFrameTree;
Quaterniond startingRotation;
TreeMap<Double,Keyframe> rotationFrameTree;
TreeMap<Double,Keyframe> scaleFrameTree;
public AnimChannel(double maxTime, double ticksPerSecond){
timeTotal = maxTime;
this.ticksPerSecond = ticksPerSecond;
positionFrameTree = new TreeMap<Double,Keyframe>();
rotationFrameTree = new TreeMap<Double,Keyframe>();
scaleFrameTree = new TreeMap<Double,Keyframe>();
}
public Vector3f getCurrentPosition(){
Vector3f rVal = new Vector3f();
Entry<Double,Keyframe> previousEntry = positionFrameTree.floorEntry(timeCurrent);
Entry<Double,Keyframe> nextEntry = positionFrameTree.ceilingEntry(timeCurrent);
Keyframe previousFrame = null;
Keyframe nextFrame = null;
if(previousEntry == nextEntry){
nextEntry = positionFrameTree.higherEntry(timeCurrent);
}
if(previousEntry != null){
previousFrame = previousEntry.getValue();
}
if(nextEntry != null){
nextFrame = nextEntry.getValue();
}
if(previousFrame != null && nextFrame != null){
double percent_Next = ((timeCurrent - previousFrame.time) / (nextFrame.time - previousFrame.time));
rVal = new Vector3f().add(new Vector3f().add(previousFrame.position).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(nextFrame.position).mul((float)(percent_Next)));
} else if(previousFrame != null){
rVal = new Vector3f().add(previousFrame.position);
} else if(nextFrame != null){
rVal = new Vector3f().add(nextFrame.position);
}
// if(positionFrameCurrent != null){
// if(positionFrameNext != null){
// double percent_Next = ((timeCurrent - positionFrameCurrent.time) / (positionFrameNext.time - positionFrameCurrent.time));
// rVal = new Vector3f().add(new Vector3f().add(positionFrameCurrent.position).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(positionFrameNext.position).mul((float)(percent_Next)));
// } else {
// rVal = new Vector3f().add(positionFrameCurrent.position);
// }
// // rVal.add(new Vector3f().add(positionFrameCurrent.position).mul(()/(positionFrameNext.time - positionFrameCurrent.time)));
// }
// rVal = rVal.sub(startingPosition);
return rVal;
}
public Quaterniond getCurrentRotation(){
Quaterniond rVal = new Quaterniond();
Entry<Double,Keyframe> previousEntry = rotationFrameTree.floorEntry(timeCurrent);
Entry<Double,Keyframe> nextEntry = rotationFrameTree.ceilingEntry(timeCurrent);
Keyframe previousFrame = null;
Keyframe nextFrame = null;
if(previousEntry == nextEntry){
nextEntry = rotationFrameTree.higherEntry(timeCurrent);
}
if(previousEntry != null){
previousFrame = previousEntry.getValue();
}
if(nextEntry != null){
nextFrame = nextEntry.getValue();
}
if(previousFrame != null && nextFrame != null){
double percent_Next = ((timeCurrent - previousFrame.time) / (nextFrame.time - previousFrame.time));
rVal = new Quaterniond(previousFrame.rotation).slerp(nextFrame.rotation, (float)percent_Next);
// rVal = new Vector3f().add(new Vector3f().add(previousFrame.position).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(nextFrame.position).mul((float)(percent_Next)));
} else if(previousFrame != null){
rVal = new Quaterniond(previousFrame.rotation);
// rVal = new Vector3f().add(previousFrame.position);
} else if(nextFrame != null){
rVal = new Quaterniond(nextFrame.rotation);
// rVal = new Vector3f().add(nextFrame.position);
}
// if(rotationFrameCurrent != null){
// if(rotationFrameNext != null){
// double percent_Next = ((timeCurrent - rotationFrameCurrent.time) / (rotationFrameNext.time - rotationFrameCurrent.time));
// // rVal = new Quaternionf(rotationFrameCurrent.rotation).normalize();//.add(rotationFrameCurrent.rotation);
// rVal = new Quaternionf(rotationFrameCurrent.rotation).slerp(rotationFrameNext.rotation, (float)percent_Next);
// // rVal = new Quaternionf(rotationFrameCurrent.rotation).normalize().slerp(new Quaternionf(rotationFrameNext.rotation).normalize(), (float)(percent_Next)).rotateAxis((float)(-Math.PI/2), new Vector3f(1,0,0));
// } else {
// rVal = new Quaternionf(rotationFrameCurrent.rotation);//.add(rotationFrameCurrent.rotation);
// }
// }
// rVal = rVal.mul(new Quaternionf(startingRotation).invert());
return rVal;
}
public Vector3f getCurrentScale(){
Vector3f rVal = new Vector3f();
Entry<Double,Keyframe> previousEntry = scaleFrameTree.floorEntry(timeCurrent);
Entry<Double,Keyframe> nextEntry = scaleFrameTree.ceilingEntry(timeCurrent);
Keyframe previousFrame = null;
Keyframe nextFrame = null;
if(previousEntry == nextEntry){
nextEntry = scaleFrameTree.higherEntry(timeCurrent);
}
if(previousEntry != null){
previousFrame = previousEntry.getValue();
}
if(nextEntry != null){
nextFrame = nextEntry.getValue();
}
if(previousFrame != null && nextFrame != null){
double percent_Next = ((timeCurrent - previousFrame.time) / (nextFrame.time - previousFrame.time));
// rVal = new Vector3f().add(new Vector3f().add(previousFrame.position).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(nextFrame.position).mul((float)(percent_Next)));
rVal = new Vector3f().add(new Vector3f().add(previousFrame.scale).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(nextFrame.scale).mul((float)(percent_Next)));
} else if(previousFrame != null){
// rVal = new Vector3f().add(previousFrame.position);
rVal = new Vector3f().add(previousFrame.scale);
} else if(nextFrame != null){
// rVal = new Vector3f().add(nextFrame.position);
rVal = new Vector3f().add(nextFrame.scale);
}
// if(scaleFrameCurrent != null){
// if(scaleFrameNext != null){
// double percent_Next = ((timeCurrent - scaleFrameCurrent.time) / (scaleFrameNext.time - scaleFrameCurrent.time));
// rVal = new Vector3f().add(new Vector3f().add(scaleFrameCurrent.scale).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(scaleFrameNext.scale).mul((float)(percent_Next)));
// } else {
// rVal = new Vector3f().add(scaleFrameCurrent.scale);
// }
// // rVal.add(new Vector3f().add(positionFrameCurrent.position).mul(()/(positionFrameNext.time - positionFrameCurrent.time)));
// }
return rVal;
}
public void incrementTime(double incrementValue){
timeCurrent = timeCurrent + incrementValue;
// Entry<Double,Keyframe> previousEntry = positionFrameTree.floorEntry(timeCurrent);
// Entry<Double,Keyframe> nextEntry = positionFrameTree.ceilingEntry(timeCurrent);
// boolean blend = true;
// if(previousEntry == nextEntry){
// if((nextEntry) == null){
// blend = false;
// }
// }
// if(positionFrameTree.higherEntry(timeCurrent) != null){
// }
// while(positionFrameNext != null && timeCurrent > positionFrameNext.time){
// positionFrameCurrent = positionFrameNext;
// if(positionFrameIterator.hasNext()){
// positionFrameNext = positionFrameIterator.next();
// } else {
// positionFrameNext = null;
// }
// }
// while(rotationFrameNext != null && timeCurrent > rotationFrameNext.time){
// rotationFrameCurrent = rotationFrameNext;
// if(rotationFrameIterator.hasNext()){
// rotationFrameNext = rotationFrameIterator.next();
// } else {
// rotationFrameNext = null;
// }
// }
// while(scaleFrameNext != null && timeCurrent > scaleFrameNext.time){
// scaleFrameCurrent = scaleFrameNext;
// if(scaleFrameIterator.hasNext()){
// scaleFrameNext = scaleFrameIterator.next();
// } else {
// scaleFrameNext = null;
// }
// }
}
public void setTime(double time){
this.timeCurrent = time;
}
public void rewind(){
timeCurrent = 0;
//TODO: Make sure has at least two frames
// positionFrameIterator = positionFrame.listIterator();
// if(positionFrameIterator.hasNext()){
// positionFrameCurrent = positionFrameIterator.next();
// if(positionFrameIterator.hasNext()){
// positionFrameNext = positionFrameIterator.next();
// nextPositionTime = positionFrameNext.time;
// } else {
// positionFrameNext = null;
// }
// }
// rotationFrameIterator = rotationFrame.listIterator();
// if(rotationFrameIterator.hasNext()){
// rotationFrameCurrent = rotationFrameIterator.next();
// if(rotationFrameIterator.hasNext()){
// rotationFrameNext = rotationFrameIterator.next();
// } else {
// rotationFrameNext = null;
// }
// }
// scaleFrameIterator = scaleFrame.listIterator();
// if(scaleFrameIterator.hasNext()){
// scaleFrameCurrent = scaleFrameIterator.next();
// if(scaleFrameIterator.hasNext()){
// scaleFrameNext = scaleFrameIterator.next();
// } else {
// scaleFrameNext = null;
// }
// }
}
public void describeChannel(){
System.out.println("Target object: " + nodeID);
System.out.println("Time: " + timeCurrent + "/" + timeTotal);
System.out.println(positionFrameTree.size() + " position Frames");
System.out.println(rotationFrameTree.size() + " rotation Frames");
System.out.println(scaleFrameTree.size() + " scale Frames");
}
public void fullDescribeChannel(){
System.out.println("Target object: " + nodeID);
System.out.println("Time: " + timeCurrent + "/" + timeTotal);
System.out.println(positionFrameTree.size() + " position Frames");
Iterator<Map.Entry<Double,Keyframe>> frameIterator = positionFrameTree.entrySet().iterator();
while(frameIterator.hasNext()){
System.out.println(frameIterator.next());
}
System.out.println(rotationFrameTree.size() + " rotation Frames");
frameIterator = rotationFrameTree.entrySet().iterator();
while(frameIterator.hasNext()){
System.out.println(frameIterator.next());
}
System.out.println(scaleFrameTree.size() + " scale Frames");
frameIterator = scaleFrameTree.entrySet().iterator();
while(frameIterator.hasNext()){
System.out.println(frameIterator.next());
}
}
public String getNodeID(){
return nodeID;
}
public void addPositionFrame(double time, Keyframe frame){
positionFrameTree.put(time, frame);
}
public void addRotationFrame(double time, Keyframe frame){
rotationFrameTree.put(time, frame);
}
public void addScaleFrame(double time, Keyframe frame){
scaleFrameTree.put(time, frame);
}
}