diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index dfd9abb9..4ef52050 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1362,6 +1362,7 @@ Fluid sim toggle on client side Lower duplicate physics frame count Various code cleanup Stop sleeping during high frame time +Actor bone spatial data caching for performance diff --git a/src/main/java/electrosphere/engine/profiler/Profiler.java b/src/main/java/electrosphere/engine/profiler/Profiler.java index e45bccf9..e89e8dc4 100644 --- a/src/main/java/electrosphere/engine/profiler/Profiler.java +++ b/src/main/java/electrosphere/engine/profiler/Profiler.java @@ -11,7 +11,7 @@ public class Profiler { //controls whether to profile or not //!!WARNING!!: when this is turned on, testing can behave weirdly!! IE GET STUCK! - public static boolean PROFILE = false; + public static boolean PROFILE = true; //pointer to the global instance long pointer = -1; diff --git a/src/main/java/electrosphere/renderer/actor/Actor.java b/src/main/java/electrosphere/renderer/actor/Actor.java index 1d56ac79..229a99d0 100644 --- a/src/main/java/electrosphere/renderer/actor/Actor.java +++ b/src/main/java/electrosphere/renderer/actor/Actor.java @@ -86,6 +86,16 @@ public class Actor { * Used for caching animation masks that should be removed */ List toRemoveMasks = new LinkedList(); + + /** + * Stores the positions of bones as they are updated + */ + Map bonePositionMap = new HashMap(); + + /** + * Stores the rotations of bones as they are updated + */ + Map boneRotationMap = new HashMap(); /** * Creates an achor @@ -388,8 +398,20 @@ public class Actor { } } + /** + * Calculates the node transforms for the actor + * @param model The model that backs the actor + */ void calculateNodeTransforms(Model model){ model.updateNodeTransform(boneRotators,staticMorph); + for(Bone bone : model.getBones()){ + //store position + Vector4d result = new Matrix4d(bone.getFinalTransform()).transform(bone.getMOffset().invert().transform(new Vector4d(0,0,0,1))); + this.bonePositionMap.put(bone.boneID,new Vector3d(result.x,result.y,result.z)); + //store rotation + Quaterniond rotation = new Matrix4d(bone.getFinalTransform()).getNormalizedRotation(new Quaterniond()); + this.boneRotationMap.put(bone.boneID,rotation); + } } public void setAnimationScalar(float animationScalar) { @@ -481,6 +503,9 @@ public class Actor { * //TODO: refactor to make failure more transparent (both for model not existing and bone not existing) */ public Vector3d getBonePosition(String boneName){ + if(bonePositionMap.containsKey(boneName)){ + return bonePositionMap.get(boneName); + } Vector3d rVal = new Vector3d(); Model model = Globals.assetManager.fetchModel(modelPath); if(model != null){ @@ -510,6 +535,9 @@ public class Actor { * @return The Quaterniond containing the rotation of the bone, or an identity Quaterniond if the lookup fails */ public Quaterniond getBoneRotation(String boneName){ + if(boneRotationMap.containsKey(boneName)){ + return boneRotationMap.get(boneName); + } Quaterniond rVal = new Quaterniond(); Model model = Globals.assetManager.fetchModel(modelPath); if(model != null){ diff --git a/src/main/java/electrosphere/server/poseactor/PoseActor.java b/src/main/java/electrosphere/server/poseactor/PoseActor.java index 3d2c8d62..01ecf48c 100644 --- a/src/main/java/electrosphere/server/poseactor/PoseActor.java +++ b/src/main/java/electrosphere/server/poseactor/PoseActor.java @@ -57,6 +57,16 @@ public class PoseActor { */ List boneGroups; + /** + * Stores the positions of bones as they are updated + */ + Map bonePositionMap = new HashMap(); + + /** + * Stores the rotations of bones as they are updated + */ + Map boneRotationMap = new HashMap(); + /** * Constructor @@ -367,6 +377,14 @@ public class PoseActor { */ void calculateNodeTransforms(PoseModel model){ model.updateNodeTransform(boneRotators,staticMorph); + for(Bone bone : model.getBones()){ + //store position + Vector4d result = new Matrix4d(bone.getFinalTransform()).transform(bone.getMOffset().invert().transform(new Vector4d(0,0,0,1))); + this.bonePositionMap.put(bone.boneID,new Vector3d(result.x,result.y,result.z)); + //store rotation + Quaterniond rotation = new Matrix4d(bone.getFinalTransform()).getNormalizedRotation(new Quaterniond()); + this.boneRotationMap.put(bone.boneID,rotation); + } } /** @@ -409,6 +427,9 @@ public class PoseActor { * @return The rotation quaternion of the bone */ public Quaterniond getBoneRotation(String boneName){ + if(boneRotationMap.containsKey(boneName)){ + return boneRotationMap.get(boneName); + } Quaterniond rVal = new Quaterniond(); PoseModel model = Globals.assetManager.fetchPoseModel(modelPath); if(model != null){ @@ -450,6 +471,9 @@ public class PoseActor { * @return */ public Vector3d getBonePosition(String boneName){ + if(bonePositionMap.containsKey(boneName)){ + return bonePositionMap.get(boneName); + } Vector3d rVal = new Vector3d(); PoseModel model = Globals.assetManager.fetchPoseModel(modelPath); if(model != null){