actor code cleanup

This commit is contained in:
austin 2025-05-29 15:30:54 -04:00
parent 083198e5e5
commit e9067af287
18 changed files with 314 additions and 152 deletions

View File

@ -2059,6 +2059,7 @@ Logging for loading thread failure
Code cleanup
More tests
Move actor masks into dedicated package
Actor code cleanup

View File

@ -55,8 +55,8 @@ public class ImGuiEntityActorTab {
}
}
} else {
ImGui.text("Model path: " + actor.getModelPath());
Model loadedModel = Globals.assetManager.fetchModel(actor.getModelPath());
ImGui.text("Model path: " + actor.getBaseModelPath());
Model loadedModel = Globals.assetManager.fetchModel(actor.getBaseModelPath());
ImGui.text("Model is loaded: " + (loadedModel != null));
}
@ -99,7 +99,7 @@ public class ImGuiEntityActorTab {
//Browsable list of all animations with their data
if(ImGui.collapsingHeader("Animation Channel Data")){
Model model = Globals.assetManager.fetchModel(actor.getModelPath());
Model model = Globals.assetManager.fetchModel(actor.getBaseModelPath());
ImGui.indent();
for(Animation animation : model.getAnimations()){
if(ImGui.collapsingHeader(animation.name)){
@ -139,7 +139,7 @@ public class ImGuiEntityActorTab {
//print animation keys
if(ImGui.button("Print animation keys")){
Model model = Globals.assetManager.fetchModel(actor.getModelPath());
Model model = Globals.assetManager.fetchModel(actor.getBaseModelPath());
model.describeAllAnimations();
}
}

View File

@ -70,7 +70,7 @@ public class DrawableUtils {
//add low-res model path to actor if present
if(modelData.getLODPath() != null){
creatureActor.setLowResPath(modelData.getLODPath());
creatureActor.setLowResBaseModelPath(modelData.getLODPath());
Globals.assetManager.addModelPathToQueue(modelData.getLODPath());
}

View File

@ -107,7 +107,7 @@ public class FirstPersonTree implements BehaviorTree {
Actor actor = EntityUtils.getActor(Globals.clientState.firstPersonEntity);
if(
(!actor.isPlayingAnimation() || !actor.isPlayingAnimation(animationName)) &&
(Globals.assetManager.fetchModel(actor.getModelPath()) != null && Globals.assetManager.fetchModel(actor.getModelPath()).getAnimation(animationName) != null)
(Globals.assetManager.fetchModel(actor.getBaseModelPath()) != null && Globals.assetManager.fetchModel(actor.getBaseModelPath()).getAnimation(animationName) != null)
){
actor.playAnimation(animationName,priority);
actor.incrementAnimationTime(offset);
@ -133,7 +133,7 @@ public class FirstPersonTree implements BehaviorTree {
Actor actor = EntityUtils.getActor(Globals.clientState.firstPersonEntity);
if(
(!actor.isPlayingAnimation() || !actor.isPlayingAnimation(animation.getNameFirstPerson())) &&
(Globals.assetManager.fetchModel(actor.getModelPath()) != null && Globals.assetManager.fetchModel(actor.getModelPath()).getAnimation(animation.getNameFirstPerson()) != null)
(Globals.assetManager.fetchModel(actor.getBaseModelPath()) != null && Globals.assetManager.fetchModel(actor.getBaseModelPath()).getAnimation(animation.getNameFirstPerson()) != null)
){
actor.playAnimation(animation, false);
actor.incrementAnimationTime(offset);
@ -150,7 +150,7 @@ public class FirstPersonTree implements BehaviorTree {
Actor actor = EntityUtils.getActor(Globals.clientState.firstPersonEntity);
if(
(actor.isPlayingAnimation() || actor.isPlayingAnimation(animation.getNameFirstPerson())) &&
(Globals.assetManager.fetchModel(actor.getModelPath()) != null && Globals.assetManager.fetchModel(actor.getModelPath()).getAnimation(animation.getNameFirstPerson()) != null)
(Globals.assetManager.fetchModel(actor.getBaseModelPath()) != null && Globals.assetManager.fetchModel(actor.getBaseModelPath()).getAnimation(animation.getNameFirstPerson()) != null)
){
actor.interruptAnimation(animation, false);
}

View File

@ -80,8 +80,8 @@ public class ClientIdleTree implements BehaviorTree {
idleData != null &&
(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(idleData.getAnimation())) &&
(
Globals.assetManager.fetchModel(entityActor.getModelPath()) != null &&
Globals.assetManager.fetchModel(entityActor.getModelPath()).getAnimation(idleData.getAnimation().getNameThirdPerson()) != null
Globals.assetManager.fetchModel(entityActor.getBaseModelPath()) != null &&
Globals.assetManager.fetchModel(entityActor.getBaseModelPath()).getAnimation(idleData.getAnimation().getNameThirdPerson()) != null
)
){

View File

@ -93,7 +93,6 @@ import electrosphere.net.server.player.Player;
import electrosphere.net.synchronization.transport.StateCollection;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorBoneRotator;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
@ -368,9 +367,6 @@ public class CommonEntityUtils {
ClientAlwaysUprightTree.attachTree(entity);
CreatureUtils.setFacingVector(entity, SpatialMathUtils.getOriginVector());
} break;
case "BLENDER_ROTATION": {
ActorUtils.applyBlenderRotation(entity);
} break;
case "SPAWNPOINT": {
//ignore on client
} break;
@ -684,9 +680,6 @@ public class CommonEntityUtils {
ServerAlwaysUprightTree.attachTree(entity);
CreatureUtils.setFacingVector(entity, SpatialMathUtils.getOriginVector());
} break;
case "BLENDER_ROTATION": {
ActorUtils.applyBlenderRotation(entity);
} break;
case "SPAWNPOINT": {
realm.registerSpawnPoint(position);
} break;

View File

@ -8,14 +8,14 @@ import electrosphere.logger.LoggerInterface;
import electrosphere.mem.JomlPool;
import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderPipelineState;
import electrosphere.renderer.actor.ActorUniformMap.UniformValue;
import electrosphere.renderer.actor.mask.ActorAnimationMask;
import electrosphere.renderer.actor.mask.ActorMeshMask;
import electrosphere.renderer.actor.mask.ActorShaderMask;
import electrosphere.renderer.actor.mask.ActorTextureMask;
import electrosphere.renderer.actor.mask.ActorUniformMap;
import electrosphere.renderer.actor.mask.ActorUniformMap.UniformValue;
import electrosphere.renderer.model.Bone;
import electrosphere.renderer.model.Model;
import electrosphere.renderer.texture.Texture;
import java.util.HashMap;
import java.util.LinkedList;
@ -64,15 +64,14 @@ public class Actor {
public static final int LOD_LEVEL_STATIC = 0;
/**
* the model path of the model backing the actor
*/
private String modelPath;
/**
* Path to the low res model
*/
private String lowResPath;
//
//
// CORE RENDER VARS
//
//
/**
* The LOD level of the actor
@ -80,16 +79,55 @@ public class Actor {
private int lodLevel = Actor.LOD_LEVEL_FULL;
/**
* used for statically binding textures in pipelines that dont bind textures on a per-mesh level
* ie when in the ui, this can be set to bind a texture at the actor level
* Controls whether the actor should obey frustum culling
*/
private String textureOverride;
private boolean frustumCull = true;
/**
* scales the time that animations are played at
*/
private float animationScalar = 1.0f;
/**
* Sets scaling applied at the actor level
*/
private float scale = 1.0f;
/**
* The transform matrix
*/
private Matrix4d modelMatrix = new Matrix4d();
/**
* The world position vector
*/
private Vector3d worldPos = new Vector3d();
//
//
// MODEL AND MESH DATA
//
//
/**
* the model path of the model backing the actor
*/
private String baseModelPath;
/**
* Path to the low res model
*/
private String lowResBaseModelPath;
/**
* The stack of animations being applied to a given actor
*/
@ -130,16 +168,20 @@ public class Actor {
*/
private ActorUniformMap uniformMap = new ActorUniformMap();
/**
* Controls whether the actor should obey frustum culling
*/
private boolean frustumCull = true;
/**
* Used for caching animation masks that should be removed
*/
private List<ActorAnimationMask> toRemoveMasks = new LinkedList<ActorAnimationMask>();
//
//
// DATA CACHING
//
//
/**
* Stores the positions of bones as they are updated
*/
@ -149,28 +191,23 @@ public class Actor {
* Stores the rotations of bones as they are updated
*/
private Map<String,Quaterniond> boneRotationMap = new HashMap<String,Quaterniond>();
/**
* Sets scaling applied at the actor level
*/
private float scale = 1.0f;
/**
* The transform matrix
*/
private Matrix4d modelMatrix = new Matrix4d();
/**
* The world position vector
*/
private Vector3d worldPos = new Vector3d();
/**
* Creates an achor
* @param modelPath The path of the model associated with the actor
*/
public Actor(String modelPath){
this.modelPath = modelPath;
this.baseModelPath = modelPath;
}
/**
@ -266,7 +303,7 @@ public class Actor {
* @param priority The priority of the animation
*/
public void playAnimation(String animationName, int priority){
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null && model.getAnimation(animationName) != null){
double length = model.getAnimation(animationName).duration;
ActorAnimationMask animMask = new ActorAnimationMask(priority, animationName, 0, length);
@ -335,11 +372,11 @@ public class Actor {
} else if(animation.getBoneGroups() != null && this.boneGroups == null){
LoggerInterface.loggerRenderer.WARNING(
"Trying to play animation on Actor that uses bone groups, but the Actor's bone group isn't defined!\n" +
"Model path: " + modelPath + "\n" +
"Model path: " + baseModelPath + "\n" +
"Animation name: " + animationName + "\n"
);
} else if(animation.getBoneGroups() == null){
Model model = Globals.assetManager.fetchModel(this.modelPath);
Model model = Globals.assetManager.fetchModel(this.baseModelPath);
if(model != null){
boneMask = new LinkedList<String>();
for(Bone bone : model.getBones()){
@ -349,7 +386,7 @@ public class Actor {
}
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null && model.getAnimation(animationName) != null){
//get data from the actual animation in the model
@ -429,7 +466,7 @@ public class Actor {
}
public void playAnimationWithMask(String animationName, int priority, List<String> boneMask){
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null){
double length = model.getAnimation(animationName).duration;
ActorAnimationMask animMask = new ActorAnimationMask(priority, animationName, 0, length, boneMask);
@ -519,7 +556,7 @@ public class Actor {
* @param worldPos The world position of the model
*/
public void applySpatialData(Matrix4d modelMatrix, Vector3d worldPos){
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null){
this.modelMatrix.set(modelMatrix);
this.worldPos.set(worldPos);
@ -534,9 +571,9 @@ public class Actor {
Globals.profiler.beginAggregateCpuSample("Actor.draw");
//fetch the model
String pathToFetch = this.modelPath;
if(this.lodLevel <= Actor.LOD_LEVEL_LOWER && this.lowResPath != null){
pathToFetch = this.lowResPath;
String pathToFetch = this.baseModelPath;
if(this.lodLevel <= Actor.LOD_LEVEL_LOWER && this.lowResBaseModelPath != null){
pathToFetch = this.lowResBaseModelPath;
}
Model model = Globals.assetManager.fetchModel(pathToFetch);
@ -559,12 +596,6 @@ public class Actor {
}
}
this.calculateNodeTransforms(model);
if(textureOverride != null){
Texture overrideTextureObject = Globals.assetManager.fetchTexture(textureOverride);
if(overrideTextureObject != null){
overrideTextureObject.bind(openGLState);
}
}
//apply uniform overrides
if(this.uniformMap.getMeshes() != null && this.uniformMap.getMeshes().size() > 0){
for(String meshName : this.uniformMap.getMeshes()){
@ -600,7 +631,6 @@ public class Actor {
this.meshMask.getBlockedMeshes().size() == 0 &&
this.textureMap == null &&
this.shaderMasks.size() == 0 &&
this.textureOverride == null &&
this.uniformMap.isEmpty() &&
this.staticMorph == null
)
@ -623,7 +653,6 @@ public class Actor {
rVal = rVal + (this.meshMask.getBlockedMeshes().size() == 0) + "\n";
rVal = rVal + (this.textureMap == null) + "\n";
rVal = rVal + (this.shaderMasks.size() == 0) + "\n";
rVal = rVal + (this.textureOverride == null) + "\n";
rVal = rVal + this.uniformMap.isEmpty() + "\n";
rVal = rVal + (this.staticMorph == null) + "\n";
return rVal;
@ -636,22 +665,29 @@ public class Actor {
* @return true if it should draw, false otherwise
*/
public boolean frustumTest(RenderPipelineState renderPipelineState, Vector3d position){
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null && Actor.isWithinFrustumBox(renderPipelineState,model,position,frustumCull)){
return true;
}
return false;
}
/**
* Draws this actor in the ui pipeline
*/
public void drawUI(){
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null){
model.drawUI();
}
}
public String getModelPath(){
return modelPath;
/**
* Gets the base model's path
* @return The base model's path
*/
public String getBaseModelPath(){
return baseModelPath;
}
/**
@ -665,7 +701,7 @@ public class Actor {
return bonePositionMap.get(boneName);
}
Vector3d rVal = new Vector3d();
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null){
this.applyAnimationMasks(model);
this.calculateNodeTransforms(model);
@ -700,7 +736,7 @@ public class Actor {
return boneRotationMap.get(boneName);
}
Quaterniond rVal = new Quaterniond();
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null){
this.applyAnimationMasks(model);
this.calculateNodeTransforms(model);
@ -722,7 +758,7 @@ public class Actor {
public Matrix4d getBoneTransform(String boneName){
Matrix4d rVal = new Matrix4d();
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null){
applyAnimationMasks(model);
calculateNodeTransforms(model);
@ -744,7 +780,7 @@ public class Actor {
* @return the list of all bones
*/
public List<Bone> getBoneValues(){
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null){
applyAnimationMasks(model);
calculateNodeTransforms(model);
@ -758,7 +794,7 @@ public class Actor {
* @return the bone
*/
public Bone getBone(String boneName){
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null){
return model.getBoneMap().get(boneName);
}
@ -771,26 +807,30 @@ public class Actor {
* @return true if it exists, false otherwise
*/
public boolean containsBone(String boneName){
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null){
return model.getBoneMap().containsKey(boneName);
}
return false;
}
/**
* Checks if the model is loaded for this actor
* @return true if it is loaded, false otherwise
*/
public boolean modelIsLoaded(){
Model model = Globals.assetManager.fetchModel(modelPath);
Model model = Globals.assetManager.fetchModel(baseModelPath);
if(model != null){
return true;
} else {
return false;
}
}
public void setTextureOverride(String override){
textureOverride = override;
}
/**
* Gets the mesh mask for this actor
* @return The mesh mask
*/
public ActorMeshMask getMeshMask(){
return meshMask;
}
@ -802,7 +842,7 @@ public class Actor {
* @param fragmentShader the fragment shader to apply
*/
public void maskShader(String mesh, String vertexShader, String fragmentShader){
shaderMasks.add(new ActorShaderMask(this.modelPath, mesh, vertexShader, fragmentShader));
shaderMasks.add(new ActorShaderMask(this.baseModelPath, mesh, vertexShader, fragmentShader));
}
/**
@ -813,6 +853,10 @@ public class Actor {
throw new UnsupportedOperationException("Not implemented yet");
}
/**
* Adds a texture mask to this actor
* @param textureMask The texture mask
*/
public void addTextureMask(ActorTextureMask textureMask){
if(textureMap == null){
textureMap = new HashMap<String,ActorTextureMask>();
@ -821,10 +865,20 @@ public class Actor {
}
/**
* Adds a rotator to a bone on this actor
* @param bone The name of the bone
* @param rotator The rotator
*/
public void addBoneRotator(String bone, ActorBoneRotator rotator){
boneRotators.put(bone, rotator);
}
/**
* Gets the rotator to apply to a bone
* @param bone The name of the bone
* @return The rotator to apply to that bone if it exists, null otherwise
*/
public ActorBoneRotator getBoneRotator(String bone){
return boneRotators.get(bone);
}
@ -839,20 +893,34 @@ public class Actor {
this.uniformMap.setUniform(meshName, uniformName, value);
}
/**
* Sets the static morph for this actor
* @param staticMorph The static morph
*/
public void setActorStaticMorph(ActorStaticMorph staticMorph){
this.staticMorph = staticMorph;
}
/**
* Gets the static morph for this actor
* @return The static morph for this actor
*/
public ActorStaticMorph getStaticMorph(){
return this.staticMorph;
}
//set should frustum cull
/**
* Sets whether this actor should frustum cull or not
* @param frustumCull true to frustum cull, false to skip frustum culling
*/
public void setFrustumCull(boolean frustumCull){
this.frustumCull = frustumCull;
}
//get should frustum cull
/**
* Gets whether this actor should frustum cull or not
* @return true to frustum cull, false otherwise
*/
public boolean getFrustumCull(){
return frustumCull;
}
@ -943,16 +1011,16 @@ public class Actor {
* Gets the path to the low res model
* @return Path to the low res model
*/
public String getLowResPath() {
return lowResPath;
public String getLowResBaseModelPath() {
return lowResBaseModelPath;
}
/**
* Sets the path to the low res model
* @param lowResPath The path to the low res model
*/
public void setLowResPath(String lowResPath) {
this.lowResPath = lowResPath;
public void setLowResBaseModelPath(String lowResPath) {
this.lowResBaseModelPath = lowResPath;
}
/**

View File

@ -8,8 +8,15 @@ import org.joml.Quaternionf;
*/
public class ActorBoneRotator {
/**
* The rotation to apply
*/
Quaternionf rotation = new Quaternionf().identity();
/**
* Gets the rotation to apply
* @return The rotation to apply
*/
public Quaternionf getRotation(){
return rotation;
}

View File

@ -29,17 +29,12 @@ public class ActorUtils {
Actor rVal = new Actor(modelPath);
return rVal;
}
@Deprecated
public static void applyBlenderTransformer(Entity actorEntity){
// Actor entityActor = EntityUtils.getActor(actorEntity);
// entityActor.setAnimationScalar(60f); //should be the value of the fps i think
}
public static void applyBlenderRotation(Entity actorEntity){
EntityUtils.getRotation(actorEntity).rotateLocalX((float)-Math.PI/2);
}
/**
* Gets the static morph of the actor on the entity
* @param actorEntity The entity
* @return The static morph if it exists, null otherwise
*/
public static ActorStaticMorph getStaticMorph(Entity actorEntity){
Actor entityActor = EntityUtils.getActor(actorEntity);
return entityActor.getStaticMorph();
@ -51,7 +46,7 @@ public class ActorUtils {
*/
public static void queueActorForDeletion(Entity actorEntity){
Actor actor = EntityUtils.getActor(actorEntity);
Globals.assetManager.queueModelForDeletion(actor.getModelPath());
Globals.assetManager.queueModelForDeletion(actor.getBaseModelPath());
}
}

View File

@ -11,8 +11,8 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderPipelineState;
import electrosphere.renderer.actor.ActorUniformMap;
import electrosphere.renderer.actor.ActorUniformMap.UniformValue;
import electrosphere.renderer.actor.mask.ActorUniformMap;
import electrosphere.renderer.actor.mask.ActorUniformMap.UniformValue;
import electrosphere.renderer.model.Material;
import electrosphere.renderer.model.Model;
import electrosphere.renderer.shader.VisualShader;

View File

@ -8,25 +8,35 @@ import java.util.List;
*/
public class ActorAnimationMask implements Comparable<ActorAnimationMask> {
//The priority of the mask
int priority;
/**
* The priority of the mask
*/
private int priority;
//The name of the animation
String animationName;
/**
* The name of the animation
*/
private String animationName;
//The current time of this mask
double time;
/**
* The current time of this mask
*/
private double time;
//The maximum time to play this mask for
double timeMax;
/**
* The maximum time to play this mask for
*/
private double timeMax;
//The mask of bones to apply this animation to
List<String> boneMask;
/**
* The mask of bones to apply this animation to
*/
private List<String> boneMask;
/**
* The number of frames to freeze this animation mask for
*/
int freezeFrames = 0;
private int freezeFrames = 0;
/**
* Constructor

View File

@ -19,30 +19,51 @@ public class ActorMeshMask {
//The map of base mesh name -> blocked status
//Ie "feet" -> true would mean that the base model feet should not be drawn
Map<String,Boolean> meshBlockerList = new HashMap<String,Boolean>();
//the list of meshes to draw that are stored in this object
//ie this would contain a mesh for boots
Map<String,Mesh> toDrawMesh = new HashMap<String,Mesh>();
/**
* The map of base mesh name -> blocked status
* <p>
* Ie "feet" -> true would mean that the base model feet should not be drawn
*/
private Map<String,Boolean> meshBlockerList = new HashMap<String,Boolean>();
//lock for queueing blockers
Semaphore queueLock = new Semaphore(1);
List<MeshDrawQueueItem> queuedMeshes = new LinkedList<MeshDrawQueueItem>();
List<MeshDrawQueueItem> queuedBlockers = new LinkedList<MeshDrawQueueItem>();
/**
* the list of meshes to draw that are stored in this object
* <p>
* ie this would contain a mesh for boots
*/
private Map<String,Mesh> toDrawMesh = new HashMap<String,Mesh>();
/**
* lock for queueing blockers
*/
private Semaphore queueLock = new Semaphore(1);
/**
* The set of queued meshes
*/
private List<MeshDrawQueueItem> queuedMeshes = new LinkedList<MeshDrawQueueItem>();
/**
* The set of queued blockers
*/
private List<MeshDrawQueueItem> queuedBlockers = new LinkedList<MeshDrawQueueItem>();
public ActorMeshMask(){
}
/**
* Quques a mesh
* @param modelName The model's name
* @param meshName The mesh's name
*/
public void queueMesh(String modelName, String meshName){
queueLock.acquireUninterruptibly();
queuedMeshes.add(new MeshDrawQueueItem(modelName, meshName));
queueLock.release();
}
/**
* Processes all items in the mesh mask queue
*/
public void processMeshMaskQueue(){
Model model;
Mesh mesh;
@ -79,14 +100,26 @@ public class ActorMeshMask {
}
}
/**
* Gets the list of meshes to draw
* @return The list of meshes to draw
*/
public List<Mesh> getToDrawMeshes(){
return toDrawMesh.values().stream().collect(Collectors.toList());
}
/**
* Ejects a mesh to draw
* @param name The mesh's name
*/
public void ejectMeshToDraw(String name){
toDrawMesh.remove(name);
}
/**
* Checks if the mesh mask is empty
* @return true if it is empty, false otherwise
*/
public boolean isEmpty(){
return toDrawMesh.size() > 0;
}
@ -103,24 +136,48 @@ public class ActorMeshMask {
//
//blocking interactions
//
/**
* Checks if this mesh mask contains a mesh by a given name which it should draw
* @param name The name of the mesh
* @return true if it should draw, false otherwise
*/
public boolean containsMeshToDraw(String name){
return toDrawMesh.containsKey(name);
}
/**
* Blocks a mesh from rendering
* @param modelName The name of the model
* @param meshName The name of the mesh
*/
public void blockMesh(String modelName, String meshName){
queueLock.acquireUninterruptibly();
queuedBlockers.add(new MeshDrawQueueItem(modelName, meshName));
queueLock.release();
}
/**
* Checks if a mesh is blocked from rendering
* @param name The name of the mesh
* @return true if it is blocked, false otherwise
*/
public boolean isBlockedMesh(String name){
return meshBlockerList.containsKey(name);
}
/**
* Unblocks a mesh from rendering
* @param name The name of the mesh
*/
public void unblockMesh(String name){
meshBlockerList.remove(name);
}
/**
* Gets the list of all meshes that are blocked
* @return The list of all meshes that are blocked
*/
public List<String> getBlockedMeshes(){
return meshBlockerList.keySet().stream().collect(Collectors.toList());
}
@ -132,21 +189,41 @@ public class ActorMeshMask {
* When a creature equips an item that would block a mesh, the mesh may not have already been loaded into memory.
* This represents an item in a queue that contains a mesh that should be eventually used to block a mesh on the parent actor.
*/
class MeshDrawQueueItem {
private class MeshDrawQueueItem {
String modelName;
String meshName;
/**
* The name of the model
*/
private String modelName;
MeshDrawQueueItem(String modelName, String meshName){
/**
* The name of the mesh
*/
private String meshName;
/**
* Constructor
* @param modelName Model name
* @param meshName Mesh name
*/
protected MeshDrawQueueItem(String modelName, String meshName){
this.modelName = modelName;
this.meshName = meshName;
}
/**
* Gets the name of the model
* @return The name of the model
*/
public String getModelName(){
return modelName;
}
/**
* Gets the name of the mesh
* @return The name of the mesh
*/
public String getMeshName(){
return meshName;
}

View File

@ -5,14 +5,25 @@ package electrosphere.renderer.actor.mask;
*/
public class ActorShaderMask {
//the model name
String modelName;
//the mesh name
String meshName;
//the vertex shader
String vertexShaderPath;
//the fragment shader
String fragmentShaderPath;
/**
* The name of the model
*/
private String modelName;
/**
* The name of the mesh to apply the shader to
*/
private String meshName;
/**
* The vertex shader's path
*/
private String vertexShaderPath;
/**
* The fragment shader's path
*/
private String fragmentShaderPath;
/**
* Constructor

View File

@ -12,22 +12,22 @@ public class ActorTextureMask {
/**
* The mesh this mask is overwriting
*/
String meshName;
private String meshName;
/**
* The texture objects used for this mask
*/
List<Texture> textures;
private List<Texture> textures;
/**
* The paths to textures to be used for this mask
*/
List<String> texturePaths;
private List<String> texturePaths;
/**
* The uniform names used for this mask
*/
List<String> uniformNames;
private List<String> uniformNames;
/**
* Constructor

View File

@ -1,4 +1,4 @@
package electrosphere.renderer.actor;
package electrosphere.renderer.actor.mask;
import java.util.HashMap;
import java.util.LinkedList;

View File

@ -85,6 +85,7 @@ public class Model {
* The root animation node
*/
private AnimNode rootAnimNode;
/**
* The map of animation node name -> node
*/
@ -100,7 +101,6 @@ public class Model {
*/
private Map<String,Animation> animMap = new HashMap<String,Animation>();
/**
* A mask that overwrites meshes themsselves
*/

View File

@ -80,7 +80,7 @@ public class DrawTargetEvaluator {
double dist = posVec.distance(cameraCenter);
//evaluate LOD level
if(currentActor.getLowResPath() != null){
if(currentActor.getLowResBaseModelPath() != null){
if(dist < LOD_LOWER_CUTOFF){
currentActor.setLodLevel(Actor.LOD_LEVEL_FULL);
} else if(dist < LOD_STATIC_CUTOFF) {
@ -104,13 +104,13 @@ public class DrawTargetEvaluator {
if(currentActor.frustumTest(Globals.renderingEngine.getRenderPipelineState(), modelTransformMatrix.getTranslation(posVec))){
//queue for batching
if(MainContentPipeline.shouldDrawSolidPass(currentEntity)){
mainAccumulator.addCall(currentActor.getModelPath(), position, modelTransformMatrix);
mainAccumulator.addCall(currentActor.getBaseModelPath(), position, modelTransformMatrix);
}
if(dist < ShadowMapPipeline.DRAW_CUTOFF_DIST && shadowList.contains(currentEntity)){
shadowAccumulator.addCall(currentActor.getModelPath(), position, modelTransformMatrix);
shadowAccumulator.addCall(currentActor.getBaseModelPath(), position, modelTransformMatrix);
}
if(dist < NormalsForOutlinePipeline.DRAW_CUTOFF_DIST && NormalsForOutlinePipeline.shouldDraw(currentEntity)){
normalAccumulator.addCall(currentActor.getModelPath(), position, modelTransformMatrix);
normalAccumulator.addCall(currentActor.getBaseModelPath(), position, modelTransformMatrix);
}
}
} else if(TerrainChunk.isBlockEntity(currentEntity)){

View File

@ -224,7 +224,7 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme
GL40.glClear(GL40.GL_COLOR_BUFFER_BIT | GL40.GL_DEPTH_BUFFER_BIT);
Model actorModel = Globals.assetManager.fetchModel(actor.getModelPath());
Model actorModel = Globals.assetManager.fetchModel(actor.getBaseModelPath());
if(currentAnim != null){
if((!actor.isPlayingAnimation() || !actor.isPlayingAnimation(currentAnim)) &&
actorModel != null &&