diff --git a/unity/Assets/Scripts/BaseFPSAgentController.cs b/unity/Assets/Scripts/BaseFPSAgentController.cs index 2088eae0b6..2d8ce92c60 100644 --- a/unity/Assets/Scripts/BaseFPSAgentController.cs +++ b/unity/Assets/Scripts/BaseFPSAgentController.cs @@ -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( diff --git a/unity/Assets/Scripts/PhysicsExtensions.cs b/unity/Assets/Scripts/PhysicsExtensions.cs index 9f4424231e..fb70fd91e8 100644 --- a/unity/Assets/Scripts/PhysicsExtensions.cs +++ b/unity/Assets/Scripts/PhysicsExtensions.cs @@ -443,6 +443,63 @@ public static int OverlapCapsuleNonAlloc( ); } + public static IEnumerable OverlapConvex( + MeshCollider meshCollider, + LayerMask layerMask, + QueryTriggerInteraction queryTriggerInteraction, + float expandBy = 0f, + HashSet ignoreColliders = null + ) { + if (ignoreColliders == null) { + ignoreColliders = new HashSet(); + } + + // 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, diff --git a/unity/Assets/Scripts/ProceduralTools.cs b/unity/Assets/Scripts/ProceduralTools.cs index dfd541f496..a1c7746a10 100644 --- a/unity/Assets/Scripts/ProceduralTools.cs +++ b/unity/Assets/Scripts/ProceduralTools.cs @@ -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(); + // 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(); 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() - .GetComponent() - .RenderProbe(); + + foreach (ReflectionProbe probe in GameObject.FindObjectsOfType()) { + probe.RenderProbe(); + } // generate objectId for newly created wall/floor objects // also add them to objectIdToSimObjPhysics dict so they can be found via diff --git a/unity/Assets/Scripts/UtilityFunctions.cs b/unity/Assets/Scripts/UtilityFunctions.cs index de2407d4e2..18e1e8cbd5 100644 --- a/unity/Assets/Scripts/UtilityFunctions.cs +++ b/unity/Assets/Scripts/UtilityFunctions.cs @@ -114,7 +114,7 @@ public static Collider firstColliderObjectCollidingWith( "Procedural0" ); foreach (CapsuleCollider cc in go.GetComponentsInChildren()) { - if (cc.isTrigger) { + if (cc.isTrigger || !cc.enabled) { continue; } foreach ( @@ -131,8 +131,11 @@ Collider c in PhysicsExtensions.OverlapCapsule( } } foreach (BoxCollider bc in go.GetComponentsInChildren()) { - 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( @@ -148,7 +151,7 @@ Collider c in PhysicsExtensions.OverlapBox( } } foreach (SphereCollider sc in go.GetComponentsInChildren()) { - if (sc.isTrigger) { + if (sc.isTrigger || !sc.enabled) { continue; } foreach ( @@ -164,6 +167,26 @@ Collider c in PhysicsExtensions.OverlapSphere( } } } + + foreach (MeshCollider mc in go.GetComponentsInChildren()) { + 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; }