server anim time scale fix
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-08-12 09:41:00 -04:00
parent 9d7ab27da7
commit 8e48250013
6 changed files with 190 additions and 18 deletions

View File

@ -2,3 +2,11 @@
Leaf Sheep Leaf Sheep
Jellyfish Jellyfish
Mushroom-men
Ogres
Troll-men
Goblins
Demons/Devils

View File

@ -537,6 +537,9 @@ Ability to serialize/deserialize a creature with equipped items
Sending initial synchronized state on player connect to chunk Sending initial synchronized state on player connect to chunk
Pass at client-server physics synchronization Pass at client-server physics synchronization
(08/12/2024)
Fix server animation playing at reduced timescale
# TODO # TODO

View File

@ -33,6 +33,8 @@ import electrosphere.renderer.model.Model;
import electrosphere.renderer.ui.imgui.ImGuiWindow; import electrosphere.renderer.ui.imgui.ImGuiWindow;
import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback;
import electrosphere.server.datacell.utils.EntityLookupUtils; import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.poseactor.PoseActor;
import electrosphere.server.poseactor.PoseModel;
import imgui.ImGui; import imgui.ImGui;
/** /**
@ -50,6 +52,7 @@ public class ImGuiEntityMacros {
//tree node values //tree node values
private static boolean showActorTab = false; //show the actor tab private static boolean showActorTab = false; //show the actor tab
private static boolean showPoseActorTab = false; //show the pose actor tab
private static boolean showEquipStateTab = false; //actor details private static boolean showEquipStateTab = false; //actor details
private static boolean showFirstPersonTab = false; //first person tab private static boolean showFirstPersonTab = false; //first person tab
private static boolean showLinkedEntitiesTab = false;//show linked entities private static boolean showLinkedEntitiesTab = false;//show linked entities
@ -111,6 +114,9 @@ public class ImGuiEntityMacros {
if(EntityUtils.getActor(detailViewEntity) != null && ImGui.checkbox("Actor Details", showActorTab)){ if(EntityUtils.getActor(detailViewEntity) != null && ImGui.checkbox("Actor Details", showActorTab)){
showActorTab = !showActorTab; showActorTab = !showActorTab;
} }
if(EntityUtils.getPoseActor(detailViewEntity) != null && ImGui.checkbox("Pose Actor Details", showPoseActorTab)){
showPoseActorTab = !showPoseActorTab;
}
if(ClientEquipState.hasEquipState(detailViewEntity) && ImGui.checkbox("Equip State", showEquipStateTab)){ if(ClientEquipState.hasEquipState(detailViewEntity) && ImGui.checkbox("Equip State", showEquipStateTab)){
showEquipStateTab = !showEquipStateTab; showEquipStateTab = !showEquipStateTab;
} }
@ -133,6 +139,7 @@ public class ImGuiEntityMacros {
} }
ImGui.nextColumn(); ImGui.nextColumn();
drawActorView(); drawActorView();
drawPoseActor();
drawEquipState(); drawEquipState();
drawFirstPersonView(); drawFirstPersonView();
drawLinkedEntities(); drawLinkedEntities();
@ -242,6 +249,82 @@ public class ImGuiEntityMacros {
} }
} }
/**
* Draws pose actor
*/
protected static void drawPoseActor(){
if(showPoseActorTab && ImGui.collapsingHeader("Pose Actor Details")){
ImGui.indent();
if(detailViewEntity != null && EntityUtils.getPoseActor(detailViewEntity) != null){
PoseActor poseActor = EntityUtils.getPoseActor(detailViewEntity);
//animation queue
if(ImGui.collapsingHeader("Animation Queue")){
Set<ActorAnimationMask> animationQueue = poseActor.getAnimationQueue();
for(ActorAnimationMask mask : animationQueue){
ImGui.text(mask.getAnimationName() + " - " + mask.getPriority());
ImGui.text(mask.getDuration() + " " + mask.getTime());
}
}
//bone values
if(ImGui.collapsingHeader("Bone Values")){
for(Bone bone : poseActor.getBoneValues()){
ImGui.text(bone.boneID);
ImGui.text("Position: " + poseActor.getBonePosition(bone.boneID));
ImGui.text("Rotation: " + poseActor.getBoneRotation(bone.boneID));
ImGui.text(bone.getFinalTransform() + "");
}
}
//Draws all the bones in the world
if(ImGui.button("Draw Bones")){
Globals.renderingEngine.getDebugContentPipeline().getDebugBonesPipeline().setEntity(detailViewEntity);
}
//Browsable list of all animations with their data
if(ImGui.collapsingHeader("Animation Channel Data")){
Model model = Globals.assetManager.fetchModel(poseActor.getModelPath());
ImGui.indent();
for(Animation animation : model.getAnimations()){
if(ImGui.collapsingHeader(animation.name)){
for(AnimChannel channel : animation.channels){
ImGui.pushID(channel.getNodeID());
if(ImGui.button("Fully describe")){
channel.fullDescribeChannel();
}
ImGui.text("=" + channel.getNodeID() + "=");
ImGui.text("" + channel.getCurrentPosition());
ImGui.text("" + channel.getCurrentRotation());
ImGui.text("" + channel.getCurrentScale());
ImGui.popID();
}
}
}
ImGui.unindent();
}
//print data macros
if(ImGui.collapsingHeader("Print Data")){
//print bone values
if(ImGui.button("Print current bone values")){
for(Bone bone : poseActor.getBoneValues()){
LoggerInterface.loggerRenderer.DEBUG(bone.boneID);
LoggerInterface.loggerRenderer.DEBUG("" + bone.getFinalTransform());
}
}
//print animation keys
if(ImGui.button("Print animation keys")){
PoseModel model = Globals.assetManager.fetchPoseModel(poseActor.getModelPath());
model.describeAllAnimations();
}
}
}
ImGui.unindent();
}
}
/** /**
* First person data * First person data
*/ */

