documentation
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-04-21 18:02:13 -04:00
parent a1d03ef59e
commit 172030b95d
7 changed files with 101 additions and 59 deletions

View File

@ -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

View File

@ -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();

View File

@ -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<InventoryMessage> networkMessageQueue = new CopyOnWriteArrayList<InventoryMessage>();
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,16 +46,16 @@ 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:
case InventoryProtocol.INVENTORY_TYPE_EQUIP: {
Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId());
boolean isInventoryItem = ItemUtils.itemIsInInventory(target);
boolean parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent);
@ -73,13 +69,13 @@ public class InventoryState implements BehaviorTree {
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();
} 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
@ -88,12 +84,11 @@ public class InventoryState implements BehaviorTree {
naturalInventory.addItem(target);
equipInventory.removeItemSlot(equipPointId);
}
break;
} 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

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}