recoil on attack block
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

Fix wrong branch commit
This commit is contained in:
railgun 2024-09-09 17:11:12 -04:00
commit 79688e8575
18 changed files with 345 additions and 68 deletions

View File

@ -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"]
}
}
},
{

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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){

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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));

View File

@ -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

View File

@ -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 {
/**

View File

@ -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);
}