break out interaction into dedicated collision eng
Some checks reported errors
studiorailgun/Renderer/pipeline/head Something is wrong with the build of this commit

This commit is contained in:
austin 2025-04-03 16:35:01 -04:00
parent 840d325b1f
commit 90a88bbd8b
13 changed files with 315 additions and 31 deletions

View File

@ -5,6 +5,22 @@
"tokens" : [ "tokens" : [
"FLAMMABLE" "FLAMMABLE"
], ],
"buttonInteraction" : {
"onInteract" : "harvest",
"interactionShape" : {
"type" : "CUBE",
"dimension1" : 1.0,
"dimension2" : 1.0,
"dimension3" : 1.0,
"rotX": 0,
"rotY": 0,
"rotZ": 0,
"rotW": 1,
"offsetX" : 0.0,
"offsetY" : 0.5,
"offsetZ" : 0.0
}
},
"graphicsTemplate": { "graphicsTemplate": {
"model": { "model": {
"path" : "Models/foliage/bush4.glb" "path" : "Models/foliage/bush4.glb"

View File

@ -4,7 +4,8 @@
"id" : "terrainTool", "id" : "terrainTool",
"tokens" : [ "tokens" : [
"GRAVITY", "GRAVITY",
"TARGETABLE" "TARGETABLE",
"CURSOR"
], ],
"equipData": { "equipData": {
"equipClass" : "tool" "equipClass" : "tool"
@ -36,7 +37,8 @@
"id" : "spawningPalette", "id" : "spawningPalette",
"tokens" : [ "tokens" : [
"GRAVITY", "GRAVITY",
"TARGETABLE" "TARGETABLE",
"CURSOR"
], ],
"equipData": { "equipData": {
"equipClass" : "tool" "equipClass" : "tool"
@ -67,7 +69,8 @@
"id" : "entityinspector", "id" : "entityinspector",
"tokens" : [ "tokens" : [
"GRAVITY", "GRAVITY",
"TARGETABLE" "TARGETABLE",
"CURSOR"
], ],
"equipData": { "equipData": {
"equipClass" : "tool" "equipClass" : "tool"
@ -97,7 +100,8 @@
"id" : "waterSpawner", "id" : "waterSpawner",
"tokens" : [ "tokens" : [
"GRAVITY", "GRAVITY",
"TARGETABLE" "TARGETABLE",
"CURSOR"
], ],
"equipData": { "equipData": {
"equipClass" : "tool" "equipClass" : "tool"

View File

@ -73,7 +73,7 @@
"offsetZ" : 0.0, "offsetZ" : 0.0,
"kinematic" : true "kinematic" : true
}, },
"interaction" : { "buttonInteraction" : {
"onInteract" : "menu", "onInteract" : "menu",
"windowTarget" : "crafting" "windowTarget" : "crafting"
}, },

View File

@ -1425,6 +1425,7 @@ Add bush entity
Add bushes to forest biome Add bushes to forest biome
Make foliage data files recursive Make foliage data files recursive
Fix bug with toolbar not unequipping items when moving to empty slot Fix bug with toolbar not unequipping items when moving to empty slot
Break out interaction ray casting into dedicated collision engine object

View File

@ -0,0 +1,213 @@
package electrosphere.client.interact;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import org.joml.Matrix4d;
import org.joml.Quaterniond;
import org.joml.Vector3d;
import org.ode4j.ode.DBody;
import electrosphere.collision.CollisionBodyCreation;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.game.data.collidable.CollidableTemplate;
/**
* Manages the interaction state
*/
public class ClientInteractionEngine {
/**
* The lock used for thread-safe-ing the engine
*/
private static ReentrantLock lock = new ReentrantLock();
/**
* The list of entities that are currently registered for interaction
*/
private static List<Entity> interactables = new LinkedList<Entity>();
/**
* Attaches a collidable template to a given entity
* @param rVal The entity
* @param physicsTemplate The collidable template
*/
public static void attachCollidableTemplate(Entity rVal, CollidableTemplate physicsTemplate){
DBody rigidBody = null;
Collidable collidable;
long categoryBit = Collidable.TYPE_OBJECT_BIT;
lock.lock();
interactables.add(rVal);
switch(physicsTemplate.getType()){
case "CYLINDER": {
//
//create dbody
rigidBody = CollisionBodyCreation.createCylinderBody(
Globals.clientSceneWrapper.getInteractionEngine(),
physicsTemplate.getDimension1(),
physicsTemplate.getDimension2(),
categoryBit
);
//
//set offset from center of entity position
CollisionBodyCreation.setOffsetPosition(
Globals.clientSceneWrapper.getInteractionEngine(),
rigidBody,
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
);
//
//create collidable and link to structures
collidable = new Collidable(rVal, Collidable.TYPE_OBJECT, true);
//
//store values
Matrix4d offsetTransform = new Matrix4d().translationRotate(
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW() //rotate
);
rVal.putData(EntityDataStrings.INTERACTION_OFFSET_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.INTERACTION_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.INTERACTION_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.INTERACTION_BODY, rigidBody);
Globals.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable);
} break;
case "CUBE": {
//
//create dbody
rigidBody = CollisionBodyCreation.createCubeBody(
Globals.clientSceneWrapper.getInteractionEngine(),
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()),
categoryBit
);
//
//set offset from center of entity position
CollisionBodyCreation.setOffsetPosition(
Globals.clientSceneWrapper.getInteractionEngine(),
rigidBody,
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
);
//
//create collidable and link to structures
collidable = new Collidable(rVal, Collidable.TYPE_OBJECT, true);
//
//store values
Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
1, 1, 1 //scale
);
rVal.putData(EntityDataStrings.INTERACTION_OFFSET_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.INTERACTION_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.INTERACTION_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.INTERACTION_BODY, rigidBody);
Globals.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable);
} break;
case "CAPSULE": {
//
//create dbody
rigidBody = CollisionBodyCreation.createCapsuleBody(
Globals.clientSceneWrapper.getInteractionEngine(),
physicsTemplate.getDimension2(),
physicsTemplate.getDimension2() - physicsTemplate.getDimension1() - physicsTemplate.getDimension1(),
categoryBit
);
//
//set offset from center of entity position
CollisionBodyCreation.setOffsetPosition(
Globals.clientSceneWrapper.getInteractionEngine(),
rigidBody,
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
);
//
//create collidable and link to structures
collidable = new Collidable(rVal, Collidable.TYPE_OBJECT, true);
//
//store values
Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
1, 1, 1 //scale
);
rVal.putData(EntityDataStrings.INTERACTION_OFFSET_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.INTERACTION_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.INTERACTION_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.INTERACTION_BODY, rigidBody);
Globals.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable);
} break;
default: {
throw new Error("Unsupported shape type! " + physicsTemplate.getType());
}
}
lock.unlock();
}
/**
* Destroys the interaction collidable attached to this entity
* @param rVal The entity
*/
public static void destroyCollidableTemplate(Entity rVal){
lock.lock();
CollisionEngine interactionEngine = Globals.clientSceneWrapper.getInteractionEngine();
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.INTERACTION_COLLIDABLE);
DBody body = (DBody)rVal.getData(EntityDataStrings.INTERACTION_BODY);
if(body != null){
PhysicsUtils.destroyBody(interactionEngine, body);
if(collidable != null){
interactionEngine.deregisterCollisionObject(body, collidable);
}
}
lock.unlock();
}
/**
* Updates the positions of all hitboxes
*/
private static void updateInteractableTransforms(){
lock.lock();
CollisionEngine interactionEngine = Globals.clientSceneWrapper.getInteractionEngine();
for(Entity entity : interactables){
if(entity != null){
Vector3d entityPosition = EntityUtils.getPosition(entity);
Quaterniond entityRotation = EntityUtils.getRotation(entity);
DBody body = (DBody)entity.getData(EntityDataStrings.INTERACTION_BODY);
PhysicsUtils.setRigidBodyTransform(interactionEngine, new Vector3d(entityPosition), new Quaterniond(entityRotation), body);
}
}
lock.unlock();
}
/**
* Ray cast to pick the current interaction target
* @return The current interaction target if it exists, null otherwise
*/
public static Entity rayCast(Vector3d centerPos, Vector3d eyePos){
lock.lock();
CollisionEngine interactionEngine = Globals.clientSceneWrapper.getInteractionEngine();
//update position of all interactables
ClientInteractionEngine.updateInteractableTransforms();
//ray cast
Entity target = interactionEngine.rayCast(centerPos, eyePos, CollisionEngine.DEFAULT_INTERACT_DISTANCE, Collidable.MASK_NO_TERRAIN);
lock.unlock();
return target;
}
}

View File

@ -41,6 +41,11 @@ public class ClientSceneWrapper {
*/ */
CollisionEngine chemistryEngine; CollisionEngine chemistryEngine;
/**
* The interaction engine
*/
CollisionEngine interactionEngine;
//The hitbox manager //The hitbox manager
HitboxManager hitboxManager; HitboxManager hitboxManager;
@ -48,12 +53,14 @@ public class ClientSceneWrapper {
* Constructor * Constructor
* @param scene The scene * @param scene The scene
* @param collisionEngine The collision engine * @param collisionEngine The collision engine
* @param chemistryEngine the chemsitry engine * @param chemistryEngine The chemsitry engine
* @param interactionEngine The interaction engine
*/ */
public ClientSceneWrapper(Scene scene, CollisionEngine collisionEngine, CollisionEngine chemistryEngine){ public ClientSceneWrapper(Scene scene, CollisionEngine collisionEngine, CollisionEngine chemistryEngine, CollisionEngine interactionEngine){
this.scene = scene; this.scene = scene;
this.collisionEngine = collisionEngine; this.collisionEngine = collisionEngine;
this.chemistryEngine = chemistryEngine; this.chemistryEngine = chemistryEngine;
this.interactionEngine = interactionEngine;
this.hitboxManager = new HitboxManager(resolutionCallback); this.hitboxManager = new HitboxManager(resolutionCallback);
} }
@ -192,7 +199,7 @@ public class ClientSceneWrapper {
/** /**
* Gets the collision engine backing the wrapper * Gets the collision engine backing the wrapper
* @return * @return The collision engine used for the physics system
*/ */
public CollisionEngine getCollisionEngine(){ public CollisionEngine getCollisionEngine(){
return collisionEngine; return collisionEngine;
@ -200,12 +207,20 @@ public class ClientSceneWrapper {
/** /**
* Gets the chemistry engine backing the wrapper * Gets the chemistry engine backing the wrapper
* @return * @return The collision engine used for the chemistry system
*/ */
public CollisionEngine getChemistryEngine(){ public CollisionEngine getChemistryEngine(){
return collisionEngine; return collisionEngine;
} }
/**
* Gets the interaction-based collision engine backing the wrapper
* @return The collision engine used for interaction ray casting
*/
public CollisionEngine getInteractionEngine(){
return interactionEngine;
}
/** /**
* Gets the hitbox manager for the client * Gets the hitbox manager for the client
* @return The hitbox manager * @return The hitbox manager

View File

@ -9,13 +9,12 @@ import org.lwjgl.glfw.GLFW;
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType; import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
import electrosphere.client.entity.camera.CameraEntityUtils; import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.client.entity.crosshair.Crosshair; import electrosphere.client.entity.crosshair.Crosshair;
import electrosphere.client.interact.ClientInteractionEngine;
import electrosphere.client.item.ItemActions; import electrosphere.client.item.ItemActions;
import electrosphere.client.ui.components.PlayerInventoryWindow; import electrosphere.client.ui.components.PlayerInventoryWindow;
import electrosphere.client.ui.menu.WindowStrings; import electrosphere.client.ui.menu.WindowStrings;
import electrosphere.client.ui.menu.WindowUtils; import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.client.ui.menu.ingame.MenuGeneratorsInGame; import electrosphere.client.ui.menu.ingame.MenuGeneratorsInGame;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.collidable.Collidable;
import electrosphere.controls.Control; import electrosphere.controls.Control;
import electrosphere.controls.Control.ControlMethod; import electrosphere.controls.Control.ControlMethod;
import electrosphere.controls.Control.ControlType; import electrosphere.controls.Control.ControlType;
@ -613,17 +612,19 @@ public class ControlCategoryMainGame {
controlMap.get(INPUT_CODE_INTERACT).setOnPress(new ControlMethod(){public void execute(MouseState mouseState){ controlMap.get(INPUT_CODE_INTERACT).setOnPress(new ControlMethod(){public void execute(MouseState mouseState){
if(Globals.playerEntity != null && Globals.playerCamera != null){ if(Globals.playerEntity != null && Globals.playerCamera != null){
Entity camera = Globals.playerCamera; Entity camera = Globals.playerCamera;
CollisionEngine collisionEngine = Globals.clientSceneWrapper.getCollisionEngine();
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(camera)).mul(-1.0); Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(camera)).mul(-1.0);
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera)); Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera));
Entity target = collisionEngine.rayCast(centerPos, eyePos, CollisionEngine.DEFAULT_INTERACT_DISTANCE, Collidable.MASK_NO_TERRAIN); Entity target = ClientInteractionEngine.rayCast(centerPos, eyePos);
if(target != null && CommonEntityFlags.isInteractable(target)){ if(target != null && CommonEntityFlags.isInteractable(target)){
Globals.interactionTarget = target; Globals.interactionTarget = target;
InteractionData interactionData = CommonEntityUtils.getCommonData(target).getInteraction(); InteractionData interactionData = CommonEntityUtils.getCommonData(target).getButtonInteraction();
switch(interactionData.getOnInteract()){ switch(interactionData.getOnInteract()){
case InteractionData.ON_INTERACT_TARGET: { case InteractionData.ON_INTERACT_MENU: {
WindowUtils.openInteractionMenu(interactionData.getWindowTarget()); WindowUtils.openInteractionMenu(interactionData.getWindowTarget());
} break; } break;
case InteractionData.ON_INTERACT_HARVEST: {
System.out.println("Harvest me! :D");
} break;
default: { default: {
throw new Error("Unhandled interaction signal " + interactionData.getOnInteract()); throw new Error("Unhandled interaction signal " + interactionData.getOnInteract());
} }

View File

@ -505,7 +505,7 @@ public class Globals {
shaderOptionMap.debug(); shaderOptionMap.debug();
//client scene wrapper //client scene wrapper
clientScene = new Scene(); clientScene = new Scene();
clientSceneWrapper = new ClientSceneWrapper(clientScene, new CollisionEngine(), CollisionEngine.create(new ClientChemistryCollisionCallback())); clientSceneWrapper = new ClientSceneWrapper(clientScene, new CollisionEngine(), CollisionEngine.create(new ClientChemistryCollisionCallback()), new CollisionEngine());
//temporary hold for skybox colors //temporary hold for skybox colors
skyboxColors = new ArrayList<Vector3f>(); skyboxColors = new ArrayList<Vector3f>();
//load asset manager //load asset manager
@ -728,7 +728,7 @@ public class Globals {
Globals.clientPlayer = null; Globals.clientPlayer = null;
Globals.playerManager = new PlayerManager(); Globals.playerManager = new PlayerManager();
Globals.clientScene = new Scene(); Globals.clientScene = new Scene();
Globals.clientSceneWrapper = new ClientSceneWrapper(Globals.clientScene, new CollisionEngine(), CollisionEngine.create(new ClientChemistryCollisionCallback())); Globals.clientSceneWrapper = new ClientSceneWrapper(Globals.clientScene, new CollisionEngine(), CollisionEngine.create(new ClientChemistryCollisionCallback()), new CollisionEngine());
Globals.clientSynchronizationManager = new ClientSynchronizationManager(); Globals.clientSynchronizationManager = new ClientSynchronizationManager();
Globals.server = null; Globals.server = null;
Globals.serverSynchronizationManager = new ServerSynchronizationManager(); Globals.serverSynchronizationManager = new ServerSynchronizationManager();

View File

@ -5,6 +5,7 @@ import java.util.List;
import org.joml.Quaterniond; import org.joml.Quaterniond;
import org.joml.Vector3d; import org.joml.Vector3d;
import electrosphere.client.interact.ClientInteractionEngine;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.state.attach.AttachUtils; import electrosphere.entity.state.attach.AttachUtils;
import electrosphere.entity.state.hitbox.HitboxCollectionState; import electrosphere.entity.state.hitbox.HitboxCollectionState;
@ -73,6 +74,7 @@ public class ClientEntityUtils {
Globals.clientScene.deregisterEntity(entity); Globals.clientScene.deregisterEntity(entity);
} }
HitboxCollectionState.destroyHitboxState(entity,false); HitboxCollectionState.destroyHitboxState(entity,false);
ClientInteractionEngine.destroyCollidableTemplate(entity);
if(entity == Globals.playerEntity && Globals.firstPersonEntity != null){ if(entity == Globals.playerEntity && Globals.firstPersonEntity != null){
ClientEntityUtils.destroyEntity(Globals.firstPersonEntity); ClientEntityUtils.destroyEntity(Globals.firstPersonEntity);
} }

View File

@ -138,6 +138,14 @@ public class EntityDataStrings {
public static final String PHYSICS_MODEL_TEMPLATE = "physicsModelTemplate"; public static final String PHYSICS_MODEL_TEMPLATE = "physicsModelTemplate";
public static final String PHYSICS_MASS = "physicsMass"; public static final String PHYSICS_MASS = "physicsMass";
public static final String PHYSICS_ENGINE_AUTHORITATIVE_TRANSFORM = "physicsEngineAuthoritativeTransform"; // The physics engine is authoritative abound transforms of object (eg position, rotation) public static final String PHYSICS_ENGINE_AUTHORITATIVE_TRANSFORM = "physicsEngineAuthoritativeTransform"; // The physics engine is authoritative abound transforms of object (eg position, rotation)
/*
* Interaction
*/
public static final String INTERACTION_OFFSET_TRANSFORM = "interactionOffsetTransform";
public static final String INTERACTION_TEMPLATE = "interactionTemplate";
public static final String INTERACTION_COLLIDABLE = "interactionCollidable";
public static final String INTERACTION_BODY = "interactionBody";
/* /*
Gravity Entity Gravity Entity

View File

@ -7,6 +7,7 @@ import org.joml.Quaterniond;
import org.joml.Vector3d; import org.joml.Vector3d;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import electrosphere.client.interact.ClientInteractionEngine;
import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.collision.collidable.Collidable; import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
@ -290,8 +291,13 @@ public class CommonEntityUtils {
// Interaction Logic // Interaction Logic
// //
// //
if(rawType.getInteraction() != null){ if(rawType.getButtonInteraction() != null){
CommonEntityFlags.setIsInteractable(entity, true); CommonEntityFlags.setIsInteractable(entity, true);
if(rawType.getButtonInteraction().getInteractionShape() != null){
ClientInteractionEngine.attachCollidableTemplate(entity, rawType.getButtonInteraction().getInteractionShape());
} else if(rawType.getCollidable() != null){
ClientInteractionEngine.attachCollidableTemplate(entity, rawType.getCollidable());
}
} }
// //
@ -592,7 +598,7 @@ public class CommonEntityUtils {
// Interaction Logic // Interaction Logic
// //
// //
if(rawType.getInteraction() != null){ if(rawType.getButtonInteraction() != null){
CommonEntityFlags.setIsInteractable(entity, true); CommonEntityFlags.setIsInteractable(entity, true);
} }

View File

@ -146,9 +146,9 @@ public class CommonEntityType {
SpawnItemDescription spawnItem; SpawnItemDescription spawnItem;
/** /**
* The behavior when this entity is interacted with * The behavior when this entity is interacted with via the button interaction
*/ */
InteractionData interaction; InteractionData buttonInteraction;
/** /**
* Gets the id for this creature type * Gets the id for this creature type
@ -375,19 +375,19 @@ public class CommonEntityType {
} }
/** /**
* Gets the behavior when this entity is interacted with * Gets the behavior when this entity is interacted with via the button interaction
* @return The behavior when this entity is interacted with * @return The behavior when this entity is interacted with via the button interaction
*/ */
public InteractionData getInteraction() { public InteractionData getButtonInteraction() {
return interaction; return buttonInteraction;
} }
/** /**
* Sets the behavior when this entity is interacted with * Sets the behavior when this entity is interacted with via the button interaction
* @return The behavior when this entity is interacted with * @return The behavior when this entity is interacted with via the button interaction
*/ */
public void setInteraction(InteractionData interaction) { public void setButtonInteraction(InteractionData interaction) {
this.interaction = interaction; this.buttonInteraction = interaction;
} }

View File

@ -1,5 +1,7 @@
package electrosphere.game.data.common.interact; package electrosphere.game.data.common.interact;
import electrosphere.game.data.collidable.CollidableTemplate;
/** /**
* Controls handling when interacting with this entity * Controls handling when interacting with this entity
*/ */
@ -8,7 +10,12 @@ public class InteractionData {
/** /**
* Pulls up a menu on interaction * Pulls up a menu on interaction
*/ */
public static final String ON_INTERACT_TARGET = "menu"; public static final String ON_INTERACT_MENU = "menu";
/**
* Try harvesting the entity on interaction
*/
public static final String ON_INTERACT_HARVEST = "harvest";
/** /**
* The function to run on interaction * The function to run on interaction
@ -20,6 +27,11 @@ public class InteractionData {
*/ */
String windowTarget; String windowTarget;
/**
* The collidable shape used for ray casting to pick entities to interact with
*/
CollidableTemplate interactionShape;
/** /**
* Gets the function to run on interaction * Gets the function to run on interaction
* @return The function to run on interaction * @return The function to run on interaction
@ -36,6 +48,12 @@ public class InteractionData {
return windowTarget; return windowTarget;
} }
/**
* Gets the template for the shape used to ray cast for interaction targets
* @return The collidable template
*/
public CollidableTemplate getInteractionShape(){
return interactionShape;
}
} }