View File

@ -4,7 +4,8 @@ import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.PriorityQueue; import java.util.Set;
import java.util.TreeSet;
import org.joml.AxisAngle4f; import org.joml.AxisAngle4f;
import org.joml.Matrix4d; import org.joml.Matrix4d;
@ -32,7 +33,7 @@ public class PoseActor {
//scalar on the speed of animation playback //scalar on the speed of animation playback
float animationScalar = 1.0f; 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.
PriorityQueue<ActorAnimationMask> animationQueue = new PriorityQueue<ActorAnimationMask>(); 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>(); 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
@ -332,6 +333,14 @@ public class PoseActor {
} }
} }
/**
* Gets the animation queue
* @return The animation queue
*/
public Set<ActorAnimationMask> getAnimationQueue(){
return animationQueue;
}
/** /**
* Calculates all node transforms for the PoseModel based on bone rotators and the static morph of this PoseActor * Calculates all node transforms for the PoseModel based on bone rotators and the static morph of this PoseActor
* @param model The PoseModel to calculate transforms for * @param model The PoseModel to calculate transforms for
@ -396,6 +405,14 @@ public class PoseActor {
return rVal; return rVal;
} }
/**
* Gets the model path associated with the pose actor
* @return The model path
*/
public String getModelPath(){
return modelPath;
}
/** /**
* Gets the position of a bone currently * Gets the position of a bone currently
* @param boneName * @param boneName
@ -407,23 +424,62 @@ public class PoseActor {
if(model != null){ if(model != null){
applyAnimationMasks(model); applyAnimationMasks(model);
calculateNodeTransforms(model); calculateNodeTransforms(model);
// if(animation != null){ Bone currentBone = model.boneMap.get(boneName);
// model.playAnimation(animation); if(currentBone != null){
// model.incrementTime(animationTime); Vector4d result = new Matrix4d(currentBone.getFinalTransform()).transform(currentBone.getMOffset().invert().transform(new Vector4d(rVal.x,rVal.y,rVal.z,1)));
// model.updateNodeTransform(); rVal.x = (float)result.x;
Bone currentBone = model.boneMap.get(boneName); rVal.y = (float)result.y;
if(currentBone != null){ rVal.z = (float)result.z;
Vector4d result = new Matrix4d(currentBone.getFinalTransform()).transform(currentBone.getMOffset().invert().transform(new Vector4d(rVal.x,rVal.y,rVal.z,1))); } else {
// currentBone.inverseBindPoseMatrix String message = "Trying to get position of bone that does not exist on model!\n" +
rVal.x = (float)result.x; "boneName: " + boneName;
rVal.y = (float)result.y; throw new IllegalArgumentException(message);
rVal.z = (float)result.z; }
} }
// } if(!Double.isFinite(rVal.x)){
throw new IllegalStateException("Bone position that is not finite!");
} }
return rVal; return rVal;
} }
/**
* Gets the transform of a given bone
* @param boneName The name of the bone
* @return The transform
*/
public Matrix4d getBoneTransform(String boneName){
Matrix4d rVal = new Matrix4d();
PoseModel model = Globals.assetManager.fetchPoseModel(modelPath);
if(model != null){
applyAnimationMasks(model);
calculateNodeTransforms(model);
Bone currentBone = model.getBoneMap().get(boneName);
if(currentBone != null){
rVal = currentBone.getFinalTransform();
} else {
throw new IllegalArgumentException("Trying to get rotation of bone that does not exist on model!");
}
}
if(!Double.isFinite(rVal.m00())){
throw new IllegalStateException("Bone rotation that is not finite!");
}
return rVal;
}
/**
* Gets the list of all bones
* @return the list of all bones
*/
public List<Bone> getBoneValues(){
PoseModel model = Globals.assetManager.fetchPoseModel(modelPath);
if(model != null){
applyAnimationMasks(model);
calculateNodeTransforms(model);
return model.getBones();
}
return null;
}
/** /**
* Sets the bone groups * Sets the bone groups
* @param boneGroups The bone groups * @param boneGroups The bone groups

View File

@ -161,6 +161,14 @@ public class PoseModel {
} }
} }
/**
* Gets the map of bone name -> bone
* @return the map
*/
public Map<String,Bone> getBoneMap(){
return boneMap;
}
/** /**
* Internal recursive method behind the public updateNodeTransform * Internal recursive method behind the public updateNodeTransform
* @param boneRotators The bone rotators * @param boneRotators The bone rotators
@ -211,6 +219,21 @@ public class PoseModel {
return animMap.get(animName); return animMap.get(animName);
} }
/**
* Logs all animations for a given model
*/
public void describeAllAnimations(){
if(animations.size() > 0){
LoggerInterface.loggerRenderer.DEBUG("=====================");
LoggerInterface.loggerRenderer.DEBUG(animations.size() + " animations available in model!");
Iterator<Animation> animIterator = animations.iterator();
while(animIterator.hasNext()){
Animation currentAnim = animIterator.next();
currentAnim.describeAnimation();
}
}
}
/** /**
* Gets the list of bones in this pose model * Gets the list of bones in this pose model
* @return The list of bones * @return The list of bones

View File

@ -5,7 +5,6 @@ import electrosphere.entity.types.attach.AttachUtils;
import java.util.Set; import java.util.Set;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityTags; import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
@ -42,7 +41,7 @@ public class MicroSimulation {
PoseActor currentPoseActor = EntityUtils.getPoseActor(currentEntity); PoseActor currentPoseActor = EntityUtils.getPoseActor(currentEntity);
//increment animations //increment animations
if(currentPoseActor.isPlayingAnimation()){ if(currentPoseActor.isPlayingAnimation()){
currentPoseActor.incrementAnimationTime(Globals.timekeeper.getSimFrameTime() / Main.targetFrameRate); currentPoseActor.incrementAnimationTime(Globals.timekeeper.getSimFrameTime());
} }
} }
} }