Skip to content

Commit

Permalink
Merge pull request #1230 from allenai/collision-fix
Browse files Browse the repository at this point in the history
Fixing collision checks to work correctly with convex colliders.
  • Loading branch information
Lucaweihs authored Aug 12, 2024
2 parents 18783a3 + ec4d7fc commit 7bd8b4d
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 17 deletions.
28 changes: 28 additions & 0 deletions unity/Assets/Scripts/BaseFPSAgentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3785,6 +3785,34 @@ protected IEnumerator setObjectPoses(ObjectPose[] objectPoses, bool placeStation
actionFinished(success, errorMessage);
}

public void FirstColliderObjectCollidingWith(string objectId) {
if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(objectId)) {
errorMessage = $"Cannot find object with id {objectId}.";
actionFinishedEmit(false);
return;
}
Collider collidingWith = UtilityFunctions.firstColliderObjectCollidingWith(
go: physicsSceneManager.ObjectIdToSimObjPhysics[objectId].gameObject,
ignoreGameObjects: null,
expandBy: 0.0f,
useBoundingBoxInChecks: false
);

string collidingWithId = null;
if (collidingWith != null) {
SimObjPhysics otherSop = ancestorSimObjPhysics(collidingWith.gameObject);
if (otherSop != null) {
collidingWithId = otherSop.ObjectID;
} else {
collidingWithId = collidingWith.gameObject.name;
}
}
#if UNITY_EDITOR
Debug.Log(collidingWithId);
#endif
actionFinishedEmit(true, actionReturn: collidingWithId);
}

// pass in a Vector3, presumably from GetReachablePositions, and try to place a sim object flush on a surface below that point
// unlike PlaceHeldObject or InitialRandomSpawn, this won't be limited by a Receptacle, but only limited by collision
public void PlaceObjectAtPoint(
Expand Down
57 changes: 57 additions & 0 deletions unity/Assets/Scripts/PhysicsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,63 @@ public static int OverlapCapsuleNonAlloc(
);
}

public static IEnumerable<Collider> OverlapConvex(
MeshCollider meshCollider,
LayerMask layerMask,
QueryTriggerInteraction queryTriggerInteraction,
float expandBy = 0f,
HashSet<Collider> ignoreColliders = null
) {
if (ignoreColliders == null) {
ignoreColliders = new HashSet<Collider>();
}

// Get the bounds of the mesh collider
Bounds bounds = meshCollider.bounds;
if (expandBy > 0f) {
bounds.Expand(expandBy * 2); // Expand in all directions
}

// Use OverlapBox to get candidate colliders
Collider[] candidateColliders = Physics.OverlapBox(
bounds.center,
bounds.extents,
meshCollider.transform.rotation,
layerMask,
queryTriggerInteraction
);

// Check each candidate collider for actual collision
foreach (Collider candidateCollider in candidateColliders) {
if (candidateCollider == meshCollider) {
continue; // Skip self-collision
}

if (ignoreColliders.Contains(candidateCollider)) {
continue; // Skip ignored colliders
}

Vector3 direction;
float distance;

// Use ComputePenetration to check for actual collision
if (
Physics.ComputePenetration(
meshCollider,
meshCollider.transform.position,
meshCollider.transform.rotation,
candidateCollider,
candidateCollider.transform.position,
candidateCollider.transform.rotation,
out direction,
out distance
)
) {
yield return candidateCollider;
}
}
}

public static void ToWorldSpaceCapsule(
this CapsuleCollider capsule,
out Vector3 point0,
Expand Down
34 changes: 21 additions & 13 deletions unity/Assets/Scripts/ProceduralTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1752,32 +1752,40 @@ public static GameObject CreateHouse(
}
}

// buildNavMesh(floorGameObject, house.proceduralParameters.navmeshVoxelSize);

buildNavMeshes(floorGameObject, house.metadata.navMeshes);

