client collidable LOD 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
60feb2ed59
commit
f9d8ad0adb
@ -2110,6 +2110,7 @@ Fix physics performance issues
|
||||
|
||||
(06/04/2025)
|
||||
ServerGroundMovementTree actually moves collidable-based entities
|
||||
Client uses non-rigid-body collidables for farther away entities (via client LOD tree)
|
||||
|
||||
|
||||
|
||||
|
||||
@ -67,7 +67,6 @@ public class PhysicsEntityUtils {
|
||||
public static void clientAttachCollidableTemplate(Entity rVal, CollidableTemplate physicsTemplate){
|
||||
Collidable collidable;
|
||||
double mass = 1.0f;
|
||||
CollisionEngine engine = Globals.clientState.clientSceneWrapper.getCollisionEngine();
|
||||
if(physicsTemplate.getMass() != null){
|
||||
mass = physicsTemplate.getMass();
|
||||
}
|
||||
@ -77,96 +76,7 @@ public class PhysicsEntityUtils {
|
||||
}
|
||||
CollisionEngine.lockOde();
|
||||
if(physicsTemplate.getKinematic()){
|
||||
DGeom geom = null;
|
||||
switch(physicsTemplate.getType()){
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
|
||||
|
||||
//
|
||||
//create dbody
|
||||
geom = CollisionBodyCreation.createCylinderShape(
|
||||
engine,
|
||||
physicsTemplate.getDimension1(),
|
||||
physicsTemplate.getDimension2(),
|
||||
categoryBit
|
||||
);
|
||||
|
||||
//
|
||||
//create collidable and link to structures
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||
PhysicsEntityUtils.setDGeom(rVal, geom);
|
||||
|
||||
//
|
||||
//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.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
|
||||
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
||||
engine.registerCollisionObject(geom, collidable, EntityUtils.getPosition(rVal));
|
||||
} break;
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
|
||||
//
|
||||
//create dbody
|
||||
geom = CollisionBodyCreation.createCubeShape(
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
|
||||
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()),
|
||||
categoryBit
|
||||
);
|
||||
|
||||
//
|
||||
//create collidable and link to structures
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||
PhysicsEntityUtils.setDGeom(rVal,geom);
|
||||
|
||||
//
|
||||
//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.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
|
||||
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
||||
engine.registerCollisionObject(geom, collidable, EntityUtils.getPosition(rVal));
|
||||
} break;
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
|
||||
//
|
||||
//create dbody
|
||||
geom = CollisionBodyCreation.createCapsuleShape(
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
|
||||
physicsTemplate.getDimension1(),
|
||||
physicsTemplate.getDimension2(),
|
||||
categoryBit
|
||||
);
|
||||
|
||||
//
|
||||
//create collidable and link to structures
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||
PhysicsEntityUtils.setDGeom(rVal,geom);
|
||||
|
||||
//
|
||||
//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.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||
|
||||
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
||||
engine.registerCollisionObject(geom, collidable, EntityUtils.getPosition(rVal));
|
||||
} break;
|
||||
}
|
||||
PhysicsEntityUtils.clientAttachGeom(rVal, physicsTemplate, EntityUtils.getPosition(rVal));
|
||||
} else {
|
||||
DBody rigidBody = null;
|
||||
switch(physicsTemplate.getType()){
|
||||
@ -366,16 +276,128 @@ public class PhysicsEntityUtils {
|
||||
} break;
|
||||
}
|
||||
//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));
|
||||
}
|
||||
ClientPhysicsSyncTree.attachTree(rVal);
|
||||
if(ClientGravityTree.hasClientGravityTree(rVal)){
|
||||
ClientGravityTree.getClientGravityTree(rVal).updatePhysicsPair(PhysicsEntityUtils.getCollidable(rVal),PhysicsEntityUtils.getDBody(rVal));
|
||||
}
|
||||
}
|
||||
CollisionEngine.unlockOde();
|
||||
}
|
||||
|
||||
/**
|
||||
* [SERVER ONLY] Attaches a collidable template to a given entity
|
||||
* @param rVal The entity
|
||||
* @param physicsTemplate The collidable template
|
||||
* @return The geometry object
|
||||
*/
|
||||
public static DGeom clientAttachGeom(Entity rVal, CollidableTemplate physicsTemplate, Vector3d position){
|
||||
DGeom geom = null;
|
||||
Collidable collidable;
|
||||
double mass = 1.0f;
|
||||
long categoryBit = Collidable.TYPE_CREATURE_BIT;
|
||||
if(physicsTemplate.getKinematic()){
|
||||
categoryBit = Collidable.TYPE_STATIC_BIT;
|
||||
}
|
||||
CollisionEngine engine = Globals.clientState.clientSceneWrapper.getCollisionEngine();
|
||||
CollisionEngine.lockOde();
|
||||
switch(physicsTemplate.getType()){
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
|
||||
|
||||
//
|
||||
//create dbody
|
||||
geom = CollisionBodyCreation.createCylinderShape(
|
||||
engine,
|
||||
physicsTemplate.getDimension1(),
|
||||
physicsTemplate.getDimension2(),
|
||||
categoryBit
|
||||
);
|
||||
|
||||
//
|
||||
//create collidable and link to structures
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||
PhysicsEntityUtils.setDGeom(rVal, geom);
|
||||
|
||||
//
|
||||
//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.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
|
||||
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
||||
engine.registerCollisionObject(geom, collidable, EntityUtils.getPosition(rVal));
|
||||
} break;
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
|
||||
//
|
||||
//create dbody
|
||||
geom = CollisionBodyCreation.createCubeShape(
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
|
||||
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()),
|
||||
categoryBit
|
||||
);
|
||||
|
||||
//
|
||||
//create collidable and link to structures
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||
PhysicsEntityUtils.setDGeom(rVal,geom);
|
||||
|
||||
//
|
||||
//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.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
|
||||
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
||||
engine.registerCollisionObject(geom, collidable, EntityUtils.getPosition(rVal));
|
||||
} break;
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
|
||||
//
|
||||
//create dbody
|
||||
geom = CollisionBodyCreation.createCapsuleShape(
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
|
||||
physicsTemplate.getDimension1(),
|
||||
physicsTemplate.getDimension2(),
|
||||
categoryBit
|
||||
);
|
||||
|
||||
//
|
||||
//create collidable and link to structures
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||
PhysicsEntityUtils.setDGeom(rVal,geom);
|
||||
|
||||
//
|
||||
//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.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||
|
||||
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
||||
engine.registerCollisionObject(geom, collidable, EntityUtils.getPosition(rVal));
|
||||
} break;
|
||||
}
|
||||
//if we successfully attached the body, add a sync tree
|
||||
ClientPhysicsSyncTree.attachTree(rVal);
|
||||
if(ClientGravityTree.hasClientGravityTree(rVal)){
|
||||
ClientGravityTree.getClientGravityTree(rVal).updatePhysicsPair(PhysicsEntityUtils.getCollidable(rVal),PhysicsEntityUtils.getDBody(rVal));
|
||||
}
|
||||
CollisionEngine.unlockOde();
|
||||
return geom;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* [SERVER ONLY] Attaches a collidable template to a given entity
|
||||
@ -599,11 +621,9 @@ public class PhysicsEntityUtils {
|
||||
} break;
|
||||
}
|
||||
//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));
|
||||
}
|
||||
ServerPhysicsSyncTree.attachTree(rVal);
|
||||
if(ServerGravityTree.hasServerGravityTree(rVal)){
|
||||
ServerGravityTree.getServerGravityTree(rVal).updatePhysicsPair(PhysicsEntityUtils.getCollidable(rVal),PhysicsEntityUtils.getDBody(rVal));
|
||||
}
|
||||
}
|
||||
CollisionEngine.unlockOde();
|
||||
@ -726,6 +746,10 @@ public class PhysicsEntityUtils {
|
||||
realm.getCollisionEngine().registerCollisionObject(geom, collidable, position);
|
||||
} break;
|
||||
}
|
||||
ServerPhysicsSyncTree.attachTree(rVal);
|
||||
if(ServerGravityTree.hasServerGravityTree(rVal)){
|
||||
ServerGravityTree.getServerGravityTree(rVal).updatePhysicsPair(PhysicsEntityUtils.getCollidable(rVal),PhysicsEntityUtils.getDBody(rVal));
|
||||
}
|
||||
CollisionEngine.unlockOde();
|
||||
return geom;
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import electrosphere.entity.Entity;
|
||||
import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums;
|
||||
import electrosphere.entity.btree.BehaviorTree;
|
||||
import electrosphere.entity.types.common.CommonEntityUtils;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||
|
||||
@ -76,6 +77,13 @@ public class ClientLODComponent implements BehaviorTree {
|
||||
PhysicsEntityUtils.getCollidable(this.parent)
|
||||
);
|
||||
}
|
||||
CommonEntityType type = CommonEntityUtils.getCommonData(this.parent);
|
||||
if(type.getCollidable() != null){
|
||||
if(CreatureUtils.hasControllerPlayerId(parent)){
|
||||
throw new Error("Should not be attaching a geometry to a player entity!");
|
||||
}
|
||||
PhysicsEntityUtils.clientAttachGeom(parent, type.getCollidable(), EntityUtils.getPosition(parent));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package electrosphere.entity.state.physicssync;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
import org.ode4j.ode.DBody;
|
||||
import org.ode4j.ode.DGeom;
|
||||
|
||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||
import electrosphere.client.terrain.foliage.FoliageCellManager;
|
||||
@ -59,6 +60,7 @@ public class ClientPhysicsSyncTree implements BehaviorTree {
|
||||
Vector3d angularForce = new Vector3d();
|
||||
boolean enabled = latestMessage.getbodyEnabled();
|
||||
DBody body = PhysicsEntityUtils.getDBody(parent);
|
||||
DGeom geom = PhysicsEntityUtils.getDGeom(parent);
|
||||
|
||||
//
|
||||
//bust distance caches if this is the player's entity and we've traveled a long distance suddenly
|
||||
@ -77,7 +79,12 @@ public class ClientPhysicsSyncTree implements BehaviorTree {
|
||||
//Synchronize data
|
||||
EntityUtils.setPosition(parent, position);
|
||||
EntityUtils.getRotation(parent).set(rotationFromServer);
|
||||
PhysicsUtils.synchronizeData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), body, position, rotationFromServer, linearVelocity, angularVelocity, linearForce, angularForce, enabled);
|
||||
if(body != null){
|
||||
PhysicsUtils.synchronizeData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), body, position, rotationFromServer, linearVelocity, angularVelocity, linearForce, angularForce, enabled);
|
||||
}
|
||||
if(geom != null){
|
||||
PhysicsUtils.setGeomTransform(Globals.clientState.clientSceneWrapper.getCollisionEngine(), position, rotationFromServer, geom);
|
||||
}
|
||||
|
||||
//
|
||||
//update facing vector if relevant
|
||||
|
||||
@ -3,6 +3,7 @@ package electrosphere.entity.state.physicssync;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
import org.ode4j.ode.DBody;
|
||||
import org.ode4j.ode.DGeom;
|
||||
|
||||
import electrosphere.collision.PhysicsEntityUtils;
|
||||
import electrosphere.collision.PhysicsUtils;
|
||||
@ -44,8 +45,8 @@ public class ServerPhysicsSyncTree implements BehaviorTree {
|
||||
Vector3d position = EntityUtils.getPosition(parent);
|
||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||
DBody body = PhysicsEntityUtils.getDBody(parent);
|
||||
if(body == null){
|
||||
} else {
|
||||
DGeom geom = PhysicsEntityUtils.getDGeom(parent);
|
||||
if(body != null){
|
||||
//velocities
|
||||
Vector3d linearVel = PhysicsUtils.odeVecToJomlVec(body.getLinearVel());
|
||||
Vector3d angularVel = PhysicsUtils.odeVecToJomlVec(body.getAngularVel());
|
||||
@ -83,6 +84,38 @@ public class ServerPhysicsSyncTree implements BehaviorTree {
|
||||
);
|
||||
}
|
||||
}
|
||||
if(geom != null){
|
||||
if(position.distance(lastSentPosition) > UPDATE_THRESHOLD || 1.0 - rotation.dot(lastSentRotation) > UPDATE_THRESHOLD){
|
||||
lastSentPosition.set(position);
|
||||
lastSentRotation.set(rotation);
|
||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
||||
EntityMessage.constructsyncPhysicsMessage(
|
||||
parent.getId(),
|
||||
Globals.engineState.timekeeper.getNumberOfSimFramesElapsed(),
|
||||
position.x,
|
||||
position.y,
|
||||
position.z,
|
||||
rotation.x,
|
||||
rotation.y,
|
||||
rotation.z,
|
||||
rotation.w,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user