diff --git a/assets/Data/creatures.json b/assets/Data/creatures.json index 21d65290..589f2344 100644 --- a/assets/Data/creatures.json +++ b/assets/Data/creatures.json @@ -5,7 +5,7 @@ { - "name" : "Human", + "creatureId" : "human", "bodyParts" : [ { "name" : "Head", @@ -197,7 +197,7 @@ { - "name" : "Goblin", + "creatureId" : "goblin", "bodyParts" : [ { "name" : "Head", @@ -350,7 +350,7 @@ { - "name" : "CUBE_MAN", + "creatureId" : "CUBE_MAN", "bodyParts" : [ { "name" : "CUBE", @@ -400,7 +400,7 @@ { - "name" : "Deer", + "creatureId" : "Deer", "bodyParts" : [ { "name" : "Head", diff --git a/assets/Data/items.json b/assets/Data/items.json index 7ac203a2..313d38b3 100644 --- a/assets/Data/items.json +++ b/assets/Data/items.json @@ -4,7 +4,7 @@ { - "name" : "Katana", + "itemId" : "Katana", "modelPath" : "Models/katana1alt.fbx", "hitboxes" : [ { @@ -30,6 +30,7 @@ "MELEE", "TARGETABLE" ], + "idleAnim" : "Sword|Idle", "collidable": { "type" : "CUBE", "dimension1" : 0.1, @@ -41,7 +42,7 @@ } }, { - "name" : "Bow", + "itemId" : "Bow", "modelPath": "Models/bow1.fbx", "tokens" : [ "GRAVITY", @@ -58,6 +59,37 @@ "offsetY" : 0.05, "offsetZ" : 0 } + }, + + { + "itemId" : "shorts1", + "modelPath": "Models/itemEntityShorts.fbx", + "tokens" : [ + "GRAVITY", + "ARMOR", + "TARGETABLE" + ], + "collidable": { + "type" : "CUBE", + "dimension1" : 0.1, + "dimension2" : 0.1, + "dimension3" : 0.35, + "offsetX" : 0, + "offsetY" : 0.05, + "offsetZ" : 0 + }, + "equipWhitelist" : [ + { + "creatureId" : "human", + "model" : "Models/shorts1.fbx", + "meshList" : [ + "ClothingItem" + ], + "meshMaskList" : [ + "Shorts" + ] + } + ] } diff --git a/assets/Data/races.json b/assets/Data/races.json index c3540e4d..e3f549f9 100644 --- a/assets/Data/races.json +++ b/assets/Data/races.json @@ -1,8 +1,9 @@ { "raceMap" : [ { - "name" : "Human", - "associatedCreature" : "Human" + "raceId" : "human", + "displayName" : "Human", + "associatedCreatureId" : "human" } ] } \ No newline at end of file diff --git a/assets/Models/baseman.fbx b/assets/Models/baseman.fbx index f8b348eb..0628ab46 100644 Binary files a/assets/Models/baseman.fbx and b/assets/Models/baseman.fbx differ diff --git a/assets/Models/itemEntityShorts.fbx b/assets/Models/itemEntityShorts.fbx new file mode 100644 index 00000000..446ded09 Binary files /dev/null and b/assets/Models/itemEntityShorts.fbx differ diff --git a/assets/Models/shorts1.fbx b/assets/Models/shorts1.fbx new file mode 100644 index 00000000..f73a858d Binary files /dev/null and b/assets/Models/shorts1.fbx differ diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java index ef373b67..15367f41 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -518,7 +518,7 @@ public class ControlHandler { controls.get(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM).setState(true); } else { if(controls.get(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM).isState() == true){ - Entity bow = ItemUtils.spawnBasicItem("Katana"); + Entity bow = ItemUtils.spawnBasicItem("shorts1"); EntityUtils.getPosition(bow).set(1, 5, 2); CollisionObjUtils.positionCharacter(bow, new Vector3f(1, 5, 2)); } diff --git a/src/main/java/electrosphere/engine/LoadingThread.java b/src/main/java/electrosphere/engine/LoadingThread.java index 8d704a81..6da12331 100644 --- a/src/main/java/electrosphere/engine/LoadingThread.java +++ b/src/main/java/electrosphere/engine/LoadingThread.java @@ -615,7 +615,7 @@ public class LoadingThread extends Thread { // ActorUtils.applyBlenderTransformer(building); //spawn evil goblin - Entity goblin = CreatureUtils.spawnBasicCreature("Goblin"); + Entity goblin = CreatureUtils.spawnBasicCreature("goblin"); CollisionObjUtils.positionCharacter(goblin, new Vector3f(4, 0, 4)); EntityUtils.getScale(goblin).set(0.005f); // //give evil goblin sword diff --git a/src/main/java/electrosphere/entity/EntityDataStrings.java b/src/main/java/electrosphere/entity/EntityDataStrings.java index 60a24489..65560ecc 100644 --- a/src/main/java/electrosphere/entity/EntityDataStrings.java +++ b/src/main/java/electrosphere/entity/EntityDataStrings.java @@ -74,6 +74,11 @@ public class EntityDataStrings { public static final String DATA_STRING_LIGHT_CUTOFF = "lightCutoff"; public static final String DATA_STRING_LIGHT_CUTOFF_OUTER = "lightCutoffOuter"; + /* + Anim related + */ + public static final String ANIM_IDLE = "animIdle"; + /* UI Entity */ @@ -135,6 +140,8 @@ public class EntityDataStrings { public static final String ITEM_IS_ITEM = "itemIsItem"; public static final String ITEM_TYPE = "itemType"; public static final String ITEM_IS_WEAPON = "itemIsWeapon"; + public static final String ITEM_IS_ARMOR = "itemIsArmor"; + public static final String ITEM_EQUIP_WHITELIST = "itemEquipWhitelist"; /* diff --git a/src/main/java/electrosphere/entity/EntityUtils.java b/src/main/java/electrosphere/entity/EntityUtils.java index 20dafd28..b73c4b6c 100644 --- a/src/main/java/electrosphere/entity/EntityUtils.java +++ b/src/main/java/electrosphere/entity/EntityUtils.java @@ -99,5 +99,13 @@ public class EntityUtils { public static void setVisible(Entity entity, boolean visible){ entity.putData(EntityDataStrings.DATA_STRING_DRAW, visible); } + + public static void setDraw(Entity entity, boolean draw){ + entity.putData(EntityDataStrings.DATA_STRING_DRAW, draw); + } + + public static boolean getDraw(Entity entity){ + return (boolean)entity.getData(EntityDataStrings.DATA_STRING_DRAW); + } } diff --git a/src/main/java/electrosphere/entity/state/equip/EquipState.java b/src/main/java/electrosphere/entity/state/equip/EquipState.java index 8cfa0d80..1fd82422 100644 --- a/src/main/java/electrosphere/entity/state/equip/EquipState.java +++ b/src/main/java/electrosphere/entity/state/equip/EquipState.java @@ -1,14 +1,21 @@ package electrosphere.entity.state.equip; +import java.util.List; + import electrosphere.collision.dispatch.CollisionObject; import electrosphere.dynamics.RigidBody; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityUtils; import electrosphere.entity.types.attach.AttachUtils; +import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.client.targeting.crosshair.Crosshair; import electrosphere.game.collision.collidable.Collidable; +import electrosphere.game.data.item.type.EquipWhitelist; import electrosphere.main.Globals; +import electrosphere.renderer.actor.Actor; +import electrosphere.renderer.actor.ActorMeshMask; /** * @@ -41,13 +48,46 @@ public class EquipState { public void attemptEquip(Entity toEquip){ if(!hasEquipPrimary() && ItemUtils.isItem(toEquip) && !AttachUtils.isAttached(toEquip)){ - equipPrimary = toEquip; - AttachUtils.attachEntityToEntityAtBone(parent, toEquip, equipPrimaryBoneName); - if(toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLIDABLE)){ - CollisionObject rigidBody = (CollisionObject)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); - Globals.collisionEngine.deregisterPhysicsObject(rigidBody); + if(ItemUtils.hasEquipList(toEquip)){ + String parentCreatureId = CreatureUtils.getType(parent); + List whitelist = ItemUtils.getEquipWhitelist(toEquip); + for(EquipWhitelist whitelistItem : whitelist){ + if(whitelistItem.getCreatureId().equals(parentCreatureId)){ + equipPrimary = toEquip; + String modelName = whitelistItem.getModel(); + Globals.assetManager.addModelPathToQueue(modelName); + Actor parentActor = EntityUtils.getActor(parent); + //queue meshes from display model to parent actor + ActorMeshMask meshMask = parentActor.getMeshMask(); + for(String toBlock : whitelistItem.getMeshMaskList()){ + meshMask.blockMesh(modelName, toBlock); + } + for(String toDraw : whitelistItem.getMeshList()){ + meshMask.queueMesh(modelName, toDraw); + } + //attach to parent bone + AttachUtils.attachEntityToEntityAtBone(parent, toEquip, equipPrimaryBoneName); + //make uncollidable + if(toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLIDABLE)){ + CollisionObject rigidBody = (CollisionObject)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); + Globals.collisionEngine.deregisterPhysicsObject(rigidBody); + } + //hide toEquip actor + EntityUtils.setDraw(toEquip, false); + //make untargetable + Globals.entityManager.setTargetable(equipPrimary, false); + break; + } + } + } else { + equipPrimary = toEquip; + AttachUtils.attachEntityToEntityAtBone(parent, toEquip, equipPrimaryBoneName); + if(toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLIDABLE)){ + CollisionObject rigidBody = (CollisionObject)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); + Globals.collisionEngine.deregisterPhysicsObject(rigidBody); + } + Globals.entityManager.setTargetable(equipPrimary, false); } - Globals.entityManager.setTargetable(equipPrimary, false); } } diff --git a/src/main/java/electrosphere/entity/types/item/ItemUtils.java b/src/main/java/electrosphere/entity/types/item/ItemUtils.java index 602999d5..417e12c5 100644 --- a/src/main/java/electrosphere/entity/types/item/ItemUtils.java +++ b/src/main/java/electrosphere/entity/types/item/ItemUtils.java @@ -14,6 +14,7 @@ import electrosphere.game.collision.PhysicsUtils; import electrosphere.game.collision.collidable.Collidable; import electrosphere.game.data.creature.type.CollidableTemplate; import electrosphere.game.data.creature.type.CreatureType; +import electrosphere.game.data.item.type.EquipWhitelist; import electrosphere.game.data.item.type.Item; import electrosphere.main.Globals; import electrosphere.net.parser.net.message.EntityMessage; @@ -23,6 +24,8 @@ import electrosphere.renderer.Model; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorUtils; +import java.util.List; + import org.joml.Quaternionf; import org.joml.Vector3d; import org.joml.Vector3f; @@ -93,8 +96,17 @@ public class ItemUtils { case "WEAPON": rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true); break; + case "ARMOR": + rVal.putData(EntityDataStrings.ITEM_IS_ARMOR, true); + break; } } + if(item.getEquipWhitelist() != null){ + rVal.putData(EntityDataStrings.ITEM_EQUIP_WHITELIST, item.getEquipWhitelist()); + } + if(item.getIdleAnim() != null){ + rVal.putData(EntityDataStrings.ANIM_IDLE,item.getIdleAnim()); + } rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true); rVal.putData(EntityDataStrings.ITEM_IS_ITEM, true); rVal.putData(EntityDataStrings.ITEM_TYPE, name); @@ -131,12 +143,11 @@ public class ItemUtils { public static void updateItemActorAnimation(Entity item){ Actor actor = EntityUtils.getActor(item); - if(!actor.isPlayingAnimation("Sword|Idle")){ -// Model model; -// if((model = Globals.assetManager.fetchModel(actor.getModelPath()))!=null){ -// model.describeAllAnimations(); -// } - actor.playAnimation("Sword|Idle",1); + if(item.getData(EntityDataStrings.ANIM_IDLE) != null){ + String idleAnim = (String)item.getData(EntityDataStrings.ANIM_IDLE); + if(!actor.isPlayingAnimation(idleAnim)){ + actor.playAnimation(idleAnim,1); + } } } @@ -168,4 +179,17 @@ public class ItemUtils { public static boolean isWeapon(Entity item){ return item.getDataKeys().contains(EntityDataStrings.ITEM_IS_WEAPON); } + + public static boolean isArmor(Entity item){ + return item.getDataKeys().contains(EntityDataStrings.ITEM_IS_ARMOR); + } + + public static boolean hasEquipList(Entity item){ + return item.getDataKeys().contains(EntityDataStrings.ITEM_EQUIP_WHITELIST); + } + + public static List getEquipWhitelist(Entity item){ + return (List)item.getData(EntityDataStrings.ITEM_EQUIP_WHITELIST); + } + } diff --git a/src/main/java/electrosphere/game/data/creature/type/CreatureType.java b/src/main/java/electrosphere/game/data/creature/type/CreatureType.java index b0a7e22c..50babb54 100644 --- a/src/main/java/electrosphere/game/data/creature/type/CreatureType.java +++ b/src/main/java/electrosphere/game/data/creature/type/CreatureType.java @@ -6,7 +6,7 @@ import electrosphere.game.data.creature.type.rotator.RotatorSystem; import java.util.List; public class CreatureType { - String name; + String creatureId; List bodyParts; List hitboxes; List tokens; @@ -18,8 +18,8 @@ public class CreatureType { LookAtSystem lookAtSystem; String modelPath; - public String getName() { - return name; + public String getCreatureId() { + return creatureId; } public List getBodyParts() { diff --git a/src/main/java/electrosphere/game/data/creature/type/model/CreatureTypeMap.java b/src/main/java/electrosphere/game/data/creature/type/model/CreatureTypeMap.java index 5a196089..cd148c56 100644 --- a/src/main/java/electrosphere/game/data/creature/type/model/CreatureTypeMap.java +++ b/src/main/java/electrosphere/game/data/creature/type/model/CreatureTypeMap.java @@ -10,7 +10,7 @@ public class CreatureTypeMap { public CreatureType getCreature(String name){ CreatureType rVal = null; for(CreatureType type : creatures){ - if(type.getName().equals(name)){ + if(type.getCreatureId().equals(name)){ rVal = type; break; } diff --git a/src/main/java/electrosphere/game/data/item/type/EquipWhitelist.java b/src/main/java/electrosphere/game/data/item/type/EquipWhitelist.java new file mode 100644 index 00000000..880b2393 --- /dev/null +++ b/src/main/java/electrosphere/game/data/item/type/EquipWhitelist.java @@ -0,0 +1,28 @@ +package electrosphere.game.data.item.type; + +import java.util.List; + +public class EquipWhitelist { + + String creatureId; + String model; + List meshList; + List meshMaskList; + + public String getCreatureId(){ + return creatureId; + } + + public String getModel(){ + return model; + } + + public List getMeshList(){ + return meshList; + } + + public List getMeshMaskList(){ + return meshMaskList; + } + +} diff --git a/src/main/java/electrosphere/game/data/item/type/Item.java b/src/main/java/electrosphere/game/data/item/type/Item.java index d86cbda8..8ff8d26d 100644 --- a/src/main/java/electrosphere/game/data/item/type/Item.java +++ b/src/main/java/electrosphere/game/data/item/type/Item.java @@ -5,14 +5,17 @@ import electrosphere.game.data.creature.type.CollidableTemplate; import java.util.List; public class Item { - String name; + + String itemId; String modelPath; List hitboxes; List tokens; CollidableTemplate collidable; + List equipWhitelist; + String idleAnim; - public String getName() { - return name; + public String getItemId() { + return itemId; } public String getModelPath() { @@ -30,6 +33,14 @@ public class Item { public CollidableTemplate getCollidable(){ return collidable; } + + public List getEquipWhitelist(){ + return equipWhitelist; + } + + public String getIdleAnim(){ + return idleAnim; + } } diff --git a/src/main/java/electrosphere/game/data/item/type/model/ItemTypeMap.java b/src/main/java/electrosphere/game/data/item/type/model/ItemTypeMap.java index 3102db1d..10d90a4b 100644 --- a/src/main/java/electrosphere/game/data/item/type/model/ItemTypeMap.java +++ b/src/main/java/electrosphere/game/data/item/type/model/ItemTypeMap.java @@ -13,7 +13,7 @@ public class ItemTypeMap { public Item getItem(String name){ Item rVal = null; for(Item item : items){ - if(item.getName().equals(name)){ + if(item.getItemId().equals(name)){ rVal = item; break; } diff --git a/src/main/java/electrosphere/net/server/ServerConnectionHandler.java b/src/main/java/electrosphere/net/server/ServerConnectionHandler.java index 8670a67e..37b7c3f0 100644 --- a/src/main/java/electrosphere/net/server/ServerConnectionHandler.java +++ b/src/main/java/electrosphere/net/server/ServerConnectionHandler.java @@ -97,7 +97,7 @@ public class ServerConnectionHandler implements Runnable { Player newPlayerObject = new Player(this); Globals.playerManager.addPlayer(newPlayerObject); //spawn player in world - Entity newPlayerCharacter = CreatureUtils.spawnBasicCreature("Human"); + Entity newPlayerCharacter = CreatureUtils.spawnBasicCreature("human"); playerCharacterID = newPlayerCharacter.getId(); CollisionObjUtils.positionCharacter(newPlayerCharacter, new Vector3f(Globals.spawnPoint.x,Globals.spawnPoint.y,Globals.spawnPoint.z)); //attach player object to player character diff --git a/src/main/java/electrosphere/renderer/Mesh.java b/src/main/java/electrosphere/renderer/Mesh.java index 51ef5484..401618bc 100644 --- a/src/main/java/electrosphere/renderer/Mesh.java +++ b/src/main/java/electrosphere/renderer/Mesh.java @@ -50,6 +50,9 @@ import static org.lwjgl.opengl.GL30.glGenVertexArrays; * @author satellite */ public class Mesh { + + //THIS IS NOT GUARANTEED TO BE THE PARENT MODEL THAT THIS WAS LOADED IN + //THIS CAN BE POST-LOAD SET IN MODEL VIA MODELMASK BEHAVIOR public Model parent; public String nodeID; public AIMesh mesh; @@ -66,14 +69,16 @@ public class Mesh { public int boneCount; public int textureCoordBuffer; public int textureCoordCount; - public ArrayList bones = new ArrayList(); - public ArrayList bone_id_list = new ArrayList(); - HashMap uniforms = new HashMap(); + //THIS IS NOT GUARANTEED TO BE THE PARENT MODEL THAT THIS WAS LOADED IN + //THIS CAN BE POST-LOAD SET IN MODEL VIA MODELMASK BEHAVIOR + public ArrayList bones = new ArrayList(); + public ArrayList bone_id_list = new ArrayList(); + HashMap uniforms = new HashMap(); int bone_map_size = 0; boolean hasBones = true; public boolean hasTextureCoords = true; - public List textureList = new ArrayList(); + public List textureList = new ArrayList(); public boolean useTextureList; public String textureListArrayUniformName; @@ -285,7 +290,7 @@ public class Mesh { currentBone.boneID = currentBoneData.mName().dataString(); currentBone.inverseBindPoseMatrix = electrosphere.util.Utilities.convertAIMatrix(currentBoneData.mOffsetMatrix()); currentBone.numWeights = currentBoneData.mNumWeights(); - currentBone.weights = new HashMap(); + currentBone.weights = new HashMap(); Iterator weightIterator = currentBoneData.mWeights().iterator(); while(weightIterator.hasNext()){ AIVertexWeight currentWeightData = weightIterator.next(); @@ -707,7 +712,15 @@ public class Mesh { } - public void complexDraw(boolean setShader, boolean bufferStandardUniforms, boolean bufferNonStandardUniforms, boolean useMaterial, boolean useShadowMap, boolean setBones, boolean useLight){ + public void complexDraw( + boolean setShader, + boolean bufferStandardUniforms, + boolean bufferNonStandardUniforms, + boolean useMaterial, + boolean useShadowMap, + boolean setBones, + boolean useLight){ + if(setShader){ Globals.renderingEngine.setActiveShader(shader); } diff --git a/src/main/java/electrosphere/renderer/Model.java b/src/main/java/electrosphere/renderer/Model.java index ebe69e74..cdd5b342 100644 --- a/src/main/java/electrosphere/renderer/Model.java +++ b/src/main/java/electrosphere/renderer/Model.java @@ -1,9 +1,11 @@ package electrosphere.renderer; import electrosphere.renderer.actor.ActorAnimationMask; +import electrosphere.renderer.actor.ActorMeshMask; import electrosphere.renderer.anim.AnimChannel; import electrosphere.renderer.anim.Animation; import electrosphere.renderer.anim.AnimNode; +import electrosphere.logger.LoggerInterface; import electrosphere.main.Globals; import java.io.File; import java.util.ArrayList; @@ -56,6 +58,7 @@ public class Model { Matrix4f globalInverseTransform; AnimNode root_anim_node; + ActorMeshMask meshMask; public static Model createModelFromAiscene(AIScene s){ Model rVal = new Model(); @@ -83,6 +86,7 @@ public class Model { meshesBuffer.rewind(); while(meshesBuffer.hasRemaining()){ AIMesh currentMeshData = AIMesh.createSafe(meshesBuffer.get()); + LoggerInterface.loggerRenderer.DEBUG("mesh name:" + currentMeshData.mName().dataString()); PointerBuffer boneBuffer = currentMeshData.mBones(); for(int j = 0; j < currentMeshData.mNumBones(); j++){ AIBone currentBone = AIBone.createSafe(boneBuffer.get()); @@ -95,14 +99,14 @@ public class Model { } } Iterator meshIterator = rVal.meshes.iterator(); - rVal.bones = new ArrayList(); - rVal.boneMap = new HashMap(); + rVal.bones = new ArrayList(); + rVal.boneMap = new HashMap(); rVal.node_map = new HashMap(); while(meshIterator.hasNext()){ Mesh currentMesh = meshIterator.next(); Iterator boneIterator = currentMesh.bones.iterator(); - ArrayList to_remove_queue = new ArrayList(); - ArrayList to_add_queue = new ArrayList(); + ArrayList to_remove_queue = new ArrayList(); + ArrayList to_add_queue = new ArrayList(); while(boneIterator.hasNext()){ Bone currentBone = boneIterator.next(); if(!rVal.boneMap.containsKey(currentBone.boneID)){ @@ -132,7 +136,7 @@ public class Model { // int animCount = s.mNumAnimations(); PointerBuffer animBuffer = s.mAnimations(); - rVal.animations = new ArrayList(); + rVal.animations = new ArrayList(); rVal.animMap = new HashMap(); for(int i = 0; i < animCount; i++){ Animation newAnim = new Animation(AIAnimation.create(animBuffer.get(i)), i); @@ -143,7 +147,7 @@ public class Model { //Load materials // if(s.mNumMaterials() > 0){ - rVal.materials = new ArrayList(); + rVal.materials = new ArrayList(); PointerBuffer material_buffer = s.mMaterials(); while(material_buffer.hasRemaining()){ rVal.materials.add(Material.load_material_from_aimaterial(AIMaterial.create(material_buffer.get()))); @@ -196,7 +200,14 @@ public class Model { Iterator mesh_Iterator = meshes.iterator(); while(mesh_Iterator.hasNext()){ Mesh currentMesh = mesh_Iterator.next(); - currentMesh.complexDraw(setShader, bufferStandardUniforms, bufferNonStandardUniforms, useMaterial, useShadowMap, setBones, useLight); + if(!meshMask.isBlockedMesh(currentMesh.nodeID)){ + currentMesh.complexDraw(setShader, bufferStandardUniforms, bufferNonStandardUniforms, useMaterial, useShadowMap, setBones, useLight); + } + } + for(Mesh toDraw : meshMask.getToDrawMeshes()){ + toDraw.bones = bones; + toDraw.parent = this; + toDraw.complexDraw(setShader, bufferStandardUniforms, bufferNonStandardUniforms, useMaterial, useShadowMap, setBones, useLight); } } @@ -441,4 +452,8 @@ public class Model { System.out.println(bone.boneID); } } + + public void setMeshMask(ActorMeshMask meshMask){ + this.meshMask = meshMask; + } } diff --git a/src/main/java/electrosphere/renderer/actor/Actor.java b/src/main/java/electrosphere/renderer/actor/Actor.java index c14055d0..c8f04cd3 100644 --- a/src/main/java/electrosphere/renderer/actor/Actor.java +++ b/src/main/java/electrosphere/renderer/actor/Actor.java @@ -3,7 +3,6 @@ import electrosphere.main.Globals; import electrosphere.renderer.Bone; import electrosphere.renderer.Model; -import electrosphere.renderer.anim.Animation; import electrosphere.renderer.texture.Texture; import java.util.LinkedList; @@ -25,6 +24,7 @@ public class Actor { String textureOverride; float animationScalar = 1.0f; PriorityQueue animationQueue = new PriorityQueue(); + ActorMeshMask meshMask = new ActorMeshMask(); public Actor(String modelPath){ this.modelPath = modelPath; @@ -168,6 +168,10 @@ public class Actor { boolean hasDrawn = false; if(model != null){ applyAnimationMasks(model); + if(!meshMask.isEmpty()){ + meshMask.processMeshMaskQueue(); + model.setMeshMask(meshMask); + } // if(animation != null){ // model.playAnimation(animation); // model.incrementTime(0.001); @@ -293,4 +297,9 @@ public class Actor { textureOverride = override; } + public ActorMeshMask getMeshMask(){ + return meshMask; + } + + } diff --git a/src/main/java/electrosphere/renderer/actor/ActorMeshMask.java b/src/main/java/electrosphere/renderer/actor/ActorMeshMask.java new file mode 100644 index 00000000..2155080b --- /dev/null +++ b/src/main/java/electrosphere/renderer/actor/ActorMeshMask.java @@ -0,0 +1,131 @@ +package electrosphere.renderer.actor; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Semaphore; + +import electrosphere.main.Globals; +import electrosphere.renderer.Mesh; +import electrosphere.renderer.Model; + +public class ActorMeshMask { + + + + // List meshMask = new LinkedList(); + Map meshBlockerList = new HashMap(); + Map toDrawMesh = new HashMap(); + + Semaphore queueLock = new Semaphore(1); + List queuedMeshes = new LinkedList(); + List queuedBlockers = new LinkedList(); + + + + public ActorMeshMask(){ + + } + + public void queueMesh(String modelName, String meshName){ + queueLock.acquireUninterruptibly(); + queuedMeshes.add(new MeshDrawQueueItem(modelName, meshName)); + queueLock.release(); + } + + public void processMeshMaskQueue(){ + Model model; + Mesh mesh; + if(queueLock.tryAcquire()){ + if(queuedMeshes.size() > 0 || queuedBlockers.size() > 0){ + //process queued meshes + List toRemove = new LinkedList(); + for(MeshDrawQueueItem item : queuedMeshes){ + if((model = Globals.assetManager.fetchModel(item.getModelName())) != null){ + if((mesh = model.getMesh(item.getMeshName())) != null){ + toDrawMesh.put(mesh.nodeID,mesh); + toRemove.add(item); + } + } + } + //remove successfully processed + for(MeshDrawQueueItem item : toRemove){ + queuedMeshes.remove(item); + } + toRemove.clear(); + //process queued blockers + for(MeshDrawQueueItem item : queuedBlockers){ + if((model = Globals.assetManager.fetchModel(item.getModelName())) != null){ + meshBlockerList.put(item.getMeshName(),true); + toRemove.add(item); + } + } + //remove successfully processed + for(MeshDrawQueueItem item : toRemove){ + queuedBlockers.remove(item); + } + } + queueLock.release(); + } + } + + public List getToDrawMeshes(){ + return toDrawMesh.values().stream().toList(); + } + + public void ejectMeshToDraw(String name){ + toDrawMesh.remove(name); + } + + public boolean isEmpty(){ + return toDrawMesh.size() > 0; + } + + + // + //blocking interactions + // + public boolean containsMeshToDraw(String name){ + return toDrawMesh.containsKey(name); + } + + public void blockMesh(String modelName, String meshName){ + queueLock.acquireUninterruptibly(); + queuedBlockers.add(new MeshDrawQueueItem(modelName, meshName)); + queueLock.release(); + } + + public boolean isBlockedMesh(String name){ + return meshBlockerList.containsKey(name); + } + + public void unblockMesh(String name){ + meshBlockerList.remove(name); + } + + + + class MeshDrawQueueItem { + + String modelName; + String meshName; + + MeshDrawQueueItem(String modelName, String meshName){ + this.modelName = modelName; + this.meshName = meshName; + } + + + public String getModelName(){ + return modelName; + } + + public String getMeshName(){ + return meshName; + } + + } + + +}