fall and gravity tree fixes
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-05-29 18:40:16 -04:00
parent ccd10c9665
commit bc29ea728e
8 changed files with 130 additions and 5 deletions

View File

@ -2067,6 +2067,7 @@ Delete ActorShaderMask
Fix string carousels
Fix sprint animation data
Color uniform on meshes
Fall and gravity tree fixes

View File

@ -21,6 +21,8 @@ import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.state.collidable.MultiShapeTriGeomData;
import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.state.collidable.TriGeomData;
import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.state.physicssync.ClientPhysicsSyncTree;
import electrosphere.entity.state.physicssync.ServerPhysicsSyncTree;
import electrosphere.server.datacell.Realm;
@ -369,6 +371,9 @@ public class PhysicsEntityUtils {
//if we successfully attached the body, add a sync tree
if(rigidBody != null){
ClientPhysicsSyncTree.attachTree(rVal);
if(ClientGravityTree.hasClientGravityTree(rVal)){
ClientGravityTree.getClientGravityTree(rVal).updatePhysicsPair(PhysicsEntityUtils.getCollidable(rVal),PhysicsEntityUtils.getDBody(rVal));
}
}
}
CollisionEngine.unlockOde();
@ -693,6 +698,9 @@ public class PhysicsEntityUtils {
//if we successfully attached the body, add a sync tree
if(rigidBody != null){
ServerPhysicsSyncTree.attachTree(rVal);
if(ServerGravityTree.hasServerGravityTree(rVal)){
ServerGravityTree.getServerGravityTree(rVal).updatePhysicsPair(PhysicsEntityUtils.getCollidable(rVal),PhysicsEntityUtils.getDBody(rVal));
}
}
}
CollisionEngine.unlockOde();

View File