if (
string.IsNullOrEmpty(house.proceduralParameters.skyboxId)
|| !materialDb.ContainsKey(house.proceduralParameters.skyboxId)
) {
var mat = new Material(Shader.Find("Standard"));
mat.color = house.proceduralParameters.skyboxColor.toUnityColor();
RenderSettings.skybox = mat;
Color flatColor = house.proceduralParameters.skyboxColor.toUnityColor();

// The below is commented out as setting the skybox color like this results in unexpected/bad behavior
// like heavily exposed scenes or arbitrarily lit objects. We instead will not use the skybox material at all in this case.
// so everything is determined by the scene lights.

// // Set the Tint color for all six sides
// Material skyboxMaterial = new Material(Shader.Find("Skybox/6 Sided"));
// skyboxMaterial.SetColor("_Tint", flatColor);
// skyboxMaterial.SetFloat("_Exposure", 0.0001f); // A very light as otherwise objects are totally overexposed

Material skyboxMaterial = null;

// var cam = GameObject.FindObjectOfType<Camera>();
// Set this material as the current skybox
RenderSettings.skybox = skyboxMaterial;

// Set the camera background color to the "skybox" color so that it renders as expected.
var cam = GameObject.Find("FirstPersonCharacter").GetComponent<Camera>();
cam.clearFlags = CameraClearFlags.SolidColor;
cam.backgroundColor = mat.color;

// RenderSettings.ambientSkyColor =
cam.backgroundColor = flatColor;
} else {
RenderSettings.skybox = materialDb.getAsset(house.proceduralParameters.skyboxId);
}
DynamicGI.UpdateEnvironment();
GameObject
.FindObjectOfType<ReflectionProbe>()
.GetComponent<ReflectionProbe>()
.RenderProbe();

foreach (ReflectionProbe probe in GameObject.FindObjectsOfType<ReflectionProbe>()) {
probe.RenderProbe();
}

// generate objectId for newly created wall/floor objects
// also add them to objectIdToSimObjPhysics dict so they can be found via
Expand Down
31 changes: 27 additions & 4 deletions unity/Assets/Scripts/UtilityFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public static Collider firstColliderObjectCollidingWith(
"Procedural0"
);
foreach (CapsuleCollider cc in go.GetComponentsInChildren<CapsuleCollider>()) {
if (cc.isTrigger) {
if (cc.isTrigger || !cc.enabled) {
continue;
}
foreach (
Expand All @@ -131,8 +131,11 @@ Collider c in PhysicsExtensions.OverlapCapsule(
}
}
foreach (BoxCollider bc in go.GetComponentsInChildren<BoxCollider>()) {
if (bc.isTrigger || ("BoundingBox" == bc.gameObject.name && (!useBoundingBoxInChecks))) {
continue;
if ("BoundingBox" != bc.gameObject.name || !useBoundingBoxInChecks) {
// If we're useBoundingBoxInChecks in we want to ignore the below checks
if (bc.isTrigger || !bc.enabled) {
continue;
}
}
foreach (
Collider c in PhysicsExtensions.OverlapBox(
Expand All @@ -148,7 +151,7 @@ Collider c in PhysicsExtensions.OverlapBox(
}
}
foreach (SphereCollider sc in go.GetComponentsInChildren<SphereCollider>()) {
if (sc.isTrigger) {
if (sc.isTrigger || !sc.enabled) {
continue;
}
foreach (
Expand All @@ -164,6 +167,26 @@ Collider c in PhysicsExtensions.OverlapSphere(
}
}
}

foreach (MeshCollider mc in go.GetComponentsInChildren<MeshCollider>()) {
if (mc.isTrigger || (!mc.convex) || (!mc.enabled)) {
continue;
}
foreach (
Collider c in PhysicsExtensions.OverlapConvex(
mc,
layerMask,
QueryTriggerInteraction.Ignore,
expandBy,
ignoreColliders
)
) {
if (!ignoreColliders.Contains(c)) {
return c;
}
}
}

return null;
}

Expand Down

0 comments on commit 7bd8b4d

Please sign in to comment.