equipable armor/clothes system

This commit is contained in:
austin 2022-02-06 23:58:14 -05:00
parent a5031f20f6
commit 4faaf8d923
22 changed files with 364 additions and 45 deletions

View File

@ -5,7 +5,7 @@
{ {
"name" : "Human", "creatureId" : "human",
"bodyParts" : [ "bodyParts" : [
{ {
"name" : "Head", "name" : "Head",
@ -197,7 +197,7 @@
{ {
"name" : "Goblin", "creatureId" : "goblin",
"bodyParts" : [ "bodyParts" : [
{ {
"name" : "Head", "name" : "Head",
@ -350,7 +350,7 @@
{ {
"name" : "CUBE_MAN", "creatureId" : "CUBE_MAN",
"bodyParts" : [ "bodyParts" : [
{ {
"name" : "CUBE", "name" : "CUBE",
@ -400,7 +400,7 @@
{ {
"name" : "Deer", "creatureId" : "Deer",
"bodyParts" : [ "bodyParts" : [
{ {
"name" : "Head", "name" : "Head",

View File

@ -4,7 +4,7 @@
{ {
"name" : "Katana", "itemId" : "Katana",
"modelPath" : "Models/katana1alt.fbx", "modelPath" : "Models/katana1alt.fbx",
"hitboxes" : [ "hitboxes" : [
{ {
@ -30,6 +30,7 @@
"MELEE", "MELEE",
"TARGETABLE" "TARGETABLE"
], ],
"idleAnim" : "Sword|Idle",
"collidable": { "collidable": {
"type" : "CUBE", "type" : "CUBE",
"dimension1" : 0.1, "dimension1" : 0.1,
@ -41,7 +42,7 @@
} }
}, },
{ {
"name" : "Bow", "itemId" : "Bow",
"modelPath": "Models/bow1.fbx", "modelPath": "Models/bow1.fbx",
"tokens" : [ "tokens" : [
"GRAVITY", "GRAVITY",
@ -58,6 +59,37 @@
"offsetY" : 0.05, "offsetY" : 0.05,
"offsetZ" : 0 "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"
]
}
]
} }

View File

@ -1,8 +1,9 @@
{ {
"raceMap" : [ "raceMap" : [
{ {
"name" : "Human", "raceId" : "human",
"associatedCreature" : "Human" "displayName" : "Human",
"associatedCreatureId" : "human"
} }
] ]
} }

Binary file not shown.

Binary file not shown.

BIN
assets/Models/shorts1.fbx Normal file

Binary file not shown.

View File

@ -518,7 +518,7 @@ public class ControlHandler {
controls.get(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM).setState(true); controls.get(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM).setState(true);
} else { } else {
if(controls.get(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM).isState() == true){ 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); EntityUtils.getPosition(bow).set(1, 5, 2);
CollisionObjUtils.positionCharacter(bow, new Vector3f(1, 5, 2)); CollisionObjUtils.positionCharacter(bow, new Vector3f(1, 5, 2));
} }

View File

@ -615,7 +615,7 @@ public class LoadingThread extends Thread {
// ActorUtils.applyBlenderTransformer(building); // ActorUtils.applyBlenderTransformer(building);
//spawn evil goblin //spawn evil goblin
Entity goblin = CreatureUtils.spawnBasicCreature("Goblin"); Entity goblin = CreatureUtils.spawnBasicCreature("goblin");
CollisionObjUtils.positionCharacter(goblin, new Vector3f(4, 0, 4)); CollisionObjUtils.positionCharacter(goblin, new Vector3f(4, 0, 4));
EntityUtils.getScale(goblin).set(0.005f); EntityUtils.getScale(goblin).set(0.005f);
// //give evil goblin sword // //give evil goblin sword

View File

@ -74,6 +74,11 @@ public class EntityDataStrings {
public static final String DATA_STRING_LIGHT_CUTOFF = "lightCutoff"; public static final String DATA_STRING_LIGHT_CUTOFF = "lightCutoff";
public static final String DATA_STRING_LIGHT_CUTOFF_OUTER = "lightCutoffOuter"; public static final String DATA_STRING_LIGHT_CUTOFF_OUTER = "lightCutoffOuter";
/*
Anim related
*/
public static final String ANIM_IDLE = "animIdle";
/* /*
UI Entity UI Entity
*/ */
@ -135,6 +140,8 @@ public class EntityDataStrings {
public static final String ITEM_IS_ITEM = "itemIsItem"; public static final String ITEM_IS_ITEM = "itemIsItem";
public static final String ITEM_TYPE = "itemType"; public static final String ITEM_TYPE = "itemType";
public static final String ITEM_IS_WEAPON = "itemIsWeapon"; public static final String ITEM_IS_WEAPON = "itemIsWeapon";
public static final String ITEM_IS_ARMOR = "itemIsArmor";
public static final String ITEM_EQUIP_WHITELIST = "itemEquipWhitelist";
/* /*

View File

@ -99,5 +99,13 @@ public class EntityUtils {
public static void setVisible(Entity entity, boolean visible){ public static void setVisible(Entity entity, boolean visible){
entity.putData(EntityDataStrings.DATA_STRING_DRAW, 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);
}
} }

View File

@ -1,14 +1,21 @@
package electrosphere.entity.state.equip; package electrosphere.entity.state.equip;
import java.util.List;
import electrosphere.collision.dispatch.CollisionObject; import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.dynamics.RigidBody; import electrosphere.dynamics.RigidBody;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.attach.AttachUtils; import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.client.targeting.crosshair.Crosshair; import electrosphere.game.client.targeting.crosshair.Crosshair;
import electrosphere.game.collision.collidable.Collidable; import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.item.type.EquipWhitelist;
import electrosphere.main.Globals; 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){ public void attemptEquip(Entity toEquip){
if(!hasEquipPrimary() && ItemUtils.isItem(toEquip) && !AttachUtils.isAttached(toEquip)){ if(!hasEquipPrimary() && ItemUtils.isItem(toEquip) && !AttachUtils.isAttached(toEquip)){
equipPrimary = toEquip; if(ItemUtils.hasEquipList(toEquip)){
AttachUtils.attachEntityToEntityAtBone(parent, toEquip, equipPrimaryBoneName); String parentCreatureId = CreatureUtils.getType(parent);
if(toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLIDABLE)){ List<EquipWhitelist> whitelist = ItemUtils.getEquipWhitelist(toEquip);
CollisionObject rigidBody = (CollisionObject)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); for(EquipWhitelist whitelistItem : whitelist){
Globals.collisionEngine.deregisterPhysicsObject(rigidBody); 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);
} }
} }

View File

@ -14,6 +14,7 @@ import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable; import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.creature.type.CollidableTemplate; import electrosphere.game.data.creature.type.CollidableTemplate;
import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.game.data.item.type.EquipWhitelist;
import electrosphere.game.data.item.type.Item; import electrosphere.game.data.item.type.Item;
import electrosphere.main.Globals; import electrosphere.main.Globals;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
@ -23,6 +24,8 @@ import electrosphere.renderer.Model;
import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorUtils; import electrosphere.renderer.actor.ActorUtils;
import java.util.List;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import org.joml.Vector3d; import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;
@ -93,8 +96,17 @@ public class ItemUtils {
case "WEAPON": case "WEAPON":
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true); rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
break; 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.DRAW_CAST_SHADOW, true);
rVal.putData(EntityDataStrings.ITEM_IS_ITEM, true); rVal.putData(EntityDataStrings.ITEM_IS_ITEM, true);
rVal.putData(EntityDataStrings.ITEM_TYPE, name); rVal.putData(EntityDataStrings.ITEM_TYPE, name);
@ -131,12 +143,11 @@ public class ItemUtils {
public static void updateItemActorAnimation(Entity item){ public static void updateItemActorAnimation(Entity item){
Actor actor = EntityUtils.getActor(item); Actor actor = EntityUtils.getActor(item);
if(!actor.isPlayingAnimation("Sword|Idle")){ if(item.getData(EntityDataStrings.ANIM_IDLE) != null){
// Model model; String idleAnim = (String)item.getData(EntityDataStrings.ANIM_IDLE);
// if((model = Globals.assetManager.fetchModel(actor.getModelPath()))!=null){ if(!actor.isPlayingAnimation(idleAnim)){
// model.describeAllAnimations(); actor.playAnimation(idleAnim,1);
// } }
actor.playAnimation("Sword|Idle",1);
} }
} }
@ -168,4 +179,17 @@ public class ItemUtils {
public static boolean isWeapon(Entity item){ public static boolean isWeapon(Entity item){
return item.getDataKeys().contains(EntityDataStrings.ITEM_IS_WEAPON); 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<EquipWhitelist> getEquipWhitelist(Entity item){
return (List<EquipWhitelist>)item.getData(EntityDataStrings.ITEM_EQUIP_WHITELIST);
}
} }

View File

@ -6,7 +6,7 @@ import electrosphere.game.data.creature.type.rotator.RotatorSystem;
import java.util.List; import java.util.List;
public class CreatureType { public class CreatureType {
String name; String creatureId;
List<BodyPart> bodyParts; List<BodyPart> bodyParts;
List<HitboxData> hitboxes; List<HitboxData> hitboxes;
List<String> tokens; List<String> tokens;
@ -18,8 +18,8 @@ public class CreatureType {
LookAtSystem lookAtSystem; LookAtSystem lookAtSystem;
String modelPath; String modelPath;
public String getName() { public String getCreatureId() {
return name; return creatureId;
} }
public List<BodyPart> getBodyParts() { public List<BodyPart> getBodyParts() {

View File

@ -10,7 +10,7 @@ public class CreatureTypeMap {
public CreatureType getCreature(String name){ public CreatureType getCreature(String name){
CreatureType rVal = null; CreatureType rVal = null;
for(CreatureType type : creatures){ for(CreatureType type : creatures){
if(type.getName().equals(name)){ if(type.getCreatureId().equals(name)){
rVal = type; rVal = type;
break; break;
} }

View File

@ -0,0 +1,28 @@
package electrosphere.game.data.item.type;
import java.util.List;
public class EquipWhitelist {
String creatureId;
String model;
List<String> meshList;
List<String> meshMaskList;
public String getCreatureId(){
return creatureId;
}
public String getModel(){
return model;
}
public List<String> getMeshList(){
return meshList;
}
public List<String> getMeshMaskList(){
return meshMaskList;
}
}

View File

@ -5,14 +5,17 @@ import electrosphere.game.data.creature.type.CollidableTemplate;
import java.util.List; import java.util.List;
public class Item { public class Item {
String name;
String itemId;
String modelPath; String modelPath;
List<HitboxData> hitboxes; List<HitboxData> hitboxes;
List<String> tokens; List<String> tokens;
CollidableTemplate collidable; CollidableTemplate collidable;
List<EquipWhitelist> equipWhitelist;
String idleAnim;
public String getName() { public String getItemId() {
return name; return itemId;
} }
public String getModelPath() { public String getModelPath() {
@ -30,6 +33,14 @@ public class Item {
public CollidableTemplate getCollidable(){ public CollidableTemplate getCollidable(){
return collidable; return collidable;
} }
public List<EquipWhitelist> getEquipWhitelist(){
return equipWhitelist;
}
public String getIdleAnim(){
return idleAnim;
}
} }

View File

@ -13,7 +13,7 @@ public class ItemTypeMap {
public Item getItem(String name){ public Item getItem(String name){
Item rVal = null; Item rVal = null;
for(Item item : items){ for(Item item : items){
if(item.getName().equals(name)){ if(item.getItemId().equals(name)){
rVal = item; rVal = item;
break; break;
} }

View File

@ -97,7 +97,7 @@ public class ServerConnectionHandler implements Runnable {
Player newPlayerObject = new Player(this); Player newPlayerObject = new Player(this);
Globals.playerManager.addPlayer(newPlayerObject); Globals.playerManager.addPlayer(newPlayerObject);
//spawn player in world //spawn player in world
Entity newPlayerCharacter = CreatureUtils.spawnBasicCreature("Human"); Entity newPlayerCharacter = CreatureUtils.spawnBasicCreature("human");
playerCharacterID = newPlayerCharacter.getId(); playerCharacterID = newPlayerCharacter.getId();
CollisionObjUtils.positionCharacter(newPlayerCharacter, new Vector3f(Globals.spawnPoint.x,Globals.spawnPoint.y,Globals.spawnPoint.z)); CollisionObjUtils.positionCharacter(newPlayerCharacter, new Vector3f(Globals.spawnPoint.x,Globals.spawnPoint.y,Globals.spawnPoint.z));
//attach player object to player character //attach player object to player character

View File

@ -50,6 +50,9 @@ import static org.lwjgl.opengl.GL30.glGenVertexArrays;
* @author satellite * @author satellite
*/ */
public class Mesh { 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 Model parent;
public String nodeID; public String nodeID;
public AIMesh mesh; public AIMesh mesh;
@ -66,14 +69,16 @@ public class Mesh {
public int boneCount; public int boneCount;
public int textureCoordBuffer; public int textureCoordBuffer;
public int textureCoordCount; public int textureCoordCount;
public ArrayList<Bone> bones = new ArrayList(); //THIS IS NOT GUARANTEED TO BE THE PARENT MODEL THAT THIS WAS LOADED IN
public ArrayList<String> bone_id_list = new ArrayList(); //THIS CAN BE POST-LOAD SET IN MODEL VIA MODELMASK BEHAVIOR
HashMap<String,Object> uniforms = new HashMap(); public ArrayList<Bone> bones = new ArrayList<Bone>();
public ArrayList<String> bone_id_list = new ArrayList<String>();
HashMap<String,Object> uniforms = new HashMap<String,Object>();
int bone_map_size = 0; int bone_map_size = 0;
boolean hasBones = true; boolean hasBones = true;
public boolean hasTextureCoords = true; public boolean hasTextureCoords = true;
public List<Texture> textureList = new ArrayList(); public List<Texture> textureList = new ArrayList<Texture>();
public boolean useTextureList; public boolean useTextureList;
public String textureListArrayUniformName; public String textureListArrayUniformName;
@ -285,7 +290,7 @@ public class Mesh {
currentBone.boneID = currentBoneData.mName().dataString(); currentBone.boneID = currentBoneData.mName().dataString();
currentBone.inverseBindPoseMatrix = electrosphere.util.Utilities.convertAIMatrix(currentBoneData.mOffsetMatrix()); currentBone.inverseBindPoseMatrix = electrosphere.util.Utilities.convertAIMatrix(currentBoneData.mOffsetMatrix());
currentBone.numWeights = currentBoneData.mNumWeights(); currentBone.numWeights = currentBoneData.mNumWeights();
currentBone.weights = new HashMap(); currentBone.weights = new HashMap<Integer,Float>();
Iterator<AIVertexWeight> weightIterator = currentBoneData.mWeights().iterator(); Iterator<AIVertexWeight> weightIterator = currentBoneData.mWeights().iterator();
while(weightIterator.hasNext()){ while(weightIterator.hasNext()){
AIVertexWeight currentWeightData = weightIterator.next(); 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){ if(setShader){
Globals.renderingEngine.setActiveShader(shader); Globals.renderingEngine.setActiveShader(shader);
} }

View File

@ -1,9 +1,11 @@
package electrosphere.renderer; package electrosphere.renderer;
import electrosphere.renderer.actor.ActorAnimationMask; import electrosphere.renderer.actor.ActorAnimationMask;
import electrosphere.renderer.actor.ActorMeshMask;
import electrosphere.renderer.anim.AnimChannel; import electrosphere.renderer.anim.AnimChannel;
import electrosphere.renderer.anim.Animation; import electrosphere.renderer.anim.Animation;
import electrosphere.renderer.anim.AnimNode; import electrosphere.renderer.anim.AnimNode;
import electrosphere.logger.LoggerInterface;
import electrosphere.main.Globals; import electrosphere.main.Globals;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -56,6 +58,7 @@ public class Model {
Matrix4f globalInverseTransform; Matrix4f globalInverseTransform;
AnimNode root_anim_node; AnimNode root_anim_node;
ActorMeshMask meshMask;
public static Model createModelFromAiscene(AIScene s){ public static Model createModelFromAiscene(AIScene s){
Model rVal = new Model(); Model rVal = new Model();
@ -83,6 +86,7 @@ public class Model {
meshesBuffer.rewind(); meshesBuffer.rewind();
while(meshesBuffer.hasRemaining()){ while(meshesBuffer.hasRemaining()){
AIMesh currentMeshData = AIMesh.createSafe(meshesBuffer.get()); AIMesh currentMeshData = AIMesh.createSafe(meshesBuffer.get());
LoggerInterface.loggerRenderer.DEBUG("mesh name:" + currentMeshData.mName().dataString());
PointerBuffer boneBuffer = currentMeshData.mBones(); PointerBuffer boneBuffer = currentMeshData.mBones();
for(int j = 0; j < currentMeshData.mNumBones(); j++){ for(int j = 0; j < currentMeshData.mNumBones(); j++){
AIBone currentBone = AIBone.createSafe(boneBuffer.get()); AIBone currentBone = AIBone.createSafe(boneBuffer.get());
@ -95,14 +99,14 @@ public class Model {
} }
} }
Iterator<Mesh> meshIterator = rVal.meshes.iterator(); Iterator<Mesh> meshIterator = rVal.meshes.iterator();
rVal.bones = new ArrayList(); rVal.bones = new ArrayList<Bone>();
rVal.boneMap = new HashMap(); rVal.boneMap = new HashMap<String,Bone>();
rVal.node_map = new HashMap<String, AnimNode>(); rVal.node_map = new HashMap<String, AnimNode>();
while(meshIterator.hasNext()){ while(meshIterator.hasNext()){
Mesh currentMesh = meshIterator.next(); Mesh currentMesh = meshIterator.next();
Iterator<Bone> boneIterator = currentMesh.bones.iterator(); Iterator<Bone> boneIterator = currentMesh.bones.iterator();
ArrayList<Bone> to_remove_queue = new ArrayList(); ArrayList<Bone> to_remove_queue = new ArrayList<Bone>();
ArrayList<Bone> to_add_queue = new ArrayList(); ArrayList<Bone> to_add_queue = new ArrayList<Bone>();
while(boneIterator.hasNext()){ while(boneIterator.hasNext()){
Bone currentBone = boneIterator.next(); Bone currentBone = boneIterator.next();
if(!rVal.boneMap.containsKey(currentBone.boneID)){ if(!rVal.boneMap.containsKey(currentBone.boneID)){
@ -132,7 +136,7 @@ public class Model {
// //
int animCount = s.mNumAnimations(); int animCount = s.mNumAnimations();
PointerBuffer animBuffer = s.mAnimations(); PointerBuffer animBuffer = s.mAnimations();
rVal.animations = new ArrayList(); rVal.animations = new ArrayList<Animation>();
rVal.animMap = new HashMap<String,Animation>(); rVal.animMap = new HashMap<String,Animation>();
for(int i = 0; i < animCount; i++){ for(int i = 0; i < animCount; i++){
Animation newAnim = new Animation(AIAnimation.create(animBuffer.get(i)), i); Animation newAnim = new Animation(AIAnimation.create(animBuffer.get(i)), i);
@ -143,7 +147,7 @@ public class Model {
//Load materials //Load materials
// //
if(s.mNumMaterials() > 0){ if(s.mNumMaterials() > 0){
rVal.materials = new ArrayList(); rVal.materials = new ArrayList<Material>();
PointerBuffer material_buffer = s.mMaterials(); PointerBuffer material_buffer = s.mMaterials();
while(material_buffer.hasRemaining()){ while(material_buffer.hasRemaining()){
rVal.materials.add(Material.load_material_from_aimaterial(AIMaterial.create(material_buffer.get()))); rVal.materials.add(Material.load_material_from_aimaterial(AIMaterial.create(material_buffer.get())));
@ -196,7 +200,14 @@ public class Model {
Iterator<Mesh> mesh_Iterator = meshes.iterator(); Iterator<Mesh> mesh_Iterator = meshes.iterator();
while(mesh_Iterator.hasNext()){ while(mesh_Iterator.hasNext()){
Mesh currentMesh = mesh_Iterator.next(); 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); System.out.println(bone.boneID);
} }
} }
public void setMeshMask(ActorMeshMask meshMask){
this.meshMask = meshMask;
}
} }

View File

@ -3,7 +3,6 @@
import electrosphere.main.Globals; import electrosphere.main.Globals;
import electrosphere.renderer.Bone; import electrosphere.renderer.Bone;
import electrosphere.renderer.Model; import electrosphere.renderer.Model;
import electrosphere.renderer.anim.Animation;
import electrosphere.renderer.texture.Texture; import electrosphere.renderer.texture.Texture;
import java.util.LinkedList; import java.util.LinkedList;
@ -25,6 +24,7 @@ public class Actor {
String textureOverride; String textureOverride;
float animationScalar = 1.0f; float animationScalar = 1.0f;
PriorityQueue<ActorAnimationMask> animationQueue = new PriorityQueue<ActorAnimationMask>(); PriorityQueue<ActorAnimationMask> animationQueue = new PriorityQueue<ActorAnimationMask>();
ActorMeshMask meshMask = new ActorMeshMask();
public Actor(String modelPath){ public Actor(String modelPath){
this.modelPath = modelPath; this.modelPath = modelPath;
@ -168,6 +168,10 @@ public class Actor {
boolean hasDrawn = false; boolean hasDrawn = false;
if(model != null){ if(model != null){
applyAnimationMasks(model); applyAnimationMasks(model);
if(!meshMask.isEmpty()){
meshMask.processMeshMaskQueue();
model.setMeshMask(meshMask);
}
// if(animation != null){ // if(animation != null){
// model.playAnimation(animation); // model.playAnimation(animation);
// model.incrementTime(0.001); // model.incrementTime(0.001);
@ -293,4 +297,9 @@ public class Actor {
textureOverride = override; textureOverride = override;
} }
public ActorMeshMask getMeshMask(){
return meshMask;
}
} }

View File

@ -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<Mesh> meshMask = new LinkedList<Mesh>();
Map<String,Boolean> meshBlockerList = new HashMap<String,Boolean>();
Map<String,Mesh> toDrawMesh = new HashMap<String,Mesh>();
Semaphore queueLock = new Semaphore(1);
List<MeshDrawQueueItem> queuedMeshes = new LinkedList<MeshDrawQueueItem>();
List<MeshDrawQueueItem> queuedBlockers = new LinkedList<MeshDrawQueueItem>();
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<MeshDrawQueueItem> toRemove = new LinkedList<MeshDrawQueueItem>();
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<Mesh> 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;
}
}
}