more allocation work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-06-08 21:31:19 -04:00
parent cacb20cf49
commit b11aa149d5
15 changed files with 196 additions and 42 deletions

View File

@ -2138,6 +2138,7 @@ Fix many places where entity position being set on vector fetched from getPositi
Undo getPosition new alloc to lower memory footprint Undo getPosition new alloc to lower memory footprint
Work to reduce allocations Work to reduce allocations
Prevent mouse event re-allocation every frame Prevent mouse event re-allocation every frame
More allocation work

View File

@ -1,5 +1,7 @@
package electrosphere.client.sim; package electrosphere.client.sim;
import java.util.HashSet;
import org.joml.Vector3d; import org.joml.Vector3d;
import electrosphere.client.entity.camera.CameraEntityUtils; import electrosphere.client.entity.camera.CameraEntityUtils;
@ -31,6 +33,11 @@ public class ClientSimulation {
//used for tracking different in player position between frames (principally for draw cell manager) //used for tracking different in player position between frames (principally for draw cell manager)
Vector3d newPlayerCharacterPosition = new Vector3d(); Vector3d newPlayerCharacterPosition = new Vector3d();
/**
* Set for storing entities of a specific tag
*/
private HashSet<Entity> entityTagSet = new HashSet<Entity>();
/** /**
* Constructor * Constructor
@ -71,7 +78,8 @@ public class ClientSimulation {
//update actor animations //update actor animations
Globals.profiler.beginCpuSample("update actor animations"); Globals.profiler.beginCpuSample("update actor animations");
for(Entity currentEntity : Globals.clientState.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){ Globals.clientState.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.DRAWABLE, entityTagSet);
for(Entity currentEntity : entityTagSet){
Actor currentActor = EntityUtils.getActor(currentEntity); Actor currentActor = EntityUtils.getActor(currentEntity);
if(currentActor.getLodLevel() == Actor.LOD_LEVEL_STATIC){ if(currentActor.getLodLevel() == Actor.LOD_LEVEL_STATIC){
continue; continue;
@ -84,7 +92,8 @@ public class ClientSimulation {
// //
//make items play idle animation //make items play idle animation
Globals.profiler.beginCpuSample("item animations"); Globals.profiler.beginCpuSample("item animations");
for(Entity item : Globals.clientState.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM)){ Globals.clientState.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM, entityTagSet);
for(Entity item : entityTagSet){
ItemUtils.updateItemActorAnimation(item); ItemUtils.updateItemActorAnimation(item);
} }
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
@ -114,7 +123,8 @@ public class ClientSimulation {
// //
//sum collidable impulses //sum collidable impulses
Globals.profiler.beginCpuSample("collidable logic"); Globals.profiler.beginCpuSample("collidable logic");
for(Entity collidable : Globals.clientState.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){ Globals.clientState.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE, entityTagSet);
for(Entity collidable : entityTagSet){
if(ClientCollidableTree.hasClientCollidableTree(collidable)){ if(ClientCollidableTree.hasClientCollidableTree(collidable)){
ClientCollidableTree.getClientCollidableTree(collidable).simulate((float)Globals.engineState.timekeeper.getSimFrameTime()); ClientCollidableTree.getClientCollidableTree(collidable).simulate((float)Globals.engineState.timekeeper.getSimFrameTime());
} }

View File

@ -52,6 +52,23 @@ public class DataFormatUtil {
} }
} }
/**
* Gets the vector in vector3d form
* @param values The list of raw float values
* @param tempVec The vec to set the values to
* @return The vector containing those values or an identity vector if no such values exist
*/
public static Vector3d getDoubleListAsVector(List<Double> values, Vector3d tempVec){
if(values == null){
return tempVec;
}
if(values.size() > 0){
return tempVec.set(values.get(0),values.get(1),values.get(2));
} else {
return tempVec;
}
}
/** /**
* Gets a vector as a list of doubles * Gets a vector as a list of doubles
* @param vec The vector * @param vec The vector

View File

@ -142,6 +142,22 @@ public class Scene {
return rVal; return rVal;
} }
/**
* Gets all entities registered to a tag
* @param tag The tag
* @param set The pre-existing set to populate
* @return A list of all entities with the tag, or null if no entities have been added to the tag yet
*/
public Set<Entity> getEntitiesWithTag(String tag, Set<Entity> set){
lock.lock();
set.clear();
if(tagEntityMap.containsKey(tag)){
set.addAll(tagEntityMap.get(tag));
}
lock.unlock();
return set;
}
/** /**
* Removes an entity from a tag * Removes an entity from a tag
* @param e The entity * @param e The entity

View File

@ -340,13 +340,44 @@ public class AttachUtils {
Vector3d bonePosition, Vector3d bonePosition,
Quaterniond boneRotation, Quaterniond boneRotation,
//parent transforms
Vector3d parentPosition,
Quaterniond parentRotation,
Vector3d parentScale
){
return AttachUtils.calculateBoneAttachmentLocalPosition(new Vector3d(), offsetVector, offsetRotation, bonePosition, boneRotation, parentPosition, parentRotation, parentScale);
}
/**
* Calculates the position of an entity attached to a bone
* @param offsetVector The offset position
* @param offsetRotation The offset rotation
* @param bonePosition The bone's position
* @param boneRotation The bone's rotation
* @param parentPosition The parent's position
* @param parentRotation The parent's rotation
* @param parentScale The parent's scale
* @return The position of the attached/child entity
*/
public static Vector3d calculateBoneAttachmentLocalPosition(
//The vector to store the result in
Vector3d res,
//optional offsets
Vector3d offsetVector,
Quaterniond offsetRotation,
//current bone transform
Vector3d bonePosition,
Quaterniond boneRotation,
//parent transforms //parent transforms
Vector3d parentPosition, Vector3d parentPosition,
Quaterniond parentRotation, Quaterniond parentRotation,
Vector3d parentScale Vector3d parentScale
){ ){
//transform bone space //transform bone space
Vector3d position = new Vector3d(offsetVector); Vector3d position = res.set(offsetVector);
position = position.rotate(new Quaterniond(boneRotation)); position = position.rotate(new Quaterniond(boneRotation));
position = position.add(bonePosition); position = position.add(bonePosition);
position = position.mul(parentScale); position = position.mul(parentScale);

View File

@ -73,12 +73,12 @@ public class ServerCollidableTree implements BehaviorTree {
Impulse[] impulses = collidable.getImpulses(); Impulse[] impulses = collidable.getImpulses();
Vector3d pos = EntityUtils.getPosition(parent); Vector3d pos = EntityUtils.getPosition(parent);
for(int i = 0; i < collidable.getImpulseCount(); i++){ for(int i = 0; i < collidable.getImpulseCount(); i++){
if(impulses[i].type.matches(Collidable.TYPE_CREATURE)){ if(impulses[i].type.equals(Collidable.TYPE_CREATURE)){
if(ServerGravityTree.getServerGravityTree(parent)!=null){ if(ServerGravityTree.getServerGravityTree(parent)!=null){
ServerGravityTree.getServerGravityTree(parent).start(); ServerGravityTree.getServerGravityTree(parent).start();
} }
} }
if(impulses[i].type.matches(Collidable.TYPE_WORLD_BOUND) || impulses[i].type.matches(Collidable.TYPE_STATIC)){ if(impulses[i].type.equals(Collidable.TYPE_WORLD_BOUND) || impulses[i].type.equals(Collidable.TYPE_STATIC)){
this.resetGravityFall(); this.resetGravityFall();
pos.add(impulses[i].getDirection().mul(impulses[i].getForce())); pos.add(impulses[i].getDirection().mul(impulses[i].getForce()));
} }

View File

@ -26,6 +26,7 @@ import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.attach.AttachUtils; import electrosphere.entity.state.attach.AttachUtils;
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState.HitboxShapeType; import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState.HitboxShapeType;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.mem.JomlPool;
import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.Realm;
import electrosphere.server.entity.poseactor.PoseActor; import electrosphere.server.entity.poseactor.PoseActor;
import electrosphere.util.math.SpatialMathUtils; import electrosphere.util.math.SpatialMathUtils;
@ -457,8 +458,13 @@ public class HitboxCollectionState {
private void updateSphereShapePosition(CollisionEngine collisionEngine, String boneName, HitboxState hitboxState, Vector3d bonePosition){ private void updateSphereShapePosition(CollisionEngine collisionEngine, String boneName, HitboxState hitboxState, Vector3d bonePosition){
DGeom geom = this.stateGeomMap.get(hitboxState); DGeom geom = this.stateGeomMap.get(hitboxState);
//get pooled objects
Vector3d offsetPosition = JomlPool.getD();
Vector3d parentScale = JomlPool.getD();
Vector3d finalPos = JomlPool.getD();
//get offset's transform //get offset's transform
Vector3d offsetPosition = DataFormatUtil.getDoubleListAsVector(hitboxState.getHitboxData().getOffset()); offsetPosition = DataFormatUtil.getDoubleListAsVector(hitboxState.getHitboxData().getOffset(),offsetPosition);
Quaterniond offsetRotation = new Quaterniond(); Quaterniond offsetRotation = new Quaterniond();
//the bone's transform //the bone's transform
@ -471,15 +477,19 @@ public class HitboxCollectionState {
//the parent's transform //the parent's transform
Vector3d parentPosition = EntityUtils.getPosition(parent); Vector3d parentPosition = EntityUtils.getPosition(parent);
Quaterniond parentRotation = EntityUtils.getRotation(parent); Quaterniond parentRotation = EntityUtils.getRotation(parent);
Vector3d parentScale = new Vector3d();
parentScale.set(EntityUtils.getScale(parent)); parentScale.set(EntityUtils.getScale(parent));
//calculate //calculate
Vector3d hitboxPos = AttachUtils.calculateBoneAttachmentLocalPosition(offsetPosition, offsetRotation, bonePositionD, boneRotation, parentPosition, parentRotation, parentScale); Vector3d hitboxPos = AttachUtils.calculateBoneAttachmentLocalPosition(finalPos, offsetPosition, offsetRotation, bonePositionD, boneRotation, parentPosition, parentRotation, parentScale);
//actually set value //actually set value
PhysicsEntityUtils.setGeometryOffsetPosition(collisionEngine, geom, hitboxPos, new Quaterniond()); PhysicsEntityUtils.setGeometryOffsetPosition(collisionEngine, geom, hitboxPos, new Quaterniond());
//release pooled objects
JomlPool.release(offsetPosition);
JomlPool.release(parentScale);
JomlPool.release(finalPos);
} }
/** /**

View File

@ -4,6 +4,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import org.joml.Matrix4d;
import org.joml.Vector3d; import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;
@ -22,6 +23,11 @@ public class JomlPool {
*/ */
static List<Vector3d> vec3dPool = new LinkedList<Vector3d>(); static List<Vector3d> vec3dPool = new LinkedList<Vector3d>();
/**
* Structure to store not-in-use objects
*/
static List<Matrix4d> mat4dPool = new LinkedList<Matrix4d>();
/** /**
* Lock for thread-safeing operations * Lock for thread-safeing operations
*/ */
@ -75,6 +81,22 @@ public class JomlPool {
return rVal; return rVal;
} }
/**
* Gets a Matrix4d from the pool. Allocates if no free one is available.
* @return A Matrix4d
*/
public static Matrix4d getMat(){
Matrix4d rVal = null;
lock.lock();
if(mat4dPool.size() > 0){
rVal = mat4dPool.remove(0);
} else {
rVal = new Matrix4d();
}
lock.unlock();
return rVal;
}
/** /**
* Releases a Vector3d back into the pool * Releases a Vector3d back into the pool
* @param data The object to release * @param data The object to release
@ -90,4 +112,17 @@ public class JomlPool {
lock.unlock(); lock.unlock();
} }
/**
* Releases a Matrix4d back into the pool
* @param data The object to release
*/
public static void release(Matrix4d data){
data.identity();
lock.lock();
if(JomlPool.mat4dPool.size() < 1000){
JomlPool.mat4dPool.add(data);
}
lock.unlock();
}
} }

View File

@ -134,6 +134,8 @@ public class ActorStaticMorph {
Vector3f offset = new Vector3f(0,0,0); Vector3f offset = new Vector3f(0,0,0);
Vector3f scale = new Vector3f(1,1,1); Vector3f scale = new Vector3f(1,1,1);
Matrix4f transform = null;
public Quaternionf getRotation(){ public Quaternionf getRotation(){
return new Quaternionf().rotateXYZ(yaw, pitch, roll); return new Quaternionf().rotateXYZ(yaw, pitch, roll);
} }
@ -147,9 +149,11 @@ public class ActorStaticMorph {
} }
public Matrix4f getTransform(){ public Matrix4f getTransform(){
Matrix4f rVal = new Matrix4f(); if(transform == null){
rVal.translationRotateScale(offset, getRotation(), scale); transform = new Matrix4f();
return rVal; }
transform.translationRotateScale(offset, getRotation(), scale);
return transform;
} }
} }

View File

@ -25,11 +25,11 @@ public class AnimNode {
this.raw_data = raw_data; this.raw_data = raw_data;
} }
public Matrix4d getTransform(){ public void getTransform(Matrix4d loc){
return new Matrix4d(transform); loc.set(transform);
} }
public void setTransform(Matrix4d transform){ public void setTransform(Matrix4d transform){
this.transform = new Matrix4d(transform); this.transform.set(transform);
} }
} }

