The animation rework

This commit is contained in:
austin 2021-12-06 00:05:02 -05:00
parent d3197547d0
commit 5b7980f545
21 changed files with 71848 additions and 409 deletions

71116
assets/Models/goblin1.gltf Normal file

File diff suppressed because one or more lines are too long

View File

@ -38,9 +38,9 @@ import electrosphere.menu.MenuUtils;
import electrosphere.net.NetUtils; import electrosphere.net.NetUtils;
import electrosphere.net.client.ClientNetworking; import electrosphere.net.client.ClientNetworking;
import electrosphere.net.server.Server; import electrosphere.net.server.Server;
import electrosphere.renderer.ActorUtils;
import electrosphere.renderer.Model; import electrosphere.renderer.Model;
import electrosphere.renderer.RenderUtils; import electrosphere.renderer.RenderUtils;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.engine.assetmanager.AssetDataStrings; import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.game.client.targeting.crosshair.Crosshair; import electrosphere.game.client.targeting.crosshair.Crosshair;
import electrosphere.game.server.ai.creature.OpportunisticAttacker; import electrosphere.game.server.ai.creature.OpportunisticAttacker;

View File

@ -10,9 +10,10 @@ import electrosphere.entity.state.movement.GroundMovementTree;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.renderer.Model; import electrosphere.renderer.Model;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.main.Globals; import electrosphere.main.Globals;
import electrosphere.renderer.Actor;
import electrosphere.renderer.ActorUtils;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import org.joml.Vector3d; import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;

View File

@ -9,7 +9,7 @@ import electrosphere.entity.types.hitbox.HitboxUtils;
import electrosphere.game.data.creature.type.AttackMove; import electrosphere.game.data.creature.type.AttackMove;
import electrosphere.main.Globals; import electrosphere.main.Globals;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.Actor; import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.anim.Animation; import electrosphere.renderer.anim.Animation;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@ -129,8 +129,8 @@ public class AttackTree {
switch(state){ switch(state){
case WINDUP: case WINDUP:
if(entityActor != null){ if(entityActor != null){
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationName)){ if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationName)){
entityActor.playAnimation(animationName); entityActor.playAnimation(animationName,1);
entityActor.incrementAnimationTime(0.01); entityActor.incrementAnimationTime(0.01);
} }
} }

View File

@ -9,7 +9,8 @@ import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable; import electrosphere.game.collision.collidable.Collidable;
import electrosphere.main.Globals; import electrosphere.main.Globals;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.Actor; import electrosphere.renderer.actor.Actor;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import org.joml.Vector3d; import org.joml.Vector3d;

View File

@ -8,7 +8,7 @@ import electrosphere.entity.state.AttackTree.AttackTreeState;
import electrosphere.entity.state.movement.GroundMovementTree.MovementTreeState; import electrosphere.entity.state.movement.GroundMovementTree.MovementTreeState;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.Actor; import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.anim.Animation; import electrosphere.renderer.anim.Animation;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Vector3d; import org.joml.Vector3d;
@ -95,8 +95,8 @@ public class IdleTree {
switch(state){ switch(state){
case IDLE: case IDLE:
if(entityActor != null){ if(entityActor != null){
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(Animation.ANIMATION_IDLE_1)){ if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(Animation.ANIMATION_IDLE_1)){
entityActor.playAnimation(Animation.ANIMATION_IDLE_1); entityActor.playAnimation(Animation.ANIMATION_IDLE_1,1);
entityActor.incrementAnimationTime(0.01); entityActor.incrementAnimationTime(0.01);
} }
} }

View File

@ -20,9 +20,10 @@ import electrosphere.main.Globals;
import electrosphere.main.Main; import electrosphere.main.Main;
import electrosphere.net.NetUtils; import electrosphere.net.NetUtils;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.Actor;
import electrosphere.renderer.anim.Animation; import electrosphere.renderer.anim.Animation;
import electrosphere.renderer.Model; import electrosphere.renderer.Model;
import electrosphere.renderer.actor.Actor;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@ -176,13 +177,13 @@ public class GroundMovementTree {
CreatureUtils.setVelocity(parent, velocity); CreatureUtils.setVelocity(parent, velocity);
if(entityActor != null){ if(entityActor != null){
if(sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING){ if(sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING){
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSprintStart)){ if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationSprintStart)){
entityActor.playAnimation(animationSprintStart); entityActor.playAnimation(animationSprintStart,1);
entityActor.incrementAnimationTime(0.01); entityActor.incrementAnimationTime(0.01);
} }
} else { } else {
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationStartUp)){ if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationStartUp)){
entityActor.playAnimation(animationStartUp); entityActor.playAnimation(animationStartUp,1);
entityActor.incrementAnimationTime(0.01); entityActor.incrementAnimationTime(0.01);
} }
} }
@ -260,13 +261,13 @@ public class GroundMovementTree {
//if yes, restart animation //if yes, restart animation
if(entityActor != null){ if(entityActor != null){
if(sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING){ if(sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING){
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSprint)){ if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationSprint)){
entityActor.playAnimation(animationSprint); entityActor.playAnimation(animationSprint,1);
entityActor.incrementAnimationTime(0.01); entityActor.incrementAnimationTime(0.01);
} }
} else { } else {
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationMain)){ if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationMain)){
entityActor.playAnimation(animationMain); entityActor.playAnimation(animationMain,1);
entityActor.incrementAnimationTime(0.01); entityActor.incrementAnimationTime(0.01);
} }
} }
@ -342,13 +343,13 @@ public class GroundMovementTree {
CreatureUtils.setVelocity(parent, velocity); CreatureUtils.setVelocity(parent, velocity);
if(entityActor != null){ if(entityActor != null){
if(sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING){ if(sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING){
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSprintWindDown)){ if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationSprintWindDown)){
entityActor.playAnimation(animationSprintWindDown); entityActor.playAnimation(animationSprintWindDown,1);
entityActor.incrementAnimationTime(0.01); entityActor.incrementAnimationTime(0.01);
} }
} else { } else {
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSlowDown)){ if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationSlowDown)){
entityActor.playAnimation(animationSlowDown); entityActor.playAnimation(animationSlowDown,1);
entityActor.incrementAnimationTime(0.01); entityActor.incrementAnimationTime(0.01);
} }
} }

View File

