recoil on attack block #4
@ -477,6 +477,14 @@
|
||||
"audioData" : {
|
||||
"audioPath" : "Audio/weapons/swoosh-03.ogg"
|
||||
}
|
||||
},
|
||||
"blockRecoilState" : {
|
||||
"animation" : {
|
||||
"nameFirstPerson" : "SwordR2HSlash1Recoil",
|
||||
"nameThirdPerson" : "SwordR2HSlash1Recoil",
|
||||
"priorityCategory" : "MOVEMENT_MODIFIER",
|
||||
"boneGroups" : ["armLeft", "armRight", "handLeft", "handRight"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -703,6 +703,10 @@ par_shapes integration
|
||||
Directed graph datastructure
|
||||
Framebuffer + RenderingEngine tests
|
||||
|
||||
(09/09/2024)
|
||||
Fix obnoxious opengl state caching bug w/ framebuffers in junit context
|
||||
Recoil on attack block
|
||||
|
||||
|
||||
# TODO
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package electrosphere.engine;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.glfwTerminate;
|
||||
import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -16,7 +15,6 @@ import electrosphere.controls.ControlHandler.ControlsState;
|
||||
import electrosphere.engine.cli.CLIParser;
|
||||
import electrosphere.engine.loadingthreads.LoadingThread;
|
||||
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
|
||||
import electrosphere.engine.threads.LabeledThread.ThreadLabel;
|
||||
import electrosphere.engine.time.Timekeeper;
|
||||
import electrosphere.game.server.world.MacroData;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
|
||||
@ -29,28 +29,29 @@ import java.util.List;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
|
||||
@SynchronizedBehaviorTree(name = "clientAttackTree", isServer = false, correspondingTree="serverAttackTree")
|
||||
/**
|
||||
* Client basic attack tree
|
||||
*/
|
||||
@SynchronizedBehaviorTree(name = "clientAttackTree", isServer = false, correspondingTree="serverAttackTree")
|
||||
public class ClientAttackTree implements BehaviorTree {
|
||||
|
||||
@SynchronizableEnum
|
||||
/**
|
||||
* States available to the attack tree
|
||||
*/
|
||||
@SynchronizableEnum
|
||||
public static enum AttackTreeState {
|
||||
WINDUP,
|
||||
HOLD,
|
||||
ATTACK,
|
||||
BLOCK_RECOIL,
|
||||
COOLDOWN,
|
||||
IDLE,
|
||||
}
|
||||
|
||||
@SynchronizableEnum
|
||||
/**
|
||||
* The state of drifting forward during the attack
|
||||
*/
|
||||
@SynchronizableEnum
|
||||
public static enum AttackTreeDriftState {
|
||||
DRIFT,
|
||||
NO_DRIFT,
|
||||
@ -177,6 +178,32 @@ public class ClientAttackTree implements BehaviorTree {
|
||||
},
|
||||
false
|
||||
),
|
||||
StateTransitionUtilItem.create(
|
||||
AttackTreeState.BLOCK_RECOIL,
|
||||
() -> {
|
||||
TreeDataState state = null;
|
||||
if(currentMove != null){
|
||||
state = currentMove.getBlockRecoilState();
|
||||
}
|
||||
if(state == null){
|
||||
return null;
|
||||
} else {
|
||||
return state.getAnimation();
|
||||
}
|
||||
},
|
||||
() -> {
|
||||
TreeDataState state = null;
|
||||
if(currentMove != null){
|
||||
state = currentMove.getBlockRecoilState();
|
||||
}
|
||||
if(state == null){
|
||||
return null;
|
||||
} else {
|
||||
return state.getAudioData();
|
||||
}
|
||||
},
|
||||
false
|
||||
),
|
||||
StateTransitionUtilItem.create(
|
||||
AttackTreeState.COOLDOWN,
|
||||
() -> {
|
||||
@ -320,6 +347,19 @@ public class ClientAttackTree implements BehaviorTree {
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case BLOCK_RECOIL: {
|
||||
this.stateTransitionUtil.simulate(AttackTreeState.BLOCK_RECOIL);
|
||||
//activate hitboxes
|
||||
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||
if(attachedEntities != null){
|
||||
for(Entity currentAttached : attachedEntities){
|
||||
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||
currentState.setActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case COOLDOWN: {
|
||||
this.stateTransitionUtil.simulate(AttackTreeState.COOLDOWN);
|
||||
//deactive hitboxes
|
||||
@ -535,10 +575,12 @@ public class ClientAttackTree implements BehaviorTree {
|
||||
return 1;
|
||||
case ATTACK:
|
||||
return 2;
|
||||
case COOLDOWN:
|
||||
case BLOCK_RECOIL:
|
||||
return 3;
|
||||
case IDLE:
|
||||
case COOLDOWN:
|
||||
return 4;
|
||||
case IDLE:
|
||||
return 5;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -560,8 +602,10 @@ public class ClientAttackTree implements BehaviorTree {
|
||||
case 2:
|
||||
return AttackTreeState.ATTACK;
|
||||
case 3:
|
||||
return AttackTreeState.COOLDOWN;
|
||||
return AttackTreeState.BLOCK_RECOIL;
|
||||
case 4:
|
||||
return AttackTreeState.COOLDOWN;
|
||||
case 5:
|
||||
return AttackTreeState.IDLE;
|
||||
default:
|
||||
return AttackTreeState.WINDUP;
|
||||
@ -632,6 +676,9 @@ public class ClientAttackTree implements BehaviorTree {
|
||||
*/
|
||||
public void transitionState(AttackTreeState newState){
|
||||
this.stateTransitionUtil.reset();
|
||||
if(newState == AttackTreeState.BLOCK_RECOIL){
|
||||
this.stateTransitionUtil.interrupt(AttackTreeState.ATTACK);
|
||||
}
|
||||
this.setState(newState);
|
||||
}
|
||||
|
||||
|
||||
@ -45,18 +45,18 @@ import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
@SynchronizedBehaviorTree(name = "serverAttackTree", isServer = true, correspondingTree="clientAttackTree")
|
||||
/**
|
||||
* Server basic attack tree
|
||||
*/
|
||||
@SynchronizedBehaviorTree(name = "serverAttackTree", isServer = true, correspondingTree="clientAttackTree")
|
||||
public class ServerAttackTree implements BehaviorTree {
|
||||
|
||||
@SyncedField(serverSendTransitionPacket = true)
|
||||
//the state of the attack tree
|
||||
@SyncedField(serverSendTransitionPacket = true)
|
||||
AttackTreeState state;
|
||||
|
||||
@SyncedField
|
||||
//the state of drifting caused by the attack animation
|
||||
@SyncedField
|
||||
AttackTreeDriftState driftState;
|
||||
|
||||
Entity parent;
|
||||
@ -91,6 +91,11 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
//The state transition util
|
||||
StateTransitionUtil stateTransitionUtil;
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
* @param e The parent entity
|
||||
* @param params The data to construct the tree with
|
||||
*/
|
||||
private ServerAttackTree(Entity e, Object ... params){
|
||||
state = AttackTreeState.IDLE;
|
||||
driftState = AttackTreeDriftState.NO_DRIFT;
|
||||
@ -126,11 +131,10 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
StateTransitionUtilItem.create(
|
||||
AttackTreeState.HOLD,
|
||||
() -> {
|
||||
TreeDataState state = currentMove.getHoldState();
|
||||
if(state == null){
|
||||
if(currentMove != null && currentMove.getHoldState() == null){
|
||||
return null;
|
||||
} else {
|
||||
return state.getAnimation();
|
||||
return currentMove.getHoldState().getAnimation();
|
||||
}
|
||||
},
|
||||
() -> {
|
||||
@ -159,6 +163,21 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
this.setState(AttackTreeState.COOLDOWN);
|
||||
}
|
||||
),
|
||||
StateTransitionUtilItem.create(
|
||||
AttackTreeState.BLOCK_RECOIL,
|
||||
() -> {
|
||||
if(currentMove != null && currentMove.getBlockRecoilState() != null){
|
||||
return currentMove.getBlockRecoilState().getAnimation();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
null,
|
||||
() -> {
|
||||
this.stateTransitionUtil.interrupt(AttackTreeState.BLOCK_RECOIL);
|
||||
this.setState(AttackTreeState.COOLDOWN);
|
||||
}
|
||||
),
|
||||
StateTransitionUtilItem.create(
|
||||
AttackTreeState.COOLDOWN,
|
||||
() -> {
|
||||
@ -188,6 +207,9 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an attack
|
||||
*/
|
||||
public void start(){
|
||||
currentMoveCanHold = false;
|
||||
currentMoveHasWindup = false;
|
||||
@ -260,6 +282,23 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes the attack tree to instead enter recoil state
|
||||
*/
|
||||
public void recoilFromBlock(){
|
||||
if(currentMove != null){
|
||||
setState(AttackTreeState.BLOCK_RECOIL);
|
||||
//deactivate hitboxes
|
||||
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||
for(Entity currentAttached : attachedEntities){
|
||||
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||
currentState.setActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simulate(float deltaTime){
|
||||
frameCurrent = frameCurrent + (float)Globals.timekeeper.getDeltaFrames();
|
||||
@ -365,6 +404,17 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
projectileToFire = null;
|
||||
}
|
||||
} break;
|
||||
case BLOCK_RECOIL: {
|
||||
this.stateTransitionUtil.simulate(AttackTreeState.BLOCK_RECOIL);
|
||||
//activate hitboxes
|
||||
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||
for(Entity currentAttached : attachedEntities){
|
||||
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||
currentState.setActive(false);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case COOLDOWN: {
|
||||
this.stateTransitionUtil.simulate(AttackTreeState.COOLDOWN);
|
||||
//deactive hitboxes
|
||||
|
||||
@ -19,6 +19,7 @@ public class AttackMove {
|
||||
TreeDataState windupState;
|
||||
TreeDataState holdState;
|
||||
TreeDataState attackState;
|
||||
TreeDataState blockRecoilState;
|
||||
TreeDataState cooldownState;
|
||||
|
||||
/*
|
||||
@ -85,6 +86,14 @@ public class AttackMove {
|
||||
return attackState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state to play for the recoil
|
||||
* @return the state data
|
||||
*/
|
||||
public TreeDataState getBlockRecoilState() {
|
||||
return blockRecoilState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state to play for the cooldown
|
||||
* @return the state data
|
||||
|
||||
@ -39,7 +39,6 @@ import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
import org.lwjgl.opengl.GL45;
|
||||
import org.lwjgl.opengl.GLCapabilities;
|
||||
import org.lwjgl.opengl.GLDebugMessageCallback;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
|
||||
@ -271,7 +270,7 @@ public class RenderingEngine {
|
||||
// setTitleBarDimensions();
|
||||
|
||||
//Creates the OpenGL capabilities for the program.)
|
||||
GLCapabilities glCapabilities = GL.createCapabilities();
|
||||
GL.createCapabilities();
|
||||
|
||||
GL45.glEnable(GL45.GL_DEBUG_OUTPUT);
|
||||
//register error callback
|
||||
|
||||
@ -77,12 +77,24 @@ public class Actor {
|
||||
|
||||
//Controls whether the actor should obey frustum culling
|
||||
boolean frustumCull = true;
|
||||
|
||||
/**
|
||||
* Used for caching animation masks that should be removed
|
||||
*/
|
||||
List<ActorAnimationMask> toRemoveMasks = new LinkedList<ActorAnimationMask>();
|
||||
|
||||
/**
|
||||
* Creates an achor
|
||||
* @param modelPath The path of the model associated with the actor
|
||||
*/
|
||||
public Actor(String modelPath){
|
||||
this.modelPath = modelPath;
|
||||
}
|
||||
|
||||
List<ActorAnimationMask> toRemoveMasks = new LinkedList<ActorAnimationMask>();
|
||||
|
||||
/**
|
||||
* Increments the animation time of the actor
|
||||
* @param deltaTime The amount of time to increment by
|
||||
*/
|
||||
public void incrementAnimationTime(double deltaTime){
|
||||
toRemoveMasks.clear();
|
||||
for(ActorAnimationMask mask : animationQueue){
|
||||
|
||||
@ -15,22 +15,57 @@ import electrosphere.logger.LoggerInterface;
|
||||
*/
|
||||
public class AnimChannel {
|
||||
|
||||
/**
|
||||
* The current time of the channel
|
||||
*/
|
||||
double timeCurrent = 0;
|
||||
|
||||
/**
|
||||
* The total time of the channel
|
||||
*/
|
||||
double timeTotal;
|
||||
|
||||
/**
|
||||
* The ticks per second of the channel
|
||||
*/
|
||||
double ticksPerSecond;
|
||||
|
||||
/**
|
||||
* The bone id associated with the channel
|
||||
*/
|
||||
String nodeID;
|
||||
|
||||
|
||||
/**
|
||||
* The starting position of the bone
|
||||
*/
|
||||
Vector3f startingPosition;
|
||||
|
||||
/**
|
||||
* All position frames
|
||||
*/
|
||||
TreeMap<Double,Keyframe> positionFrameTree;
|
||||
|
||||
|
||||
/**
|
||||
* The starting rotation of the bone
|
||||
*/
|
||||
Quaterniond startingRotation;
|
||||
|
||||
/**
|
||||
* All rotation frames
|
||||
*/
|
||||
TreeMap<Double,Keyframe> rotationFrameTree;
|
||||
|
||||
/**
|
||||
* All scale frames
|
||||
*/
|
||||
TreeMap<Double,Keyframe> scaleFrameTree;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an anim channel
|
||||
* @param maxTime The max time of the channel
|
||||
* @param ticksPerSecond The ticks per second
|
||||
*/
|
||||
public AnimChannel(double maxTime, double ticksPerSecond){
|
||||
timeTotal = maxTime;
|
||||
this.ticksPerSecond = ticksPerSecond;
|
||||
@ -269,43 +304,60 @@ public class AnimChannel {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments time on the channel
|
||||
* @param incrementValue The amount to increment by
|
||||
*/
|
||||
public void incrementTime(double incrementValue){
|
||||
timeCurrent = timeCurrent + incrementValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current time of the channel
|
||||
* @param time The time
|
||||
*/
|
||||
public void setTime(double time){
|
||||
this.timeCurrent = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewinds the channel
|
||||
*/
|
||||
public void rewind(){
|
||||
timeCurrent = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the channel at a high level
|
||||
*/
|
||||
public void describeChannel(){
|
||||
System.out.println("Target object: " + nodeID);
|
||||
System.out.println("Time: " + timeCurrent + "/" + timeTotal);
|
||||
System.out.println(positionFrameTree.size() + " position Frames");
|
||||
System.out.println(rotationFrameTree.size() + " rotation Frames");
|
||||
System.out.println(scaleFrameTree.size() + " scale Frames");
|
||||
LoggerInterface.loggerEngine.INFO("Target object: " + nodeID);
|
||||
LoggerInterface.loggerEngine.INFO("Time: " + timeCurrent + "/" + timeTotal);
|
||||
LoggerInterface.loggerEngine.INFO(positionFrameTree.size() + " position Frames");
|
||||
LoggerInterface.loggerEngine.INFO(rotationFrameTree.size() + " rotation Frames");
|
||||
LoggerInterface.loggerEngine.INFO(scaleFrameTree.size() + " scale Frames");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fully describes the channel
|
||||
*/
|
||||
public void fullDescribeChannel(){
|
||||
System.out.println("Target object: " + nodeID);
|
||||
System.out.println("Time: " + timeCurrent + "/" + timeTotal);
|
||||
System.out.println(positionFrameTree.size() + " position Frames");
|
||||
LoggerInterface.loggerEngine.INFO("Target object: " + nodeID);
|
||||
LoggerInterface.loggerEngine.INFO("Time: " + timeCurrent + "/" + timeTotal);
|
||||
LoggerInterface.loggerEngine.INFO(positionFrameTree.size() + " position Frames");
|
||||
Iterator<Map.Entry<Double,Keyframe>> frameIterator = positionFrameTree.entrySet().iterator();
|
||||
while(frameIterator.hasNext()){
|
||||
System.out.println(frameIterator.next());
|
||||
LoggerInterface.loggerEngine.INFO(frameIterator.next() + "");
|
||||
}
|
||||
System.out.println(rotationFrameTree.size() + " rotation Frames");
|
||||
LoggerInterface.loggerEngine.INFO(rotationFrameTree.size() + " rotation Frames");
|
||||
frameIterator = rotationFrameTree.entrySet().iterator();
|
||||
while(frameIterator.hasNext()){
|
||||
System.out.println(frameIterator.next());
|
||||
LoggerInterface.loggerEngine.INFO(frameIterator.next() + "");
|
||||
}
|
||||
System.out.println(scaleFrameTree.size() + " scale Frames");
|
||||
LoggerInterface.loggerEngine.INFO(scaleFrameTree.size() + " scale Frames");
|
||||
frameIterator = scaleFrameTree.entrySet().iterator();
|
||||
while(frameIterator.hasNext()){
|
||||
System.out.println(frameIterator.next());
|
||||
LoggerInterface.loggerEngine.INFO(frameIterator.next() + "");
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,18 +415,37 @@ public class AnimChannel {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the bone associated with the channel
|
||||
* @return The name of the bone
|
||||
*/
|
||||
public String getNodeID(){
|
||||
return nodeID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a position frame to the channel
|
||||
* @param time The time the frame occurs at
|
||||
* @param frame The frame itself
|
||||
*/
|
||||
public void addPositionFrame(double time, Keyframe frame){
|
||||
positionFrameTree.put(time, frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a rotation frame to the channel
|
||||
* @param time The time the frame occurs at
|
||||
* @param frame The frame itself
|
||||
*/
|
||||
public void addRotationFrame(double time, Keyframe frame){
|
||||
rotationFrameTree.put(time, frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a scale frame to the channel
|
||||
* @param time The time the frame occurs at
|
||||
* @param frame The frame itself
|
||||
*/
|
||||
public void addScaleFrame(double time, Keyframe frame){
|
||||
scaleFrameTree.put(time, frame);
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ import org.joml.Quaterniond;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4d;
|
||||
import org.lwjgl.assimp.AIAnimation;
|
||||
import org.lwjgl.assimp.AIMeshAnim;
|
||||
import org.lwjgl.assimp.AINodeAnim;
|
||||
import org.lwjgl.assimp.AIQuatKey;
|
||||
import org.lwjgl.assimp.AIVectorKey;
|
||||
@ -17,11 +16,11 @@ import org.lwjgl.assimp.AIVectorKey;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
* An animation on a model
|
||||
*/
|
||||
public class Animation {
|
||||
|
||||
//common animations
|
||||
public static final String ANIMATION_MOVEMENT_STARTUP = "WalkStart";
|
||||
public static final String ANIMATION_MOVEMENT_MOVE = "Walk";
|
||||
public static final String ANIMATION_IDLE_1 = "Idle1";
|
||||
@ -34,19 +33,46 @@ public class Animation {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The anim data associated with the animation
|
||||
*/
|
||||
AIAnimation animData;
|
||||
|
||||
/**
|
||||
* The name of the animation
|
||||
*/
|
||||
public String name;
|
||||
public int ID;
|
||||
ArrayList<AINodeAnim> nodeChannelData;
|
||||
ArrayList<AIMeshAnim> meshChannelData;
|
||||
|
||||
/**
|
||||
* The channels that contain the animation data
|
||||
*/
|
||||
public ArrayList<AnimChannel> channels;
|
||||
|
||||
/**
|
||||
* The duration of the animation
|
||||
*/
|
||||
public double duration = 0;
|
||||
|
||||
/**
|
||||
* The current time of the animation
|
||||
*/
|
||||
public double timeCurrent = 0;
|
||||
|
||||
/**
|
||||
* The ticks per second of animation
|
||||
*/
|
||||
public double ticksPerSecond;
|
||||
|
||||
/**
|
||||
* The map of bone name to animation channel
|
||||
*/
|
||||
Map<String, AnimChannel> channelMap;
|
||||
|
||||
public Animation(AIAnimation animData, int ID){
|
||||
/**
|
||||
* Creates an animation
|
||||
* @param animData The data for the animation
|
||||
*/
|
||||
public Animation(AIAnimation animData){
|
||||
//
|
||||
//Create structures
|
||||
//
|
||||
@ -59,16 +85,6 @@ public class Animation {
|
||||
name = animData.mName().dataString();
|
||||
this.ticksPerSecond = animData.mTicksPerSecond();
|
||||
this.duration = animData.mDuration() / this.ticksPerSecond;
|
||||
this.ID = ID;
|
||||
//
|
||||
//Print metadata
|
||||
//
|
||||
// System.out.println("Animation name: \"" + name + "\"");
|
||||
// System.out.println("ID:(" + ID + ")");
|
||||
// System.out.println("Ticks per second: " + ticksPerSecond);
|
||||
// System.out.println("Anim sizeof: " + animData.sizeof());
|
||||
// System.out.println("Duration: " + duration);
|
||||
|
||||
|
||||
//
|
||||
//Read in anim channels (bone modifications)
|
||||
@ -200,14 +216,14 @@ public class Animation {
|
||||
|
||||
}
|
||||
}
|
||||
//gotta free things
|
||||
nodeChannelData = null;
|
||||
meshChannelData = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the animation at high level
|
||||
*/
|
||||
public void describeAnimation(){
|
||||
LoggerInterface.loggerRenderer.DEBUG("=====================");
|
||||
LoggerInterface.loggerRenderer.DEBUG("Name: \"" + name + "\"");
|
||||
LoggerInterface.loggerRenderer.DEBUG("ID: " + ID);
|
||||
LoggerInterface.loggerRenderer.DEBUG("Duration: " + duration);
|
||||
LoggerInterface.loggerRenderer.DEBUG("Ticks per second: " + ticksPerSecond);
|
||||
Iterator<AnimChannel> channelIterator = channels.iterator();
|
||||
@ -218,10 +234,13 @@ public class Animation {
|
||||
}
|
||||
LoggerInterface.loggerRenderer.DEBUG("=====================");
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the animation is as much detail as possible
|
||||
*/
|
||||
public void fullDescribeAnimation(){
|
||||
LoggerInterface.loggerRenderer.DEBUG("=====================");
|
||||
LoggerInterface.loggerRenderer.DEBUG("Name: " + name);
|
||||
LoggerInterface.loggerRenderer.DEBUG("ID: " + ID);
|
||||
LoggerInterface.loggerRenderer.DEBUG("Duration: " + duration);
|
||||
LoggerInterface.loggerRenderer.DEBUG("Ticks per second: " + ticksPerSecond);
|
||||
Iterator<AnimChannel> channelIterator = channels.iterator();
|
||||
@ -233,19 +252,33 @@ public class Animation {
|
||||
LoggerInterface.loggerRenderer.DEBUG("=====================");
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments time on the animation
|
||||
* @param time The amount of time to increment by
|
||||
* @return true if the animation has completed, false otherwise
|
||||
*/
|
||||
public boolean incrementTime(double time){
|
||||
timeCurrent += time;
|
||||
if(timeCurrent > duration){
|
||||
if(timeCurrent > duration || timeCurrent < 0){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time of the animation
|
||||
* @param time The time
|
||||
*/
|
||||
public void setTime(double time){
|
||||
timeCurrent = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the channel data for a given bone
|
||||
* @param name The name of the bone
|
||||
* @return The channel data if it exists, null otherwise
|
||||
*/
|
||||
public AnimChannel getChannel(String name){
|
||||
return channelMap.get(name);
|
||||
}
|
||||
|
||||
@ -7,11 +7,31 @@ import org.joml.Vector3f;
|
||||
* A single keyframe of a single node within an animation
|
||||
*/
|
||||
public class Keyframe implements Comparable<Keyframe>{
|
||||
|
||||
/**
|
||||
* The time the keyframe occurs at
|
||||
*/
|
||||
double time;
|
||||
|
||||
/**
|
||||
* The position of the keyframe
|
||||
*/
|
||||
Vector3f position;
|
||||
|
||||
/**
|
||||
* The rotation of the keyframe
|
||||
*/
|
||||
Quaterniond rotation;
|
||||
|
||||
/**
|
||||
* The scale of the keyframe
|
||||
*/
|
||||
Vector3f scale;
|
||||
|
||||
/**
|
||||
* Creates a keyframe
|
||||
* @param time The time the keyframe occurs at
|
||||
*/
|
||||
public Keyframe(double time){
|
||||
this.time = time;
|
||||
}
|
||||
@ -27,6 +47,10 @@ public class Keyframe implements Comparable<Keyframe>{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time of the keyframe
|
||||
* @return The time
|
||||
*/
|
||||
public double getTime(){
|
||||
return time;
|
||||
}
|
||||
|
||||
@ -187,7 +187,7 @@ public class Model {
|
||||
rVal.animations = new ArrayList<Animation>();
|
||||
rVal.animMap = new HashMap<String,Animation>();
|
||||
for(int i = 0; i < animCount; i++){
|
||||
Animation newAnim = new Animation(AIAnimation.create(animBuffer.get(i)), i);
|
||||
Animation newAnim = new Animation(AIAnimation.create(animBuffer.get(i)));
|
||||
rVal.animations.add(newAnim);
|
||||
rVal.animMap.put(newAnim.name,newAnim);
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
||||
|
||||
//
|
||||
//handle attacker
|
||||
this.handleAttackerCollision(impactorEntity,receiverEntity);
|
||||
this.handleAttackerCollision(impactorEntity,receiverEntity, isDamageEvent);
|
||||
}
|
||||
|
||||
if(isBlockEvent){
|
||||
@ -192,7 +192,7 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
||||
|
||||
//
|
||||
//handle attacker
|
||||
this.handleAttackerCollision(impactorEntity,receiverEntity);
|
||||
this.handleAttackerCollision(impactorEntity,receiverEntity, isBlockEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,8 +200,9 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
||||
* Handles collision tracking from the impactor's side
|
||||
* @param impactorEntity The impactor hitbox's parent entity
|
||||
* @param receiverParent The receiver hitbox's parent entity
|
||||
* @param isBlock true if this is a block, false otherwise
|
||||
*/
|
||||
private void handleAttackerCollision(Entity impactorEntity, Entity receiverEntity){
|
||||
private void handleAttackerCollision(Entity impactorEntity, Entity receiverEntity, boolean isBlock){
|
||||
boolean receiverIsItem = ItemUtils.isItem(receiverEntity);
|
||||
boolean receiverHasParent = AttachUtils.hasParent(receiverEntity);
|
||||
|
||||
@ -210,6 +211,7 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
||||
if(impactorEntity != null && ServerAttackTree.getServerAttackTree(impactorEntity) != null){
|
||||
ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(impactorEntity);
|
||||
impactorAttackTree.collideEntity(receiverEntity);
|
||||
impactorAttackTree.recoilFromBlock();
|
||||
//if the receiver is an item that is equipped, collide with parent too
|
||||
if(receiverIsItem && receiverHasParent){
|
||||
impactorAttackTree.collideEntity(AttachUtils.getParent(receiverEntity));
|
||||
@ -222,6 +224,7 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
||||
} else if(impactorEntity != null && AttachUtils.hasParent(impactorEntity) && AttachUtils.getParent(impactorEntity) != null && ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorEntity)) != null){
|
||||
ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorEntity));
|
||||
impactorAttackTree.collideEntity(receiverEntity);
|
||||
impactorAttackTree.recoilFromBlock();
|
||||
//if the receiver is an item that is equipped, collide with parent too
|
||||
if(receiverIsItem && receiverHasParent){
|
||||
impactorAttackTree.collideEntity(AttachUtils.getParent(receiverEntity));
|
||||
|
||||
@ -29,17 +29,34 @@ import electrosphere.renderer.model.Bone;
|
||||
*/
|
||||
public class PoseActor {
|
||||
|
||||
/**
|
||||
* The path of the model for the pose actor
|
||||
*/
|
||||
String modelPath;
|
||||
//scalar on the speed of animation playback
|
||||
|
||||
/**
|
||||
* Scalar on the speed of animation playback
|
||||
*/
|
||||
float animationScalar = 1.0f;
|
||||
//priority queue of animations to play. Allows masking a higher priority animation over a lower priority one.
|
||||
|
||||
/**
|
||||
* Priority queue of animations to play. Allows masking a higher priority animation over a lower priority one.
|
||||
*/
|
||||
Set<ActorAnimationMask> animationQueue = new TreeSet<ActorAnimationMask>();
|
||||
//bone rotation map. Used to apply rotator functionality to bones (think hair, cloth, and camera rotation on looking)
|
||||
|
||||
/**
|
||||
* Bone rotation map. Used to apply rotator functionality to bones (think hair, cloth, and camera rotation on looking)
|
||||
*/
|
||||
Map<String,ActorBoneRotator> boneRotators = new HashMap<String,ActorBoneRotator>();
|
||||
//static morph used to apply an initial, static modification to the layout of bones in the pose model
|
||||
|
||||
/**
|
||||
* Static morph used to apply an initial, static modification to the layout of bones in the pose model
|
||||
*/
|
||||
ActorStaticMorph staticMorph;
|
||||
|
||||
//The bone groups for this pose actor
|
||||
/**
|
||||
* The bone groups for this pose actor
|
||||
*/
|
||||
List<BoneGroup> boneGroups;
|
||||
|
||||
|
||||
@ -55,6 +72,7 @@ public class PoseActor {
|
||||
//Used to keep track of which animations have completed and therefore should be removed
|
||||
//Separate variable so no concurrent modification to anim lists/maps
|
||||
List<ActorAnimationMask> toRemoveMasks = new LinkedList<ActorAnimationMask>();
|
||||
|
||||
/**
|
||||
* Increments time of all currently played animations
|
||||
* @param deltaTime
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
package electrosphere.server.poseactor;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
|
||||
/**
|
||||
* Utilities for working with pose actors
|
||||
*/
|
||||
public class PoseActorUtils {
|
||||
|
||||
/**
|
||||
|
||||
@ -98,7 +98,7 @@ public class PoseModel {
|
||||
animations = new ArrayList<Animation>();
|
||||
animMap = new HashMap<String,Animation>();
|
||||
for(int i = 0; i < animCount; i++){
|
||||
Animation newAnim = new Animation(AIAnimation.create(animBuffer.get(i)), i);
|
||||
Animation newAnim = new Animation(AIAnimation.create(animBuffer.get(i)));
|
||||
animations.add(newAnim);
|
||||
animMap.put(newAnim.name,newAnim);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user