View File

@ -13,6 +13,7 @@ import electrosphere.renderer.meshgen.MeshLoader;
import electrosphere.renderer.anim.AnimNode; import electrosphere.renderer.anim.AnimNode;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.mem.JomlPool;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -415,9 +416,10 @@ public class Model {
* @param staticMorph The static morph to apply * @param staticMorph The static morph to apply
*/ */
private void updateNodeTransform(AnimNode n, Map<String,ActorBoneRotator> boneRotators, ActorStaticMorph staticMorph){ private void updateNodeTransform(AnimNode n, Map<String,ActorBoneRotator> boneRotators, ActorStaticMorph staticMorph){
Matrix4d currentTransform = n.getTransform().identity(); Matrix4d poolMat = JomlPool.getMat();
//grab parent transform if exists
if(n.parent != null){ if(n.parent != null){
currentTransform.set(n.parent.getTransform()); n.parent.getTransform(poolMat);
} }
if(n.is_bone){ if(n.is_bone){
// //
@ -430,33 +432,33 @@ public class Model {
message = message + "bone map key set: " + boneMap.keySet() + "\n"; message = message + "bone map key set: " + boneMap.keySet() + "\n";
throw new Error(message); throw new Error(message);
} }
currentTransform.mul(target_bone.getDeform()); poolMat.mul(target_bone.getDeform());
if(boneRotators.containsKey(target_bone.boneID)){ if(boneRotators.containsKey(target_bone.boneID)){
currentTransform.rotate(boneRotators.get(target_bone.boneID).getRotation()); poolMat.rotate(boneRotators.get(target_bone.boneID).getRotation());
} }
// //
//static morph (changing nose size, eye distance, etc) //static morph (changing nose size, eye distance, etc)
if(staticMorph != null && staticMorph.getBoneTransforms(n.id) != null){ if(staticMorph != null && staticMorph.getBoneTransforms(n.id) != null){
currentTransform.mul(staticMorph.getBoneTransforms(n.id).getTransform()); poolMat.mul(staticMorph.getBoneTransforms(n.id).getTransform());
} }
// //
Matrix4d bone_matrix = currentTransform; n.setTransform(poolMat);
n.setTransform(currentTransform);
// //
//Calculate final offset from initial bone //Calculate final offset from initial bone
//https://stackoverflow.com/a/59869381 //https://stackoverflow.com/a/59869381
bone_matrix.mul(target_bone.getMOffset()); poolMat.mul(target_bone.getMOffset());
bone_matrix = globalInverseTransform.mul(bone_matrix, bone_matrix); poolMat = globalInverseTransform.mul(poolMat, poolMat);
target_bone.setFinalTransform(bone_matrix); target_bone.setFinalTransform(poolMat);
} else { } else {
n.setTransform(currentTransform.mul(electrosphere.util.Utilities.convertAIMatrix(n.raw_data.mTransformation()))); n.setTransform(poolMat.mul(electrosphere.util.Utilities.convertAIMatrix(n.raw_data.mTransformation())));
} }
Iterator<AnimNode> node_iterator = n.children.iterator(); Iterator<AnimNode> node_iterator = n.children.iterator();
while(node_iterator.hasNext()){ while(node_iterator.hasNext()){
AnimNode current_node = node_iterator.next(); AnimNode current_node = node_iterator.next();
updateNodeTransform(current_node,boneRotators,staticMorph); updateNodeTransform(current_node,boneRotators,staticMorph);
} }
JomlPool.release(poolMat);
} }
/** /**

View File

@ -1,5 +1,6 @@
package electrosphere.renderer.pipelines; package electrosphere.renderer.pipelines;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.joml.Matrix4d; import org.joml.Matrix4d;
@ -26,9 +27,14 @@ public class FoliagePipeline implements RenderPipeline {
*/ */
static Sphered boundingSphere = new Sphered(0.5,0.5,0.5,8); static Sphered boundingSphere = new Sphered(0.5,0.5,0.5,8);
/**
* Set for storing entities of a specific tag
*/
private HashSet<Entity> entityTagSet = new HashSet<Entity>();
@Override @Override
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
Set<Entity> foliageEntities = Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAW_FOLIAGE_PASS); Set<Entity> foliageEntities = Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAW_FOLIAGE_PASS, entityTagSet);
if(foliageEntities != null){ if(foliageEntities != null){
for(Entity foliageEntity : foliageEntities){ for(Entity foliageEntity : foliageEntities){
Matrix4d modelMatrix = new Matrix4d(); Matrix4d modelMatrix = new Matrix4d();

View File

@ -1,5 +1,6 @@
package electrosphere.renderer.pipelines; package electrosphere.renderer.pipelines;
import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -49,6 +50,11 @@ public class MainContentPipeline implements RenderPipeline {
*/ */
private int terrainChunks = 0; private int terrainChunks = 0;
/**
* Set for storing entities of a specific tag
*/
private HashSet<Entity> entityTagSet = new HashSet<Entity>();
@Override @Override
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
Globals.profiler.beginCpuSample("MainContentPipeline.render"); Globals.profiler.beginCpuSample("MainContentPipeline.render");
@ -202,7 +208,8 @@ public class MainContentPipeline implements RenderPipeline {
Globals.renderingEngine.getFoliagePipeline().render(openGLState, renderPipelineState); Globals.renderingEngine.getFoliagePipeline().render(openGLState, renderPipelineState);
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
Globals.profiler.beginCpuSample("MainContentPipeline.render - Solids instanced"); Globals.profiler.beginCpuSample("MainContentPipeline.render - Solids instanced");
for(Entity currentEntity : Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED)){ Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED, entityTagSet);
for(Entity currentEntity : entityTagSet){
Vector3d position = EntityUtils.getPosition(currentEntity); Vector3d position = EntityUtils.getPosition(currentEntity);
if(MainContentPipeline.shouldDrawSolidPass(currentEntity)){ if(MainContentPipeline.shouldDrawSolidPass(currentEntity)){
//fetch actor //fetch actor
@ -266,7 +273,8 @@ public class MainContentPipeline implements RenderPipeline {
// //
Globals.profiler.beginCpuSample("MainContentPipeline.render - Transparents non-instanced"); Globals.profiler.beginCpuSample("MainContentPipeline.render - Transparents non-instanced");
for(Entity currentEntity : Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE, entityTagSet);
for(Entity currentEntity : entityTagSet){
Vector3d position = EntityUtils.getPosition(currentEntity); Vector3d position = EntityUtils.getPosition(currentEntity);
if(MainContentPipeline.shouldDrawTransparentPass(currentEntity)){ if(MainContentPipeline.shouldDrawTransparentPass(currentEntity)){
//fetch actor //fetch actor
@ -285,7 +293,8 @@ public class MainContentPipeline implements RenderPipeline {
} }
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
Globals.profiler.beginCpuSample("MainContentPipeline.render - Transparents instanced"); Globals.profiler.beginCpuSample("MainContentPipeline.render - Transparents instanced");
for(Entity currentEntity : Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED)){ Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED, entityTagSet);
for(Entity currentEntity : entityTagSet){
Vector3d position = EntityUtils.getPosition(currentEntity); Vector3d position = EntityUtils.getPosition(currentEntity);
if(MainContentPipeline.shouldDrawTransparentPass(currentEntity)){ if(MainContentPipeline.shouldDrawTransparentPass(currentEntity)){
//fetch actor //fetch actor

View File

@ -1,5 +1,6 @@
package electrosphere.renderer.target; package electrosphere.renderer.target;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -33,6 +34,16 @@ public class DrawTargetEvaluator {
* Cutoff after which we draw lower resolution models * Cutoff after which we draw lower resolution models
*/ */
public static final int LOD_LOWER_CUTOFF = 30; public static final int LOD_LOWER_CUTOFF = 30;
/**
* Set for storing entities of a specific tag
*/
private static final HashSet<Entity> drawableSet = new HashSet<Entity>();
/**
* Set for storing entities of a specific tag
*/
private static final HashSet<Entity> shadowSet = new HashSet<Entity>();
/** /**
* Evaluates the draw targets * Evaluates the draw targets
@ -67,8 +78,8 @@ public class DrawTargetEvaluator {
Vector3d positionVec = new Vector3d(); Vector3d positionVec = new Vector3d();
//different entity lists //different entity lists
Set<Entity> drawables = Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE); Set<Entity> drawables = Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE, drawableSet);
Set<Entity> shadowList = Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAW_CAST_SHADOW); Set<Entity> shadowList = Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAW_CAST_SHADOW, shadowSet);
for(Entity currentEntity : drawables){ for(Entity currentEntity : drawables){
Vector3d position = EntityUtils.getPosition(currentEntity); Vector3d position = EntityUtils.getPosition(currentEntity);

View File

@ -17,6 +17,7 @@ import org.lwjgl.assimp.AIScene;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.mem.JomlPool;
import electrosphere.renderer.actor.ActorBoneRotator; import electrosphere.renderer.actor.ActorBoneRotator;
import electrosphere.renderer.actor.ActorStaticMorph; import electrosphere.renderer.actor.ActorStaticMorph;
import electrosphere.renderer.anim.AnimChannel; import electrosphere.renderer.anim.AnimChannel;
@ -200,10 +201,10 @@ public class PoseModel {
* @param staticMorph The static morph * @param staticMorph The static morph
*/ */
private void updateNodeTransform(AnimNode n, Map<String,ActorBoneRotator> boneRotators, ActorStaticMorph staticMorph){ private void updateNodeTransform(AnimNode n, Map<String,ActorBoneRotator> boneRotators, ActorStaticMorph staticMorph){
Matrix4d poolMat = JomlPool.getMat();
//grab parent transform if exists //grab parent transform if exists
Matrix4d currentTransform = n.getTransform().identity();
if(n.parent != null){ if(n.parent != null){
currentTransform.set(n.parent.getTransform()); n.parent.getTransform(poolMat);
} }
//if this is a bone, calculate the transform for the bone //if this is a bone, calculate the transform for the bone
if(n.is_bone){ if(n.is_bone){
@ -215,23 +216,23 @@ public class PoseModel {
message = message + "bone map key set: " + boneMap.keySet() + "\n"; message = message + "bone map key set: " + boneMap.keySet() + "\n";
throw new Error(message); throw new Error(message);
} }
currentTransform.mul(target_bone.getDeform()); poolMat.mul(target_bone.getDeform());
if(boneRotators.containsKey(target_bone.boneID)){ if(boneRotators.containsKey(target_bone.boneID)){
currentTransform.rotate(boneRotators.get(target_bone.boneID).getRotation()); poolMat.rotate(boneRotators.get(target_bone.boneID).getRotation());
} }
n.setTransform(currentTransform); n.setTransform(poolMat);
if(staticMorph != null && staticMorph.getBoneTransforms(n.id) != null){ if(staticMorph != null && staticMorph.getBoneTransforms(n.id) != null){
currentTransform.mul(staticMorph.getBoneTransforms(n.id).getTransform()); poolMat.mul(staticMorph.getBoneTransforms(n.id).getTransform());
} }
// //
//Calculate final offset from initial bone //Calculate final offset from initial bone
//https://stackoverflow.com/a/59869381 //https://stackoverflow.com/a/59869381
currentTransform.mul(target_bone.getMOffset()); poolMat.mul(target_bone.getMOffset());
currentTransform = globalInverseTransform.mul(currentTransform, currentTransform); poolMat = globalInverseTransform.mul(poolMat, poolMat);
target_bone.setFinalTransform(currentTransform); target_bone.setFinalTransform(poolMat);
} else { } else {
//not a bone, so use transform directly from data //not a bone, so use transform directly from data
n.setTransform(currentTransform.mul(electrosphere.util.Utilities.convertAIMatrix(n.raw_data.mTransformation()))); n.setTransform(poolMat.mul(electrosphere.util.Utilities.convertAIMatrix(n.raw_data.mTransformation())));
} }
//update all children accordingly //update all children accordingly
Iterator<AnimNode> node_iterator = n.children.iterator(); Iterator<AnimNode> node_iterator = n.children.iterator();
@ -239,6 +240,7 @@ public class PoseModel {
AnimNode current_node = node_iterator.next(); AnimNode current_node = node_iterator.next();
this.updateNodeTransform(current_node,boneRotators,staticMorph); this.updateNodeTransform(current_node,boneRotators,staticMorph);
} }
JomlPool.release(poolMat);
} }
/** /**