@ -5,8 +5,9 @@ import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.main.Globals; import electrosphere.main.Globals;
import electrosphere.renderer.Actor;
import electrosphere.renderer.Model; import electrosphere.renderer.Model;
import electrosphere.renderer.actor.Actor;
import java.util.LinkedList; import java.util.LinkedList;
import org.joml.Quaterniond; import org.joml.Quaterniond;
import org.joml.Quaternionf; import org.joml.Quaternionf;

View File

@ -30,9 +30,9 @@ import electrosphere.net.NetUtils;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.net.parser.net.message.NetworkMessage; import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.net.server.Player; import electrosphere.net.server.Player;
import electrosphere.renderer.Actor;
import electrosphere.renderer.ActorUtils;
import electrosphere.renderer.Model; import electrosphere.renderer.Model;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.util.ModelLoader; import electrosphere.util.ModelLoader;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import org.joml.Vector3d; import org.joml.Vector3d;

View File

@ -11,7 +11,8 @@ import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.foliage.type.FoliageType; import electrosphere.game.data.foliage.type.FoliageType;
import electrosphere.game.data.foliage.type.PhysicsObject; import electrosphere.game.data.foliage.type.PhysicsObject;
import electrosphere.main.Globals; import electrosphere.main.Globals;
import electrosphere.renderer.ActorUtils; import electrosphere.renderer.actor.ActorUtils;
import java.util.List; import java.util.List;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.joml.Quaternionf; import org.joml.Quaternionf;

View File

@ -19,9 +19,10 @@ import electrosphere.main.Globals;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.net.parser.net.message.NetworkMessage; import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.net.server.Player; import electrosphere.net.server.Player;
import electrosphere.renderer.Actor;
import electrosphere.renderer.ActorUtils;
import electrosphere.renderer.Model; import electrosphere.renderer.Model;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorUtils;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import org.joml.Vector3d; import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;
@ -130,12 +131,12 @@ public class ItemUtils {
public static void updateItemActorAnimation(Entity item){ public static void updateItemActorAnimation(Entity item){
Actor actor = EntityUtils.getActor(item); Actor actor = EntityUtils.getActor(item);
if(actor.getCurrentAnimation() == null){ if(!actor.isPlayingAnimation("Sword|Idle")){
// Model model; // Model model;
// if((model = Globals.assetManager.fetchModel(actor.getModelPath()))!=null){ // if((model = Globals.assetManager.fetchModel(actor.getModelPath()))!=null){
// model.describeAllAnimations(); // model.describeAllAnimations();
// } // }
actor.playAnimation("Sword|Idle"); actor.playAnimation("Sword|Idle",1);
} }
} }

View File

@ -19,8 +19,10 @@ import electrosphere.entity.state.movement.SprintTree;
import electrosphere.entity.types.particle.ParticleUtils; import electrosphere.entity.types.particle.ParticleUtils;
import electrosphere.game.client.targeting.crosshair.Crosshair; import electrosphere.game.client.targeting.crosshair.Crosshair;
import electrosphere.main.Globals; import electrosphere.main.Globals;
import electrosphere.renderer.actor.Actor;
import static electrosphere.main.Main.deltaTime; import static electrosphere.main.Main.deltaTime;
import electrosphere.renderer.Actor;
import org.joml.Vector3f; import org.joml.Vector3f;
/** /**
@ -49,7 +51,7 @@ public class MicroSimulation {
//fetch actor //fetch actor
Actor currentActor = EntityUtils.getActor(currentEntity); Actor currentActor = EntityUtils.getActor(currentEntity);
//increment animations //increment animations
if(currentActor.getCurrentAnimation() != null){ if(currentActor.isPlayingAnimation()){
currentActor.incrementAnimationTime(deltaTime); currentActor.incrementAnimationTime(deltaTime);
} }
} }

View File

@ -1,187 +0,0 @@
package electrosphere.renderer;
import electrosphere.main.Globals;
import electrosphere.renderer.anim.Animation;
import electrosphere.renderer.texture.Texture;
import org.joml.AxisAngle4f;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.joml.Vector4f;
/**
*
* @author amaterasu
*/
public class Actor {
String modelPath;
String textureOverride;
String animation;
double animationTime;
boolean playingAnimation;
float animationScalar = 1.0f;
public Actor(String modelPath){
playingAnimation = false;
this.modelPath = modelPath;
}
public void incrementAnimationTime(double deltaTime){
Model model = Globals.assetManager.fetchModel(modelPath);
if(playingAnimation){
animationTime = animationTime + deltaTime * animationScalar;
}
if(model != null){
if(animation != null){
model.playAnimation(animation);
model.incrementTime(animationTime);
if(model.currentAnimation == null){
playingAnimation = false;
}
}
}
}
public double getAnimationTime(){
return animationTime;
}
public String getCurrentAnimation(){
return animation;
}
public void playAnimation(String animationName){
animationTime = 0;
playingAnimation = true;
animation = animationName;
}
public boolean isPlayingAnimation(){
return playingAnimation;
}
public void setAnimationScalar(float animationScalar) {
this.animationScalar = animationScalar;
}
public void applyModelMatrix(Matrix4f modelMatrix){
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
model.modelMatrix = modelMatrix;
}
}
public void draw(){
Model model = Globals.assetManager.fetchModel(modelPath);
boolean hasDrawn = false;
if(model != null){
if(animation != null){
model.playAnimation(animation);
model.incrementTime(0.001);
model.incrementTime(animationTime);
if(model.currentAnimation == null){
playingAnimation = false;
}
}
if(textureOverride != null){
Texture overrideTextureObject = Globals.assetManager.fetchTexture(textureOverride);
if(overrideTextureObject != null){
overrideTextureObject.bind();
hasDrawn = true;
model.draw(true, true, false, false, true, true, true);
}
}
if(!hasDrawn){
model.draw(true, true, false, true, true, true, true);
}
}
}
public void drawForDepthBuffer(){
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
if(animation != null){
model.playAnimation(animation);
model.incrementTime(animationTime);
if(model.currentAnimation == null){
playingAnimation = false;
}
}
model.drawForDepthBuffer();
}
}
public void drawUI(){
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
model.drawUI();
}
}
public String getModelPath(){
return modelPath;
}
public Vector3f getBonePosition(String boneName){
Vector3f rVal = new Vector3f();
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
if(animation != null){
model.playAnimation(animation);
model.incrementTime(animationTime);
model.update_node_transform(model.root_anim_node);
Bone currentBone = model.boneMap.get(boneName);
if(currentBone != null){
Vector4f result = currentBone.final_transform.transform(new Matrix4f(currentBone.inverseBindPoseMatrix).invert().transform(new Vector4f(rVal.x,rVal.y,rVal.z,1)));
// currentBone.inverseBindPoseMatrix
rVal.x = result.x;
rVal.y = result.y;
rVal.z = result.z;
}
}
}
return rVal;
}
public Quaternionf getBoneRotation(String boneName){
Quaternionf rVal = new Quaternionf();
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
if(animation != null){
model.playAnimation(animation);
model.incrementTime(animationTime);
Bone currentBone = model.boneMap.get(boneName);
if(currentBone != null){
AxisAngle4f axisAngle = new AxisAngle4f();
currentBone.final_transform.getRotation(axisAngle);
Quaternionf rotation = new Quaternionf(axisAngle);
rVal.set(rotation);
}
}
}
return rVal;
}
public Matrix4f getBoneTransform(String boneName){
Matrix4f rVal = new Matrix4f();
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
if(animation != null){
model.playAnimation(animation);
model.incrementTime(animationTime);
model.update_node_transform(model.root_anim_node);
Bone currentBone = model.boneMap.get(boneName);
if(currentBone != null){
rVal = currentBone.final_transform;
// currentBone.inverseBindPoseMatrix
}
}
}
return rVal;
}
public void setTextureOverride(String override){
textureOverride = override;
}
}

