fix scene re-adding trees after delete
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-06-08 16:48:09 -04:00
parent e2d0c0cd88
commit 0014b98c85
6 changed files with 51 additions and 7 deletions

View File

@ -2127,6 +2127,9 @@ Synchronization change for memory pressure
Lerp non-body height differential based on distance (holds closer to ground) Lerp non-body height differential based on distance (holds closer to ground)
Sim range update Sim range update
(06/08/2025)
Fix scene re-adding tree that was previously removed

View File

@ -944,6 +944,7 @@ public class CollisionEngine {
//create the ray //create the ray
DRay ray = OdeHelper.createRay(space, length); DRay ray = OdeHelper.createRay(space, length);
ray.set(start.x - this.floatingOrigin.x, start.y - this.floatingOrigin.y, start.z - this.floatingOrigin.z, unitDir.x, unitDir.y, unitDir.z); ray.set(start.x - this.floatingOrigin.x, start.y - this.floatingOrigin.y, start.z - this.floatingOrigin.z, unitDir.x, unitDir.y, unitDir.z);
ray.setCategoryBits(Collidable.TYPE_OBJECT_BIT);
//collide //collide
RayCastCallbackData data = new RayCastCallbackData(bodyPointerMap, geomPointerMap, null); RayCastCallbackData data = new RayCastCallbackData(bodyPointerMap, geomPointerMap, null);
rayCastCallback.setLength(length); rayCastCallback.setLength(length);
@ -968,6 +969,7 @@ public class CollisionEngine {
//create the ray //create the ray
DRay ray = OdeHelper.createRay(space, length); DRay ray = OdeHelper.createRay(space, length);
ray.set(start.x - this.floatingOrigin.x, start.y - this.floatingOrigin.y, start.z - this.floatingOrigin.z, unitDir.x, unitDir.y, unitDir.z); ray.set(start.x - this.floatingOrigin.x, start.y - this.floatingOrigin.y, start.z - this.floatingOrigin.z, unitDir.x, unitDir.y, unitDir.z);
ray.setCategoryBits(Collidable.TYPE_OBJECT_BIT);
//collide //collide
RayCastCallbackData data = new RayCastCallbackData(bodyPointerMap, geomPointerMap, typeMask); RayCastCallbackData data = new RayCastCallbackData(bodyPointerMap, geomPointerMap, typeMask);
rayCastCallback.setLength(length); rayCastCallback.setLength(length);

View File

@ -59,16 +59,22 @@ void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) {
@Override @Override
public void call(Object data, DGeom o1, DGeom o2) { public void call(Object data, DGeom o1, DGeom o2) {
// if (o1->body && o2->body) return;
RayCastCallbackData rayCastData = (RayCastCallbackData)data; RayCastCallbackData rayCastData = (RayCastCallbackData)data;
//Don't self-collide
if(o1 == o2){
return;
}
//null out potentially previous results //null out potentially previous results
// rayCastData.collisionPosition = null; // rayCastData.collisionPosition = null;
// rayCastData.collidedEntity = null; // rayCastData.collidedEntity = null;
// exit without doing anything if the two bodies are connected by a joint // exit without doing anything if the two bodies are connected by a joint
DBody b1 = o1.getBody(); DBody b1 = o1.getBody();
DBody b2 = o2.getBody(); DBody b2 = o2.getBody();
if (b1!=null && b2!=null && areConnectedExcluding (b1,b2,DContactJoint.class)) return; if(b1 != null && b2 != null && areConnectedExcluding(b1,b2,DContactJoint.class)){
return;
}
Collidable collidable1 = rayCastData.bodyEntityMap.get(b1); Collidable collidable1 = rayCastData.bodyEntityMap.get(b1);
Collidable collidable2 = rayCastData.bodyEntityMap.get(b2); Collidable collidable2 = rayCastData.bodyEntityMap.get(b2);
@ -106,8 +112,8 @@ void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) {
//calculate collisions //calculate collisions
int numc = OdeHelper.collide(o1,o2,MAX_CONTACTS,contacts.getGeomBuffer()); int numc = OdeHelper.collide(o1,o2,MAX_CONTACTS,contacts.getGeomBuffer());
//create DContacts based on each collision that occurs //create DContacts based on each collision that occurs
if (numc != 0) { if(numc != 0){
for (int i=0; i<numc; i++) { for(int i=0; i<numc; i++){
DContact contact = contacts.get(i); DContact contact = contacts.get(i);
double depth = contact.geom.depth; double depth = contact.geom.depth;

View File

@ -241,6 +241,9 @@ public class Scene {
public void registerBehaviorTree(BehaviorTree tree){ public void registerBehaviorTree(BehaviorTree tree){
lock.lock(); lock.lock();
this.additionList.add(tree); this.additionList.add(tree);
if(this.removalList.contains(tree)){
this.removalList.remove(tree);
}
lock.unlock(); lock.unlock();
} }
@ -263,6 +266,9 @@ public class Scene {
public void deregisterBehaviorTree(BehaviorTree tree){ public void deregisterBehaviorTree(BehaviorTree tree){
lock.lock(); lock.lock();
this.removalList.add(tree); this.removalList.add(tree);
if(this.additionList.contains(tree)){
this.additionList.remove(tree);
}
lock.unlock(); lock.unlock();
} }
@ -272,12 +278,15 @@ public class Scene {
public void simulateBehaviorTrees(float deltaTime){ public void simulateBehaviorTrees(float deltaTime){
lock.lock(); lock.lock();
Globals.profiler.beginAggregateCpuSample("Scene.simulateBehaviorTrees"); Globals.profiler.beginAggregateCpuSample("Scene.simulateBehaviorTrees");
//remove all trees that were queued to be removed
this.behaviorTreeList.removeAll(this.removalList);
//additions should happen before removals so that we don't re-introduce a tree that shouldn't be simulated
//in other words its better to fail by not simulating instead of fail by simulating
//add all trees that were queued to be added //add all trees that were queued to be added
this.behaviorTreeList.addAll(this.additionList); this.behaviorTreeList.addAll(this.additionList);
//remove all trees that were queued to be removed
this.behaviorTreeList.removeAll(this.removalList);
//clear both the lists that are accumulating //clear both the lists that are accumulating
this.removalList.clear(); this.removalList.clear();
this.additionList.clear(); this.additionList.clear();

View File

@ -586,6 +586,9 @@ public class ItemUtils {
if(Globals.serverState.entityDataCellMapper.getEntityDataCell(rVal) == null){ if(Globals.serverState.entityDataCellMapper.getEntityDataCell(rVal) == null){
throw new Error("Failed to get data cell or the entity"); throw new Error("Failed to get data cell or the entity");
} }
if(ServerGravityTree.hasServerGravityTree(rVal)){
throw new Error("In-inventory item has gravity tree!");
}
return rVal; return rVal;
} else { } else {

View File

@ -6,6 +6,10 @@ import org.joml.Vector3d;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.state.attach.AttachUtils;
import electrosphere.entity.types.EntityTypes.EntityType;
import electrosphere.entity.types.common.CommonEntityUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell; import electrosphere.server.datacell.ServerDataCell;
@ -26,7 +30,24 @@ public class DataCellSearchUtils {
} }
Realm realm = Globals.serverState.realmManager.getEntityRealm(entity); Realm realm = Globals.serverState.realmManager.getEntityRealm(entity);
if(realm == null){ if(realm == null){
LoggerInterface.loggerEngine.ERROR(new IllegalArgumentException("Trying to get entity data cell of an entity that is not assigned to a realm!")); String message = "Trying to get entity data cell of an entity that is not assigned to a realm!\n";
message = message + entity + "\n";
EntityType type = CommonEntityUtils.getEntityType(entity);
message = message + type + "\n";
switch(type){
case ITEM: {
if(ItemUtils.itemIsInInventory(entity)){
message = message + "In inventory: true\n";
message = message + "Containing parent: " + ItemUtils.getContainingParent(entity);
} else {
message = message + "In inventory: false\n";
}
} break;
default: {
} break;
}
message = message + "Attach parent: " + AttachUtils.getParent(entity) + "\n";
LoggerInterface.loggerEngine.ERROR(new Error(message));
return null; return null;
} }
return Globals.serverState.entityDataCellMapper.getEntityDataCell(entity); return Globals.serverState.entityDataCellMapper.getEntityDataCell(entity);