The animation rework
This commit is contained in:
parent
d3197547d0
commit
5b7980f545
71116
assets/Models/goblin1.gltf
Normal file
71116
assets/Models/goblin1.gltf
Normal file
File diff suppressed because one or more lines are too long
@ -38,9 +38,9 @@ import electrosphere.menu.MenuUtils;
|
||||
import electrosphere.net.NetUtils;
|
||||
import electrosphere.net.client.ClientNetworking;
|
||||
import electrosphere.net.server.Server;
|
||||
import electrosphere.renderer.ActorUtils;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.RenderUtils;
|
||||
import electrosphere.renderer.actor.ActorUtils;
|
||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||
import electrosphere.game.client.targeting.crosshair.Crosshair;
|
||||
import electrosphere.game.server.ai.creature.OpportunisticAttacker;
|
||||
|
||||
@ -10,9 +10,10 @@ import electrosphere.entity.state.movement.GroundMovementTree;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.entity.types.item.ItemUtils;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.actor.ActorUtils;
|
||||
import electrosphere.main.Globals;
|
||||
import electrosphere.renderer.Actor;
|
||||
import electrosphere.renderer.ActorUtils;
|
||||
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
@ -9,7 +9,7 @@ import electrosphere.entity.types.hitbox.HitboxUtils;
|
||||
import electrosphere.game.data.creature.type.AttackMove;
|
||||
import electrosphere.main.Globals;
|
||||
import electrosphere.net.parser.net.message.EntityMessage;
|
||||
import electrosphere.renderer.Actor;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.anim.Animation;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
@ -129,8 +129,8 @@ public class AttackTree {
|
||||
switch(state){
|
||||
case WINDUP:
|
||||
if(entityActor != null){
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationName)){
|
||||
entityActor.playAnimation(animationName);
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationName)){
|
||||
entityActor.playAnimation(animationName,1);
|
||||
entityActor.incrementAnimationTime(0.01);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,8 @@ import electrosphere.game.collision.PhysicsUtils;
|
||||
import electrosphere.game.collision.collidable.Collidable;
|
||||
import electrosphere.main.Globals;
|
||||
import electrosphere.net.parser.net.message.EntityMessage;
|
||||
import electrosphere.renderer.Actor;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
@ -8,7 +8,7 @@ import electrosphere.entity.state.AttackTree.AttackTreeState;
|
||||
import electrosphere.entity.state.movement.GroundMovementTree.MovementTreeState;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.net.parser.net.message.EntityMessage;
|
||||
import electrosphere.renderer.Actor;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.anim.Animation;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import org.joml.Vector3d;
|
||||
@ -95,8 +95,8 @@ public class IdleTree {
|
||||
switch(state){
|
||||
case IDLE:
|
||||
if(entityActor != null){
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(Animation.ANIMATION_IDLE_1)){
|
||||
entityActor.playAnimation(Animation.ANIMATION_IDLE_1);
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(Animation.ANIMATION_IDLE_1)){
|
||||
entityActor.playAnimation(Animation.ANIMATION_IDLE_1,1);
|
||||
entityActor.incrementAnimationTime(0.01);
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,9 +20,10 @@ import electrosphere.main.Globals;
|
||||
import electrosphere.main.Main;
|
||||
import electrosphere.net.NetUtils;
|
||||
import electrosphere.net.parser.net.message.EntityMessage;
|
||||
import electrosphere.renderer.Actor;
|
||||
import electrosphere.renderer.anim.Animation;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
@ -176,13 +177,13 @@ public class GroundMovementTree {
|
||||
CreatureUtils.setVelocity(parent, velocity);
|
||||
if(entityActor != null){
|
||||
if(sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING){
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSprintStart)){
|
||||
entityActor.playAnimation(animationSprintStart);
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationSprintStart)){
|
||||
entityActor.playAnimation(animationSprintStart,1);
|
||||
entityActor.incrementAnimationTime(0.01);
|
||||
}
|
||||
} else {
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationStartUp)){
|
||||
entityActor.playAnimation(animationStartUp);
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationStartUp)){
|
||||
entityActor.playAnimation(animationStartUp,1);
|
||||
entityActor.incrementAnimationTime(0.01);
|
||||
}
|
||||
}
|
||||
@ -260,13 +261,13 @@ public class GroundMovementTree {
|
||||
//if yes, restart animation
|
||||
if(entityActor != null){
|
||||
if(sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING){
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSprint)){
|
||||
entityActor.playAnimation(animationSprint);
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationSprint)){
|
||||
entityActor.playAnimation(animationSprint,1);
|
||||
entityActor.incrementAnimationTime(0.01);
|
||||
}
|
||||
} else {
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationMain)){
|
||||
entityActor.playAnimation(animationMain);
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationMain)){
|
||||
entityActor.playAnimation(animationMain,1);
|
||||
entityActor.incrementAnimationTime(0.01);
|
||||
}
|
||||
}
|
||||
@ -342,13 +343,13 @@ public class GroundMovementTree {
|
||||
CreatureUtils.setVelocity(parent, velocity);
|
||||
if(entityActor != null){
|
||||
if(sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING){
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSprintWindDown)){
|
||||
entityActor.playAnimation(animationSprintWindDown);
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationSprintWindDown)){
|
||||
entityActor.playAnimation(animationSprintWindDown,1);
|
||||
entityActor.incrementAnimationTime(0.01);
|
||||
}
|
||||
} else {
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSlowDown)){
|
||||
entityActor.playAnimation(animationSlowDown);
|
||||
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationSlowDown)){
|
||||
entityActor.playAnimation(animationSlowDown,1);
|
||||
entityActor.incrementAnimationTime(0.01);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,8 +5,9 @@ import electrosphere.entity.EntityDataStrings;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.main.Globals;
|
||||
import electrosphere.renderer.Actor;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Quaternionf;
|
||||
|
||||
@ -30,9 +30,9 @@ import electrosphere.net.NetUtils;
|
||||
import electrosphere.net.parser.net.message.EntityMessage;
|
||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||
import electrosphere.net.server.Player;
|
||||
import electrosphere.renderer.Actor;
|
||||
import electrosphere.renderer.ActorUtils;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.actor.ActorUtils;
|
||||
import electrosphere.util.ModelLoader;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
@ -11,7 +11,8 @@ import electrosphere.game.collision.collidable.Collidable;
|
||||
import electrosphere.game.data.foliage.type.FoliageType;
|
||||
import electrosphere.game.data.foliage.type.PhysicsObject;
|
||||
import electrosphere.main.Globals;
|
||||
import electrosphere.renderer.ActorUtils;
|
||||
import electrosphere.renderer.actor.ActorUtils;
|
||||
|
||||
import java.util.List;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
|
||||
@ -19,9 +19,10 @@ import electrosphere.main.Globals;
|
||||
import electrosphere.net.parser.net.message.EntityMessage;
|
||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||
import electrosphere.net.server.Player;
|
||||
import electrosphere.renderer.Actor;
|
||||
import electrosphere.renderer.ActorUtils;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.actor.ActorUtils;
|
||||
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
@ -130,12 +131,12 @@ public class ItemUtils {
|
||||
|
||||
public static void updateItemActorAnimation(Entity item){
|
||||
Actor actor = EntityUtils.getActor(item);
|
||||
if(actor.getCurrentAnimation() == null){
|
||||
if(!actor.isPlayingAnimation("Sword|Idle")){
|
||||
// Model model;
|
||||
// if((model = Globals.assetManager.fetchModel(actor.getModelPath()))!=null){
|
||||
// model.describeAllAnimations();
|
||||
// }
|
||||
actor.playAnimation("Sword|Idle");
|
||||
actor.playAnimation("Sword|Idle",1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -19,8 +19,10 @@ import electrosphere.entity.state.movement.SprintTree;
|
||||
import electrosphere.entity.types.particle.ParticleUtils;
|
||||
import electrosphere.game.client.targeting.crosshair.Crosshair;
|
||||
import electrosphere.main.Globals;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
|
||||
import static electrosphere.main.Main.deltaTime;
|
||||
import electrosphere.renderer.Actor;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
@ -49,7 +51,7 @@ public class MicroSimulation {
|
||||
//fetch actor
|
||||
Actor currentActor = EntityUtils.getActor(currentEntity);
|
||||
//increment animations
|
||||
if(currentActor.getCurrentAnimation() != null){
|
||||
if(currentActor.isPlayingAnimation()){
|
||||
currentActor.incrementAnimationTime(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package electrosphere.renderer;
|
||||
|
||||
import electrosphere.renderer.actor.ActorAnimationMask;
|
||||
import electrosphere.renderer.anim.AnimChannel;
|
||||
import electrosphere.renderer.anim.Animation;
|
||||
import electrosphere.renderer.anim.AnimNode;
|
||||
@ -41,18 +42,18 @@ import org.lwjgl.assimp.AINode;
|
||||
* @author satellite
|
||||
*/
|
||||
public class Model {
|
||||
public boolean is_Ready_To_Display = false;
|
||||
public AIScene scene;
|
||||
boolean is_Ready_To_Display = false;
|
||||
AIScene scene;
|
||||
public ArrayList<Mesh> meshes;
|
||||
public ArrayList<Animation> animations;
|
||||
public ArrayList<Bone> bones;
|
||||
public HashMap<String,Bone> boneMap;
|
||||
HashMap<String,Animation> animMap;
|
||||
public HashMap<String,AnimNode> node_map;
|
||||
public ArrayList<Material> materials;
|
||||
public Matrix4f modelMatrix = new Matrix4f();
|
||||
ShaderProgram program;
|
||||
public Animation currentAnimation;
|
||||
public Matrix4f globalInverseTransform;
|
||||
Matrix4f globalInverseTransform;
|
||||
|
||||
AnimNode root_anim_node;
|
||||
|
||||
@ -68,7 +69,7 @@ public class Model {
|
||||
//
|
||||
int meshCount = s.mNumMeshes();
|
||||
PointerBuffer meshesBuffer = s.mMeshes();
|
||||
rVal.meshes = new ArrayList();
|
||||
rVal.meshes = new ArrayList<Mesh>();
|
||||
while(meshesBuffer.hasRemaining()){
|
||||
Mesh currentMesh = Mesh.create_mesh_from_aimesh(AIMesh.create(meshesBuffer.get()));
|
||||
rVal.meshes.add(currentMesh);
|
||||
@ -77,8 +78,8 @@ public class Model {
|
||||
//
|
||||
//register bones
|
||||
//
|
||||
rVal.bones = new ArrayList();
|
||||
rVal.boneMap = new HashMap();
|
||||
rVal.bones = new ArrayList<Bone>();
|
||||
rVal.boneMap = new HashMap<String, Bone>();
|
||||
meshesBuffer.rewind();
|
||||
while(meshesBuffer.hasRemaining()){
|
||||
AIMesh currentMeshData = AIMesh.createSafe(meshesBuffer.get());
|
||||
@ -96,7 +97,7 @@ public class Model {
|
||||
Iterator<Mesh> meshIterator = rVal.meshes.iterator();
|
||||
rVal.bones = new ArrayList();
|
||||
rVal.boneMap = new HashMap();
|
||||
rVal.node_map = new HashMap();
|
||||
rVal.node_map = new HashMap<String, AnimNode>();
|
||||
while(meshIterator.hasNext()){
|
||||
Mesh currentMesh = meshIterator.next();
|
||||
Iterator<Bone> boneIterator = currentMesh.bones.iterator();
|
||||
@ -132,8 +133,11 @@ public class Model {
|
||||
int animCount = s.mNumAnimations();
|
||||
PointerBuffer animBuffer = s.mAnimations();
|
||||
rVal.animations = new ArrayList();
|
||||
rVal.animMap = new HashMap<String,Animation>();
|
||||
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
|
||||
@ -176,7 +180,6 @@ public class Model {
|
||||
materials = null;
|
||||
modelMatrix = new Matrix4f();
|
||||
program = null;
|
||||
currentAnimation = null;
|
||||
globalInverseTransform = null;
|
||||
}
|
||||
|
||||
@ -198,72 +201,92 @@ public class Model {
|
||||
}
|
||||
|
||||
|
||||
public void playAnimation(String s){
|
||||
this.currentAnimation = null;
|
||||
Iterator<Animation> animationIterator = animations.iterator();
|
||||
while(animationIterator.hasNext()){
|
||||
Animation current_iterator_item = animationIterator.next();
|
||||
if(current_iterator_item.name.equals(s)){
|
||||
this.currentAnimation = current_iterator_item;
|
||||
}
|
||||
}
|
||||
if(currentAnimation != null){
|
||||
// if(s.contains("Walk")){
|
||||
// currentAnimation.describeAnimation();
|
||||
//// currentAnimation.fullDescribeAnimation();
|
||||
// System.exit(0);
|
||||
// }
|
||||
currentAnimation.timeCurrent = 0;
|
||||
Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator();
|
||||
while(channelIterator.hasNext()){
|
||||
AnimChannel currentChannel = channelIterator.next();
|
||||
currentChannel.rewind();
|
||||
// public void playAnimation(String s){
|
||||
// this.currentAnimation = null;
|
||||
// Iterator<Animation> animationIterator = animations.iterator();
|
||||
// while(animationIterator.hasNext()){
|
||||
// Animation current_iterator_item = animationIterator.next();
|
||||
// if(current_iterator_item.name.equals(s)){
|
||||
// this.currentAnimation = current_iterator_item;
|
||||
// }
|
||||
// }
|
||||
// if(currentAnimation != null){
|
||||
// // if(s.contains("Walk")){
|
||||
// // currentAnimation.describeAnimation();
|
||||
// //// currentAnimation.fullDescribeAnimation();
|
||||
// // System.exit(0);
|
||||
// // }
|
||||
// currentAnimation.timeCurrent = 0;
|
||||
// Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator();
|
||||
// while(channelIterator.hasNext()){
|
||||
// AnimChannel currentChannel = channelIterator.next();
|
||||
// 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){
|
||||
if(currentAnimation != null){
|
||||
boolean isDone = currentAnimation.incrementTime(time);
|
||||
if(isDone){
|
||||
currentAnimation.timeCurrent = 0;
|
||||
Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator();
|
||||
while(channelIterator.hasNext()){
|
||||
AnimChannel currentChannel = channelIterator.next();
|
||||
currentChannel.rewind();
|
||||
}
|
||||
Iterator<Bone> boneIterator = bones.iterator();
|
||||
while(boneIterator.hasNext()){
|
||||
Bone currentBone = boneIterator.next();
|
||||
currentBone.transform = new Matrix4f();
|
||||
}
|
||||
currentAnimation = null;
|
||||
} 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
|
||||
//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
|
||||
// Iterator<Bone> boneIterator = bones.iterator();
|
||||
// while(boneIterator.hasNext()){
|
||||
// Bone currentBone = boneIterator.next();
|
||||
//// currentBone.deform = currentBone.transformFromParent;
|
||||
// }
|
||||
//Once that's done, for every channel we set the corresponding bone's deform to the channels TRS
|
||||
Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator();
|
||||
while(channelIterator.hasNext()){
|
||||
AnimChannel currentChannel = channelIterator.next();
|
||||
currentChannel.incrementTime(time);
|
||||
Bone currentBone = boneMap.get(currentChannel.nodeID);
|
||||
if(currentBone != null){
|
||||
//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){
|
||||
// if(currentAnimation != null){
|
||||
// boolean isDone = currentAnimation.incrementTime(time);
|
||||
// if(isDone){
|
||||
// currentAnimation.timeCurrent = 0;
|
||||
// Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator();
|
||||
// while(channelIterator.hasNext()){
|
||||
// AnimChannel currentChannel = channelIterator.next();
|
||||
// currentChannel.rewind();
|
||||
// }
|
||||
// Iterator<Bone> boneIterator = bones.iterator();
|
||||
// while(boneIterator.hasNext()){
|
||||
// Bone currentBone = boneIterator.next();
|
||||
// currentBone.transform = new Matrix4f();
|
||||
// }
|
||||
// currentAnimation = null;
|
||||
// } 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
|
||||
// //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
|
||||
// // Iterator<Bone> boneIterator = bones.iterator();
|
||||
// // while(boneIterator.hasNext()){
|
||||
// // Bone currentBone = boneIterator.next();
|
||||
// //// currentBone.deform = currentBone.transformFromParent;
|
||||
// // }
|
||||
// //Once that's done, for every channel we set the corresponding bone's deform to the channels TRS
|
||||
// Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator();
|
||||
// while(channelIterator.hasNext()){
|
||||
// AnimChannel currentChannel = channelIterator.next();
|
||||
// currentChannel.incrementTime(time);
|
||||
// Bone currentBone = boneMap.get(currentChannel.getNodeID());
|
||||
// if(currentBone != null){
|
||||
// //T * S * R
|
||||
// currentBone.deform = new Matrix4f();
|
||||
// currentBone.deform.translate(currentChannel.getCurrentPosition());
|
||||
// currentBone.deform.rotate(currentChannel.getCurrentRotation());
|
||||
// currentBone.deform.scale(currentChannel.getCurrentScale());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public void describeAllAnimations(){
|
||||
if(animations.size() > 0){
|
||||
@ -300,7 +323,11 @@ public class Model {
|
||||
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){
|
||||
n.transform = new Matrix4f(n.parent.transform);
|
||||
} else {
|
||||
@ -395,6 +422,10 @@ public class Model {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Animation getAnimation(String animName){
|
||||
return animMap.get(animName);
|
||||
}
|
||||
|
||||
public void describeHighLevel(){
|
||||
System.out.println("Meshes: ");
|
||||
|
||||
@ -15,6 +15,8 @@ import electrosphere.main.Globals;
|
||||
import static electrosphere.main.Main.deltaTime;
|
||||
import static electrosphere.main.Main.view_Range;
|
||||
import static electrosphere.renderer.RenderUtils.createScreenTextureVAO;
|
||||
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.framebuffer.Framebuffer;
|
||||
import electrosphere.renderer.framebuffer.FramebufferUtils;
|
||||
import electrosphere.renderer.framebuffer.Renderbuffer;
|
||||
|
||||
287
src/main/java/electrosphere/renderer/actor/Actor.java
Normal file
287
src/main/java/electrosphere/renderer/actor/Actor.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package electrosphere.renderer;
|
||||
package electrosphere.renderer.actor;
|
||||
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
@ -3,6 +3,10 @@ package electrosphere.renderer.anim;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
@ -14,171 +18,268 @@ import org.joml.Vector3f;
|
||||
public class AnimChannel {
|
||||
double timeCurrent;
|
||||
double timeTotal;
|
||||
public String nodeID;
|
||||
String nodeID;
|
||||
|
||||
|
||||
public Vector3f startingPosition;
|
||||
public ArrayList<Keyframe> positionFrame;
|
||||
public ListIterator<Keyframe> positionFrameIterator;
|
||||
Keyframe positionFrameCurrent;
|
||||
Keyframe positionFrameNext;
|
||||
double nextPositionTime;
|
||||
Vector3f startingPosition;
|
||||
TreeMap<Double,Keyframe> positionFrameTree;
|
||||
|
||||
|
||||
public Quaternionf startingRotation;
|
||||
public ArrayList<Keyframe> rotationFrame;
|
||||
public ListIterator<Keyframe> rotationFrameIterator;
|
||||
Keyframe rotationFrameCurrent;
|
||||
Keyframe rotationFrameNext;
|
||||
double nextRotationTime;
|
||||
Quaternionf startingRotation;
|
||||
TreeMap<Double,Keyframe> rotationFrameTree;
|
||||
|
||||
|
||||
public ArrayList<Keyframe> scaleFrame;
|
||||
public ListIterator<Keyframe> scaleFrameIterator;
|
||||
Keyframe scaleFrameCurrent;
|
||||
Keyframe scaleFrameNext;
|
||||
double nextScaleTime;
|
||||
TreeMap<Double,Keyframe> scaleFrameTree;
|
||||
|
||||
|
||||
public AnimChannel(double maxTime){
|
||||
timeTotal = maxTime;
|
||||
positionFrameTree = new TreeMap<Double,Keyframe>();
|
||||
rotationFrameTree = new TreeMap<Double,Keyframe>();
|
||||
scaleFrameTree = new TreeMap<Double,Keyframe>();
|
||||
}
|
||||
|
||||
public Vector3f getCurrentPosition(){
|
||||
Vector3f rVal = new Vector3f();
|
||||
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)));
|
||||
|
||||
Entry<Double,Keyframe> previousEntry = positionFrameTree.floorEntry(timeCurrent);
|
||||
Entry<Double,Keyframe> nextEntry = positionFrameTree.ceilingEntry(timeCurrent);
|
||||
Keyframe previousFrame = null;
|
||||
Keyframe nextFrame = null;
|
||||
if(previousEntry == nextEntry){
|
||||
nextEntry = positionFrameTree.higherEntry(timeCurrent);
|
||||
}
|
||||
if(previousEntry != null){
|
||||
previousFrame = previousEntry.getValue();
|
||||
}
|
||||
if(nextEntry != null){
|
||||
nextFrame = nextEntry.getValue();
|
||||
}
|
||||
if(previousFrame != null && nextFrame != null){
|
||||
double percent_Next = ((timeCurrent - previousFrame.time) / (nextFrame.time - previousFrame.time));
|
||||
rVal = new Vector3f().add(new Vector3f().add(previousFrame.position).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(nextFrame.position).mul((float)(percent_Next)));
|
||||
} else if(previousFrame != null){
|
||||
rVal = new Vector3f().add(previousFrame.position);
|
||||
} else if(nextFrame != null){
|
||||
rVal = new Vector3f().add(nextFrame.position);
|
||||
}
|
||||
|
||||
|
||||
// if(positionFrameCurrent != null){
|
||||
// if(positionFrameNext != null){
|
||||
// double percent_Next = ((timeCurrent - positionFrameCurrent.time) / (positionFrameNext.time - positionFrameCurrent.time));
|
||||
// rVal = new Vector3f().add(new Vector3f().add(positionFrameCurrent.position).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(positionFrameNext.position).mul((float)(percent_Next)));
|
||||
// } else {
|
||||
// rVal = new Vector3f().add(positionFrameCurrent.position);
|
||||
// }
|
||||
// // rVal.add(new Vector3f().add(positionFrameCurrent.position).mul(()/(positionFrameNext.time - positionFrameCurrent.time)));
|
||||
// }
|
||||
// rVal = rVal.sub(startingPosition);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public Quaternionf getCurrentRotation(){
|
||||
Quaternionf rVal = new Quaternionf();
|
||||
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);
|
||||
}
|
||||
|
||||
Entry<Double,Keyframe> previousEntry = rotationFrameTree.floorEntry(timeCurrent);
|
||||
Entry<Double,Keyframe> nextEntry = rotationFrameTree.ceilingEntry(timeCurrent);
|
||||
Keyframe previousFrame = null;
|
||||
Keyframe nextFrame = null;
|
||||
if(previousEntry == nextEntry){
|
||||
nextEntry = rotationFrameTree.higherEntry(timeCurrent);
|
||||
}
|
||||
if(previousEntry != null){
|
||||
previousFrame = previousEntry.getValue();
|
||||
}
|
||||
if(nextEntry != null){
|
||||
nextFrame = nextEntry.getValue();
|
||||
}
|
||||
if(previousFrame != null && nextFrame != null){
|
||||
double percent_Next = ((timeCurrent - previousFrame.time) / (nextFrame.time - previousFrame.time));
|
||||
rVal = new 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());
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public Vector3f getCurrentScale(){
|
||||
Vector3f rVal = new Vector3f();
|
||||
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)));
|
||||
|
||||
Entry<Double,Keyframe> previousEntry = scaleFrameTree.floorEntry(timeCurrent);
|
||||
Entry<Double,Keyframe> nextEntry = scaleFrameTree.ceilingEntry(timeCurrent);
|
||||
Keyframe previousFrame = null;
|
||||
Keyframe nextFrame = null;
|
||||
if(previousEntry == nextEntry){
|
||||
nextEntry = scaleFrameTree.higherEntry(timeCurrent);
|
||||
}
|
||||
if(previousEntry != null){
|
||||
previousFrame = previousEntry.getValue();
|
||||
}
|
||||
if(nextEntry != null){
|
||||
nextFrame = nextEntry.getValue();
|
||||
}
|
||||
if(previousFrame != null && nextFrame != null){
|
||||
double percent_Next = ((timeCurrent - previousFrame.time) / (nextFrame.time - previousFrame.time));
|
||||
// rVal = new Vector3f().add(new Vector3f().add(previousFrame.position).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(nextFrame.position).mul((float)(percent_Next)));
|
||||
rVal = new Vector3f().add(new Vector3f().add(previousFrame.scale).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(nextFrame.scale).mul((float)(percent_Next)));
|
||||
} else if(previousFrame != null){
|
||||
// rVal = new Vector3f().add(previousFrame.position);
|
||||
rVal = new Vector3f().add(previousFrame.scale);
|
||||
} else if(nextFrame != null){
|
||||
// rVal = new Vector3f().add(nextFrame.position);
|
||||
rVal = new Vector3f().add(nextFrame.scale);
|
||||
}
|
||||
|
||||
// if(scaleFrameCurrent != null){
|
||||
// if(scaleFrameNext != null){
|
||||
// double percent_Next = ((timeCurrent - scaleFrameCurrent.time) / (scaleFrameNext.time - scaleFrameCurrent.time));
|
||||
// rVal = new Vector3f().add(new Vector3f().add(scaleFrameCurrent.scale).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(scaleFrameNext.scale).mul((float)(percent_Next)));
|
||||
// } else {
|
||||
// rVal = new Vector3f().add(scaleFrameCurrent.scale);
|
||||
// }
|
||||
// // rVal.add(new Vector3f().add(positionFrameCurrent.position).mul(()/(positionFrameNext.time - positionFrameCurrent.time)));
|
||||
// }
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public void incrementTime(double incrementValue){
|
||||
timeCurrent = timeCurrent + incrementValue;
|
||||
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;
|
||||
}
|
||||
}
|
||||
// Entry<Double,Keyframe> previousEntry = positionFrameTree.floorEntry(timeCurrent);
|
||||
// Entry<Double,Keyframe> nextEntry = positionFrameTree.ceilingEntry(timeCurrent);
|
||||
// boolean blend = true;
|
||||
// if(previousEntry == nextEntry){
|
||||
// if((nextEntry) == null){
|
||||
// blend = false;
|
||||
// }
|
||||
// }
|
||||
// if(positionFrameTree.higherEntry(timeCurrent) != null){
|
||||
|
||||
// }
|
||||
// while(positionFrameNext != null && timeCurrent > positionFrameNext.time){
|
||||
// positionFrameCurrent = positionFrameNext;
|
||||
// if(positionFrameIterator.hasNext()){
|
||||
// positionFrameNext = positionFrameIterator.next();
|
||||
// } else {
|
||||
// positionFrameNext = null;
|
||||
// }
|
||||
// }
|
||||
// while(rotationFrameNext != null && timeCurrent > rotationFrameNext.time){
|
||||
// rotationFrameCurrent = rotationFrameNext;
|
||||
// if(rotationFrameIterator.hasNext()){
|
||||
// rotationFrameNext = rotationFrameIterator.next();
|
||||
// } else {
|
||||
// rotationFrameNext = null;
|
||||
// }
|
||||
// }
|
||||
// while(scaleFrameNext != null && timeCurrent > scaleFrameNext.time){
|
||||
// scaleFrameCurrent = scaleFrameNext;
|
||||
// if(scaleFrameIterator.hasNext()){
|
||||
// scaleFrameNext = scaleFrameIterator.next();
|
||||
// } else {
|
||||
// scaleFrameNext = null;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public void setTime(double time){
|
||||
this.timeCurrent = time;
|
||||
}
|
||||
|
||||
public void rewind(){
|
||||
timeCurrent = 0;
|
||||
|
||||
//TODO: Make sure has at least two frames
|
||||
positionFrameIterator = positionFrame.listIterator();
|
||||
if(positionFrameIterator.hasNext()){
|
||||
positionFrameCurrent = positionFrameIterator.next();
|
||||
if(positionFrameIterator.hasNext()){
|
||||
positionFrameNext = positionFrameIterator.next();
|
||||
nextPositionTime = positionFrameNext.time;
|
||||
} else {
|
||||
positionFrameNext = null;
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// scaleFrameIterator = scaleFrame.listIterator();
|
||||
// if(scaleFrameIterator.hasNext()){
|
||||
// scaleFrameCurrent = scaleFrameIterator.next();
|
||||
// if(scaleFrameIterator.hasNext()){
|
||||
// scaleFrameNext = scaleFrameIterator.next();
|
||||
// } else {
|
||||
// scaleFrameNext = null;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public void describeChannel(){
|
||||
System.out.println("Target object: " + nodeID);
|
||||
System.out.println("Time: " + timeCurrent + "/" + timeTotal);
|
||||
System.out.println(positionFrame.size() + " position Frames");
|
||||
System.out.println(rotationFrame.size() + " rotation Frames");
|
||||
System.out.println(scaleFrame.size() + " scale Frames");
|
||||
System.out.println(positionFrameTree.size() + " position Frames");
|
||||
System.out.println(rotationFrameTree.size() + " rotation Frames");
|
||||
System.out.println(scaleFrameTree.size() + " scale Frames");
|
||||
}
|
||||
|
||||
public void fullDescribeChannel(){
|
||||
System.out.println("Target object: " + nodeID);
|
||||
System.out.println("Time: " + timeCurrent + "/" + timeTotal);
|
||||
System.out.println(positionFrame.size() + " position Frames");
|
||||
Iterator<Keyframe> frameIterator = positionFrame.iterator();
|
||||
System.out.println(positionFrameTree.size() + " position Frames");
|
||||
Iterator<Map.Entry<Double,Keyframe>> frameIterator = positionFrameTree.entrySet().iterator();
|
||||
while(frameIterator.hasNext()){
|
||||
System.out.println(frameIterator.next());
|
||||
}
|
||||
System.out.println(rotationFrame.size() + " rotation Frames");
|
||||
frameIterator = rotationFrame.iterator();
|
||||
System.out.println(rotationFrameTree.size() + " rotation Frames");
|
||||
frameIterator = rotationFrameTree.entrySet().iterator();
|
||||
while(frameIterator.hasNext()){
|
||||
System.out.println(frameIterator.next());
|
||||
}
|
||||
System.out.println(scaleFrame.size() + " scale Frames");
|
||||
frameIterator = scaleFrame.iterator();
|
||||
System.out.println(scaleFrameTree.size() + " scale Frames");
|
||||
frameIterator = scaleFrameTree.entrySet().iterator();
|
||||
while(frameIterator.hasNext()){
|
||||
System.out.println(frameIterator.next());
|
||||
}
|
||||
}
|
||||
|
||||
public String getNodeID(){
|
||||
return nodeID;
|
||||
}
|
||||
|
||||
public void addPositionFrame(double time, Keyframe frame){
|
||||
positionFrameTree.put(time, frame);
|
||||
}
|
||||
|
||||
public void addRotationFrame(double time, Keyframe frame){
|
||||
rotationFrameTree.put(time, frame);
|
||||
}
|
||||
|
||||
public void addScaleFrame(double time, Keyframe frame){
|
||||
scaleFrameTree.put(time, frame);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package electrosphere.renderer.anim;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.PriorityQueue;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
@ -39,7 +40,15 @@ public class Animation {
|
||||
public double duration = 0;
|
||||
public double timeCurrent = 0;
|
||||
public double ticksPerSecond;
|
||||
|
||||
Map<String, AnimChannel> channelMap;
|
||||
|
||||
public Animation(AIAnimation animData, int ID){
|
||||
//
|
||||
//Create structures
|
||||
//
|
||||
channelMap = new HashMap<String, AnimChannel>();
|
||||
|
||||
//
|
||||
//Read in metadata
|
||||
//
|
||||
@ -69,11 +78,13 @@ public class Animation {
|
||||
|
||||
//Create channel
|
||||
AnimChannel currentChannel = new AnimChannel(duration);
|
||||
currentChannel.positionFrame = new ArrayList();
|
||||
currentChannel.rotationFrame = new ArrayList();
|
||||
currentChannel.scaleFrame = new ArrayList();
|
||||
// currentChannel.positionFrame = new ArrayList();
|
||||
// currentChannel.rotationFrame = new ArrayList();
|
||||
// currentChannel.scaleFrame = new ArrayList();
|
||||
currentChannel.nodeID = currentChannelData.mNodeName().dataString();
|
||||
channels.add(currentChannel);
|
||||
|
||||
channelMap.put(currentChannel.nodeID,currentChannel);
|
||||
|
||||
|
||||
//get channel data
|
||||
@ -92,7 +103,7 @@ public class Animation {
|
||||
AIVectorKey key = buff.get();
|
||||
Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
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);
|
||||
currentChannel.startingPosition = currentFrame.position;
|
||||
|
||||
@ -110,7 +121,7 @@ public class Animation {
|
||||
previousFrame.position.z == currentFrame.position.z
|
||||
){
|
||||
} else {
|
||||
currentChannel.positionFrame.add(currentFrame);
|
||||
currentChannel.addPositionFrame(key.mTime(),currentFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,7 +135,7 @@ public class Animation {
|
||||
currentFrame.rotation = new Quaternionf();
|
||||
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());
|
||||
currentChannel.rotationFrame.add(currentFrame);
|
||||
currentChannel.addRotationFrame(key.mTime(),currentFrame);
|
||||
|
||||
currentChannel.startingRotation = currentFrame.rotation;
|
||||
|
||||
@ -144,7 +155,7 @@ public class Animation {
|
||||
previousFrame.rotation.z == currentFrame.rotation.z
|
||||
){
|
||||
} else {
|
||||
currentChannel.rotationFrame.add(currentFrame);
|
||||
currentChannel.addRotationFrame(key.mTime(),currentFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -170,7 +181,7 @@ public class Animation {
|
||||
AIVectorKey key = buff.get();
|
||||
Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.scale = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
currentChannel.scaleFrame.add(currentFrame);
|
||||
currentChannel.addScaleFrame(key.mTime(),currentFrame);
|
||||
Keyframe previousFrame;
|
||||
while(buff.hasRemaining()){
|
||||
previousFrame = currentFrame;
|
||||
@ -182,7 +193,7 @@ public class Animation {
|
||||
currentFrame.scale.z == previousFrame.scale.z
|
||||
){
|
||||
} else {
|
||||
currentChannel.scaleFrame.add(currentFrame);
|
||||
currentChannel.addScaleFrame(key.mTime(),currentFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -261,4 +272,8 @@ public class Animation {
|
||||
public void setTime(double time){
|
||||
timeCurrent = time;
|
||||
}
|
||||
|
||||
public AnimChannel getChannel(String name){
|
||||
return channelMap.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,9 +4,9 @@ import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityDataStrings;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.main.Globals;
|
||||
import electrosphere.renderer.ActorUtils;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.ModelUtils;
|
||||
import electrosphere.renderer.actor.ActorUtils;
|
||||
import electrosphere.renderer.ui.font.RawFontMap.Glyph;
|
||||
import java.util.HashMap;
|
||||
import org.joml.Quaternionf;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user