View File

@ -1,5 +1,6 @@
package electrosphere.renderer; package electrosphere.renderer;
import electrosphere.renderer.actor.ActorAnimationMask;
import electrosphere.renderer.anim.AnimChannel; import electrosphere.renderer.anim.AnimChannel;
import electrosphere.renderer.anim.Animation; import electrosphere.renderer.anim.Animation;
import electrosphere.renderer.anim.AnimNode; import electrosphere.renderer.anim.AnimNode;
@ -41,18 +42,18 @@ import org.lwjgl.assimp.AINode;
* @author satellite * @author satellite
*/ */
public class Model { public class Model {
public boolean is_Ready_To_Display = false; boolean is_Ready_To_Display = false;
public AIScene scene; AIScene scene;
public ArrayList<Mesh> meshes; public ArrayList<Mesh> meshes;
public ArrayList<Animation> animations; public ArrayList<Animation> animations;
public ArrayList<Bone> bones; public ArrayList<Bone> bones;
public HashMap<String,Bone> boneMap; public HashMap<String,Bone> boneMap;
HashMap<String,Animation> animMap;
public HashMap<String,AnimNode> node_map; public HashMap<String,AnimNode> node_map;
public ArrayList<Material> materials; public ArrayList<Material> materials;
public Matrix4f modelMatrix = new Matrix4f(); public Matrix4f modelMatrix = new Matrix4f();
ShaderProgram program; ShaderProgram program;
public Animation currentAnimation; Matrix4f globalInverseTransform;
public Matrix4f globalInverseTransform;
AnimNode root_anim_node; AnimNode root_anim_node;
@ -68,7 +69,7 @@ public class Model {
// //
int meshCount = s.mNumMeshes(); int meshCount = s.mNumMeshes();
PointerBuffer meshesBuffer = s.mMeshes(); PointerBuffer meshesBuffer = s.mMeshes();
rVal.meshes = new ArrayList(); rVal.meshes = new ArrayList<Mesh>();
while(meshesBuffer.hasRemaining()){ while(meshesBuffer.hasRemaining()){
Mesh currentMesh = Mesh.create_mesh_from_aimesh(AIMesh.create(meshesBuffer.get())); Mesh currentMesh = Mesh.create_mesh_from_aimesh(AIMesh.create(meshesBuffer.get()));
rVal.meshes.add(currentMesh); rVal.meshes.add(currentMesh);
@ -77,8 +78,8 @@ public class Model {
// //
//register bones //register bones
// //
rVal.bones = new ArrayList(); rVal.bones = new ArrayList<Bone>();
rVal.boneMap = new HashMap(); rVal.boneMap = new HashMap<String, Bone>();
meshesBuffer.rewind(); meshesBuffer.rewind();
while(meshesBuffer.hasRemaining()){ while(meshesBuffer.hasRemaining()){
AIMesh currentMeshData = AIMesh.createSafe(meshesBuffer.get()); AIMesh currentMeshData = AIMesh.createSafe(meshesBuffer.get());
@ -96,7 +97,7 @@ public class Model {
Iterator<Mesh> meshIterator = rVal.meshes.iterator(); Iterator<Mesh> meshIterator = rVal.meshes.iterator();
rVal.bones = new ArrayList(); rVal.bones = new ArrayList();
rVal.boneMap = new HashMap(); rVal.boneMap = new HashMap();
rVal.node_map = new HashMap(); rVal.node_map = new HashMap<String, AnimNode>();
while(meshIterator.hasNext()){ while(meshIterator.hasNext()){
Mesh currentMesh = meshIterator.next(); Mesh currentMesh = meshIterator.next();
Iterator<Bone> boneIterator = currentMesh.bones.iterator(); Iterator<Bone> boneIterator = currentMesh.bones.iterator();
@ -132,8 +133,11 @@ public class Model {
int animCount = s.mNumAnimations(); int animCount = s.mNumAnimations();
PointerBuffer animBuffer = s.mAnimations(); PointerBuffer animBuffer = s.mAnimations();
rVal.animations = new ArrayList(); rVal.animations = new ArrayList();
rVal.animMap = new HashMap<String,Animation>();
for(int i = 0; i < animCount; i++){ for(int i = 0; i < animCount; i++){
rVal.animations.add(new Animation(AIAnimation.create(animBuffer.get(i)), i)); Animation newAnim = new Animation(AIAnimation.create(animBuffer.get(i)), i);
rVal.animations.add(newAnim);
rVal.animMap.put(newAnim.name,newAnim);
} }
// //
//Load materials //Load materials
@ -176,7 +180,6 @@ public class Model {
materials = null; materials = null;
modelMatrix = new Matrix4f(); modelMatrix = new Matrix4f();
program = null; program = null;
currentAnimation = null;
globalInverseTransform = null; globalInverseTransform = null;
} }
@ -198,72 +201,92 @@ public class Model {
} }
public void playAnimation(String s){ // public void playAnimation(String s){
this.currentAnimation = null; // this.currentAnimation = null;
Iterator<Animation> animationIterator = animations.iterator(); // Iterator<Animation> animationIterator = animations.iterator();
while(animationIterator.hasNext()){ // while(animationIterator.hasNext()){
Animation current_iterator_item = animationIterator.next(); // Animation current_iterator_item = animationIterator.next();
if(current_iterator_item.name.equals(s)){ // if(current_iterator_item.name.equals(s)){
this.currentAnimation = current_iterator_item; // this.currentAnimation = current_iterator_item;
} // }
} // }
if(currentAnimation != null){ // if(currentAnimation != null){
// if(s.contains("Walk")){ // // if(s.contains("Walk")){
// currentAnimation.describeAnimation(); // // currentAnimation.describeAnimation();
//// currentAnimation.fullDescribeAnimation(); // //// currentAnimation.fullDescribeAnimation();
// System.exit(0); // // System.exit(0);
// } // // }
currentAnimation.timeCurrent = 0; // currentAnimation.timeCurrent = 0;
Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator(); // Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator();
while(channelIterator.hasNext()){ // while(channelIterator.hasNext()){
AnimChannel currentChannel = channelIterator.next(); // AnimChannel currentChannel = channelIterator.next();
currentChannel.rewind(); // currentChannel.rewind();
// }
// }
// }
public void applyAnimationMask(String animationName, double time, List<String> mask){
Animation animationCurrent = animMap.get(animationName);
if(animationCurrent != null){
for(String boneName : mask){
AnimChannel currentChannel = animationCurrent.getChannel(boneName);
Bone currentBone = boneMap.get(currentChannel.getNodeID());
currentChannel.setTime(time);
// System.out.println(currentChannel + " " + currentBone);
if(currentBone != null){
// System.out.println("Applying to bone");
//T * S * R
currentBone.deform = new Matrix4f();
currentBone.deform.translate(currentChannel.getCurrentPosition());
currentBone.deform.rotate(currentChannel.getCurrentRotation());
currentBone.deform.scale(currentChannel.getCurrentScale());
}
} }
} }
} }
public void incrementTime(double time){ // public void incrementTime(double time){
if(currentAnimation != null){ // if(currentAnimation != null){
boolean isDone = currentAnimation.incrementTime(time); // boolean isDone = currentAnimation.incrementTime(time);
if(isDone){ // if(isDone){
currentAnimation.timeCurrent = 0; // currentAnimation.timeCurrent = 0;
Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator(); // Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator();
while(channelIterator.hasNext()){ // while(channelIterator.hasNext()){
AnimChannel currentChannel = channelIterator.next(); // AnimChannel currentChannel = channelIterator.next();
currentChannel.rewind(); // currentChannel.rewind();
} // }
Iterator<Bone> boneIterator = bones.iterator(); // Iterator<Bone> boneIterator = bones.iterator();
while(boneIterator.hasNext()){ // while(boneIterator.hasNext()){
Bone currentBone = boneIterator.next(); // Bone currentBone = boneIterator.next();
currentBone.transform = new Matrix4f(); // currentBone.transform = new Matrix4f();
} // }
currentAnimation = null; // currentAnimation = null;
} else { // } else {
//First we push transformFromParent into deform so that later in the pipeline bones without a current animation take on transformFromParent as their transformation to the hierarchy // //First we push transformFromParent into deform so that later in the pipeline bones without a current animation take on transformFromParent as their transformation to the hierarchy
//I BELIEVE this is so that control bones still apply their offset to the hierarchy even when they're not animated :tm: // //I BELIEVE this is so that control bones still apply their offset to the hierarchy even when they're not animated :tm:
//4/5/20 // //4/5/20
// Iterator<Bone> boneIterator = bones.iterator(); // // Iterator<Bone> boneIterator = bones.iterator();
// while(boneIterator.hasNext()){ // // while(boneIterator.hasNext()){
// Bone currentBone = boneIterator.next(); // // Bone currentBone = boneIterator.next();
//// currentBone.deform = currentBone.transformFromParent; // //// currentBone.deform = currentBone.transformFromParent;
// } // // }
//Once that's done, for every channel we set the corresponding bone's deform to the channels TRS // //Once that's done, for every channel we set the corresponding bone's deform to the channels TRS
Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator(); // Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator();
while(channelIterator.hasNext()){ // while(channelIterator.hasNext()){
AnimChannel currentChannel = channelIterator.next(); // AnimChannel currentChannel = channelIterator.next();
currentChannel.incrementTime(time); // currentChannel.incrementTime(time);
Bone currentBone = boneMap.get(currentChannel.nodeID); // Bone currentBone = boneMap.get(currentChannel.getNodeID());
if(currentBone != null){ // if(currentBone != null){
//T * S * R // //T * S * R
currentBone.deform = new Matrix4f(); // currentBone.deform = new Matrix4f();
currentBone.deform.translate(currentChannel.getCurrentPosition()); // currentBone.deform.translate(currentChannel.getCurrentPosition());
currentBone.deform.rotate(currentChannel.getCurrentRotation()); // currentBone.deform.rotate(currentChannel.getCurrentRotation());
currentBone.deform.scale(currentChannel.getCurrentScale()); // currentBone.deform.scale(currentChannel.getCurrentScale());
} // }
} // }
} // }
} // }
} // }
public void describeAllAnimations(){ public void describeAllAnimations(){
if(animations.size() > 0){ if(animations.size() > 0){
@ -300,7 +323,11 @@ public class Model {
return node_object; return node_object;
} }
public void update_node_transform(AnimNode n){ public void updateNodeTransform(){
update_node_transform(this.root_anim_node);
}
void update_node_transform(AnimNode n){
if(n.parent != null){ if(n.parent != null){
n.transform = new Matrix4f(n.parent.transform); n.transform = new Matrix4f(n.parent.transform);
} else { } else {
@ -395,6 +422,10 @@ public class Model {
} }
return null; return null;
} }
public Animation getAnimation(String animName){
return animMap.get(animName);
}
public void describeHighLevel(){ public void describeHighLevel(){
System.out.println("Meshes: "); System.out.println("Meshes: ");

View File

@ -15,6 +15,8 @@ import electrosphere.main.Globals;
import static electrosphere.main.Main.deltaTime; import static electrosphere.main.Main.deltaTime;
import static electrosphere.main.Main.view_Range; import static electrosphere.main.Main.view_Range;
import static electrosphere.renderer.RenderUtils.createScreenTextureVAO; import static electrosphere.renderer.RenderUtils.createScreenTextureVAO;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.Framebuffer;
import electrosphere.renderer.framebuffer.FramebufferUtils; import electrosphere.renderer.framebuffer.FramebufferUtils;
import electrosphere.renderer.framebuffer.Renderbuffer; import electrosphere.renderer.framebuffer.Renderbuffer;

View File

@ -0,0 +1,287 @@
package electrosphere.renderer.actor;
import electrosphere.main.Globals;
import electrosphere.renderer.Bone;
import electrosphere.renderer.Model;
import electrosphere.renderer.anim.Animation;
import electrosphere.renderer.texture.Texture;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import org.joml.AxisAngle4f;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.joml.Vector4f;
/**
*
* @author amaterasu
*/
public class Actor {
String modelPath;
String textureOverride;
float animationScalar = 1.0f;
PriorityQueue<ActorAnimationMask> animationQueue = new PriorityQueue<ActorAnimationMask>();
public Actor(String modelPath){
this.modelPath = modelPath;
}
List<ActorAnimationMask> toRemoveMasks = new LinkedList<ActorAnimationMask>();
public void incrementAnimationTime(double deltaTime){
toRemoveMasks.clear();
for(ActorAnimationMask mask : animationQueue){
mask.setTime(mask.getTime() + deltaTime * animationScalar);
if(mask.getTime() > mask.getDuration()){
toRemoveMasks.add(mask);
}
}
for(ActorAnimationMask mask : toRemoveMasks){
animationQueue.remove(mask);
}
// if(playingAnimation){
// animationTime = animationTime + deltaTime * animationScalar;
// }
// if(model != null){
// if(animation != null){
// model.playAnimation(animation);
// model.incrementTime(animationTime);
// if(model.currentAnimation == null){
// playingAnimation = false;
// }
// }
// }
}
public double getAnimationTime(String animationName){
for(ActorAnimationMask mask : animationQueue){
if(mask.getAnimationName().contains(animationName)){
return mask.getTime();
}
}
return -1.0f;
}
public boolean isPlayingAnimation(String animationName){
for(ActorAnimationMask mask : animationQueue){
if(mask.getAnimationName().contains(animationName)){
return true;
}
}
return false;
}
public boolean isPlayingAnimation(){
return animationQueue.size() > 0;
}
// public String getCurrentAnimation(){
// return animation;
// }
public void playAnimation(String animationName, int priority){
// animationTime = 0;
// playingAnimation = true;
// animation = animationName;
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
double length = model.getAnimation(animationName).duration;
ActorAnimationMask animMask = new ActorAnimationMask(priority, animationName, 0, length);
for(Bone bone : model.bones){
animMask.addBone(bone.boneID);
}
toRemoveMasks.clear();
for(ActorAnimationMask currentMask : animationQueue){
if(currentMask.getPriority() == animMask.getPriority()){
toRemoveMasks.add(currentMask);
break;
}
}
for(ActorAnimationMask currentMask : toRemoveMasks){
animationQueue.remove(currentMask);
}
animationQueue.add(animMask);
}
}
public void playAnimationWithMask(String animationName, int priority, List<String> boneMask){
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
double length = model.getAnimation(animationName).duration;
ActorAnimationMask animMask = new ActorAnimationMask(priority, animationName, 0, length, boneMask);
toRemoveMasks.clear();
for(ActorAnimationMask currentMask : animationQueue){
if(currentMask.getPriority() == animMask.getPriority()){
toRemoveMasks.add(currentMask);
break;
}
}
for(ActorAnimationMask currentMask : toRemoveMasks){
animationQueue.remove(currentMask);
}
animationQueue.add(animMask);
}
}
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){
currentAnimationMask.clear();
for(String currentBone : mask.boneMask){
if(!bonesUsed.contains(currentBone)){
bonesUsed.add(currentBone);
currentAnimationMask.add(currentBone);
}
}
model.applyAnimationMask(mask.getAnimationName(), mask.getTime(), currentAnimationMask);
}
// }
}
void calculateNodeTransforms(Model model){
model.updateNodeTransform();
}
// public boolean isPlayingAnimation(){
// return playingAnimation;
// }
public void setAnimationScalar(float animationScalar) {
this.animationScalar = animationScalar;
}
public void applyModelMatrix(Matrix4f modelMatrix){
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
model.modelMatrix = modelMatrix;
}
}
public void draw(){
Model model = Globals.assetManager.fetchModel(modelPath);
boolean hasDrawn = false;
if(model != null){
applyAnimationMasks(model);
// if(animation != null){
// model.playAnimation(animation);
// model.incrementTime(0.001);
// model.incrementTime(animationTime);
// if(model.currentAnimation == null){
// playingAnimation = false;
// }
// }
if(textureOverride != null){
Texture overrideTextureObject = Globals.assetManager.fetchTexture(textureOverride);
if(overrideTextureObject != null){
overrideTextureObject.bind();
hasDrawn = true;
model.draw(true, true, false, false, true, true, true);
}
}
if(!hasDrawn){
model.draw(true, true, false, true, true, true, true);
}
}
}
public void drawForDepthBuffer(){
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
// if(animation != null){
// model.playAnimation(animation);
// model.incrementTime(animationTime);
// if(model.currentAnimation == null){
// playingAnimation = false;
// }
// }
applyAnimationMasks(model);
model.drawForDepthBuffer();
}
}
public void drawUI(){
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
model.drawUI();
}
}
public String getModelPath(){
return modelPath;
}
public Vector3f getBonePosition(String boneName){
Vector3f rVal = new Vector3f();
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
applyAnimationMasks(model);
calculateNodeTransforms(model);
// if(animation != null){
// model.playAnimation(animation);
// model.incrementTime(animationTime);
// model.updateNodeTransform();
Bone currentBone = model.boneMap.get(boneName);
if(currentBone != null){
Vector4f result = currentBone.final_transform.transform(new Matrix4f(currentBone.inverseBindPoseMatrix).invert().transform(new Vector4f(rVal.x,rVal.y,rVal.z,1)));
// currentBone.inverseBindPoseMatrix
rVal.x = result.x;
rVal.y = result.y;
rVal.z = result.z;
}
// }
}
return rVal;
}
public Quaternionf getBoneRotation(String boneName){
Quaternionf rVal = new Quaternionf();
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
applyAnimationMasks(model);
calculateNodeTransforms(model);
// if(animation != null){
// model.playAnimation(animation);
// model.incrementTime(animationTime);
Bone currentBone = model.boneMap.get(boneName);
if(currentBone != null){
AxisAngle4f axisAngle = new AxisAngle4f();
currentBone.final_transform.getRotation(axisAngle);
Quaternionf rotation = new Quaternionf(axisAngle);
rVal.set(rotation);
}
// }
}
return rVal;
}
public Matrix4f getBoneTransform(String boneName){
Matrix4f rVal = new Matrix4f();
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
applyAnimationMasks(model);
calculateNodeTransforms(model);
// if(animation != null){
// model.playAnimation(animation);
// model.incrementTime(animationTime);
// model.updateNodeTransform();
Bone currentBone = model.boneMap.get(boneName);
if(currentBone != null){
rVal = currentBone.final_transform;
// currentBone.inverseBindPoseMatrix
}
// }
}
return rVal;
}
public void setTextureOverride(String override){
textureOverride = override;
}
}

View File

@ -0,0 +1,66 @@
package electrosphere.renderer.actor;
import java.util.LinkedList;
import java.util.List;
public class ActorAnimationMask implements Comparable {
int priority;
String animationName;
double time;
double timeMax;
List<String> boneMask;
public ActorAnimationMask(int priority, String animationName, double time, double timeMax, List<String> boneMask){
this.priority = priority;
this.animationName = animationName;
this.time = time;
this.timeMax = timeMax;
this.boneMask = boneMask;
}
public ActorAnimationMask(int priority, String animationName, double time, double timeMax){
this(priority, animationName, time, timeMax, new LinkedList<String>());
}
public void addBone(String boneName){
boneMask.add(boneName);
}
public List<String> getBones(){
return boneMask;
}
public String getAnimationName(){
return animationName;
}
public int getPriority(){
return priority;
}
public double getTime(){
return time;
}
public void setTime(double time){
this.time = time;
}
public double getDuration(){
return timeMax;
}
@Override
public int compareTo(Object o) {
ActorAnimationMask otherMask = (ActorAnimationMask)o;
if(otherMask.priority > this.priority){
return -1;
} else if(otherMask.priority < this.priority){
return 1;
} else {
return 0;
}
}
}

View File

@ -1,4 +1,4 @@
package electrosphere.renderer; package electrosphere.renderer.actor;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;

View File

@ -3,6 +3,10 @@ package electrosphere.renderer.anim;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import org.joml.Vector3f; import org.joml.Vector3f;
@ -14,171 +18,268 @@ import org.joml.Vector3f;
public class AnimChannel { public class AnimChannel {
double timeCurrent; double timeCurrent;
double timeTotal; double timeTotal;
public String nodeID; String nodeID;
public Vector3f startingPosition; Vector3f startingPosition;
public ArrayList<Keyframe> positionFrame; TreeMap<Double,Keyframe> positionFrameTree;
public ListIterator<Keyframe> positionFrameIterator;
Keyframe positionFrameCurrent;
Keyframe positionFrameNext;
double nextPositionTime;
public Quaternionf startingRotation; Quaternionf startingRotation;
public ArrayList<Keyframe> rotationFrame; TreeMap<Double,Keyframe> rotationFrameTree;
public ListIterator<Keyframe> rotationFrameIterator;
Keyframe rotationFrameCurrent;
Keyframe rotationFrameNext;
double nextRotationTime;
TreeMap<Double,Keyframe> scaleFrameTree;
public ArrayList<Keyframe> scaleFrame;
public ListIterator<Keyframe> scaleFrameIterator;
Keyframe scaleFrameCurrent;
Keyframe scaleFrameNext;
double nextScaleTime;
public AnimChannel(double maxTime){ public AnimChannel(double maxTime){
timeTotal = maxTime; timeTotal = maxTime;
positionFrameTree = new TreeMap<Double,Keyframe>();
rotationFrameTree = new TreeMap<Double,Keyframe>();
scaleFrameTree = new TreeMap<Double,Keyframe>();
} }
public Vector3f getCurrentPosition(){ public Vector3f getCurrentPosition(){
Vector3f rVal = new Vector3f(); Vector3f rVal = new Vector3f();
if(positionFrameCurrent != null){
if(positionFrameNext != null){ Entry<Double,Keyframe> previousEntry = positionFrameTree.floorEntry(timeCurrent);
double percent_Next = ((timeCurrent - positionFrameCurrent.time) / (positionFrameNext.time - positionFrameCurrent.time)); Entry<Double,Keyframe> nextEntry = positionFrameTree.ceilingEntry(timeCurrent);
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))); Keyframe previousFrame = null;
} else { Keyframe nextFrame = null;
rVal = new Vector3f().add(positionFrameCurrent.position); if(previousEntry == nextEntry){
} nextEntry = positionFrameTree.higherEntry(timeCurrent);
// rVal.add(new Vector3f().add(positionFrameCurrent.position).mul(()/(positionFrameNext.time - positionFrameCurrent.time)));
} }
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); // rVal = rVal.sub(startingPosition);
return rVal; return rVal;
} }
public Quaternionf getCurrentRotation(){ public Quaternionf getCurrentRotation(){
Quaternionf rVal = new Quaternionf(); Quaternionf rVal = new Quaternionf();
if(rotationFrameCurrent != null){
if(rotationFrameNext != null){ Entry<Double,Keyframe> previousEntry = rotationFrameTree.floorEntry(timeCurrent);
double percent_Next = ((timeCurrent - rotationFrameCurrent.time) / (rotationFrameNext.time - rotationFrameCurrent.time)); Entry<Double,Keyframe> nextEntry = rotationFrameTree.ceilingEntry(timeCurrent);
// rVal = new Quaternionf(rotationFrameCurrent.rotation).normalize();//.add(rotationFrameCurrent.rotation); Keyframe previousFrame = null;
rVal = new Quaternionf(rotationFrameCurrent.rotation).slerp(rotationFrameNext.rotation, (float)percent_Next); Keyframe nextFrame = null;
// 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)); if(previousEntry == nextEntry){
} else { nextEntry = rotationFrameTree.higherEntry(timeCurrent);
rVal = new Quaternionf(rotationFrameCurrent.rotation);//.add(rotationFrameCurrent.rotation);
}
} }
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 Quaternionf(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 Quaternionf(previousFrame.rotation);
// rVal = new Vector3f().add(previousFrame.position);
} else if(nextFrame != null){
rVal = new Quaternionf(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()); // rVal = rVal.mul(new Quaternionf(startingRotation).invert());
return rVal; return rVal;
} }
public Vector3f getCurrentScale(){ public Vector3f getCurrentScale(){
Vector3f rVal = new Vector3f(); Vector3f rVal = new Vector3f();
if(scaleFrameCurrent != null){
if(scaleFrameNext != null){ Entry<Double,Keyframe> previousEntry = scaleFrameTree.floorEntry(timeCurrent);
double percent_Next = ((timeCurrent - scaleFrameCurrent.time) / (scaleFrameNext.time - scaleFrameCurrent.time)); Entry<Double,Keyframe> nextEntry = scaleFrameTree.ceilingEntry(timeCurrent);
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))); Keyframe previousFrame = null;
} else { Keyframe nextFrame = null;
rVal = new Vector3f().add(scaleFrameCurrent.scale); if(previousEntry == nextEntry){
} nextEntry = scaleFrameTree.higherEntry(timeCurrent);
// rVal.add(new Vector3f().add(positionFrameCurrent.position).mul(()/(positionFrameNext.time - positionFrameCurrent.time)));
} }
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; return rVal;
} }
public void incrementTime(double incrementValue){ public void incrementTime(double incrementValue){
timeCurrent = timeCurrent + incrementValue; timeCurrent = timeCurrent + incrementValue;
while(positionFrameNext != null && timeCurrent > positionFrameNext.time){ // Entry<Double,Keyframe> previousEntry = positionFrameTree.floorEntry(timeCurrent);
positionFrameCurrent = positionFrameNext; // Entry<Double,Keyframe> nextEntry = positionFrameTree.ceilingEntry(timeCurrent);
if(positionFrameIterator.hasNext()){ // boolean blend = true;
positionFrameNext = positionFrameIterator.next(); // if(previousEntry == nextEntry){
} else { // if((nextEntry) == null){
positionFrameNext = null; // blend = false;
} // }
} // }
while(rotationFrameNext != null && timeCurrent > rotationFrameNext.time){ // if(positionFrameTree.higherEntry(timeCurrent) != null){
rotationFrameCurrent = rotationFrameNext;
if(rotationFrameIterator.hasNext()){ // }
rotationFrameNext = rotationFrameIterator.next(); // while(positionFrameNext != null && timeCurrent > positionFrameNext.time){
} else { // positionFrameCurrent = positionFrameNext;
rotationFrameNext = null; // if(positionFrameIterator.hasNext()){
} // positionFrameNext = positionFrameIterator.next();
} // } else {
while(scaleFrameNext != null && timeCurrent > scaleFrameNext.time){ // positionFrameNext = null;
scaleFrameCurrent = scaleFrameNext; // }
if(scaleFrameIterator.hasNext()){ // }
scaleFrameNext = scaleFrameIterator.next(); // while(rotationFrameNext != null && timeCurrent > rotationFrameNext.time){
} else { // rotationFrameCurrent = rotationFrameNext;
scaleFrameNext = null; // 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(){ public void rewind(){
timeCurrent = 0; timeCurrent = 0;
//TODO: Make sure has at least two frames //TODO: Make sure has at least two frames
positionFrameIterator = positionFrame.listIterator(); // positionFrameIterator = positionFrame.listIterator();
if(positionFrameIterator.hasNext()){ // if(positionFrameIterator.hasNext()){
positionFrameCurrent = positionFrameIterator.next(); // positionFrameCurrent = positionFrameIterator.next();
if(positionFrameIterator.hasNext()){ // if(positionFrameIterator.hasNext()){
positionFrameNext = positionFrameIterator.next(); // positionFrameNext = positionFrameIterator.next();
nextPositionTime = positionFrameNext.time; // nextPositionTime = positionFrameNext.time;
} else { // } else {
positionFrameNext = null; // positionFrameNext = null;
} // }
} // }
rotationFrameIterator = rotationFrame.listIterator(); // rotationFrameIterator = rotationFrame.listIterator();
if(rotationFrameIterator.hasNext()){ // if(rotationFrameIterator.hasNext()){
rotationFrameCurrent = rotationFrameIterator.next(); // rotationFrameCurrent = rotationFrameIterator.next();
if(rotationFrameIterator.hasNext()){ // if(rotationFrameIterator.hasNext()){
rotationFrameNext = rotationFrameIterator.next(); // rotationFrameNext = rotationFrameIterator.next();
} else { // } else {
rotationFrameNext = null; // rotationFrameNext = null;
} // }
} // }
scaleFrameIterator = scaleFrame.listIterator(); // scaleFrameIterator = scaleFrame.listIterator();
if(scaleFrameIterator.hasNext()){ // if(scaleFrameIterator.hasNext()){
scaleFrameCurrent = scaleFrameIterator.next(); // scaleFrameCurrent = scaleFrameIterator.next();
if(scaleFrameIterator.hasNext()){ // if(scaleFrameIterator.hasNext()){
scaleFrameNext = scaleFrameIterator.next(); // scaleFrameNext = scaleFrameIterator.next();
} else { // } else {
scaleFrameNext = null; // scaleFrameNext = null;
} // }
} // }
} }
public void describeChannel(){ public void describeChannel(){
System.out.println("Target object: " + nodeID); System.out.println("Target object: " + nodeID);
System.out.println("Time: " + timeCurrent + "/" + timeTotal); System.out.println("Time: " + timeCurrent + "/" + timeTotal);
System.out.println(positionFrame.size() + " position Frames"); System.out.println(positionFrameTree.size() + " position Frames");
System.out.println(rotationFrame.size() + " rotation Frames"); System.out.println(rotationFrameTree.size() + " rotation Frames");
System.out.println(scaleFrame.size() + " scale Frames"); System.out.println(scaleFrameTree.size() + " scale Frames");
} }
public void fullDescribeChannel(){ public void fullDescribeChannel(){
System.out.println("Target object: " + nodeID); System.out.println("Target object: " + nodeID);
System.out.println("Time: " + timeCurrent + "/" + timeTotal); System.out.println("Time: " + timeCurrent + "/" + timeTotal);
System.out.println(positionFrame.size() + " position Frames"); System.out.println(positionFrameTree.size() + " position Frames");
Iterator<Keyframe> frameIterator = positionFrame.iterator(); Iterator<Map.Entry<Double,Keyframe>> frameIterator = positionFrameTree.entrySet().iterator();
while(frameIterator.hasNext()){ while(frameIterator.hasNext()){
System.out.println(frameIterator.next()); System.out.println(frameIterator.next());
} }
System.out.println(rotationFrame.size() + " rotation Frames"); System.out.println(rotationFrameTree.size() + " rotation Frames");
frameIterator = rotationFrame.iterator(); frameIterator = rotationFrameTree.entrySet().iterator();
while(frameIterator.hasNext()){ while(frameIterator.hasNext()){
System.out.println(frameIterator.next()); System.out.println(frameIterator.next());
} }
System.out.println(scaleFrame.size() + " scale Frames"); System.out.println(scaleFrameTree.size() + " scale Frames");
frameIterator = scaleFrame.iterator(); frameIterator = scaleFrameTree.entrySet().iterator();
while(frameIterator.hasNext()){ while(frameIterator.hasNext()){
System.out.println(frameIterator.next()); 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);
}
} }

View File

@ -3,6 +3,7 @@ package electrosphere.renderer.anim;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map;
import java.util.PriorityQueue; import java.util.PriorityQueue;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import org.joml.Vector3f; import org.joml.Vector3f;
@ -39,7 +40,15 @@ public class Animation {
public double duration = 0; public double duration = 0;
public double timeCurrent = 0; public double timeCurrent = 0;
public double ticksPerSecond; public double ticksPerSecond;
Map<String, AnimChannel> channelMap;
public Animation(AIAnimation animData, int ID){ public Animation(AIAnimation animData, int ID){
//
//Create structures
//
channelMap = new HashMap<String, AnimChannel>();
// //
//Read in metadata //Read in metadata
// //
@ -69,11 +78,13 @@ public class Animation {
//Create channel //Create channel
AnimChannel currentChannel = new AnimChannel(duration); AnimChannel currentChannel = new AnimChannel(duration);
currentChannel.positionFrame = new ArrayList(); // currentChannel.positionFrame = new ArrayList();
currentChannel.rotationFrame = new ArrayList(); // currentChannel.rotationFrame = new ArrayList();
currentChannel.scaleFrame = new ArrayList(); // currentChannel.scaleFrame = new ArrayList();
currentChannel.nodeID = currentChannelData.mNodeName().dataString(); currentChannel.nodeID = currentChannelData.mNodeName().dataString();
channels.add(currentChannel); channels.add(currentChannel);
channelMap.put(currentChannel.nodeID,currentChannel);
//get channel data //get channel data
@ -92,7 +103,7 @@ public class Animation {
AIVectorKey key = buff.get(); AIVectorKey key = buff.get();
Keyframe currentFrame = new Keyframe(key.mTime()); Keyframe currentFrame = new Keyframe(key.mTime());
currentFrame.position = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z()); currentFrame.position = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
currentChannel.positionFrame.add(currentFrame); currentChannel.addPositionFrame(key.mTime(),currentFrame);
// System.out.println(currentFrame.position); // System.out.println(currentFrame.position);
currentChannel.startingPosition = currentFrame.position; currentChannel.startingPosition = currentFrame.position;
@ -110,7 +121,7 @@ public class Animation {
previousFrame.position.z == currentFrame.position.z previousFrame.position.z == currentFrame.position.z
){ ){
} else { } else {
currentChannel.positionFrame.add(currentFrame); currentChannel.addPositionFrame(key.mTime(),currentFrame);
} }
} }
} }
@ -124,7 +135,7 @@ public class Animation {
currentFrame.rotation = new Quaternionf(); currentFrame.rotation = new Quaternionf();
currentFrame.rotation.set(key.mValue().x(), key.mValue().y(), key.mValue().z(), key.mValue().w()); currentFrame.rotation.set(key.mValue().x(), key.mValue().y(), key.mValue().z(), key.mValue().w());
// currentFrame.rotation = new Quaternionf(key.mValue().x(),key.mValue().y(),key.mValue().z(),key.mValue().w()); // currentFrame.rotation = new Quaternionf(key.mValue().x(),key.mValue().y(),key.mValue().z(),key.mValue().w());
currentChannel.rotationFrame.add(currentFrame); currentChannel.addRotationFrame(key.mTime(),currentFrame);
currentChannel.startingRotation = currentFrame.rotation; currentChannel.startingRotation = currentFrame.rotation;
@ -144,7 +155,7 @@ public class Animation {
previousFrame.rotation.z == currentFrame.rotation.z previousFrame.rotation.z == currentFrame.rotation.z
){ ){
} else { } else {
currentChannel.rotationFrame.add(currentFrame); currentChannel.addRotationFrame(key.mTime(),currentFrame);
} }
} }
} }
@ -170,7 +181,7 @@ public class Animation {
AIVectorKey key = buff.get(); AIVectorKey key = buff.get();
Keyframe currentFrame = new Keyframe(key.mTime()); Keyframe currentFrame = new Keyframe(key.mTime());
currentFrame.scale = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z()); currentFrame.scale = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
currentChannel.scaleFrame.add(currentFrame); currentChannel.addScaleFrame(key.mTime(),currentFrame);
Keyframe previousFrame; Keyframe previousFrame;
while(buff.hasRemaining()){ while(buff.hasRemaining()){
previousFrame = currentFrame; previousFrame = currentFrame;
@ -182,7 +193,7 @@ public class Animation {
currentFrame.scale.z == previousFrame.scale.z currentFrame.scale.z == previousFrame.scale.z
){ ){
} else { } else {
currentChannel.scaleFrame.add(currentFrame); currentChannel.addScaleFrame(key.mTime(),currentFrame);
} }
} }
} }
@ -261,4 +272,8 @@ public class Animation {
public void setTime(double time){ public void setTime(double time){
timeCurrent = time; timeCurrent = time;
} }
public AnimChannel getChannel(String name){
return channelMap.get(name);
}
} }

View File

@ -4,9 +4,9 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.main.Globals; import electrosphere.main.Globals;
import electrosphere.renderer.ActorUtils;
import electrosphere.renderer.Model; import electrosphere.renderer.Model;
import electrosphere.renderer.ModelUtils; import electrosphere.renderer.ModelUtils;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.renderer.ui.font.RawFontMap.Glyph; import electrosphere.renderer.ui.font.RawFontMap.Glyph;
import java.util.HashMap; import java.util.HashMap;
import org.joml.Quaternionf; import org.joml.Quaternionf;