macro pathfinding progressive iteration fix
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-06-05 12:14:13 -04:00
parent 8bc8fb464b
commit 25d2dcd943
13 changed files with 181 additions and 15 deletions

View File

@ -2120,6 +2120,8 @@ Fix projection matrix being sent to light manager
(06/05/2025) (06/05/2025)
voxel tests voxel tests
Physics work Physics work
Debug rendering for facing vectors
Fix progressive pathfinding iteration

View File

@ -71,6 +71,9 @@ public class ImGuiRenderer {
if(ImGui.button("Draw Server Cell Colliders")){ if(ImGui.button("Draw Server Cell Colliders")){
Globals.gameConfigCurrent.getSettings().setGraphicsDebugDrawServerCellColliders(!Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawServerCellColliders()); Globals.gameConfigCurrent.getSettings().setGraphicsDebugDrawServerCellColliders(!Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawServerCellColliders());
} }
if(ImGui.button("Draw Server Facing Vectors")){
Globals.gameConfigCurrent.getSettings().setGraphicsDebugDrawServerFacingVectors(!Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawServerFacingVectors());
}
ImGui.unindent(); ImGui.unindent();
} }
if(ImGui.collapsingHeader("OpenGL Details")){ if(ImGui.collapsingHeader("OpenGL Details")){

View File

@ -57,6 +57,7 @@ public class UserSettings {
boolean graphicsDebugDrawMacroColliders; boolean graphicsDebugDrawMacroColliders;
boolean graphicsDebugDrawClientCellColliders; boolean graphicsDebugDrawClientCellColliders;
boolean graphicsDebugDrawServerCellColliders; boolean graphicsDebugDrawServerCellColliders;
boolean graphicsDebugDrawServerFacingVectors;
//debug network //debug network
boolean netRunNetMonitor; boolean netRunNetMonitor;
@ -256,6 +257,16 @@ public class UserSettings {
this.graphicsDebugDrawServerCellColliders = graphicsDebugDrawServerCellColliders; this.graphicsDebugDrawServerCellColliders = graphicsDebugDrawServerCellColliders;
} }
public boolean getGraphicsDebugDrawServerFacingVectors() {
return graphicsDebugDrawServerFacingVectors;
}
public void setGraphicsDebugDrawServerFacingVectors(boolean graphicsDebugDrawServerFacingVectors) {
this.graphicsDebugDrawServerFacingVectors = graphicsDebugDrawServerFacingVectors;
}

View File

@ -35,6 +35,7 @@ import electrosphere.renderer.anim.Animation;
import electrosphere.server.ai.AI; import electrosphere.server.ai.AI;
import electrosphere.server.datacell.utils.DataCellSearchUtils; import electrosphere.server.datacell.utils.DataCellSearchUtils;
import electrosphere.server.utils.ServerScriptUtils; import electrosphere.server.utils.ServerScriptUtils;
import electrosphere.util.math.BasicMathUtils;
import electrosphere.util.math.SpatialMathUtils; import electrosphere.util.math.SpatialMathUtils;
import java.util.LinkedList; import java.util.LinkedList;
@ -52,6 +53,16 @@ Behavior tree for movement in an entity
*/ */
public class ServerGroundMovementTree implements BehaviorTree { public class ServerGroundMovementTree implements BehaviorTree {
/**
* Denotes an invalid elevation to lerp non-body collidables towards
*/
public static final double INVALID_ELEVATION = -1;
/**
* Amount to lerp non-body collidable elevation by
*/
public static final double ELEVATION_LERP_FACTOR = 0.01;
/** /**
* Lock for handling threading with network messages * Lock for handling threading with network messages
*/ */
@ -86,6 +97,11 @@ public class ServerGroundMovementTree implements BehaviorTree {
//the vector organizing the direction the entity will move in //the vector organizing the direction the entity will move in
Vector3d movementVector = new Vector3d(1,0,0); Vector3d movementVector = new Vector3d(1,0,0);
/**
* Target elevation for specifically non-body collidables to lerp to organically
*/
private double collidableElevationTarget = -1;
private ServerGroundMovementTree(Entity e, Object ... params){ private ServerGroundMovementTree(Entity e, Object ... params){
@ -106,8 +122,8 @@ public class ServerGroundMovementTree implements BehaviorTree {
* @param facing The facing dir to start with * @param facing The facing dir to start with
*/ */
public void start(MovementRelativeFacing facing){ public void start(MovementRelativeFacing facing){
if(canStartMoving()){ if(this.canStartMoving()){
setFacing(facing); this.setFacing(facing);
state = MovementTreeState.STARTUP; state = MovementTreeState.STARTUP;
//if we aren't the server, alert the server we intend to walk forward //if we aren't the server, alert the server we intend to walk forward
Vector3d position = EntityUtils.getPosition(parent); Vector3d position = EntityUtils.getPosition(parent);
@ -241,11 +257,11 @@ public class ServerGroundMovementTree implements BehaviorTree {
//0 is startup //0 is startup
case 0: { case 0: {
// System.out.println("Receive move packet from client treestate " + message.gettreeState()); // System.out.println("Receive move packet from client treestate " + message.gettreeState());
start(ClientGroundMovementTree.getMovementRelativeFacingShortAsEnum((short)message.getpropertyValueInt())); this.start(ClientGroundMovementTree.getMovementRelativeFacingShortAsEnum((short)message.getpropertyValueInt()));
} break; } break;
case 2: { case 2: {
// System.out.println("Receive move packet from client treestate " + message.gettreeState()); // System.out.println("Receive move packet from client treestate " + message.gettreeState());
slowdown(); this.slowdown();
} break; } break;
default: { default: {
@ -294,6 +310,9 @@ public class ServerGroundMovementTree implements BehaviorTree {
Vector3d velVec = new Vector3d(movementVector); Vector3d velVec = new Vector3d(movementVector);
velVec.mul(velocity * Globals.engineState.timekeeper.getSimFrameTime() * Timekeeper.ENGINE_STEP_SIZE); velVec.mul(velocity * Globals.engineState.timekeeper.getSimFrameTime() * Timekeeper.ENGINE_STEP_SIZE);
velVec.add(position); velVec.add(position);
if(this.collidableElevationTarget != ServerGroundMovementTree.INVALID_ELEVATION){
velVec.y = BasicMathUtils.lerp(position.y, this.collidableElevationTarget, ServerGroundMovementTree.ELEVATION_LERP_FACTOR);
}
ServerEntityUtils.repositionEntity(parent, velVec); ServerEntityUtils.repositionEntity(parent, velVec);
} else { } else {
body.enable(); body.enable();
@ -346,6 +365,9 @@ public class ServerGroundMovementTree implements BehaviorTree {
Vector3d velVec = new Vector3d(movementVector); Vector3d velVec = new Vector3d(movementVector);
velVec.mul(velocity * Globals.engineState.timekeeper.getSimFrameTime() * Timekeeper.ENGINE_STEP_SIZE); velVec.mul(velocity * Globals.engineState.timekeeper.getSimFrameTime() * Timekeeper.ENGINE_STEP_SIZE);
velVec.add(position); velVec.add(position);
if(this.collidableElevationTarget != ServerGroundMovementTree.INVALID_ELEVATION){
velVec.y = BasicMathUtils.lerp(position.y, this.collidableElevationTarget, ServerGroundMovementTree.ELEVATION_LERP_FACTOR);
}
ServerEntityUtils.repositionEntity(parent, velVec); ServerEntityUtils.repositionEntity(parent, velVec);
} else { } else {
body.enable(); body.enable();
@ -417,6 +439,9 @@ public class ServerGroundMovementTree implements BehaviorTree {
Vector3d velVec = new Vector3d(movementVector); Vector3d velVec = new Vector3d(movementVector);
velVec.mul(velocity * Globals.engineState.timekeeper.getSimFrameTime() * Timekeeper.ENGINE_STEP_SIZE); velVec.mul(velocity * Globals.engineState.timekeeper.getSimFrameTime() * Timekeeper.ENGINE_STEP_SIZE);
velVec.add(position); velVec.add(position);
if(this.collidableElevationTarget != ServerGroundMovementTree.INVALID_ELEVATION){
velVec.y = BasicMathUtils.lerp(position.y, this.collidableElevationTarget, ServerGroundMovementTree.ELEVATION_LERP_FACTOR);
}
ServerEntityUtils.repositionEntity(parent, velVec); ServerEntityUtils.repositionEntity(parent, velVec);
} else { } else {
body.enable(); body.enable();
@ -880,4 +905,12 @@ public class ServerGroundMovementTree implements BehaviorTree {
return entity.containsKey(EntityDataStrings.TREE_SERVERGROUNDMOVEMENTTREE); return entity.containsKey(EntityDataStrings.TREE_SERVERGROUNDMOVEMENTTREE);
} }
/**
* Sets the target elevation for non-body collidables to lerp to
* @param collidableElevationTarget The target elevation
*/
public void setCollidableElevationTarget(double collidableElevationTarget){
this.collidableElevationTarget = collidableElevationTarget;
}
} }

View File

@ -3,6 +3,7 @@ package electrosphere.entity.state.physicssync.upright;
import org.joml.Quaterniond; import org.joml.Quaterniond;
import org.joml.Vector3d; import org.joml.Vector3d;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import org.ode4j.ode.DGeom;
import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.collision.PhysicsUtils; import electrosphere.collision.PhysicsUtils;
@ -12,6 +13,8 @@ import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.physicssync.ClientPhysicsSyncTree; import electrosphere.entity.state.physicssync.ClientPhysicsSyncTree;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.util.math.SpatialMathUtils;
public class ClientAlwaysUprightTree implements BehaviorTree { public class ClientAlwaysUprightTree implements BehaviorTree {
@ -45,6 +48,23 @@ public class ClientAlwaysUprightTree implements BehaviorTree {
EntityUtils.getRotation(parent).set(sourceRotation); EntityUtils.getRotation(parent).set(sourceRotation);
PhysicsUtils.synchronizeData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), body, position, sourceRotation, linearVelocity, angularVelocity, linearForce, angularForce); PhysicsUtils.synchronizeData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), body, position, sourceRotation, linearVelocity, angularVelocity, linearForce, angularForce);
} }
DGeom geom = PhysicsEntityUtils.getDGeom(parent);
if(geom != null){
Vector3d position = EntityUtils.getPosition(parent);
Quaterniond sourceRotation = new Quaterniond(EntityUtils.getRotation(parent));
//make sure rotation is vertical
// sourceRotation = sourceRotation.mul(0.001, 0.001, 0.001, 1).normalize();
//calculate rotation based on facing vector
if(CreatureUtils.getFacingVector(parent) != null){
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
sourceRotation = new Quaterniond().rotationTo(SpatialMathUtils.getOriginVector(), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
}
EntityUtils.setPosition(parent, position);
EntityUtils.getRotation(parent).set(sourceRotation);
PhysicsUtils.setGeomTransform(Globals.clientState.clientSceneWrapper.getCollisionEngine(), position, sourceRotation, geom);
}
} }
/** /**

View File

@ -3,6 +3,7 @@ package electrosphere.entity.state.physicssync.upright;
import org.joml.Quaterniond; import org.joml.Quaterniond;
import org.joml.Vector3d; import org.joml.Vector3d;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import org.ode4j.ode.DGeom;
import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.collision.PhysicsUtils; import electrosphere.collision.PhysicsUtils;
@ -55,6 +56,24 @@ public class ServerAlwaysUprightTree implements BehaviorTree {
EntityUtils.getRotation(parent).set(sourceRotation); EntityUtils.getRotation(parent).set(sourceRotation);
PhysicsUtils.synchronizeData(realm.getCollisionEngine(), body, position, sourceRotation, linearVelocity, angularVelocity, linearForce, angularForce); PhysicsUtils.synchronizeData(realm.getCollisionEngine(), body, position, sourceRotation, linearVelocity, angularVelocity, linearForce, angularForce);
} }
DGeom geom = PhysicsEntityUtils.getDGeom(parent);
if(geom != null){
Realm realm = Globals.serverState.realmManager.getEntityRealm(parent);
Vector3d position = EntityUtils.getPosition(parent);
Quaterniond sourceRotation = new Quaterniond(EntityUtils.getRotation(parent));
//make sure rotation is vertical
// sourceRotation = sourceRotation.mul(0.001, 0.001, 0.001, 1).normalize();
//calculate rotation based on facing vector
if(CreatureUtils.getFacingVector(parent) != null){
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
sourceRotation = new Quaterniond().rotationTo(SpatialMathUtils.getOriginVector(), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
}
EntityUtils.setPosition(parent, position);
EntityUtils.getRotation(parent).set(sourceRotation);
PhysicsUtils.setGeomTransform(realm.getCollisionEngine(), position, sourceRotation, geom);
}
} }
/** /**

View File

@ -1,5 +1,6 @@
package electrosphere.renderer.pipelines.debug; package electrosphere.renderer.pipelines.debug;
import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -39,6 +40,7 @@ import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.hitbox.HitboxCollectionState; import electrosphere.entity.state.hitbox.HitboxCollectionState;
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState; import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState;
import electrosphere.entity.types.common.CommonEntityUtils; import electrosphere.entity.types.common.CommonEntityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.renderer.OpenGLState; import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.RenderPipelineState;
import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.RenderingEngine;
@ -334,6 +336,18 @@ public class DebugContentPipeline implements RenderPipeline {
} }
} }
//
//Draw facing vectors
if(Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawServerFacingVectors()){
Realm realm = Globals.serverState.realmManager.first();
Collection<Entity> entities = realm.getDataCellManager().entityLookup(CameraEntityUtils.getCameraCenter(Globals.clientState.playerCamera), 100);
for(Entity ent : entities){
if(CreatureUtils.getFacingVector(ent) != null){
DebugContentPipeline.renderTube(openGLState, renderPipelineState, modelTransformMatrix, EntityUtils.getPosition(ent), new Vector3d(EntityUtils.getPosition(ent)).add(CreatureUtils.getFacingVector(ent)), 0.3, AssetDataStrings.TEXTURE_BLUE_TRANSPARENT);
}
}
}
//update pipeline state to use mats again //update pipeline state to use mats again
renderPipelineState.setUseMaterial(true); renderPipelineState.setUseMaterial(true);
@ -395,7 +409,7 @@ public class DebugContentPipeline implements RenderPipeline {
* @param physicsEntity The entity * @param physicsEntity The entity
* @param template The template * @param template The template
*/ */
static void renderCollidable(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, Entity physicsEntity, CollidableTemplate template){ private static void renderCollidable(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, Entity physicsEntity, CollidableTemplate template){
Model physicsGraphicsModel; Model physicsGraphicsModel;
if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){ if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){
switch(template.getType()){ switch(template.getType()){
@ -469,7 +483,7 @@ public class DebugContentPipeline implements RenderPipeline {
* @param modelTransformMatrix The model transform matrix * @param modelTransformMatrix The model transform matrix
* @param hitboxState The hitbox collection state * @param hitboxState The hitbox collection state
*/ */
static void renderHitboxes(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, HitboxCollectionState hitboxState){ private static void renderHitboxes(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, HitboxCollectionState hitboxState){
Model hitboxModel; Model hitboxModel;
for(DGeom geom : hitboxState.getGeometries()){ for(DGeom geom : hitboxState.getGeometries()){
if(geom instanceof DSphere){ if(geom instanceof DSphere){
@ -527,7 +541,7 @@ public class DebugContentPipeline implements RenderPipeline {
* @param modelTransformMatrix The model transform matrix * @param modelTransformMatrix The model transform matrix
* @param areaSelection The area selection * @param areaSelection The area selection
*/ */
static void renderAreaSelection(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, AreaSelection areaSelection, String texturePath){ private static void renderAreaSelection(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, AreaSelection areaSelection, String texturePath){
Model model = Globals.assetManager.fetchModel(AssetDataStrings.UNITCUBE); Model model = Globals.assetManager.fetchModel(AssetDataStrings.UNITCUBE);
if(model != null){ if(model != null){
Texture texture = Globals.assetManager.fetchTexture(texturePath); Texture texture = Globals.assetManager.fetchTexture(texturePath);
@ -553,7 +567,7 @@ public class DebugContentPipeline implements RenderPipeline {
* @param modelTransformMatrix The model transform matrix * @param modelTransformMatrix The model transform matrix
* @param areaSelection The area selection * @param areaSelection The area selection
*/ */
static void renderPoint(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, Vector3d point, double size, String texturePath){ private static void renderPoint(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, Vector3d point, double size, String texturePath){
Model model = Globals.assetManager.fetchModel(AssetDataStrings.UNITSPHERE); Model model = Globals.assetManager.fetchModel(AssetDataStrings.UNITSPHERE);
if(model != null){ if(model != null){
Texture texture = Globals.assetManager.fetchTexture(texturePath); Texture texture = Globals.assetManager.fetchTexture(texturePath);
@ -577,7 +591,7 @@ public class DebugContentPipeline implements RenderPipeline {
* @param modelTransformMatrix The model transform matrix * @param modelTransformMatrix The model transform matrix
* @param areaSelection The area selection * @param areaSelection The area selection
*/ */
static void renderAABB(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, AABBd aabb, String texturePath){ private static void renderAABB(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, AABBd aabb, String texturePath){
DebugContentPipeline.renderAABB(openGLState, renderPipelineState, modelTransformMatrix, new Vector3d(aabb.minX,aabb.minY,aabb.minZ), new Vector3d(aabb.maxX,aabb.maxY,aabb.maxZ), texturePath); DebugContentPipeline.renderAABB(openGLState, renderPipelineState, modelTransformMatrix, new Vector3d(aabb.minX,aabb.minY,aabb.minZ), new Vector3d(aabb.maxX,aabb.maxY,aabb.maxZ), texturePath);
} }
@ -588,7 +602,7 @@ public class DebugContentPipeline implements RenderPipeline {
* @param modelTransformMatrix The model transform matrix * @param modelTransformMatrix The model transform matrix
* @param areaSelection The area selection * @param areaSelection The area selection
*/ */
static void renderAABB(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, Vector3d start, Vector3d end, String texturePath){ private static void renderAABB(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, Vector3d start, Vector3d end, String texturePath){
Model model = Globals.assetManager.fetchModel(AssetDataStrings.UNITCUBE); Model model = Globals.assetManager.fetchModel(AssetDataStrings.UNITCUBE);
if(model != null){ if(model != null){
Texture texture = Globals.assetManager.fetchTexture(texturePath); Texture texture = Globals.assetManager.fetchTexture(texturePath);
@ -612,7 +626,7 @@ public class DebugContentPipeline implements RenderPipeline {
* @param modelTransformMatrix The model transform matrix * @param modelTransformMatrix The model transform matrix
* @param areaSelection The area selection * @param areaSelection The area selection
*/ */
static void renderTube(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, Vector3d start, Vector3d end, double radius, String texturePath){ private static void renderTube(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, Vector3d start, Vector3d end, double radius, String texturePath){
Model model = Globals.assetManager.fetchModel(AssetDataStrings.UNITCYLINDER); Model model = Globals.assetManager.fetchModel(AssetDataStrings.UNITCYLINDER);
if(model != null){ if(model != null){
Texture texture = Globals.assetManager.fetchTexture(texturePath); Texture texture = Globals.assetManager.fetchTexture(texturePath);

View File

@ -0,0 +1,55 @@
package electrosphere.server.ai.nodes.actions.move;
import org.joml.Vector3d;
import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree;
import electrosphere.server.ai.blackboard.Blackboard;
import electrosphere.server.ai.nodes.AITreeNode;
import electrosphere.server.macro.structure.VirtualStructure;
/**
* Lerps the elevation of non-body collidables
*/
public class CollidableElevationLerpNode implements AITreeNode {
/**
* The key to lookup the target under
*/
private String targetKey;
/**
* Constructor
* @param targetKey The key to lookup the target under
*/
public CollidableElevationLerpNode(String targetKey){
this.targetKey = targetKey;
}
@Override
public AITreeNodeResult evaluate(Entity entity, Blackboard blackboard) {
if(PhysicsEntityUtils.containsDGeom(entity)){
Object targetRaw = blackboard.get(this.targetKey);
Vector3d targetPos = null;
if(targetRaw == null){
throw new Error("Target undefined!");
}
if(targetRaw instanceof Vector3d){
targetPos = (Vector3d)targetRaw;
} else if(targetRaw instanceof Entity){
targetPos = EntityUtils.getPosition((Entity)targetRaw);
} else if(targetRaw instanceof VirtualStructure){
targetPos = ((VirtualStructure)targetRaw).getPos();
} else {
throw new Error("Unsupported target type " + targetRaw);
}
if(ServerGroundMovementTree.hasServerGroundMovementTree(entity)){
ServerGroundMovementTree tree = ServerGroundMovementTree.getServerGroundMovementTree(entity);
tree.setCollidableElevationTarget(targetPos.y);
}
}
return AITreeNodeResult.SUCCESS;
}
}

View File

@ -49,7 +49,8 @@ public class FaceTargetNode implements AITreeNode {
Vector3d parentPos = EntityUtils.getPosition(entity); Vector3d parentPos = EntityUtils.getPosition(entity);
Quaterniond rotation = SpatialMathUtils.calculateRotationFromPointToPoint(parentPos, targetPos); Quaterniond rotation = SpatialMathUtils.calculateRotationFromPointToPoint(parentPos, targetPos);
EntityUtils.getRotation(entity).set(rotation); EntityUtils.getRotation(entity).set(rotation);
CreatureUtils.setFacingVector(entity, CameraEntityUtils.getFacingVec(rotation)); Vector3d faceVec = CameraEntityUtils.getFacingVec(rotation);
CreatureUtils.setFacingVector(entity, faceVec);
return AITreeNodeResult.SUCCESS; return AITreeNodeResult.SUCCESS;
} }

View File

@ -25,12 +25,12 @@ public class MacroPathfindingNode implements AITreeNode {
/** /**
* The value used to check if the entity is close to a pathing point horizontally * The value used to check if the entity is close to a pathing point horizontally
*/ */
public static final double CLOSENESS_CHECK_BOUND_HORIZONTAL = 0.3f; public static final double CLOSENESS_CHECK_BOUND_HORIZONTAL = 0.3;
/** /**
* The value used to check if the entity is close to a pathing point vertically * The value used to check if the entity is close to a pathing point vertically
*/ */
public static final double CLOSENESS_CHECK_BOUND_VERTICAL = 0.7f; public static final double CLOSENESS_CHECK_BOUND_VERTICAL = 0.7;
/** /**
* The blackboard key to lookup the target entity under * The blackboard key to lookup the target entity under
@ -129,6 +129,8 @@ public class MacroPathfindingNode implements AITreeNode {
){ ){
pathingProgressiveData.setCurrentPoint(pathingProgressiveData.getCurrentPoint() + 1); pathingProgressiveData.setCurrentPoint(pathingProgressiveData.getCurrentPoint() + 1);
currentPathPos = pathingProgressiveData.getPoints().get(pathingProgressiveData.getCurrentPoint()); currentPathPos = pathingProgressiveData.getPoints().get(pathingProgressiveData.getCurrentPoint());
vertDist = Math.abs(currentPathPos.y - entityPos.y);
horizontalDist = Math.sqrt((currentPathPos.x - entityPos.x) * (currentPathPos.x - entityPos.x) + (currentPathPos.z - entityPos.z) * (currentPathPos.z - entityPos.z));
} }
//if we're close enough to the final pathing point, always path to actual final point //if we're close enough to the final pathing point, always path to actual final point

View File

@ -126,6 +126,8 @@ public class PathfindingNode implements AITreeNode {
){ ){
pathingProgressiveData.setCurrentPoint(pathingProgressiveData.getCurrentPoint() + 1); pathingProgressiveData.setCurrentPoint(pathingProgressiveData.getCurrentPoint() + 1);
currentPathPos = pathingProgressiveData.getPoints().get(pathingProgressiveData.getCurrentPoint()); currentPathPos = pathingProgressiveData.getPoints().get(pathingProgressiveData.getCurrentPoint());
vertDist = Math.abs(currentPathPos.y - entityPos.y);
horizontalDist = Math.sqrt((currentPathPos.x - entityPos.x) * (currentPathPos.x - entityPos.x) + (currentPathPos.z - entityPos.z) * (currentPathPos.z - entityPos.z));
} }
//if we're close enough to the final pathing point, always path to actual final point //if we're close enough to the final pathing point, always path to actual final point

View File

@ -3,6 +3,7 @@ package electrosphere.server.ai.trees.creature;
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing;
import electrosphere.server.ai.blackboard.BlackboardKeys; import electrosphere.server.ai.blackboard.BlackboardKeys;
import electrosphere.server.ai.nodes.AITreeNode; import electrosphere.server.ai.nodes.AITreeNode;
import electrosphere.server.ai.nodes.actions.move.CollidableElevationLerpNode;
import electrosphere.server.ai.nodes.actions.move.FaceTargetNode; import electrosphere.server.ai.nodes.actions.move.FaceTargetNode;
import electrosphere.server.ai.nodes.actions.move.MoveStartNode; import electrosphere.server.ai.nodes.actions.move.MoveStartNode;
import electrosphere.server.ai.nodes.actions.move.MoveStopNode; import electrosphere.server.ai.nodes.actions.move.MoveStopNode;
@ -53,7 +54,7 @@ public class MacroMoveToTree {
new SequenceNode( new SequenceNode(
"MacroMoveToTree", "MacroMoveToTree",
//check if in range of target //check if in range of target
new TargetRangeCheckNode(dist, targetKey), new TargetRangeCheckNode(dist, targetKey),
new DataDeleteNode(BlackboardKeys.PATHFINDING_POINT), new DataDeleteNode(BlackboardKeys.PATHFINDING_POINT),
new DataDeleteNode(BlackboardKeys.PATHFINDING_DATA), new DataDeleteNode(BlackboardKeys.PATHFINDING_DATA),
//if in range, stop moving fowards and return SUCCESS //if in range, stop moving fowards and return SUCCESS
@ -65,6 +66,7 @@ public class MacroMoveToTree {
"MacroMoveToTree", "MacroMoveToTree",
MacroPathfindingNode.createPathEntity(targetKey), MacroPathfindingNode.createPathEntity(targetKey),
new FaceTargetNode(BlackboardKeys.PATHFINDING_POINT), new FaceTargetNode(BlackboardKeys.PATHFINDING_POINT),
new CollidableElevationLerpNode(BlackboardKeys.PATHFINDING_POINT),
new RunnerNode(new MoveStartNode(MovementRelativeFacing.FORWARD)) new RunnerNode(new MoveStartNode(MovementRelativeFacing.FORWARD))
) )
); );

View File

@ -3,6 +3,7 @@ package electrosphere.server.ai.trees.creature;
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing;
import electrosphere.server.ai.blackboard.BlackboardKeys; import electrosphere.server.ai.blackboard.BlackboardKeys;
import electrosphere.server.ai.nodes.AITreeNode; import electrosphere.server.ai.nodes.AITreeNode;
import electrosphere.server.ai.nodes.actions.move.CollidableElevationLerpNode;
import electrosphere.server.ai.nodes.actions.move.FaceTargetNode; import electrosphere.server.ai.nodes.actions.move.FaceTargetNode;
import electrosphere.server.ai.nodes.actions.move.MoveStartNode; import electrosphere.server.ai.nodes.actions.move.MoveStartNode;
import electrosphere.server.ai.nodes.actions.move.MoveStopNode; import electrosphere.server.ai.nodes.actions.move.MoveStopNode;
@ -64,6 +65,7 @@ public class MoveToTree {
"MoveToTree", "MoveToTree",
PathfindingNode.createPathEntity(targetKey), PathfindingNode.createPathEntity(targetKey),
new FaceTargetNode(BlackboardKeys.PATHFINDING_POINT), new FaceTargetNode(BlackboardKeys.PATHFINDING_POINT),
new CollidableElevationLerpNode(BlackboardKeys.PATHFINDING_POINT),
new RunnerNode(new MoveStartNode(MovementRelativeFacing.FORWARD)) new RunnerNode(new MoveStartNode(MovementRelativeFacing.FORWARD))
) )
); );