This commit is contained in:
parent
ec7c1371c2
commit
c083aaf05f
@ -7,6 +7,7 @@
|
||||
"Data/entity/items/debug_tools.json",
|
||||
"Data/entity/items/hand_tools.json",
|
||||
"Data/entity/items/clothing.json",
|
||||
"Data/entity/items/materials.json"
|
||||
"Data/entity/items/materials.json",
|
||||
"Data/entity/items/fabs.json"
|
||||
]
|
||||
}
|
||||
7
assets/Data/entity/items/fabs.json
Normal file
7
assets/Data/entity/items/fabs.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"items" : [
|
||||
],
|
||||
"files" : [
|
||||
"Data/entity/items/fabs/floors.json"
|
||||
]
|
||||
}
|
||||
40
assets/Data/entity/items/fabs/floors.json
Normal file
40
assets/Data/entity/items/fabs/floors.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"items" : [
|
||||
{
|
||||
"id" : "woodfloor",
|
||||
"tokens" : [
|
||||
"GRAVITY",
|
||||
"TARGETABLE"
|
||||
],
|
||||
"fabData" : {
|
||||
"fabPath" : "Data/fab/wood_refined_floor.block"
|
||||
},
|
||||
"clientSideSecondary" : "PLACE_FAB",
|
||||
"itemAudio": {
|
||||
"uiGrabAudio" : "Audio/ui/items/specific/Pick Up Wood A.wav",
|
||||
"uiReleaseAudio" : "Audio/ui/items/specific/Drop Wood A.wav"
|
||||
},
|
||||
"graphicsTemplate": {
|
||||
"model": {
|
||||
"path" : "Models/items/minicrate.glb"
|
||||
}
|
||||
},
|
||||
"collidable": {
|
||||
"type" : "CUBE",
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.1,
|
||||
"dimension3" : 0.35,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.05,
|
||||
"offsetZ" : 0
|
||||
},
|
||||
"iconPath" : "Textures/icons/itemIconItemGeneric.png"
|
||||
}
|
||||
],
|
||||
"files" : [
|
||||
]
|
||||
}
|
||||
BIN
assets/Models/items/minicrate.glb
Normal file
BIN
assets/Models/items/minicrate.glb
Normal file
Binary file not shown.
BIN
assets/Models/items/woodplanks1.png
Normal file
BIN
assets/Models/items/woodplanks1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 981 KiB |
@ -1602,6 +1602,7 @@ Flower foliage item
|
||||
Texture loading from model files (ie can load texture path from model file)
|
||||
Clean up material class a bit
|
||||
Cleaning up dead code
|
||||
Fab items
|
||||
|
||||
|
||||
|
||||
|
||||
@ -48,6 +48,11 @@ public class AssetDataStrings {
|
||||
public static final String UI_FRAME_TEXTURE_DEFAULT_2 = "Textures/ui/uiFrame2.png";
|
||||
public static final String UI_FRAME_TEXTURE_DEFAULT_3 = "Textures/ui/panel-001.png";
|
||||
|
||||
/**
|
||||
* UI icon textures
|
||||
*/
|
||||
public static final String UI_TEXTURE_ITEM_ICON_GENERIC = "Textures/icons/itemIconItemGeneric.png";
|
||||
|
||||
/**
|
||||
* UI generic audio
|
||||
*/
|
||||
|
||||
@ -211,6 +211,11 @@ public class EntityDataStrings {
|
||||
public static final String ITEM_CONTAINING_PARENT = "itemContainingParent";
|
||||
public static final String TREE_SERVERCHARGESTATE = "treeServerChargeState";
|
||||
public static final String TREE_CLIENTCHARGESTATE = "treeClientChargeState";
|
||||
|
||||
/**
|
||||
* Data for placing fabs with an item
|
||||
*/
|
||||
public static final String ITEM_FAB_DATA = "itemFabData";
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@ -9,6 +9,7 @@ import electrosphere.entity.state.inventory.InventoryUtils;
|
||||
import electrosphere.entity.state.inventory.RelationalInventoryState;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.entity.types.item.ItemUtils;
|
||||
import electrosphere.game.data.block.BlockFab;
|
||||
import electrosphere.game.data.common.treedata.TreeDataAnimation;
|
||||
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
||||
import electrosphere.game.data.creature.type.equip.ToolbarData;
|
||||
@ -31,6 +32,7 @@ import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.actor.ActorMeshMask;
|
||||
import electrosphere.util.FileUtils;
|
||||
import electrosphere.net.parser.net.message.InventoryMessage;
|
||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||
@ -191,6 +193,10 @@ public class ClientToolbarState implements BehaviorTree {
|
||||
} else if(itemData.getTokens().contains(CursorState.CURSOR_BLOCK_TOKEN)) {
|
||||
Globals.cursorState.setClampToExistingBlock(true);
|
||||
CursorState.makeBlockVisible(AssetDataStrings.TEXTURE_RED_TRANSPARENT);
|
||||
} else if(itemData.getFabData() != null){
|
||||
Globals.cursorState.setSelectedFab(BlockFab.read(FileUtils.getAssetFile(itemData.getFabData().getFabPath())));
|
||||
Globals.cursorState.setSelectedFabPath(FileUtils.getAssetFileString(itemData.getFabData().getFabPath()));
|
||||
CursorState.makeFabVisible();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,9 +7,9 @@ import org.joml.Vector3d;
|
||||
import org.ode4j.ode.DBody;
|
||||
|
||||
import electrosphere.collision.PhysicsEntityUtils;
|
||||
import electrosphere.collision.PhysicsUtils;
|
||||
import electrosphere.collision.collidable.Collidable;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||
import electrosphere.entity.ClientEntityUtils;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityCreationUtils;
|
||||
@ -47,9 +47,11 @@ import electrosphere.server.entity.poseactor.PoseActor;
|
||||
*/
|
||||
public class ItemUtils {
|
||||
|
||||
//generic item icon filepath
|
||||
static final String genericItemIconPath = "Textures/icons/itemIconItemGeneric.png";
|
||||
|
||||
/**
|
||||
* Spawns an item on the client
|
||||
* @param name The name of the item type
|
||||
* @return The item entity
|
||||
*/
|
||||
public static Entity clientSpawnBasicItem(String name){
|
||||
Item item = Globals.gameConfigCurrent.getItemMap().getItem(name);
|
||||
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
||||
@ -81,7 +83,7 @@ public class ItemUtils {
|
||||
if(item.getIconPath() != null && !item.getIconPath().equals("")){
|
||||
rVal.putData(EntityDataStrings.ITEM_ICON,item.getIconPath());
|
||||
} else {
|
||||
rVal.putData(EntityDataStrings.ITEM_ICON,genericItemIconPath);
|
||||
rVal.putData(EntityDataStrings.ITEM_ICON,AssetDataStrings.UI_TEXTURE_ITEM_ICON_GENERIC);
|
||||
}
|
||||
if(item.getItemAudio() != null){
|
||||
ItemAudio audio = item.getItemAudio();
|
||||
@ -108,6 +110,14 @@ public class ItemUtils {
|
||||
}
|
||||
}
|
||||
rVal.putData(EntityDataStrings.ITEM_IS_IN_INVENTORY, false);
|
||||
|
||||
|
||||
//
|
||||
// Fab data
|
||||
//
|
||||
if(item.getFabData() != null){
|
||||
rVal.putData(EntityDataStrings.ITEM_FAB_DATA, item.getFabData());
|
||||
}
|
||||
|
||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.ITEM);
|
||||
return rVal;
|
||||
@ -174,7 +184,7 @@ public class ItemUtils {
|
||||
if(item.getIconPath() != null && !item.getIconPath().equals("")){
|
||||
rVal.putData(EntityDataStrings.ITEM_ICON,item.getIconPath());
|
||||
} else {
|
||||
rVal.putData(EntityDataStrings.ITEM_ICON,genericItemIconPath);
|
||||
rVal.putData(EntityDataStrings.ITEM_ICON,AssetDataStrings.UI_TEXTURE_ITEM_ICON_GENERIC);
|
||||
}
|
||||
//
|
||||
//
|
||||
@ -191,6 +201,14 @@ public class ItemUtils {
|
||||
}
|
||||
}
|
||||
rVal.putData(EntityDataStrings.ITEM_IS_IN_INVENTORY, false);
|
||||
|
||||
//
|
||||
// Fab data
|
||||
//
|
||||
if(item.getFabData() != null){
|
||||
rVal.putData(EntityDataStrings.ITEM_FAB_DATA, item.getFabData());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -81,6 +81,11 @@ public class Item extends CommonEntityType {
|
||||
* The usage logic for a secondary usage of this item
|
||||
*/
|
||||
ItemUsage secondaryUsage;
|
||||
|
||||
/**
|
||||
* Item fab data
|
||||
*/
|
||||
ItemFabData fabData;
|
||||
|
||||
/**
|
||||
* Creates item data from a spawn item description
|
||||
@ -261,4 +266,12 @@ public class Item extends CommonEntityType {
|
||||
this.primaryUsage = primaryUsage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fab data for this item
|
||||
* @return The fab data
|
||||
*/
|
||||
public ItemFabData getFabData(){
|
||||
return fabData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
29
src/main/java/electrosphere/game/data/item/ItemFabData.java
Normal file
29
src/main/java/electrosphere/game/data/item/ItemFabData.java
Normal file
@ -0,0 +1,29 @@
|
||||
package electrosphere.game.data.item;
|
||||
|
||||
/**
|
||||
* Data for placing fabs
|
||||
*/
|
||||
public class ItemFabData {
|
||||
|
||||
/**
|
||||
* The path for the fab to place when this item is consumed
|
||||
*/
|
||||
String fabPath;
|
||||
|
||||
/**
|
||||
* Gets the path for the corresponding fab file
|
||||
* @return The path for the corresponding fab file
|
||||
*/
|
||||
public String getFabPath() {
|
||||
return fabPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path for the corresponding fab file
|
||||
* @param fabPath The path for the corresponding fab file
|
||||
*/
|
||||
public void setFabPath(String fabPath) {
|
||||
this.fabPath = fabPath;
|
||||
}
|
||||
|
||||
}
|
||||
@ -8,6 +8,7 @@ import electrosphere.util.FileUtils;
|
||||
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.assimp.AIMaterial;
|
||||
import org.lwjgl.assimp.AIMaterialProperty;
|
||||
import org.lwjgl.assimp.AIScene;
|
||||
import org.lwjgl.assimp.AIString;
|
||||
import org.lwjgl.assimp.AITexture;
|
||||
@ -94,6 +95,7 @@ public class Material {
|
||||
texPaths[i] = tex.mFilename().dataString();
|
||||
}
|
||||
//discover diffuse
|
||||
boolean foundDiffuse = false;
|
||||
int textureCount = Assimp.aiGetMaterialTextureCount(input, Assimp.aiTextureType_DIFFUSE);
|
||||
if(textureCount > 0){
|
||||
//for the time being, only load the first diffuse
|
||||
@ -118,6 +120,7 @@ public class Material {
|
||||
rVal.usesFetch = true;
|
||||
rVal.diffuse = resolved;
|
||||
Globals.assetManager.addTexturePathtoQueue(rVal.diffuse);
|
||||
foundDiffuse = true;
|
||||
}
|
||||
} else {
|
||||
String resolved = Material.resolveTexturePath(path, texturePath);
|
||||
@ -125,6 +128,45 @@ public class Material {
|
||||
rVal.usesFetch = true;
|
||||
rVal.diffuse = resolved;
|
||||
Globals.assetManager.addTexturePathtoQueue(rVal.diffuse);
|
||||
foundDiffuse = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!foundDiffuse){
|
||||
textureCount = Assimp.aiGetMaterialTextureCount(input, Assimp.aiTextureType_BASE_COLOR);
|
||||
if(textureCount > 0){
|
||||
//for the time being, only load the first diffuse
|
||||
int textureIndex = 0;
|
||||
int retCode = Assimp.aiGetMaterialTexture(input, Assimp.aiTextureType_BASE_COLOR, textureIndex, aiPathString, (IntBuffer)null, null, null, null, null, null);
|
||||
if(retCode != Assimp.aiReturn_SUCCESS){
|
||||
throw new Error("Failed to read diffuse! " + textureCount + " " + Assimp.aiGetErrorString());
|
||||
}
|
||||
String texturePath = aiPathString.dataString();
|
||||
if(texturePath == null || texturePath.length() <= 0){
|
||||
throw new Error("Texture path is empty " + texturePath);
|
||||
}
|
||||
if(texturePath.length() == 2 && texturePath.startsWith("*")){
|
||||
//older versions of Assimp require you to read the INDEX of the texture from the material, then look up that texture in the scene itself
|
||||
//format looks like "*<index>" ie "*0"
|
||||
int indexInLoadedTexturePaths = Integer.parseInt(texturePath.substring(1));
|
||||
if(indexInLoadedTexturePaths >= texPaths.length){
|
||||
throw new Error("Index discovered is outside the array's length " + indexInLoadedTexturePaths + " " + texPaths.length);
|
||||
}
|
||||
String resolved = Material.resolveTexturePath(path, texPaths[indexInLoadedTexturePaths]);
|
||||
if(resolved != null && resolved.length() > 0){
|
||||
rVal.usesFetch = true;
|
||||
rVal.diffuse = resolved;
|
||||
Globals.assetManager.addTexturePathtoQueue(rVal.diffuse);
|
||||
foundDiffuse = true;
|
||||
}
|
||||
} else {
|
||||
String resolved = Material.resolveTexturePath(path, texturePath);
|
||||
if(resolved != null && resolved.length() > 0){
|
||||
rVal.usesFetch = true;
|
||||
rVal.diffuse = resolved;
|
||||
Globals.assetManager.addTexturePathtoQueue(rVal.diffuse);
|
||||
foundDiffuse = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -135,6 +177,25 @@ public class Material {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the properties of a material
|
||||
* @param material The material
|
||||
*/
|
||||
public static void listMaterialProps(AIMaterial material){
|
||||
LoggerInterface.loggerRenderer.WARNING("Describing material");
|
||||
for(int i = 0; i < material.mNumProperties(); i++){
|
||||
AIMaterialProperty prop = AIMaterialProperty.create(material.mProperties().get(i));
|
||||
String key = prop.mKey().dataString();
|
||||
int propType = prop.mSemantic();
|
||||
if(propType == Assimp.aiTextureType_NONE){
|
||||
//non-texture prop
|
||||
LoggerInterface.loggerRenderer.WARNING("Prop \"" + key + "\" is not a texture");
|
||||
} else {
|
||||
LoggerInterface.loggerRenderer.WARNING("Prop \"" + key + "\" is a texture");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the filepath of the texture
|
||||
* @param path The path of the ai scene itself
|
||||
|
||||
@ -209,6 +209,16 @@ public class FileUtils {
|
||||
return targetFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an assets file
|
||||
* @param pathName The relative path in the assets folder
|
||||
* @return The file
|
||||
*/
|
||||
public static String getAssetFileString(String pathName){
|
||||
String sanitizedFilePath = sanitizeFilePath(pathName);
|
||||
return "./assets" + sanitizedFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an assets file as a byte buffer
|
||||
* @param pathName The relative path in the assets folder
|
||||
|
||||
Loading…
Reference in New Issue
Block a user