@ -89,13 +89,13 @@ public class ClientGravityTree implements BehaviorTree {
//state machine
switch(state){
case ACTIVE:
if(this.hadGroundCollision() || !this.bodyIsActive()){
if(this.hadGroundCollision() || !this.bodyIsActive() || this.body == null){
ClientJumpTree jumpTree;
if((jumpTree = ClientJumpTree.getClientJumpTree(parent))!=null){
if((jumpTree = ClientJumpTree.getClientJumpTree(parent))!=null && jumpTree.isJumping()){
jumpTree.land();
}
ClientFallTree fallTree;
if((fallTree = ClientFallTree.getFallTree(parent))!=null){
if((fallTree = ClientFallTree.getFallTree(parent))!=null && fallTree.isFalling()){
fallTree.land();
}
frameCurrent = 0;
@ -108,7 +108,6 @@ public class ClientGravityTree implements BehaviorTree {
}
}
frameCurrent++;
}
break;
case NOT_ACTIVE:
@ -151,6 +150,24 @@ public class ClientGravityTree implements BehaviorTree {
}
return rVal;
}
/**
* Checks if the physics on the tree is valid
* @return true if it is valid, false otherwise
*/
public boolean physicsIsValid(){
return collidable != null && body != null;
}
/**
* Updates the physics pair in this tree
* @param collidable The collidable
* @param body The rigid body
*/
public void updatePhysicsPair(Collidable collidable, DBody body){
this.collidable = collidable;
this.body = body;
}
/**
* <p> (initially) Automatically generated </p>

View File

@ -173,6 +173,24 @@ public class ServerGravityTree implements BehaviorTree {
}
return rVal;
}
/**
* Checks if the physics on the tree is valid
* @return true if it is valid, false otherwise
*/
public boolean physicsIsValid(){
return collidable != null && body != null;
}
/**
* Updates the physics pair in this tree
* @param collidable The collidable
* @param body The rigid body
*/
public void updatePhysicsPair(Collidable collidable, DBody body){
this.collidable = collidable;
this.body = body;
}
/**
* <p> Automatically generated </p>

View File

@ -2,6 +2,8 @@ package electrosphere.entity.state.movement.fall;
import electrosphere.audio.movement.MovementAudioService.InteractionType;
import electrosphere.client.terrain.sampling.ClientVoxelSampler;
import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.data.entity.creature.movement.FallMovementSystem;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
@ -12,6 +14,7 @@ import electrosphere.entity.btree.StateTransitionUtil;
import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem;
import electrosphere.entity.state.AnimationPriorities;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.state.movement.jump.ClientJumpTree;
import electrosphere.renderer.actor.Actor;
@ -125,11 +128,29 @@ public class ClientFallTree implements BehaviorTree {
boolean rVal =
frameCurrent > ServerFallTree.MIN_FRAMES_BEFORE_ACTIVATION_SCAN &&
ClientGravityTree.getClientGravityTree(parent).isActive() &&
!isPlayingJump
!isPlayingJump &&
!this.hadGroundCollision()
;
return rVal;
}
/**
* Checks if the entity had a collision with the ground this frame
* @return true if it had a collision with the ground, false otherwise
*/
public boolean hadGroundCollision(){
boolean rVal = false;
if(PhysicsEntityUtils.getCollidable(parent) != null){
for(Impulse impulse : PhysicsEntityUtils.getCollidable(parent).getImpulses()){
if(impulse.getType().equals(Collidable.TYPE_STATIC)){
rVal = true;
break;
}
}
}
return rVal;
}
/**
* Triggers the falling tree to land
*/

View File

@ -0,0 +1,43 @@
package electrosphere.collision.collision;
import static electrosphere.test.testutils.Assertions.assertEventually;
import org.joml.Vector3d;
import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.types.EntityTypes.EntityType;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.creature.ObjectTemplate;
import electrosphere.test.annotations.IntegrationTest;
import electrosphere.test.template.EntityTestTemplate;
import electrosphere.test.testutils.TestEngineUtils;
/**
* Tests for physics entity utils
*/
public class PhysicsEntityUtilsTests extends EntityTestTemplate {
@IntegrationTest
public void test_server_RigidBody_NotNull(){
Entity serverEntity = CreatureUtils.serverSpawnBasicCreature(Globals.serverState.realmManager.first(), new Vector3d(), "human", ObjectTemplate.createDefault(EntityType.CREATURE, "human"));
//warm up engine
TestEngineUtils.simulateFrames(3);
assertEventually(() -> PhysicsEntityUtils.getDBody(serverEntity) != null);
}
@IntegrationTest
public void test_client_RigidBody_NotNull(){
Entity serverEntity = CreatureUtils.serverSpawnBasicCreature(Globals.serverState.realmManager.first(), new Vector3d(), "human", ObjectTemplate.createDefault(EntityType.CREATURE, "human"));
Entity clientEntity = TestEngineUtils.getClientEquivalent(serverEntity);
//warm up engine
TestEngineUtils.simulateFrames(3);
assertEventually(() -> PhysicsEntityUtils.getDBody(clientEntity) != null);
}
}

View File

@ -29,6 +29,15 @@ public class ClientGravityTreeTests extends EntityTestTemplate {
assertEquals(false, clientGravityTree.isActive());
}
@IntegrationTest
public void physicsIsValid_eventually_true(){
Entity serverEntity = CreatureUtils.serverSpawnBasicCreature(Globals.serverState.realmManager.first(), new Vector3d(), "human", ObjectTemplate.createDefault(EntityType.CREATURE, "human"));
Entity clientEntity = TestEngineUtils.getClientEquivalent(serverEntity);
ClientGravityTree clientGravityTree = ClientGravityTree.getClientGravityTree(clientEntity);
assertEventually(() -> clientGravityTree.physicsIsValid());
}
@IntegrationTest
public void activates_on_jump(){
Entity serverEntity = CreatureUtils.serverSpawnBasicCreature(Globals.serverState.realmManager.first(), new Vector3d(), "human", ObjectTemplate.createDefault(EntityType.CREATURE, "human"));

View File

@ -29,6 +29,14 @@ public class ServerGravityTreeTests extends EntityTestTemplate {
assertTrue(serverGravityTree.isActive());
}
@IntegrationTest
public void physicsIsValid_eventually_true(){
Entity serverEntity = CreatureUtils.serverSpawnBasicCreature(Globals.serverState.realmManager.first(), new Vector3d(), "human", ObjectTemplate.createDefault(EntityType.CREATURE, "human"));
ServerGravityTree serverGravityTree = ServerGravityTree.getServerGravityTree(serverEntity);
assertEventually(() -> serverGravityTree.physicsIsValid());
}
@IntegrationTest
public void isActive_AfterOneFrame_false(){
Entity serverEntity = CreatureUtils.serverSpawnBasicCreature(Globals.serverState.realmManager.first(), new Vector3d(), "human", ObjectTemplate.createDefault(EntityType.CREATURE, "human"));