interaction target work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
589833b32f
commit
75fe5a9d1a
@ -1547,6 +1547,7 @@ Fab selection tool actually loads fab files
|
|||||||
Fix fab file reading
|
Fix fab file reading
|
||||||
Fab tool can show transparent, loaded version of fab file
|
Fab tool can show transparent, loaded version of fab file
|
||||||
Interaction target tooltip at top of window
|
Interaction target tooltip at top of window
|
||||||
|
Interaction target tooltip shows entity target, voxel targets
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -7,9 +7,12 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
import org.joml.Matrix4d;
|
import org.joml.Matrix4d;
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
|
import org.joml.Vector3i;
|
||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DBody;
|
||||||
|
|
||||||
|
import electrosphere.client.block.BlockChunkData;
|
||||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||||
|
import electrosphere.client.terrain.cache.ChunkData;
|
||||||
import electrosphere.client.ui.menu.ingame.InteractionTargetMenu;
|
import electrosphere.client.ui.menu.ingame.InteractionTargetMenu;
|
||||||
import electrosphere.collision.CollisionBodyCreation;
|
import electrosphere.collision.CollisionBodyCreation;
|
||||||
import electrosphere.collision.CollisionEngine;
|
import electrosphere.collision.CollisionEngine;
|
||||||
@ -19,8 +22,10 @@ import electrosphere.engine.Globals;
|
|||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.types.EntityTypes.EntityType;
|
||||||
import electrosphere.entity.types.common.CommonEntityUtils;
|
import electrosphere.entity.types.common.CommonEntityUtils;
|
||||||
import electrosphere.game.data.collidable.CollidableTemplate;
|
import electrosphere.game.data.collidable.CollidableTemplate;
|
||||||
|
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the interaction state
|
* Manages the interaction state
|
||||||
@ -220,14 +225,68 @@ public class ClientInteractionEngine {
|
|||||||
if(Globals.playerEntity != null && Globals.playerCamera != null){
|
if(Globals.playerEntity != null && Globals.playerCamera != null){
|
||||||
boolean set = false;
|
boolean set = false;
|
||||||
Entity camera = Globals.playerCamera;
|
Entity camera = Globals.playerCamera;
|
||||||
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(camera)).mul(-1.0);
|
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(camera));
|
||||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera));
|
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera));
|
||||||
Entity target = ClientInteractionEngine.rayCast(centerPos, eyePos);
|
Entity target = ClientInteractionEngine.rayCast(centerPos, new Vector3d(eyePos).mul(-1));
|
||||||
if(target != null){
|
if(target != null){
|
||||||
String text = CommonEntityUtils.getEntitySubtype(target);
|
String text = CommonEntityUtils.getEntitySubtype(target);
|
||||||
InteractionTargetMenu.setInteractionTargetString(text);
|
InteractionTargetMenu.setInteractionTargetString(text);
|
||||||
set = true;
|
set = true;
|
||||||
}
|
}
|
||||||
|
if(!set){
|
||||||
|
target = Globals.clientSceneWrapper.getCollisionEngine().rayCast(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
|
||||||
|
if(target != null){
|
||||||
|
EntityType type = CommonEntityUtils.getEntityType(target);
|
||||||
|
if(type == null){
|
||||||
|
throw new Error("Entity does not have a type defined!");
|
||||||
|
}
|
||||||
|
switch(type){
|
||||||
|
case CREATURE: {
|
||||||
|
InteractionTargetMenu.setInteractionTargetString(CommonEntityUtils.getEntitySubtype(target));
|
||||||
|
set = true;
|
||||||
|
} break;
|
||||||
|
case ITEM: {
|
||||||
|
InteractionTargetMenu.setInteractionTargetString(CommonEntityUtils.getEntitySubtype(target));
|
||||||
|
set = true;
|
||||||
|
} break;
|
||||||
|
case FOLIAGE: {
|
||||||
|
InteractionTargetMenu.setInteractionTargetString(CommonEntityUtils.getEntitySubtype(target));
|
||||||
|
set = true;
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
//silently ignore
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!set){
|
||||||
|
Vector3d collisionPosition = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(centerPos, new Vector3d(eyePos).mul(-1), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
|
||||||
|
if(collisionPosition != null && collisionPosition.distance(centerPos) < CollisionEngine.DEFAULT_INTERACT_DISTANCE){
|
||||||
|
//grab block at point
|
||||||
|
BlockChunkData blockChunkData = Globals.clientBlockManager.getChunkDataAtWorldPoint(Globals.clientWorldData.convertRealToWorldSpace(collisionPosition), 0);
|
||||||
|
if(blockChunkData != null){
|
||||||
|
Vector3i blockPos = Globals.clientWorldData.convertRealToBlockSpace(collisionPosition);
|
||||||
|
if(!blockChunkData.isEmpty(blockPos.x, blockPos.y, blockPos.z)){
|
||||||
|
short type = blockChunkData.getType(blockPos.x, blockPos.y, blockPos.z);
|
||||||
|
String text = Globals.gameConfigCurrent.getBlockData().getTypeFromId(type).getName();
|
||||||
|
InteractionTargetMenu.setInteractionTargetString(text);
|
||||||
|
set = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if we didn't find a block type, try terrain
|
||||||
|
if(!set){
|
||||||
|
ChunkData chunkData = Globals.clientTerrainManager.getChunkDataAtWorldPoint(Globals.clientWorldData.convertRealToWorldSpace(collisionPosition), 0);
|
||||||
|
if(chunkData != null){
|
||||||
|
int voxelType = chunkData.getType(Globals.clientWorldData.convertRealToVoxelSpace(collisionPosition));
|
||||||
|
if(voxelType != ServerTerrainChunk.VOXEL_TYPE_AIR){
|
||||||
|
String text = Globals.gameConfigCurrent.getVoxelData().getTypeFromId(voxelType).getName();
|
||||||
|
InteractionTargetMenu.setInteractionTargetString(text);
|
||||||
|
set = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if(!set){
|
if(!set){
|
||||||
InteractionTargetMenu.setInteractionTargetString("");
|
InteractionTargetMenu.setInteractionTargetString("");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,7 +68,9 @@ public class ClientTerrainManager {
|
|||||||
*/
|
*/
|
||||||
static final int CACHE_SIZE_IN_MB = (CACHE_SIZE * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * 2 * 4) / 1024 / 1024;
|
static final int CACHE_SIZE_IN_MB = (CACHE_SIZE * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * 2 * 4) / 1024 / 1024;
|
||||||
|
|
||||||
//used for caching the macro values
|
/**
|
||||||
|
* used for caching the macro values
|
||||||
|
*/
|
||||||
ClientTerrainCache terrainCache;
|
ClientTerrainCache terrainCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,10 +78,14 @@ public class ClientTerrainManager {
|
|||||||
*/
|
*/
|
||||||
BlockChunkCache blockCache;
|
BlockChunkCache blockCache;
|
||||||
|
|
||||||
//The world data for the client
|
/**
|
||||||
|
* The world data for the client
|
||||||
|
*/
|
||||||
ClientWorldData clientWorldData;
|
ClientWorldData clientWorldData;
|
||||||
|
|
||||||
//The queue of terrain chunk data to be buffered to gpu
|
/**
|
||||||
|
* The queue of terrain chunk data to be buffered to gpu
|
||||||
|
*/
|
||||||
static List<TerrainChunkGenQueueItem> terrainChunkGenerationQueue = new LinkedList<TerrainChunkGenQueueItem>();
|
static List<TerrainChunkGenQueueItem> terrainChunkGenerationQueue = new LinkedList<TerrainChunkGenQueueItem>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -634,7 +634,7 @@ public class CollisionEngine {
|
|||||||
* @return The entity that the ray collides with if successful, null otherwise
|
* @return The entity that the ray collides with if successful, null otherwise
|
||||||
*/
|
*/
|
||||||
public Entity rayCast(Vector3d start, Vector3d direction, double length){
|
public Entity rayCast(Vector3d start, Vector3d direction, double length){
|
||||||
return rayCast(start,direction,length,null);
|
return this.rayCast(start,direction,length,null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import org.ode4j.ode.OdeHelper;
|
|||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.state.attach.AttachUtils;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
|
|
||||||
public class RayCastCallback implements DNearCallback {
|
public class RayCastCallback implements DNearCallback {
|
||||||
@ -79,6 +80,13 @@ void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) {
|
|||||||
if(collidable2 != null && collidable2.getParent() == Globals.playerEntity){
|
if(collidable2 != null && collidable2.getParent() == Globals.playerEntity){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//don't collide with entities that are attached to the parent either
|
||||||
|
if(collidable1 != null && AttachUtils.getParent(collidable1.getParent()) != null && AttachUtils.getParent(collidable1.getParent()) == Globals.playerEntity){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(collidable2 != null && AttachUtils.getParent(collidable2.getParent()) != null && AttachUtils.getParent(collidable2.getParent()) == Globals.playerEntity){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Globals.profiler.beginAggregateCpuSample("RayCastCallback - try collisions");
|
Globals.profiler.beginAggregateCpuSample("RayCastCallback - try collisions");
|
||||||
if(
|
if(
|
||||||
@ -137,14 +145,27 @@ void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) {
|
|||||||
* Data object that contains the information for a ray cast check
|
* Data object that contains the information for a ray cast check
|
||||||
*/
|
*/
|
||||||
static class RayCastCallbackData {
|
static class RayCastCallbackData {
|
||||||
//The map of ode DBody -> collidable
|
|
||||||
|
/**
|
||||||
|
* The map of ode DBody -> collidable
|
||||||
|
*/
|
||||||
Map<DBody,Collidable> bodyEntityMap;
|
Map<DBody,Collidable> bodyEntityMap;
|
||||||
//The mask of collidable types to filter collisions by. Can be null.
|
|
||||||
|
/**
|
||||||
|
* The mask of collidable types to filter collisions by. Can be null.
|
||||||
|
*/
|
||||||
List<String> collidableTypeMask;
|
List<String> collidableTypeMask;
|
||||||
//The entity that the ray cast collided with. If null, no entity was collided with.
|
|
||||||
|
/**
|
||||||
|
* The entity that the ray cast collided with. If null, no entity was collided with.
|
||||||
|
*/
|
||||||
Entity collidedEntity = null;
|
Entity collidedEntity = null;
|
||||||
//The position in world space that the collision happened
|
|
||||||
|
/**
|
||||||
|
* The position in world space that the collision happened
|
||||||
|
*/
|
||||||
Vector3d collisionPosition = null;
|
Vector3d collisionPosition = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param bodyEntityMap The map of ode DBody -> collidable
|
* @param bodyEntityMap The map of ode DBody -> collidable
|
||||||
|
|||||||
@ -26,7 +26,11 @@ public class EntityTypes {
|
|||||||
/**
|
/**
|
||||||
* A piece of foliage
|
* A piece of foliage
|
||||||
*/
|
*/
|
||||||
FOLIAGE(3)
|
FOLIAGE(3),
|
||||||
|
/**
|
||||||
|
* Special engine-created entities (ie not defined in a json file)
|
||||||
|
*/
|
||||||
|
ENGINE(4),
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,7 +42,7 @@ public class EntityTypes {
|
|||||||
* Constructor
|
* Constructor
|
||||||
* @param newValue The value
|
* @param newValue The value
|
||||||
*/
|
*/
|
||||||
EntityType(final int newValue){
|
private EntityType(final int newValue){
|
||||||
value = newValue;
|
value = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,9 @@ import electrosphere.entity.Entity;
|
|||||||
import electrosphere.entity.EntityCreationUtils;
|
import electrosphere.entity.EntityCreationUtils;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.types.EntityTypes.EntityType;
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||||
|
import electrosphere.entity.types.common.CommonEntityUtils;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.renderer.meshgen.TransvoxelModelGeneration;
|
import electrosphere.renderer.meshgen.TransvoxelModelGeneration;
|
||||||
import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData;
|
import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData;
|
||||||
@ -59,6 +61,7 @@ public class TerrainChunk {
|
|||||||
Globals.profiler.beginAggregateCpuSample("TerrainChunk.clientCreateTerrainChunkEntity");
|
Globals.profiler.beginAggregateCpuSample("TerrainChunk.clientCreateTerrainChunkEntity");
|
||||||
|
|
||||||
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
||||||
|
CommonEntityUtils.setEntityType(rVal, EntityType.ENGINE);
|
||||||
if(hasPolygons && chunkData.terrainGrid != null && chunkData.textureGrid != null){
|
if(hasPolygons && chunkData.terrainGrid != null && chunkData.textureGrid != null){
|
||||||
generationService.submit(() -> {
|
generationService.submit(() -> {
|
||||||
TerrainChunkData data;
|
TerrainChunkData data;
|
||||||
@ -149,4 +152,13 @@ public class TerrainChunk {
|
|||||||
generationService.shutdownNow();
|
generationService.shutdownNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this is a terrain entity
|
||||||
|
* @param entity The entity
|
||||||
|
* @return True if it is a terrain entity, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean isTerrainEntity(Entity entity){
|
||||||
|
return entity.containsKey(EntityDataStrings.TERRAIN_IS_TERRAIN);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user