diff --git a/docs/src/rendering/actors/meshmask.md b/docs/src/rendering/actors/meshmask.md index 6b3499dc..db85597a 100644 --- a/docs/src/rendering/actors/meshmask.md +++ b/docs/src/rendering/actors/meshmask.md @@ -1,5 +1,44 @@ @page meshmask Mesh Mask -TODO +# High Level Overview +The actor mesh mask primarily keeps track of two lists: + - A list of all meshes within the original model of the actor that SHOULD NOT be drawn + - A list of meshes that are NOT within the original model that SHOULD be drawn +By its very nature, this class is only client facing + +# Relevant Classes + +[ActorMeshMask.java](@ref #electrosphere.renderer.actor.ActorMeshMask) - The main class concerned with here. Essentially just an object that holds data. Does not perform complex operations. + +[Actor.java](@ref #electrosphere.renderer.actor.Actor) - Utilizes the ActorMeskMask object while doing the main render call to determine what meshes to draw/not draw. + +[ClientEquipState.java](@ref #electrosphere.entity.state.equip.ClientEquipState) - Behavior Tree that performs operations on ActorMeshMask for item equip/dequip. +Particularly look at the methods `clientAttemptEquip` and `clientTransformUnequipPoint`. + + +# Architecture Notes +When modifying the mesh mask, you are actually queueing changes. Because the new meshes to draw may not already be in memory, they sit in a queue until asset manager gets to them. + +# Usage +## Turning off a mesh on an actor +``` +//loop through the Mesh Mask and turn off the meshes (by name) +ActorMeshMask meshMask = parentActor.getMeshMask(); +for(String toBlock : whitelistItem.getMeshMaskList()){ + meshMask.blockMesh(modelName, toBlock); +} +``` + + +## Drawing a mesh on an actor +``` +//make sure to queue the model in asset manager so we eventually load the mesh to draw +String modelName = whitelistItem.getModel(); +Globals.assetManager.addModelPathToQueue(modelName); +//loop through the Mesh Mask and add the mesh names that we want to draw +ActorMeshMask meshMask = parentActor.getMeshMask(); +for(String toDraw : whitelistItem.getMeshList()){ + meshMask.queueMesh(modelName, toDraw); +} +``` -use example: overwriting a mesh without clothing to one with clothing \ No newline at end of file diff --git a/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java b/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java index 55d3f855..cda3ce18 100644 --- a/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java +++ b/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java @@ -63,6 +63,11 @@ public class ClientEquipState { } } + /** + * Performs the actual logic to term meshes on/off when equpping an item + * @param toEquip The entity to equip + * @param point The equipment point to equip to + */ public void clientAttemptEquip(Entity toEquip, EquipPoint point){ boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId()); boolean targetIsItem = ItemUtils.isItem(toEquip); @@ -223,6 +228,10 @@ public class ClientEquipState { } } + /** + * Performs the actual logic to turn meshes on/off when unequipping an item + * @param pointId The equipment point to unequip + */ public void clientTransformUnequipPoint(String pointId){ Entity equipped = equipMap.remove(pointId); if(equipped != null){ @@ -234,7 +243,6 @@ public class ClientEquipState { for(EquipWhitelist whitelistItem : whitelist){ if(whitelistItem.getCreatureId().equals(parentCreatureId)){ //put in map - String modelName = whitelistItem.getModel(); Actor parentActor = EntityUtils.getActor(parent); //queue meshes from display model to parent actor ActorMeshMask meshMask = parentActor.getMeshMask(); diff --git a/src/main/java/electrosphere/entity/state/inventory/InventoryState.java b/src/main/java/electrosphere/entity/state/inventory/ClientInventoryState.java similarity index 55% rename from src/main/java/electrosphere/entity/state/inventory/InventoryState.java rename to src/main/java/electrosphere/entity/state/inventory/ClientInventoryState.java index a9940767..fd129813 100644 --- a/src/main/java/electrosphere/entity/state/inventory/InventoryState.java +++ b/src/main/java/electrosphere/entity/state/inventory/ClientInventoryState.java @@ -8,29 +8,25 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.types.item.ItemUtils; -import electrosphere.game.data.creature.type.equip.EquipPoint; -import electrosphere.menu.WindowStrings; import electrosphere.menu.WindowUtils; import electrosphere.net.parser.net.message.InventoryMessage; import electrosphere.net.server.protocol.InventoryProtocol; -import electrosphere.server.datacell.utils.EntityLookupUtils; -import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils; /** * Principally used to handle network messages related to inventory and thread synchronization */ -public class InventoryState implements BehaviorTree { +public class ClientInventoryState implements BehaviorTree { CopyOnWriteArrayList networkMessageQueue = new CopyOnWriteArrayList(); Entity parent; - InventoryState() { + ClientInventoryState() { } - public static InventoryState clientCreateInventoryState(Entity parent){ - InventoryState rVal = new InventoryState(); + public static ClientInventoryState clientCreateInventoryState(Entity parent){ + ClientInventoryState rVal = new ClientInventoryState(); rVal.parent = parent; Globals.clientSceneWrapper.getScene().registerBehaviorTree(rVal); return rVal; @@ -41,7 +37,7 @@ public class InventoryState implements BehaviorTree { for(InventoryMessage message : networkMessageQueue){ networkMessageQueue.remove(message); switch(message.getMessageSubtype()){ - case ADDITEMTOINVENTORY: + case ADDITEMTOINVENTORY: { //the ID we get is of the in-inventory item Entity inInventorySpawnedItem = InventoryUtils.clientConstructInInventoryItem(parent,message.getitemTemplate()); //map id @@ -50,50 +46,49 @@ public class InventoryState implements BehaviorTree { } //attempt re-render ui WindowUtils.attemptRedrawInventoryWindows(); - break; - case REMOVEITEMFROMINVENTORY: + } break; + case REMOVEITEMFROMINVENTORY: { InventoryUtils.removeItemFromInventories(parent, Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId())); //attempt re-render ui WindowUtils.attemptRedrawInventoryWindows(); - break; + } break; case SERVERCOMMANDMOVEITEMCONTAINER: { //this is a command to switch an item from one inventory to another (ie equip->natural or vice-versa) switch(message.getcontainerType()){ - case InventoryProtocol.INVENTORY_TYPE_EQUIP: - Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()); - boolean isInventoryItem = ItemUtils.itemIsInInventory(target); - boolean parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent); - boolean parentHasEquipInventory = InventoryUtils.hasEquipInventory(parent); - String equipPointId = message.getequipPointId(); - //check that we can do the transform - if(isInventoryItem && parentHasEquipInventory && parentHasNaturalInventory){ - //switch containers - UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent); - RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent); - naturalInventory.removeItem(target); - equipInventory.addItem(equipPointId, target); - } - break; - case InventoryProtocol.INVENTORY_TYPE_NATURAL: - target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()); - isInventoryItem = ItemUtils.itemIsInInventory(target); - parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent); - parentHasEquipInventory = InventoryUtils.hasEquipInventory(parent); - equipPointId = message.getequipPointId(); - //check that we can do the transform - if(isInventoryItem && parentHasEquipInventory && parentHasNaturalInventory){ - //switch containers - UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent); - RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent); - naturalInventory.addItem(target); - equipInventory.removeItemSlot(equipPointId); - } - break; + case InventoryProtocol.INVENTORY_TYPE_EQUIP: { + Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()); + boolean isInventoryItem = ItemUtils.itemIsInInventory(target); + boolean parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent); + boolean parentHasEquipInventory = InventoryUtils.hasEquipInventory(parent); + String equipPointId = message.getequipPointId(); + //check that we can do the transform + if(isInventoryItem && parentHasEquipInventory && parentHasNaturalInventory){ + //switch containers + UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent); + RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent); + naturalInventory.removeItem(target); + equipInventory.addItem(equipPointId, target); + } + } break; + case InventoryProtocol.INVENTORY_TYPE_NATURAL: { + Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()); + boolean isInventoryItem = ItemUtils.itemIsInInventory(target); + boolean parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent); + boolean parentHasEquipInventory = InventoryUtils.hasEquipInventory(parent); + String equipPointId = message.getequipPointId(); + //check that we can do the transform + if(isInventoryItem && parentHasEquipInventory && parentHasNaturalInventory){ + //switch containers + UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent); + RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent); + naturalInventory.addItem(target); + equipInventory.removeItemSlot(equipPointId); + } + } break; } //once we've switched the items around, redraw the inventory to reflect the updated contents WindowUtils.attemptRedrawInventoryWindows(); - } - break; + } break; case SERVERCOMMANDUNEQUIPITEM: { if(Globals.playerEntity != null && ClientEquipState.hasEquipState(Globals.playerEntity)){ //unequip the item diff --git a/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java b/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java index 626562f7..8c43b816 100644 --- a/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java +++ b/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java @@ -47,8 +47,8 @@ public class InventoryUtils { * @param target the entity to get inventory state from * @return The inventory state behavior tree or null */ - public static InventoryState clientGetInventoryState(Entity target){ - return (InventoryState)target.getData(EntityDataStrings.CLIENT_INVENTORY_STATE); + public static ClientInventoryState clientGetInventoryState(Entity target){ + return (ClientInventoryState)target.getData(EntityDataStrings.CLIENT_INVENTORY_STATE); } /** @@ -65,7 +65,7 @@ public class InventoryUtils { * @param target The entity to attach inventory state to * @param state The inventory state to attach */ - public static void clientSetInventoryState(Entity target, InventoryState state){ + public static void clientSetInventoryState(Entity target, ClientInventoryState state){ target.putData(EntityDataStrings.CLIENT_INVENTORY_STATE, state); } diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java index b1ec00b0..5d7e86ae 100644 --- a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java +++ b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java @@ -31,7 +31,7 @@ import electrosphere.entity.state.gravity.ClientGravityTree; import electrosphere.entity.state.gravity.ServerGravityTree; import electrosphere.entity.state.idle.IdleTree; import electrosphere.entity.state.idle.ServerIdleTree; -import electrosphere.entity.state.inventory.InventoryState; +import electrosphere.entity.state.inventory.ClientInventoryState; import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.state.inventory.RelationalInventoryState; import electrosphere.entity.state.inventory.ServerInventoryState; @@ -273,7 +273,7 @@ public class CreatureUtils { break; case "INVENTORY": rVal.putData(EntityDataStrings.NATURAL_INVENTORY,UnrelationalInventoryState.createUnrelationalInventory(10)); - InventoryUtils.clientSetInventoryState(rVal, InventoryState.clientCreateInventoryState(rVal)); + InventoryUtils.clientSetInventoryState(rVal, ClientInventoryState.clientCreateInventoryState(rVal)); break; case "OUTLINE": rVal.putData(EntityDataStrings.DRAW_OUTLINE, true); diff --git a/src/main/java/electrosphere/entity/types/object/ObjectUtils.java b/src/main/java/electrosphere/entity/types/object/ObjectUtils.java index b7b6257a..307d35fb 100644 --- a/src/main/java/electrosphere/entity/types/object/ObjectUtils.java +++ b/src/main/java/electrosphere/entity/types/object/ObjectUtils.java @@ -23,7 +23,7 @@ import electrosphere.entity.state.collidable.ServerCollidableTree; import electrosphere.entity.state.gravity.ClientGravityTree; import electrosphere.entity.state.gravity.ServerGravityTree; import electrosphere.entity.state.idle.IdleTree; -import electrosphere.entity.state.inventory.InventoryState; +import electrosphere.entity.state.inventory.ClientInventoryState; import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.state.inventory.ServerInventoryState; import electrosphere.entity.state.inventory.UnrelationalInventoryState; @@ -102,7 +102,7 @@ public class ObjectUtils { break; case "INVENTORY": rVal.putData(EntityDataStrings.NATURAL_INVENTORY,UnrelationalInventoryState.createUnrelationalInventory(10)); - InventoryUtils.clientSetInventoryState(rVal, InventoryState.clientCreateInventoryState(rVal)); + InventoryUtils.clientSetInventoryState(rVal, ClientInventoryState.clientCreateInventoryState(rVal)); break; case "OUTLINE": rVal.putData(EntityDataStrings.DRAW_OUTLINE, true); diff --git a/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java b/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java index 5c528ded..083054d3 100644 --- a/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java @@ -3,7 +3,7 @@ package electrosphere.net.client.protocol; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.state.equip.ClientEquipState; -import electrosphere.entity.state.inventory.InventoryState; +import electrosphere.entity.state.inventory.ClientInventoryState; import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.data.creature.type.equip.EquipPoint; @@ -16,7 +16,7 @@ public class InventoryProtocol { case ADDITEMTOINVENTORY: LoggerInterface.loggerNetworking.DEBUG("[CLIENT] ADD ITEM TO INVENTORY " + message.getentityId()); if(Globals.playerEntity != null){ - InventoryState inventoryState; + ClientInventoryState inventoryState; if((inventoryState = InventoryUtils.clientGetInventoryState(Globals.playerEntity))!=null){ inventoryState.addNetworkMessage(message); } @@ -45,7 +45,7 @@ public class InventoryProtocol { case REMOVEITEMFROMINVENTORY: LoggerInterface.loggerNetworking.DEBUG("[CLIENT] REMOVE ITEM FROM INVENTORY " + message.getentityId()); if(Globals.playerEntity != null){ - InventoryState inventoryState; + ClientInventoryState inventoryState; if((inventoryState = InventoryUtils.clientGetInventoryState(Globals.playerEntity))!=null){ inventoryState.addNetworkMessage(message); } @@ -54,7 +54,7 @@ public class InventoryProtocol { case SERVERCOMMANDMOVEITEMCONTAINER: LoggerInterface.loggerNetworking.DEBUG("[CLIENT] MOVE ITEM INVENTORY " + message.getentityId()); if(Globals.playerEntity != null){ - InventoryState inventoryState; + ClientInventoryState inventoryState; if((inventoryState = InventoryUtils.clientGetInventoryState(Globals.playerEntity))!=null){ inventoryState.addNetworkMessage(message); } @@ -63,7 +63,7 @@ public class InventoryProtocol { case SERVERCOMMANDUNEQUIPITEM: { LoggerInterface.loggerNetworking.DEBUG("[CLIENT] UNEQUIP ITEM " + message.getentityId()); if(Globals.playerEntity != null){ - InventoryState inventoryState; + ClientInventoryState inventoryState; if((inventoryState = InventoryUtils.clientGetInventoryState(Globals.playerEntity))!=null){ inventoryState.addNetworkMessage(message); }