animation/attachment bugfix
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-07-26 23:12:19 -04:00
parent 8484fad7da
commit 57f2befc0e
21 changed files with 353 additions and 196 deletions

View File

@ -457,6 +457,7 @@ Viewmodel equipped item rotates inverted to bone rotation
Visually block
Utility object for reducing boilerplate when writing btree transitions that just play an animation then transition
First animations flickering in first person (enforce animation priority requirement)
Debug third person animations flickering (attachments not reflecting animations that were played that frame)
# TODO

View File

@ -138,6 +138,8 @@ public class ClientSimulation {
InstanceUpdater.updateInstancedActorPriority();
Globals.cameraHandler.updateGlobalCamera();
updateFirstPersonAttachments();
//bones have potenitally moved, so need to update where attached entities actually are before drawing
AttachUtils.clientUpdateAttachedEntityPositions();
// updateCellManager();
Globals.profiler.endCpuSample();
}

View File

@ -249,7 +249,7 @@ public class ControlHandler {
boolean shouldRecaptureScreen = false;
//controls whether the camera is first or third person
boolean cameraIsThirdPerson = false;
boolean cameraIsThirdPerson = true;
//The list of window strings that would block main game controls
static String[] controlBlockingWindows = new String[]{

View File

@ -6,6 +6,11 @@ package electrosphere.entity.state;
public class AnimationPriorities {
//
//1
//
public static final int DEATH = 1;
//
//2
//
@ -25,6 +30,12 @@ public class AnimationPriorities {
public static final int GROUND_MOVE = 5;
//
//7
//
public static final int ITEM_INTERACTION = 7;
//
//10

View File

@ -241,7 +241,7 @@ public class ClientAttackTree implements BehaviorTree {
if(currentMove != null){
if(entityActor != null){
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getWindupAnimationName())){
entityActor.playAnimation(currentMove.getWindupAnimationName(),1);
entityActor.playAnimation(currentMove.getWindupAnimationName(),AnimationPriorities.ATTACK);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonWindup().getName(), AnimationPriorities.ATTACK);
@ -251,7 +251,7 @@ public class ClientAttackTree implements BehaviorTree {
case HOLD: {
if(entityActor != null){
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getHoldAnimationName())){
entityActor.playAnimation(currentMove.getHoldAnimationName(),1);
entityActor.playAnimation(currentMove.getHoldAnimationName(),AnimationPriorities.ATTACK);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonHold().getName(), AnimationPriorities.ATTACK);
@ -260,7 +260,7 @@ public class ClientAttackTree implements BehaviorTree {
case ATTACK: {
if(entityActor != null && currentMove != null){
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getAttackAnimationName())){
entityActor.playAnimation(currentMove.getAttackAnimationName(),1);
entityActor.playAnimation(currentMove.getAttackAnimationName(),AnimationPriorities.ATTACK);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonAttack().getName(), AnimationPriorities.ATTACK);

View File

@ -15,6 +15,7 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.AnimationPriorities;
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeDriftState;
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState;
import electrosphere.entity.state.collidable.Impulse;
@ -220,7 +221,7 @@ public class ServerAttackTree implements BehaviorTree {
}
if(entityPoseActor != null){
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationName)){
entityPoseActor.playAnimation(animationName,1);
entityPoseActor.playAnimation(animationName,AnimationPriorities.ATTACK);
entityPoseActor.incrementAnimationTime(0.0001);
}
}
@ -249,7 +250,7 @@ public class ServerAttackTree implements BehaviorTree {
case HOLD: {
if(entityPoseActor != null){
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationName)){
entityPoseActor.playAnimation(animationName,1);
entityPoseActor.playAnimation(animationName,AnimationPriorities.ATTACK);
entityPoseActor.incrementAnimationTime(0.0001);
}
}

View File

@ -93,6 +93,14 @@ public class ClientBlockTree implements BehaviorTree {
}
}
/**
* returns if the client block tree is active or not
* @return true if active, false otherwise
*/
public boolean isActive(){
return this.state != BlockState.NOT_BLOCKING;
}
/**

View File

@ -98,7 +98,7 @@ public class ClientIdleTree implements BehaviorTree {
(Globals.assetManager.fetchModel(entityActor.getModelPath()) != null && Globals.assetManager.fetchModel(entityActor.getModelPath()).getAnimation(idleData.getIdleAnimation()) != null)
){
entityActor.playAnimation(idleData.getIdleAnimation(),3);
entityActor.playAnimation(idleData.getIdleAnimation(),AnimationPriorities.IDLE);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, idleData.getFirstPersonIdleAnimation(), AnimationPriorities.IDLE);

View File

@ -2,6 +2,7 @@ package electrosphere.entity.state.idle;
import electrosphere.net.synchronization.FieldIdEnums;
import electrosphere.entity.state.AnimationPriorities;
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState;
import electrosphere.entity.state.attack.ServerAttackTree;
import electrosphere.entity.state.idle.ClientIdleTree.IdleTreeState;
@ -92,7 +93,7 @@ public class ServerIdleTree implements BehaviorTree {
if(
(!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(Animation.ANIMATION_IDLE_1))
){
poseActor.playAnimation(Animation.ANIMATION_IDLE_1,3);
poseActor.playAnimation(Animation.ANIMATION_IDLE_1,AnimationPriorities.IDLE);
poseActor.incrementAnimationTime(0.0001);
}
}

View File

@ -8,6 +8,7 @@ import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.AnimationPriorities;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.game.data.creature.type.HealthSystem;
@ -174,7 +175,7 @@ public class LifeState implements BehaviorTree {
if(
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationToPlay)
){
entityActor.playAnimation(animationToPlay,1);
entityActor.playAnimation(animationToPlay,AnimationPriorities.DEATH);
entityActor.incrementAnimationTime(0.0001);
}
}

View File

@ -50,7 +50,7 @@ public class FallTree implements BehaviorTree {
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(fallMovementSystem.getAnimationFall().getName()) &&
(jumpTree == null || !jumpTree.isJumping())
){
entityActor.playAnimation(fallMovementSystem.getAnimationFall().getName(),1);
entityActor.playAnimation(fallMovementSystem.getAnimationFall().getName(),AnimationPriorities.FALL);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, fallMovementSystem.getAnimationFirstPersonFall().getName(), AnimationPriorities.FALL);
@ -87,7 +87,7 @@ public class FallTree implements BehaviorTree {
if(
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(fallMovementSystem.getAnimationLand().getName())
){
entityActor.playAnimation(fallMovementSystem.getAnimationLand().getName(),1);
entityActor.playAnimation(fallMovementSystem.getAnimationLand().getName(),AnimationPriorities.LAND);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, fallMovementSystem.getAnimationFirstPersonLand().getName(), AnimationPriorities.LAND);

View File

@ -61,7 +61,7 @@ public class JumpTree implements BehaviorTree {
case ACTIVE:
if(entityActor != null){
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(jumpData.getAnimationJump().getName())){
entityActor.playAnimation(jumpData.getAnimationJump().getName(),1);
entityActor.playAnimation(jumpData.getAnimationJump().getName(),AnimationPriorities.JUMP);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, jumpData.getAnimationFirstPersonJump().getName(), AnimationPriorities.JUMP);

View File

@ -4,6 +4,7 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.AnimationPriorities;
import electrosphere.server.poseactor.PoseActor;
public class ServerFallTree implements BehaviorTree {
@ -37,7 +38,7 @@ public class ServerFallTree implements BehaviorTree {
!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay) &&
(jumpTree == null || !jumpTree.isJumping())
){
poseActor.playAnimation(animationToPlay,1);
poseActor.playAnimation(animationToPlay,AnimationPriorities.FALL);
poseActor.incrementAnimationTime(0.0001);
}
}
@ -64,7 +65,7 @@ public class ServerFallTree implements BehaviorTree {
if(
!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay)
){
poseActor.playAnimation(animationToPlay,1);
poseActor.playAnimation(animationToPlay,AnimationPriorities.LAND);
poseActor.incrementAnimationTime(0.0001);
}
}

View File

@ -8,6 +8,7 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.AnimationPriorities;
import electrosphere.entity.state.gravity.GravityUtils;
import electrosphere.server.poseactor.PoseActor;
@ -55,7 +56,7 @@ public class ServerJumpTree implements BehaviorTree {
if(poseActor != null){
String animationToPlay = determineCorrectAnimation();
if(!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay)){
poseActor.playAnimation(animationToPlay,1);
poseActor.playAnimation(animationToPlay,AnimationPriorities.JUMP);
poseActor.incrementAnimationTime(0.0001);
}
}

View File

@ -291,7 +291,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
(jumpTree == null || !jumpTree.isJumping()) &&
(fallTree == null || !fallTree.isFalling())
){
entityActor.playAnimation(animationToPlay,1);
entityActor.playAnimation(animationToPlay,AnimationPriorities.GROUND_MOVE);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationFirstPersonStartup().getName(), AnimationPriorities.GROUND_MOVE);
@ -325,7 +325,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
(jumpTree == null || !jumpTree.isJumping()) &&
(fallTree == null || !fallTree.isFalling())
){
entityActor.playAnimation(animationToPlay,1);
entityActor.playAnimation(animationToPlay,AnimationPriorities.GROUND_MOVE);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationFirstPersonLoop().getName(), AnimationPriorities.GROUND_MOVE);
@ -353,7 +353,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
(jumpTree == null || !jumpTree.isJumping()) &&
(fallTree == null || !fallTree.isFalling())
){
entityActor.playAnimation(animationToPlay,1);
entityActor.playAnimation(animationToPlay,AnimationPriorities.GROUND_MOVE);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationFirstPersonWindDown().getName(), AnimationPriorities.GROUND_MOVE);

View File

@ -16,6 +16,7 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.AnimationPriorities;
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState;
import electrosphere.entity.state.attack.ServerAttackTree;
import electrosphere.entity.state.movement.ServerFallTree;
@ -252,7 +253,7 @@ public class ServerGroundMovementTree implements BehaviorTree {
(jumpTree == null || !jumpTree.isJumping()) &&
(fallTree == null || !fallTree.isFalling())
){
poseActor.playAnimation(animationToPlay,1);
poseActor.playAnimation(animationToPlay,AnimationPriorities.GROUND_MOVE);
poseActor.incrementAnimationTime(0.0001);
}
}
@ -307,7 +308,7 @@ public class ServerGroundMovementTree implements BehaviorTree {
(jumpTree == null || !jumpTree.isJumping()) &&
(fallTree == null || !fallTree.isFalling())
){
poseActor.playAnimation(animationToPlay,1);
poseActor.playAnimation(animationToPlay,AnimationPriorities.GROUND_MOVE);
poseActor.incrementAnimationTime(0.0001);
}
}
@ -359,7 +360,7 @@ public class ServerGroundMovementTree implements BehaviorTree {
(jumpTree == null || !jumpTree.isJumping()) &&
(fallTree == null || !fallTree.isFalling())
){
poseActor.playAnimation(animationToPlay,1);
poseActor.playAnimation(animationToPlay,AnimationPriorities.GROUND_MOVE);
poseActor.incrementAnimationTime(0.0001);
}
}

View File

@ -14,6 +14,7 @@ import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.state.AnimationPriorities;
import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.state.hitbox.HitboxCollectionState;
@ -238,7 +239,7 @@ public class ItemUtils {
if(actor != null && item.getData(EntityDataStrings.ANIM_IDLE) != null){
String idleAnim = (String)item.getData(EntityDataStrings.ANIM_IDLE);
if(!actor.isPlayingAnimation(idleAnim)){
actor.playAnimation(idleAnim,1);
actor.playAnimation(idleAnim,AnimationPriorities.ITEM_INTERACTION);
actor.incrementAnimationTime(0.0001);
}
}
@ -253,7 +254,7 @@ public class ItemUtils {
if(actor != null && item.getData(EntityDataStrings.ANIM_IDLE) != null){
String idleAnim = (String)item.getData(EntityDataStrings.ANIM_IDLE);
if(!actor.isPlayingAnimation(idleAnim)){
actor.playAnimation(idleAnim,1);
actor.playAnimation(idleAnim,AnimationPriorities.ITEM_INTERACTION);
actor.incrementAnimationTime(0.0001);
}
}

View File

@ -142,6 +142,7 @@ public class ImGuiEntityMacros {
*/
protected static void drawActorView(){
if(showActorTab && ImGui.collapsingHeader("Actor Details")){
ImGui.indent();
if(detailViewEntity != null && EntityUtils.getActor(detailViewEntity) != null){
Actor actor = EntityUtils.getActor(detailViewEntity);
@ -162,20 +163,38 @@ public class ImGuiEntityMacros {
if(ImGui.collapsingHeader("Animation Queue")){
PriorityQueue<ActorAnimationMask> animationQueue = actor.getAnimationQueue();
for(ActorAnimationMask mask : animationQueue){
ImGui.text(mask.getPriority() + " " + mask.getAnimationName());
ImGui.text(mask.getAnimationName() + " - " + mask.getPriority());
ImGui.text(mask.getDuration() + " " + mask.getTime());
}
}
//bone values
if(ImGui.collapsingHeader("Bone Values")){
for(Bone bone : actor.getBoneValues()){
ImGui.text(bone.boneID);
ImGui.text("Position: " + actor.getBonePosition(bone.boneID));
ImGui.text("Rotation: " + actor.getBoneRotation(bone.boneID));
ImGui.text(bone.getFinalTransform() + "");
}
}
//Browsable list of all animations with their data
if(ImGui.collapsingHeader("Animation Channel Data")){
Model model = Globals.assetManager.fetchModel(actor.getModelPath());
ImGui.indent();
for(Animation animation : model.getAnimations()){
ImGui.text(" - " + animation.name);
if(ImGui.collapsingHeader(animation.name)){
for(AnimChannel channel : animation.channels){
ImGui.pushID(channel.getNodeID());
if(ImGui.button("Fully describe")){
channel.fullDescribeChannel();
}
ImGui.text("=" + channel.getNodeID() + "=");
ImGui.text("" + channel.getCurrentPosition());
ImGui.text("" + channel.getCurrentRotation());
ImGui.text("" + channel.getCurrentScale());
ImGui.popID();
}
}
}
}
@ -205,7 +224,8 @@ public class ImGuiEntityMacros {
*/
protected static void drawFirstPersonView(){
if(showFirstPersonTab && ImGui.collapsingHeader("First Person Tree")){
FirstPersonTree firstPersonTree = FirstPersonTree.getTree(detailViewEntity);
ImGui.indent();
// FirstPersonTree firstPersonTree = FirstPersonTree.getTree(detailViewEntity);
}
}
@ -223,6 +243,7 @@ public class ImGuiEntityMacros {
*/
protected static void drawEquipState(){
if(showEquipStateTab && ImGui.collapsingHeader("Equip State Details")){
ImGui.indent();
if(detailViewEntity != null && ClientEquipState.getClientEquipState(detailViewEntity) != null){
ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(detailViewEntity);
if(ImGui.collapsingHeader("All Equip Points")){
@ -272,6 +293,7 @@ public class ImGuiEntityMacros {
*/
protected static void drawLinkedEntities(){
if(showLinkedEntitiesTab && ImGui.collapsingHeader("Linked entities")){
ImGui.indent();
if(detailViewEntity == Globals.playerEntity && ImGui.button("View Model")){
showEntity(Globals.firstPersonEntity);
}

View File

@ -178,8 +178,6 @@ public class Actor {
}
void applyAnimationMasks(Model model){
// Model model = Globals.assetManager.fetchModel(modelPath);
// if(model != null){
List<String> bonesUsed = new LinkedList<String>();
List<String> currentAnimationMask = new LinkedList<String>();
for(ActorAnimationMask mask : animationQueue){
@ -192,7 +190,6 @@ public class Actor {
}
model.applyAnimationMask(mask.getAnimationName(), mask.getTime(), currentAnimationMask);
}
// }
}
void calculateNodeTransforms(Model model){
@ -283,19 +280,18 @@ public class Actor {
if(model != null){
applyAnimationMasks(model);
calculateNodeTransforms(model);
// if(animation != null){
// model.playAnimation(animation);
// model.incrementTime(animationTime);
// model.updateNodeTransform();
Bone currentBone = model.getBoneMap().get(boneName);
if(currentBone != null){
Vector4d result = new Matrix4d(currentBone.getFinalTransform()).transform(currentBone.getMOffset().invert().transform(new Vector4d(rVal.x,rVal.y,rVal.z,1)));
// currentBone.inverseBindPoseMatrix
rVal.x = (float)result.x;
rVal.y = (float)result.y;
rVal.z = (float)result.z;
} else {
throw new IllegalArgumentException("Trying to get rotation of bone that does not exist on model!");
}
// }
}
if(!Double.isFinite(rVal.x)){
throw new IllegalStateException("Bone rotation that is not finite!");
}
return rVal;
}
@ -306,17 +302,18 @@ public class Actor {
if(model != null){
applyAnimationMasks(model);
calculateNodeTransforms(model);
// if(animation != null){
// model.playAnimation(animation);
// model.incrementTime(animationTime);
Bone currentBone = model.getBoneMap().get(boneName);
if(currentBone != null){
AxisAngle4f axisAngle = new AxisAngle4f();
new Matrix4f(currentBone.getFinalTransform()).getRotation(axisAngle);
Quaterniond rotation = new Quaterniond(axisAngle);
rVal.set(rotation);
} else {
throw new IllegalArgumentException("Trying to get rotation of bone that does not exist on model!");
}
// }
}
if(!Double.isFinite(rVal.x)){
throw new IllegalStateException("Bone rotation that is not finite!");
}
return rVal;
}
@ -327,16 +324,15 @@ public class Actor {
if(model != null){
applyAnimationMasks(model);
calculateNodeTransforms(model);
// if(animation != null){
// model.playAnimation(animation);
// model.incrementTime(animationTime);
// model.updateNodeTransform();
Bone currentBone = model.getBoneMap().get(boneName);
if(currentBone != null){
rVal = currentBone.getFinalTransform();
// currentBone.inverseBindPoseMatrix
} else {
throw new IllegalArgumentException("Trying to get rotation of bone that does not exist on model!");
}
// }
}
if(!Double.isFinite(rVal.m00())){
throw new IllegalStateException("Bone rotation that is not finite!");
}
return rVal;
}
@ -355,6 +351,18 @@ public class Actor {
return null;
}
/**
* Gets the value of a single bone
* @return the bone
*/
public Bone getBone(String boneName){
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
return model.getBoneMap().get(boneName);
}
return null;
}
public boolean modelIsLoaded(){
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){

View File

@ -8,12 +8,14 @@ import java.util.Map.Entry;
import org.joml.Quaterniond;
import org.joml.Vector3f;
import electrosphere.logger.LoggerInterface;
/**
* A single channel of keyframes in an animation
*/
public class AnimChannel {
double timeCurrent;
double timeCurrent = 0;
double timeTotal;
double ticksPerSecond;
String nodeID;
@ -37,6 +39,10 @@ public class AnimChannel {
scaleFrameTree = new TreeMap<Double,Keyframe>();
}
/**
* Gets the current position of this anim channel
* @return The position
*/
public Vector3f getCurrentPosition(){
Vector3f rVal = new Vector3f();
@ -44,7 +50,15 @@ public class AnimChannel {
Entry<Double,Keyframe> nextEntry = positionFrameTree.ceilingEntry(timeCurrent);
Keyframe previousFrame = null;
Keyframe nextFrame = null;
if(previousEntry == nextEntry){
//error checking
if(previousEntry == null && nextEntry == null){
LoggerInterface.loggerEngine.WARNING("Animation channel with no keys!");
return rVal;
}
//find the frames from the enties in the tree
if(previousEntry != null && nextEntry != null && previousEntry.getValue() == nextEntry.getValue()){
nextEntry = positionFrameTree.higherEntry(timeCurrent);
}
if(previousEntry != null){
@ -53,7 +67,21 @@ public class AnimChannel {
if(nextEntry != null){
nextFrame = nextEntry.getValue();
}
if(previousFrame != null && nextFrame != null){
//error checking
if(previousFrame != null && previousFrame == nextFrame){
LoggerInterface.loggerEngine.WARNING("Animation channel with same frames for different enties?!");
LoggerInterface.loggerEngine.WARNING("entry comparison: " + (nextEntry == previousEntry));
LoggerInterface.loggerEngine.WARNING("previous entry: " + nextEntry);
LoggerInterface.loggerEngine.WARNING("next entry: " + previousEntry);
LoggerInterface.loggerEngine.WARNING("frame comparison: " + (previousFrame == nextFrame));
LoggerInterface.loggerEngine.WARNING("previous frame: " + previousFrame);
LoggerInterface.loggerEngine.WARNING("next frame: " + nextFrame);
this.validate();
}
//calculate position
if(previousFrame != null && nextFrame != null && previousFrame != nextFrame){
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){
@ -62,20 +90,36 @@ public class AnimChannel {
rVal = new Vector3f().add(nextFrame.position);
}
//error checking
if(this.timeCurrent >= 0 && previousFrame == null && nextFrame == null){
LoggerInterface.loggerEngine.WARNING("previousFrame: " + previousFrame);
LoggerInterface.loggerEngine.WARNING("nextFrame: " + nextFrame);
LoggerInterface.loggerEngine.WARNING("timeCurrent: " + timeCurrent);
LoggerInterface.loggerEngine.WARNING("timeTotal: " + timeTotal);
LoggerInterface.loggerEngine.WARNING("positionFrameTree.size(): " + positionFrameTree.size());
throw new IllegalStateException("Anim channel with time set has no available frames!");
}
if(!Float.isFinite(rVal.x)){
LoggerInterface.loggerEngine.WARNING("Frame comparison: " + (previousEntry == nextEntry));
LoggerInterface.loggerEngine.WARNING("previousFrame: " + previousFrame);
LoggerInterface.loggerEngine.WARNING("previousFrame.position: " + previousFrame.position);
LoggerInterface.loggerEngine.WARNING("nextFrame: " + nextFrame);
LoggerInterface.loggerEngine.WARNING("nextFrame.position: " + nextFrame.position);
if(previousFrame != null && nextFrame != null){
LoggerInterface.loggerEngine.WARNING("percent_Next: " + ((timeCurrent - previousFrame.time) / (nextFrame.time - previousFrame.time)));
}
LoggerInterface.loggerEngine.WARNING("Position: " + rVal);
throw new IllegalStateException("Anim channel position is not finite!");
}
// 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;
}
/**
* Gets the current rotation of this anim channel
* @return The rotation
*/
public Quaterniond getCurrentRotation(){
Quaterniond rVal = new Quaterniond();
@ -83,7 +127,15 @@ public class AnimChannel {
Entry<Double,Keyframe> nextEntry = rotationFrameTree.ceilingEntry(timeCurrent);
Keyframe previousFrame = null;
Keyframe nextFrame = null;
if(previousEntry == nextEntry){
//error checking
if(previousEntry == null && nextEntry == null){
LoggerInterface.loggerEngine.WARNING("Animation channel with no keys!");
return rVal;
}
//find the frames from the enties in the tree
if(previousEntry != null && nextEntry != null && previousEntry.getValue() == nextEntry.getValue()){
nextEntry = rotationFrameTree.higherEntry(timeCurrent);
}
if(previousEntry != null){
@ -92,32 +144,60 @@ public class AnimChannel {
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);
//error checking
if(previousFrame != null && previousFrame == nextFrame){
LoggerInterface.loggerEngine.WARNING("Animation channel with same frames for different enties?!");
LoggerInterface.loggerEngine.WARNING("entry comparison: " + (nextEntry == previousEntry));
LoggerInterface.loggerEngine.WARNING("previous entry: " + nextEntry);
LoggerInterface.loggerEngine.WARNING("next entry: " + previousEntry);
LoggerInterface.loggerEngine.WARNING("frame comparison: " + (previousFrame == nextFrame));
LoggerInterface.loggerEngine.WARNING("previous frame: " + previousFrame);
LoggerInterface.loggerEngine.WARNING("next frame: " + nextFrame);
this.validate();
}
//calculate rotation
if(previousFrame != null && nextFrame != null && previousFrame != nextFrame){
double percent_Next = ((timeCurrent - previousFrame.time) / (nextFrame.time - previousFrame.time));
rVal = new Quaterniond(previousFrame.rotation).slerp(nextFrame.rotation, (float)percent_Next);
} else if(previousFrame != null){
rVal = new Quaterniond(previousFrame.rotation);
} else if(nextFrame != null){
rVal = new Quaterniond(nextFrame.rotation);
}
//error checking
if(this.timeCurrent >= 0 && previousFrame == null && nextFrame == null){
LoggerInterface.loggerEngine.WARNING("previousFrame: " + previousFrame);
LoggerInterface.loggerEngine.WARNING("nextFrame: " + nextFrame);
LoggerInterface.loggerEngine.WARNING("timeCurrent: " + timeCurrent);
LoggerInterface.loggerEngine.WARNING("timeTotal: " + timeTotal);
LoggerInterface.loggerEngine.WARNING("rotationFrameTree.size(): " + rotationFrameTree.size());
throw new IllegalStateException("Anim channel with time set has no available frames!");
}
if(!Double.isFinite(rVal.x)){
LoggerInterface.loggerEngine.WARNING("Frame comparison: " + (previousEntry == nextEntry));
LoggerInterface.loggerEngine.WARNING("previousFrame: " + previousFrame);
LoggerInterface.loggerEngine.WARNING("previousFrame.rotation: " + previousFrame.rotation);
LoggerInterface.loggerEngine.WARNING("nextFrame: " + nextFrame);
LoggerInterface.loggerEngine.WARNING("nextFrame.rotation: " + nextFrame.rotation);
if(previousFrame != null && nextFrame != null){
LoggerInterface.loggerEngine.WARNING("percent_Next: " + ((timeCurrent - previousFrame.time) / (nextFrame.time - previousFrame.time)));
}
LoggerInterface.loggerEngine.WARNING("Rotation: " + rVal);
throw new IllegalStateException("Anim channel rotation is not finite!");
}
// 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;
}
/**
* Gets the current scale of this anim channel
* @return The scale
*/
public Vector3f getCurrentScale(){
Vector3f rVal = new Vector3f();
@ -125,7 +205,10 @@ public class AnimChannel {
Entry<Double,Keyframe> nextEntry = scaleFrameTree.ceilingEntry(timeCurrent);
Keyframe previousFrame = null;
Keyframe nextFrame = null;
if(previousEntry == nextEntry){
//find the frames from the enties in the tree
if(previousEntry != null && nextEntry != null && previousEntry.getValue() == nextEntry.getValue()){
nextEntry = scaleFrameTree.higherEntry(timeCurrent);
}
if(previousEntry != null){
@ -134,67 +217,60 @@ public class AnimChannel {
if(nextEntry != null){
nextFrame = nextEntry.getValue();
}
if(previousFrame != null && nextFrame != null){
//error checking
if(previousFrame != null && previousFrame == nextFrame){
LoggerInterface.loggerEngine.WARNING("Animation channel with same frames for different enties?!");
LoggerInterface.loggerEngine.WARNING("entry comparison: " + (nextEntry == previousEntry));
LoggerInterface.loggerEngine.WARNING("previous entry: " + nextEntry);
LoggerInterface.loggerEngine.WARNING("next entry: " + previousEntry);
LoggerInterface.loggerEngine.WARNING("frame comparison: " + (previousFrame == nextFrame));
LoggerInterface.loggerEngine.WARNING("previous frame: " + previousFrame);
LoggerInterface.loggerEngine.WARNING("next frame: " + nextFrame);
this.validate();
}
//calculate scale
if(previousFrame != null && nextFrame != null && previousFrame != nextFrame){
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)));
// }
//error checking
if(this.timeCurrent >= 0 && previousFrame == null && nextFrame == null){
LoggerInterface.loggerEngine.WARNING("previousFrame: " + previousFrame);
LoggerInterface.loggerEngine.WARNING("nextFrame: " + nextFrame);
LoggerInterface.loggerEngine.WARNING("timeCurrent: " + timeCurrent);
LoggerInterface.loggerEngine.WARNING("timeTotal: " + timeTotal);
LoggerInterface.loggerEngine.WARNING("scaleFrameTree.size(): " + scaleFrameTree.size());
throw new IllegalStateException("Anim channel with time set has no available frames!");
}
if(!Float.isFinite(rVal.x)){
LoggerInterface.loggerEngine.WARNING("Frame comparison: " + (previousEntry == nextEntry));
LoggerInterface.loggerEngine.WARNING("previousFrame: " + previousFrame);
LoggerInterface.loggerEngine.WARNING("previousFrame.scale: " + previousFrame.scale);
LoggerInterface.loggerEngine.WARNING("nextFrame: " + nextFrame);
LoggerInterface.loggerEngine.WARNING("nextFrame.scale: " + nextFrame.scale);
if(previousFrame != null && nextFrame != null){
LoggerInterface.loggerEngine.WARNING("percent_Next: " + ((timeCurrent - previousFrame.time) / (nextFrame.time - previousFrame.time)));
}
LoggerInterface.loggerEngine.WARNING("Scale: " + rVal);
throw new IllegalStateException("Anim channel scale is not finite!");
}
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){
@ -203,38 +279,6 @@ public class AnimChannel {
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(){
@ -265,6 +309,60 @@ public class AnimChannel {
}
}
/**
* Validates the data in the anim channel
*/
public void validate(){
for(Double key1 : positionFrameTree.keySet()){
//check if different keys have the same values
for(Double key2 : positionFrameTree.keySet()){
if(
key1 != key2 &&
positionFrameTree.get(key1) == positionFrameTree.get(key2)
){
LoggerInterface.loggerEngine.WARNING("Different keys in the position frame tree have the same value!");
LoggerInterface.loggerEngine.WARNING("key1: " + key1);
LoggerInterface.loggerEngine.WARNING(positionFrameTree.get(key1) + "");
LoggerInterface.loggerEngine.WARNING("key2: " + key2);
LoggerInterface.loggerEngine.WARNING(positionFrameTree.get(key2) + "");
}
}
}
for(Double key1 : rotationFrameTree.keySet()){
//check if different keys have the same values
for(Double key2 : rotationFrameTree.keySet()){
if(
key1 != key2 &&
rotationFrameTree.get(key1) == rotationFrameTree.get(key2)
){
LoggerInterface.loggerEngine.WARNING("Different keys in the position frame tree have the same value!");
LoggerInterface.loggerEngine.WARNING("key1: " + key1);
LoggerInterface.loggerEngine.WARNING(rotationFrameTree.get(key1) + "");
LoggerInterface.loggerEngine.WARNING("key2: " + key2);
LoggerInterface.loggerEngine.WARNING(rotationFrameTree.get(key2) + "");
}
}
}
for(Double key1 : scaleFrameTree.keySet()){
//check if different keys have the same values
for(Double key2 : scaleFrameTree.keySet()){
if(
key1 != key2 &&
scaleFrameTree.get(key1) == scaleFrameTree.get(key2)
){
LoggerInterface.loggerEngine.WARNING("Different keys in the position frame tree have the same value!");
LoggerInterface.loggerEngine.WARNING("key1: " + key1);
LoggerInterface.loggerEngine.WARNING(scaleFrameTree.get(key1) + "");
LoggerInterface.loggerEngine.WARNING("key2: " + key2);
LoggerInterface.loggerEngine.WARNING(scaleFrameTree.get(key2) + "");
}
}
}
}
public String getNodeID(){
return nodeID;
}

View File

@ -33,8 +33,8 @@ public class Keyframe implements Comparable<Keyframe>{
@Override
public String toString(){
String rVal = "";
rVal = rVal + "[" + time + "]";
String rVal = "hash[" + this.hashCode() + "] ";
rVal = rVal + "time[" + time + "]";
if(position != null){
rVal = rVal + " position:" + position.toString();
}