From 4cf87e7e0b535fafec90f8f02d3c36bff1856e8c Mon Sep 17 00:00:00 2001 From: winthos Date: Thu, 26 Aug 2021 03:21:07 -0700 Subject: [PATCH 01/10] fix to isInteractable/Obstructed object flag logic previously, the `obstructed` value of metadata simply reported if the object was not visible by checking only against visibility. This has been switched to reflect a possible object state of an object being visible, but unable to be interacted with because it is obstructed by some transparent geometry (glass, window, glass door etc.) additionally, the `obstructed` metadata has been renamed to `obstructedByTransparentObject` to be more descriptive --- unity/Assets/Scripts/AgentManager.cs | 4 +- .../Assets/Scripts/BaseFPSAgentController.cs | 15 ++- unity/Assets/Scripts/DebugInputField.cs | 21 ++-- .../PhysicsRemoteFPSAgentController.cs | 104 +++--------------- unity/Assets/Scripts/SimObjPhysics.cs | 10 +- 5 files changed, 41 insertions(+), 113 deletions(-) diff --git a/unity/Assets/Scripts/AgentManager.cs b/unity/Assets/Scripts/AgentManager.cs index 91a9036740..e43029454b 100644 --- a/unity/Assets/Scripts/AgentManager.cs +++ b/unity/Assets/Scripts/AgentManager.cs @@ -1353,9 +1353,9 @@ public class ObjectMetadata { // public float cameraHorizon; moved to AgentMetadata, objects don't have a camerahorizon public bool visible; - // If true, object is obstructed by something and actions cannot be performed on it. + // If true, object is obstructed by something and actions cannot be performed on it unless forced. // This means an object behind glass will be obstructed=True and visible=True - public bool obstructed; + public bool obstructedByTransparentObject; // is this object a receptacle? public bool receptacle; diff --git a/unity/Assets/Scripts/BaseFPSAgentController.cs b/unity/Assets/Scripts/BaseFPSAgentController.cs index 8252eb9f0f..be939331ab 100644 --- a/unity/Assets/Scripts/BaseFPSAgentController.cs +++ b/unity/Assets/Scripts/BaseFPSAgentController.cs @@ -1671,11 +1671,10 @@ public virtual ObjectMetadata ObjectMetadataFromSimObjPhysics(SimObjPhysics simO // in the multiagent setting, explicitly giving this information for now. objMeta.visible = isVisible; // simObj.isVisible; - objMeta.obstructed = !isVisible;// if object is not interactable, it means it is obstructed + objMeta.obstructedByTransparentObject = !simObj.isInteractable;// object is not interactable. It may still be visible, but occluded by some transparent object (glass) objMeta.isMoving = simObj.inMotion;// keep track of if this object is actively moving - objMeta.objectOrientedBoundingBox = simObj.ObjectOrientedBoundingBox; objMeta.axisAlignedBoundingBox = simObj.AxisAlignedBoundingBox; @@ -2020,6 +2019,10 @@ protected SimObjPhysics getTargetObject(string objectId, bool forceAction = fals if (target == null) { throw new NullReferenceException("Target object not found within the specified visibility."); } + + if(!target.isInteractable && !forceAction) { + throw new NullReferenceException("Target object is visible but not interactable. It is likely obstructed by some clear object like glass."); + } return target; } @@ -2969,6 +2972,7 @@ protected bool CheckIfVisibilityPointRaycast( bool includeInvisible ) { bool result = false; + sop.isInteractable = false; // now cast a ray out toward the point, if anything occludes this point, that point is not visible RaycastHit hit; @@ -2995,11 +2999,12 @@ bool includeInvisible || (isSopHeldByArm && Arm.heldObjects[sop].Contains(hit.collider)) ) { result = true; - sop.debugIsInteractable = true; + sop.isInteractable = true; #if UNITY_EDITOR Debug.DrawLine(camera.transform.position, point.position, Color.cyan); #endif } else { + sop.isInteractable = false; result = false; } } @@ -3016,7 +3021,7 @@ bool includeInvisible // if this line is drawn, then this visibility point is in camera frame and not occluded // might want to use this for a targeting check as well at some point.... result = true; - sop.debugIsInteractable = true; + sop.isInteractable = true; } else { // we didn't directly hit the sop we are checking for with this cast, // check if it's because we hit something see-through @@ -3047,6 +3052,8 @@ bool includeInvisible || (isSopHeldByArm && Arm.heldObjects[sop].Contains(hit.collider)) ) { // found the object we are looking for, great! + //set it to visible via 'result' but the object is not interactable because it is behind some transparent object + sop.isInteractable = false; result = true; break; } else { diff --git a/unity/Assets/Scripts/DebugInputField.cs b/unity/Assets/Scripts/DebugInputField.cs index db0f100558..a334d8c274 100644 --- a/unity/Assets/Scripts/DebugInputField.cs +++ b/unity/Assets/Scripts/DebugInputField.cs @@ -1731,16 +1731,6 @@ IEnumerator executeBatch(JArray jActions) { break; } - // Force pickup object - case "fpu": { - ServerAction action = new ServerAction(); - action.action = "PickupObject"; - action.objectId = splitcommand[1]; - action.forceAction = true; - CurrentActiveController().ProcessControlCommand(action); - break; - } - // Get objects in box case "oib": { Dictionary action = new Dictionary(); @@ -2069,6 +2059,17 @@ IEnumerator executeBatch(JArray jActions) { break; } + // Force pickup object + case "fpu": { + Dictionary action = new Dictionary(); + action["action"] = "PickupObject"; + if (splitcommand.Length > 1) { + action["objectId"] = splitcommand[1]; + } + action["forceAction"] = true; + CurrentActiveController().ProcessControlCommand(action); + break; + } // pickup using screen coordinates case "puxy": { Dictionary action = new Dictionary(); diff --git a/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs b/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs index 87f018d558..ea2e1c0a0d 100644 --- a/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs +++ b/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs @@ -2111,16 +2111,6 @@ public void ApplyForceObject(ServerAction action) { target = getSimObjectFromId(action.objectId); } - // SimObjPhysics[] simObjPhysicsArray = VisibleSimObjs(action); - - // foreach (SimObjPhysics sop in simObjPhysicsArray) { - // if (action.objectId == sop.ObjectID) { - // target = sop; - // } - // } - // print(target.objectID); - // print(target.isInteractable); - if (target == null) { errorMessage = "No valid target!"; Debug.Log(errorMessage); @@ -3085,14 +3075,9 @@ public void ScaleObject( float scaleOverSeconds = 1.0f, bool forceAction = false ) { - if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(objectId)) { - errorMessage = "Object ID appears to be invalid."; - actionFinished(false); - return; - } // if object is in the scene and visible, assign it to 'target' - SimObjPhysics target = getInteractableSimObjectFromId(objectId, forceAction); + SimObjPhysics target = getTargetObject(objectId: objectId, forceAction: forceAction); // neither objectId nor coordinates found an object if (target == null) { @@ -4108,14 +4093,8 @@ public void PlaceHeldObject(string objectId, float maxDistance, bool forceAction // get the target receptacle based on the action object ID SimObjPhysics targetReceptacle = null; - if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(objectId)) { - errorMessage = "Object ID appears to be invalid."; - actionFinished(false); - return; - } - // if object is in the scene and visible, assign it to 'target' - targetReceptacle = getInteractableSimObjectFromId(objectId: objectId, forceVisible: forceAction); + targetReceptacle = getTargetObject(objectId: objectId, forceAction: forceAction); placeHeldObject( targetReceptacle: targetReceptacle, @@ -4945,14 +4924,8 @@ public void CookObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { - if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(action.objectId)) { - errorMessage = "Object ID appears to be invalid."; - actionFinished(false); - return; - } - // if object is in the scene and visible, assign it to 'target' - target = getInteractableSimObjectFromId(action.objectId, action.forceVisible); + target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); } @@ -5068,14 +5041,9 @@ private void toggleObject(string objectId, bool toggleOn, bool forceAction) { SimObjPhysics target = null; bool forceVisible = forceAction; - if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(objectId)) { - errorMessage = "Object ID appears to be invalid."; - actionFinished(false); - return; - } - // if object is in the scene and visible, assign it to 'target' - target = getInteractableSimObjectFromId(objectId: objectId, forceVisible: forceVisible); + target = getTargetObject(objectId: objectId, forceAction: forceAction); + if (!target) { // target not found in currently visible objects, report not found @@ -5313,8 +5281,7 @@ public void OpenObject( ); } - // XXX: To get all objects contained in a receptacle, target it with this Function and it will return a list of strings, each being the - // object ID of an object in this receptacle + // XXX: This will return contained objects, but should not be used. Likely depracate this later public void Contains(ServerAction action) { if (action.objectId == null) { errorMessage = "Hey, actually give me an object ID check containment for, yeah?"; @@ -5322,7 +5289,7 @@ public void Contains(ServerAction action) { return; } - SimObjPhysics target = getInteractableSimObjectFromId(action.objectId, action.forceVisible); + SimObjPhysics target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); if (target) { List ids = target.GetAllSimObjectsInReceptacleTriggersByObjectID(); @@ -8098,14 +8065,8 @@ public void SliceObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { - if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(action.objectId)) { - errorMessage = "Object ID appears to be invalid."; - actionFinished(false); - return; - } - // if object is in the scene and visible, assign it to 'target' - target = getInteractableSimObjectFromId(action.objectId, action.forceVisible); + target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); } // we found it! @@ -8160,14 +8121,8 @@ public void BreakObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { - if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(action.objectId)) { - errorMessage = "Object ID appears to be invalid."; - actionFinished(false); - return; - } - // if object is in the scene and visible, assign it to 'target' - target = getInteractableSimObjectFromId(action.objectId, action.forceVisible); + target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); } // we found it! @@ -8232,14 +8187,8 @@ public void DirtyObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { - if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(action.objectId)) { - errorMessage = "Object ID appears to be invalid."; - actionFinished(false); - return; - } - // if object is in the scene and visible, assign it to 'target' - target = getInteractableSimObjectFromId(action.objectId, action.forceVisible); + target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); } if (target) { @@ -8288,14 +8237,8 @@ public void CleanObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { - if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(action.objectId)) { - errorMessage = "Object ID appears to be invalid."; - actionFinished(false); - return; - } - // if object is in the scene and visible, assign it to 'target' - target = getInteractableSimObjectFromId(action.objectId, action.forceVisible); + target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); } if (target) { @@ -8345,14 +8288,8 @@ public void FillObjectWithLiquid(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { - if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(action.objectId)) { - errorMessage = "Object ID appears to be invalid."; - actionFinished(false); - return; - } - // if object is in the scene and visible, assign it to 'target' - target = getInteractableSimObjectFromId(action.objectId, action.forceVisible); + target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); } if (action.fillLiquid == null) { @@ -8408,14 +8345,8 @@ public void EmptyLiquidFromObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { - if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(action.objectId)) { - errorMessage = "Object ID appears to be invalid."; - actionFinished(false); - return; - } - // if object is in the scene and visible, assign it to 'target' - target = getInteractableSimObjectFromId(action.objectId, action.forceVisible); + target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); } if (target) { @@ -8466,14 +8397,7 @@ public void UseUpObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { - if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(action.objectId)) { - errorMessage = "Object ID appears to be invalid."; - actionFinished(false); - return; - } - - // if object is in the scene and visible, assign it to 'target' - target = getInteractableSimObjectFromId(action.objectId, action.forceVisible); + target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); } if (target) { diff --git a/unity/Assets/Scripts/SimObjPhysics.cs b/unity/Assets/Scripts/SimObjPhysics.cs index 113b72c5e3..f732e80651 100644 --- a/unity/Assets/Scripts/SimObjPhysics.cs +++ b/unity/Assets/Scripts/SimObjPhysics.cs @@ -48,7 +48,7 @@ public class SimObjPhysics : MonoBehaviour, SimpleSimObj { #if UNITY_EDITOR public bool debugIsVisible = false; #endif - public bool debugIsInteractable = false; + public bool isInteractable = false; public bool isInAgentHand = false; // these collider references are used for switching physics materials for all colliders on this object @@ -925,8 +925,7 @@ public bool DoesThisObjectHaveThisSecondaryProperty(SimObjSecondaryProperty prop } // Update is called once per frame void Update() { - debugIsInteractable = false; - + isInteractable = false; if (sceneManager.AllowDecayTemperature)// only do this if the scene is initialized to use Temperature decay over time { // if this object is either hot or col, begin a timer that counts until the object becomes room temperature again @@ -950,9 +949,6 @@ void LateUpdate() { lastVelocity = Math.Abs(myRigidbody.angularVelocity.sqrMagnitude + myRigidbody.velocity.sqrMagnitude); } } - private void FixedUpdate() { - // isInteractable = false; - } // used for throwing the sim object, or anything that requires adding force for some reason public void ApplyForce(ServerAction action) { @@ -1093,7 +1089,7 @@ void OnDrawGizmos() { } // interactable drawn in magenta - if (debugIsInteractable == true && gameObject.GetComponentInChildren()) { + if (isInteractable == true && gameObject.GetComponentInChildren()) { MeshFilter mf = gameObject.GetComponentInChildren(false); Gizmos.color = Color.magenta; Gizmos.DrawWireMesh(mf.sharedMesh, -1, mf.transform.position, mf.transform.rotation, mf.transform.lossyScale); From 77542f8e1fe0ee2d95369062440581fa48a5b030 Mon Sep 17 00:00:00 2001 From: winthos Date: Thu, 26 Aug 2021 10:55:41 -0700 Subject: [PATCH 02/10] Update metadata-schema.json update metadata scheme to use new name for `obstructed`->`obstructedByTransparentObject` --- ai2thor/tests/data/metadata-schema.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ai2thor/tests/data/metadata-schema.json b/ai2thor/tests/data/metadata-schema.json index b2c714c09a..64546bef46 100644 --- a/ai2thor/tests/data/metadata-schema.json +++ b/ai2thor/tests/data/metadata-schema.json @@ -43,7 +43,7 @@ "visible": { "type": "boolean" }, - "obstructed": { + "obstructedByTransparentObject": { "type": "boolean" }, "receptacle": { @@ -268,7 +268,7 @@ "objectId", "objectOrientedBoundingBox", "objectType", - "obstructed", + "obstructedByTransparentObject", "openable", "parentReceptacles", "pickupable", From 3847809f1572a0526001cb462b9a00a63f96da8e Mon Sep 17 00:00:00 2001 From: winthos Date: Thu, 26 Aug 2021 12:23:11 -0700 Subject: [PATCH 03/10] Update arm-metadata-schema.json also updating arm meta test with new name for obstructed --- ai2thor/tests/data/arm-metadata-schema.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ai2thor/tests/data/arm-metadata-schema.json b/ai2thor/tests/data/arm-metadata-schema.json index 46367cf552..2a5ff43bba 100644 --- a/ai2thor/tests/data/arm-metadata-schema.json +++ b/ai2thor/tests/data/arm-metadata-schema.json @@ -179,7 +179,7 @@ "visible": { "type": "boolean" }, - "obstructed": { + "obstructedByTransparentObject": { "type": "boolean" }, "receptacle": { @@ -404,7 +404,7 @@ "objectId", "objectOrientedBoundingBox", "objectType", - "obstructed", + "obstructedByTransparentObject", "openable", "parentReceptacles", "pickupable", From dd3479238ac3d70ccb729ee9cb5c7ede97b76d4b Mon Sep 17 00:00:00 2001 From: winthos Date: Thu, 26 Aug 2021 19:53:47 -0700 Subject: [PATCH 04/10] adds obstructed object test --- unity/Assets/UnitTests/TestObstructed.cs | 75 +++++++++++++++++++ unity/Assets/UnitTests/TestObstructed.cs.meta | 11 +++ 2 files changed, 86 insertions(+) create mode 100644 unity/Assets/UnitTests/TestObstructed.cs create mode 100644 unity/Assets/UnitTests/TestObstructed.cs.meta diff --git a/unity/Assets/UnitTests/TestObstructed.cs b/unity/Assets/UnitTests/TestObstructed.cs new file mode 100644 index 0000000000..cdcfdf66aa --- /dev/null +++ b/unity/Assets/UnitTests/TestObstructed.cs @@ -0,0 +1,75 @@ +using System.Collections; +using System.Collections.Generic; +using NUnit.Framework; +using System; +using UnityEngine; +using UnityEngine.TestTools; +using UnityStandardAssets.Characters.FirstPerson; + +namespace Tests { + public class TestObstructed : TestBase { + + [SetUp] + public override void Setup() { + UnityEngine.SceneManagement.SceneManager.LoadScene("FloorPlan402_physics"); + } + + [UnityTest] + public IEnumerator TestBehindGlassThenOpenDoor() { + Debug.Log("what is the current scene? " + UnityEngine.SceneManagement.SceneManager.GetActiveScene().name); + + Dictionary action = new Dictionary(); + + action["action"] = "Initialize"; + action["fieldOfView"] = 90f; + action["snapToGrid"] = true; + //action["scene"] = "FloorPlan402_physics"; + yield return step(action); + + action.Clear(); + + //teleport to position + action["action"] = "Teleport"; + action["position"] = new Vector3(-1.25f, 0.9006702f, 2.75f); + action["horizon"] = 30f; + action["rotation"] = new Vector3(0, -180f, 0); + yield return step(action); + + action.Clear(); + + action["action"] = "SetObjectPoses"; + ObjectPose pose = new ObjectPose() { + objectName = "SoapBottle_445f0dcf", + position = new Vector3(-1.022f, 0f, 1.456f), + rotation = new Vector3(0, -180f, 0) + }; + ObjectPose[] poses = new ObjectPose[1]; + poses[0] = pose; + action["objectPoses"] = poses; + yield return step(action); + + action.Clear(); + + GameObject bottle = GameObject.Find("SoapBottle_445f0dcf"); + + action["action"] = "PickupObject"; + action["objectId"] = bottle.GetComponent().objectID; + yield return step(action); + + Assert.AreEqual(lastActionSuccess, false); + + action.Clear(); + + //note normal OpenObject doesn't seem to work as the next action executes before door is fully open? + action["action"] = "OpenObjectImmediate"; + action["objectId"] = "ShowerDoor|-00.28|+01.23|+01.73"; + yield return step(action); + + action["action"] = "PickupObject"; + action["objectId"] = bottle.GetComponent().objectID; + yield return step(action); + + Assert.AreEqual(lastActionSuccess, true); + } + } +} diff --git a/unity/Assets/UnitTests/TestObstructed.cs.meta b/unity/Assets/UnitTests/TestObstructed.cs.meta new file mode 100644 index 0000000000..13840004c4 --- /dev/null +++ b/unity/Assets/UnitTests/TestObstructed.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63923a38901f69041808ac09761aa015 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 7c762859bb073daa6f6370e961d3559b830a94c7 Mon Sep 17 00:00:00 2001 From: winthos Date: Fri, 27 Aug 2021 11:15:33 -0700 Subject: [PATCH 05/10] addressing lgtm alert for useless assignment --- unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs b/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs index ea2e1c0a0d..48ac260260 100644 --- a/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs +++ b/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs @@ -5039,7 +5039,6 @@ private void toggleObject(float x, float y, bool toggleOn, bool forceAction) { private void toggleObject(string objectId, bool toggleOn, bool forceAction) { SimObjPhysics target = null; - bool forceVisible = forceAction; // if object is in the scene and visible, assign it to 'target' target = getTargetObject(objectId: objectId, forceAction: forceAction); From 02fac86152a99fca49eee90cc60bdaf98fb761d5 Mon Sep 17 00:00:00 2001 From: winthos Date: Fri, 27 Aug 2021 14:09:32 -0700 Subject: [PATCH 06/10] switch obstructedByTranasparentObject->isInteractable -additional syntax cleanup -note: will need to document that `isInteractable` is false only when a transparent object is in between the agent camera and some target object. --- ai2thor/tests/data/arm-metadata-schema.json | 4 ++-- ai2thor/tests/data/metadata-schema.json | 4 ++-- unity/Assets/Scripts/AgentManager.cs | 2 +- unity/Assets/Scripts/BaseFPSAgentController.cs | 4 +++- unity/Assets/Scripts/SimObjPhysics.cs | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ai2thor/tests/data/arm-metadata-schema.json b/ai2thor/tests/data/arm-metadata-schema.json index 2a5ff43bba..7a922be331 100644 --- a/ai2thor/tests/data/arm-metadata-schema.json +++ b/ai2thor/tests/data/arm-metadata-schema.json @@ -179,7 +179,7 @@ "visible": { "type": "boolean" }, - "obstructedByTransparentObject": { + "isInteractable": { "type": "boolean" }, "receptacle": { @@ -404,7 +404,7 @@ "objectId", "objectOrientedBoundingBox", "objectType", - "obstructedByTransparentObject", + "isInteractable", "openable", "parentReceptacles", "pickupable", diff --git a/ai2thor/tests/data/metadata-schema.json b/ai2thor/tests/data/metadata-schema.json index 64546bef46..fe12678ce9 100644 --- a/ai2thor/tests/data/metadata-schema.json +++ b/ai2thor/tests/data/metadata-schema.json @@ -43,7 +43,7 @@ "visible": { "type": "boolean" }, - "obstructedByTransparentObject": { + "isInteractable": { "type": "boolean" }, "receptacle": { @@ -268,7 +268,7 @@ "objectId", "objectOrientedBoundingBox", "objectType", - "obstructedByTransparentObject", + "isInteractable", "openable", "parentReceptacles", "pickupable", diff --git a/unity/Assets/Scripts/AgentManager.cs b/unity/Assets/Scripts/AgentManager.cs index e43029454b..2a83a73994 100644 --- a/unity/Assets/Scripts/AgentManager.cs +++ b/unity/Assets/Scripts/AgentManager.cs @@ -1355,7 +1355,7 @@ public class ObjectMetadata { // If true, object is obstructed by something and actions cannot be performed on it unless forced. // This means an object behind glass will be obstructed=True and visible=True - public bool obstructedByTransparentObject; + public bool isInteractable; // is this object a receptacle? public bool receptacle; diff --git a/unity/Assets/Scripts/BaseFPSAgentController.cs b/unity/Assets/Scripts/BaseFPSAgentController.cs index be939331ab..f0b664cecd 100644 --- a/unity/Assets/Scripts/BaseFPSAgentController.cs +++ b/unity/Assets/Scripts/BaseFPSAgentController.cs @@ -1671,7 +1671,9 @@ public virtual ObjectMetadata ObjectMetadataFromSimObjPhysics(SimObjPhysics simO // in the multiagent setting, explicitly giving this information for now. objMeta.visible = isVisible; // simObj.isVisible; - objMeta.obstructedByTransparentObject = !simObj.isInteractable;// object is not interactable. It may still be visible, but occluded by some transparent object (glass) + //determines if the objects is unobstructed and interactable. Objects visible behind see-through geometry like glass will be isInteractable=False even if visible + //note using forceAction=True will ignore the isInteractable requirement + objMeta.isInteractable = simObj.isInteractable; objMeta.isMoving = simObj.inMotion;// keep track of if this object is actively moving diff --git a/unity/Assets/Scripts/SimObjPhysics.cs b/unity/Assets/Scripts/SimObjPhysics.cs index f732e80651..456dd7ec32 100644 --- a/unity/Assets/Scripts/SimObjPhysics.cs +++ b/unity/Assets/Scripts/SimObjPhysics.cs @@ -1089,7 +1089,7 @@ void OnDrawGizmos() { } // interactable drawn in magenta - if (isInteractable == true && gameObject.GetComponentInChildren()) { + if (isInteractable && gameObject.GetComponentInChildren()) { MeshFilter mf = gameObject.GetComponentInChildren(false); Gizmos.color = Color.magenta; Gizmos.DrawWireMesh(mf.sharedMesh, -1, mf.transform.position, mf.transform.rotation, mf.transform.lossyScale); From 6702e2ea1189bbf4e328089526617c463bccece2 Mon Sep 17 00:00:00 2001 From: Eric Kolve Date: Thu, 2 Sep 2021 14:58:28 -0700 Subject: [PATCH 07/10] adding VisibilityCheck class to aid in differentiating between 'visible' and 'interactable' --- .../Assets/Scripts/BaseFPSAgentController.cs | 177 +++++++++++------- .../Assets/Scripts/DroneFPSAgentController.cs | 2 +- ...emoteFPSAgentController_partial_ExpRoom.cs | 11 +- .../PhysicsRemoteFPSAgentController.cs | 10 +- unity/Assets/Scripts/SimObjPhysics.cs | 5 +- 5 files changed, 122 insertions(+), 83 deletions(-) diff --git a/unity/Assets/Scripts/BaseFPSAgentController.cs b/unity/Assets/Scripts/BaseFPSAgentController.cs index f0b664cecd..e2d08c5792 100644 --- a/unity/Assets/Scripts/BaseFPSAgentController.cs +++ b/unity/Assets/Scripts/BaseFPSAgentController.cs @@ -1524,11 +1524,15 @@ public virtual ObjectMetadata[] generateObjectMetadata() { simObjects = GameObject.FindObjectsOfType(); } + SimObjPhysics[] interactable; HashSet visibleSimObjsHash = new HashSet(GetAllVisibleSimObjPhysics( this.m_Camera, this.maxVisibleDistance, + out interactable, this.simObjFilter)); + HashSet interactableSimObjsHash = new HashSet(interactable); + int numObj = simObjects.Length; List metadata = new List(); Dictionary> parentReceptacles = new Dictionary>(); @@ -1540,7 +1544,7 @@ public virtual ObjectMetadata[] generateObjectMetadata() { for (int k = 0; k < numObj; k++) { SimObjPhysics simObj = simObjects[k]; - ObjectMetadata meta = ObjectMetadataFromSimObjPhysics(simObj, visibleSimObjsHash.Contains(simObj)); + ObjectMetadata meta = ObjectMetadataFromSimObjPhysics(simObj, visibleSimObjsHash.Contains(simObj), interactableSimObjsHash.Contains(simObj)); if (meta.toggleable) { SimObjPhysics[] controlled = simObj.GetComponent().ReturnControlledSimObjects(); List controlledList = new List(); @@ -1577,7 +1581,7 @@ public virtual ObjectMetadata[] generateObjectMetadata() { } // generates object metatada based on sim object's properties - public virtual ObjectMetadata ObjectMetadataFromSimObjPhysics(SimObjPhysics simObj, bool isVisible) { + public virtual ObjectMetadata ObjectMetadataFromSimObjPhysics(SimObjPhysics simObj, bool isVisible, bool isInteractable) { ObjectMetadata objMeta = new ObjectMetadata(); GameObject o = simObj.gameObject; objMeta.name = o.name; @@ -1673,7 +1677,7 @@ public virtual ObjectMetadata ObjectMetadataFromSimObjPhysics(SimObjPhysics simO //determines if the objects is unobstructed and interactable. Objects visible behind see-through geometry like glass will be isInteractable=False even if visible //note using forceAction=True will ignore the isInteractable requirement - objMeta.isInteractable = simObj.isInteractable; + objMeta.isInteractable = isInteractable; objMeta.isMoving = simObj.inMotion;// keep track of if this object is actively moving @@ -2013,20 +2017,25 @@ protected SimObjPhysics getTargetObject(string objectId, bool forceAction = fals if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(objectId)) { throw new ArgumentException($"objectId: {objectId} is not the objectId on any object in the scene!"); } - - // if object is in the scene and visible, assign it to 'target' - SimObjPhysics target = getInteractableSimObjectFromId(objectId: objectId, forceVisible: forceAction); + + SimObjPhysics sop = getSimObjectFromId(objectId); + if (sop == null) { + throw new NullReferenceException("Object with id'" + objectId + "' is null"); + } + + SimObjPhysics[] interactable; + bool visible = GetAllVisibleSimObjPhysics(camera: this.m_Camera, maxDistance: this.maxVisibleDistance, out interactable, filterSimObjs: new List { sop }).Length == 1; // target not found! - if (target == null) { + if (!visible && !forceAction) { throw new NullReferenceException("Target object not found within the specified visibility."); } - if(!target.isInteractable && !forceAction) { + if(interactable.Length == 0 && !forceAction) { throw new NullReferenceException("Target object is visible but not interactable. It is likely obstructed by some clear object like glass."); } - return target; + return sop; } // Helper method that parses (x and y) parameters to return the @@ -2673,12 +2682,11 @@ protected bool objectIsWithinViewport(SimObjPhysics sop) { return false; } - public bool isSimObjVisible(Camera camera, SimObjPhysics sop, float maxDistance) { - bool visible = false; + public VisibilityCheck isSimObjVisible(Camera camera, SimObjPhysics sop, float maxDistance) { + VisibilityCheck visCheck = new VisibilityCheck(); // check against all visibility points, accumulate count. If at least one point is visible, set object to visible if (sop.VisibilityPoints != null && sop.VisibilityPoints.Length > 0) { Transform[] visPoints = sop.VisibilityPoints; - int visPointCount = 0; float maxDistanceSquared = maxDistance * maxDistance; foreach (Transform point in visPoints) { @@ -2704,8 +2712,8 @@ public bool isSimObjVisible(Camera camera, SimObjPhysics sop, float maxDistance) } // if this particular point is in view... - if (CheckIfVisibilityPointInViewport(sop, point, camera, sop.IsReceptacle)) { - visPointCount++; + visCheck |= CheckIfVisibilityPointInViewport(sop, point, camera, sop.IsReceptacle); + if (visCheck.visible && visCheck.interactable){ #if !UNITY_EDITOR // If we're in the unity editor then don't break on finding a visible // point as we want to draw lines to each visible point. @@ -2715,25 +2723,21 @@ public bool isSimObjVisible(Camera camera, SimObjPhysics sop, float maxDistance) } // if we see at least one vis point, the object is "visible" - if (visPointCount > 0) { #if UNITY_EDITOR - sop.debugIsVisible = true; + sop.debugIsVisible = visCheck.visible; + sop.debugIsInteractable = visCheck.interactable; #endif - visible = true; - } } else { Debug.Log("Error! Set at least 1 visibility point on SimObjPhysics " + sop + "."); } - return visible; + return visCheck; } - public bool isSimObjVisible(Camera camera, SimObjPhysics sop, float maxDistance, Plane[] planes) { - bool visible = false; + public VisibilityCheck isSimObjVisible(Camera camera, SimObjPhysics sop, float maxDistance, Plane[] planes) { // check against all visibility points, accumulate count. If at least one point is visible, set object to visible + VisibilityCheck visCheck = new VisibilityCheck(); if (sop.VisibilityPoints != null && sop.VisibilityPoints.Length > 0) { Transform[] visPoints = sop.VisibilityPoints; - int visPointCount = 0; - float maxDistanceSquared = maxDistance * maxDistance; foreach (Transform point in visPoints) { bool outsidePlane = false; @@ -2771,9 +2775,9 @@ public bool isSimObjVisible(Camera camera, SimObjPhysics sop, float maxDistance, } // if this particular point is in view... - if (CheckIfVisibilityPointRaycast(sop, point, camera, false) || - CheckIfVisibilityPointRaycast(sop, point, camera, true)) { - visPointCount++; + visCheck |= (CheckIfVisibilityPointRaycast(sop, point, camera, false) | CheckIfVisibilityPointRaycast(sop, point, camera, true)); + if (visCheck.visible && visCheck.interactable){ + #if !UNITY_EDITOR // If we're in the unity editor then don't break on finding a visible // point as we want to draw lines to each visible point. @@ -2783,16 +2787,14 @@ public bool isSimObjVisible(Camera camera, SimObjPhysics sop, float maxDistance, } // if we see at least one vis point, the object is "visible" - if (visPointCount > 0) { #if UNITY_EDITOR - sop.debugIsVisible = true; -#endif - visible = true; - } + sop.debugIsVisible = visCheck.visible; + sop.debugIsInteractable = visCheck.interactable; +#endif } else { Debug.Log("Error! Set at least 1 visibility point on SimObjPhysics " + sop + "."); } - return visible; + return visCheck; } // pass in forceVisible bool to force grab all objects of type sim obj @@ -2809,11 +2811,25 @@ protected SimObjPhysics[] GetAllVisibleSimObjPhysics( float maxDistance, IEnumerable filterSimObjs = null ) { + SimObjPhysics[] interactable; + + if (this.visibilityScheme == VisibilityScheme.Collider) { + return GetAllVisibleSimObjPhysicsCollider(camera, maxDistance, filterSimObjs, out interactable); + } else { + return GetAllVisibleSimObjPhysicsDistance(camera, maxDistance, filterSimObjs, out interactable); + } + } + protected SimObjPhysics[] GetAllVisibleSimObjPhysics( + Camera camera, + float maxDistance, + out SimObjPhysics[] interactable, + IEnumerable filterSimObjs = null + ) { if (this.visibilityScheme == VisibilityScheme.Collider) { - return GetAllVisibleSimObjPhysicsCollider(camera, maxDistance, filterSimObjs); + return GetAllVisibleSimObjPhysicsCollider(camera, maxDistance, filterSimObjs, out interactable); } else { - return GetAllVisibleSimObjPhysicsDistance(camera, maxDistance, filterSimObjs); + return GetAllVisibleSimObjPhysicsDistance(camera, maxDistance, filterSimObjs, out interactable); } } @@ -2823,29 +2839,39 @@ protected SimObjPhysics[] GetAllVisibleSimObjPhysics( // range and is visibile outside of the range, it will get reported as invisible // by the new scheme, but visible in the current scheme. protected SimObjPhysics[] GetAllVisibleSimObjPhysicsDistance( - Camera camera, float maxDistance, IEnumerable filterSimObjs + Camera camera, float maxDistance, IEnumerable filterSimObjs, out SimObjPhysics[] interactable ) { if (filterSimObjs == null) { filterSimObjs = physicsSceneManager.ObjectIdToSimObjPhysics.Values; } List visible = new List(); + List interactableItems = new List(); Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera); foreach (var sop in filterSimObjs) { - if (isSimObjVisible(camera, sop, this.maxVisibleDistance, planes)) { + VisibilityCheck visCheck = isSimObjVisible(camera, sop, this.maxVisibleDistance, planes); + if (visCheck.visible) { visible.Add(sop); } + + if (visCheck.interactable) { + interactableItems.Add(sop); + } } + + interactable = interactableItems.ToArray(); return visible.ToArray(); } - private SimObjPhysics[] GetAllVisibleSimObjPhysicsCollider(Camera camera, float maxDistance, IEnumerable filterSimObjs) { + private SimObjPhysics[] GetAllVisibleSimObjPhysicsCollider(Camera camera, float maxDistance, IEnumerable filterSimObjs, out SimObjPhysics[] interactable) { List currentlyVisibleItems = new List(); + List interactableItems = new List(); #if UNITY_EDITOR foreach (KeyValuePair pair in physicsSceneManager.ObjectIdToSimObjPhysics) { // Set all objects to not be visible pair.Value.debugIsVisible = false; + pair.Value.debugIsInteractable = false; } #endif @@ -2853,6 +2879,7 @@ private SimObjPhysics[] GetAllVisibleSimObjPhysicsCollider(Camera camera, float if (filterSimObjs != null) { filter = new HashSet(filterSimObjs); if (filter.Count == 0) { + interactable = interactableItems.ToArray(); return currentlyVisibleItems.ToArray(); } } @@ -2925,14 +2952,13 @@ private SimObjPhysics[] GetAllVisibleSimObjPhysicsCollider(Camera camera, float // check against all visibility points, accumulate count. If at least one point is visible, set object to visible if (sop.VisibilityPoints != null && sop.VisibilityPoints.Length > 0) { Transform[] visPoints = sop.VisibilityPoints; - int visPointCount = 0; + VisibilityCheck visCheck = new VisibilityCheck(); foreach (Transform point in visPoints) { // if this particular point is in view... - if (CheckIfVisibilityPointInViewport( - sop, point, camera, includeInvisible - )) { - visPointCount++; + // if we see at least one vis point, the object is "visible" + visCheck |= CheckIfVisibilityPointInViewport(sop, point, camera, includeInvisible); + if (visCheck.visible && visCheck.interactable) { #if !UNITY_EDITOR // If we're in the unity editor then don't break on finding a visible // point as we want to draw lines to each visible point. @@ -2941,14 +2967,16 @@ private SimObjPhysics[] GetAllVisibleSimObjPhysicsCollider(Camera camera, float } } - // if we see at least one vis point, the object is "visible" - if (visPointCount > 0) { #if UNITY_EDITOR - sop.debugIsVisible = true; -#endif - if (!currentlyVisibleItems.Contains(sop)) { - currentlyVisibleItems.Add(sop); - } + sop.debugIsVisible = visCheck.visible; + sop.debugIsInteractable = visCheck.interactable; +#endif + if (visCheck.visible && !currentlyVisibleItems.Contains(sop)) { + currentlyVisibleItems.Add(sop); + } + + if (visCheck.interactable && !interactableItems.Contains(sop)) { + interactableItems.Add(sop); } } else { Debug.Log("Error! Set at least 1 visibility point on SimObjPhysics " + sop + "."); @@ -2961,20 +2989,21 @@ private SimObjPhysics[] GetAllVisibleSimObjPhysicsCollider(Camera camera, float updateAllAgentCollidersForVisibilityCheck(true); // populate array of visible items in order by distance + interactableItems.Sort((x, y) => Vector3.Distance(x.transform.position, agentCameraPos).CompareTo(Vector3.Distance(y.transform.position, agentCameraPos))); currentlyVisibleItems.Sort((x, y) => Vector3.Distance(x.transform.position, agentCameraPos).CompareTo(Vector3.Distance(y.transform.position, agentCameraPos))); + interactable = interactableItems.ToArray(); return currentlyVisibleItems.ToArray(); } // check if the visibility point on a sim object, sop, is within the viewport // has a inclueInvisible bool to check against triggerboxes as well, to check for visibility with things like Cabinets/Drawers - protected bool CheckIfVisibilityPointRaycast( + protected VisibilityCheck CheckIfVisibilityPointRaycast( SimObjPhysics sop, Transform point, Camera camera, bool includeInvisible ) { - bool result = false; - sop.isInteractable = false; + VisibilityCheck visCheck = new VisibilityCheck(); // now cast a ray out toward the point, if anything occludes this point, that point is not visible RaycastHit hit; @@ -3000,15 +3029,12 @@ bool includeInvisible hit.transform == sop.transform || (isSopHeldByArm && Arm.heldObjects[sop].Contains(hit.collider)) ) { - result = true; - sop.isInteractable = true; + visCheck.visible = true; + visCheck.interactable = true; #if UNITY_EDITOR Debug.DrawLine(camera.transform.position, point.position, Color.cyan); #endif - } else { - sop.isInteractable = false; - result = false; - } + } } } @@ -3022,8 +3048,8 @@ bool includeInvisible ) { // if this line is drawn, then this visibility point is in camera frame and not occluded // might want to use this for a targeting check as well at some point.... - result = true; - sop.isInteractable = true; + visCheck.visible = true; + visCheck.interactable = true; } else { // we didn't directly hit the sop we are checking for with this cast, // check if it's because we hit something see-through @@ -3055,8 +3081,8 @@ bool includeInvisible ) { // found the object we are looking for, great! //set it to visible via 'result' but the object is not interactable because it is behind some transparent object - sop.isInteractable = false; - result = true; + visCheck.visible = true; + visCheck.interactable = false; break; } else { // Didn't find it, continue on only if the hit object was translucent @@ -3071,23 +3097,23 @@ bool includeInvisible } #if UNITY_EDITOR - if (result) { + if (visCheck.visible) { Debug.DrawLine(camera.transform.position, point.position, Color.cyan); } #endif } } - return result; + return visCheck; } - protected bool CheckIfVisibilityPointInViewport( + protected VisibilityCheck CheckIfVisibilityPointInViewport( SimObjPhysics sop, Transform point, Camera camera, bool includeInvisible ) { - bool result = false; + VisibilityCheck visCheck = new VisibilityCheck(); Vector3 viewPoint = camera.WorldToViewportPoint(point.position); @@ -3100,16 +3126,16 @@ bool includeInvisible && viewPoint.y < ViewPointRangeHigh && viewPoint.y > ViewPointRangeLow) // within y bounds of viewport { - result = CheckIfVisibilityPointRaycast(sop, point, camera, includeInvisible); + visCheck = CheckIfVisibilityPointRaycast(sop, point, camera, includeInvisible); } #if UNITY_EDITOR - if (result == true) { + if (visCheck.visible) { Debug.DrawLine(camera.transform.position, point.position, Color.cyan); } #endif - return result; + return visCheck; } public void DefaultAgentHand() { @@ -4436,4 +4462,17 @@ public void TestActionDispatchFindConflicts(string typeName) { actionFinished(true, conflicts); } } + + public class VisibilityCheck { + public bool visible; + public bool interactable; + + public static VisibilityCheck operator |(VisibilityCheck a, VisibilityCheck b) { + VisibilityCheck c = new VisibilityCheck(); + c.interactable = a.interactable | b.interactable; + c.visible = a.visible | b.visible; + return c; + } + } + } diff --git a/unity/Assets/Scripts/DroneFPSAgentController.cs b/unity/Assets/Scripts/DroneFPSAgentController.cs index 810186cf2a..7f969ed8d0 100644 --- a/unity/Assets/Scripts/DroneFPSAgentController.cs +++ b/unity/Assets/Scripts/DroneFPSAgentController.cs @@ -145,7 +145,7 @@ void FixedUpdate() { } // generates object metadata based on sim object's properties - public override ObjectMetadata ObjectMetadataFromSimObjPhysics(SimObjPhysics simObj, bool isVisible) { + public override ObjectMetadata ObjectMetadataFromSimObjPhysics(SimObjPhysics simObj, bool isVisible, bool isInteractable) { DroneObjectMetadata objMeta = new DroneObjectMetadata(); objMeta.isCaught = this.GetComponent().isObjectCaught(simObj); objMeta.numSimObjHits = simObj.numSimObjHit; diff --git a/unity/Assets/Scripts/ExpRoom/PhysicsRemoteFPSAgentController_partial_ExpRoom.cs b/unity/Assets/Scripts/ExpRoom/PhysicsRemoteFPSAgentController_partial_ExpRoom.cs index aa8849abf1..6a8d4be96a 100644 --- a/unity/Assets/Scripts/ExpRoom/PhysicsRemoteFPSAgentController_partial_ExpRoom.cs +++ b/unity/Assets/Scripts/ExpRoom/PhysicsRemoteFPSAgentController_partial_ExpRoom.cs @@ -180,7 +180,7 @@ SimObjPhysics cover in availableExpRoomContainersDict.OrderBy( return false; } if (i == 0) { - if (isSimObjVisible(visibilityCheckCamera, toCover, 10f)) { + if (isSimObjVisible(visibilityCheckCamera, toCover, 10f).visible) { return false; } } @@ -415,9 +415,11 @@ public void ObjectsVisibleFromThirdPartyCamera(int thirdPartyCameraIndex, float? if (!maxDistance.HasValue) { maxDistance = maxVisibleDistance; } + + SimObjPhysics[] interactable; actionFinishedEmit(true, GetAllVisibleSimObjPhysicsDistance( - agentManager.thirdPartyCameras[thirdPartyCameraIndex], maxDistance.Value, null + agentManager.thirdPartyCameras[thirdPartyCameraIndex], maxDistance.Value, null, out interactable ).Select(sop => sop.ObjectID).ToList() ); } @@ -441,9 +443,8 @@ public void ProportionOfObjectVisible( Camera camera = thirdPartyCameraIndex.HasValue ? agentManager.thirdPartyCameras[thirdPartyCameraIndex.Value] : m_Camera; foreach (Transform point in visPoints) { // if this particular point is in view... - if (CheckIfVisibilityPointInViewport( - target, point, camera, false - )) { + + if (CheckIfVisibilityPointInViewport(target, point, camera, false).visible) { visPointCount++; } } diff --git a/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs b/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs index 48ac260260..fb74aa9b91 100644 --- a/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs +++ b/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs @@ -164,8 +164,8 @@ public override MetadataWrapper generateMetadataWrapper() { return metaWrapper; } - public override ObjectMetadata ObjectMetadataFromSimObjPhysics(SimObjPhysics simObj, bool isVisible) { - return base.ObjectMetadataFromSimObjPhysics(simObj, isVisible); + public override ObjectMetadata ObjectMetadataFromSimObjPhysics(SimObjPhysics simObj, bool isVisible, bool isInteractable) { + return base.ObjectMetadataFromSimObjPhysics(simObj, isVisible, isInteractable); } // change the radius of the agent's capsule on the char controller component, and the capsule collider component @@ -5992,8 +5992,8 @@ public bool objectIsCurrentlyVisible(SimObjPhysics sop, float maxDistance) { // Debug.Log(Vector3.Distance(tmp, transform.position)); if (Vector3.Distance(tmp, transform.position) < maxDistance) { // if this particular point is in view... - if (CheckIfVisibilityPointInViewport(sop, point, m_Camera, false) || - CheckIfVisibilityPointInViewport(sop, point, m_Camera, true)) { + if ((CheckIfVisibilityPointInViewport(sop, point, m_Camera, false) | + CheckIfVisibilityPointInViewport(sop, point, m_Camera, true)).visible) { updateAllAgentCollidersForVisibilityCheck(true); return true; } @@ -6979,7 +6979,7 @@ protected float approxPercentScreenObjectOccupies(SimObjPhysics sop, bool update foreach (Transform point in sop.VisibilityPoints) { Vector3 viewPoint = m_Camera.WorldToViewportPoint(point.position); - if (CheckIfVisibilityPointInViewport(sop, point, m_Camera, false)) { + if (CheckIfVisibilityPointInViewport(sop, point, m_Camera, false).visible) { minX = Math.Min(viewPoint.x, minX); maxX = Math.Max(viewPoint.x, maxX); minY = Math.Min(viewPoint.y, minY); diff --git a/unity/Assets/Scripts/SimObjPhysics.cs b/unity/Assets/Scripts/SimObjPhysics.cs index 456dd7ec32..416f352f63 100644 --- a/unity/Assets/Scripts/SimObjPhysics.cs +++ b/unity/Assets/Scripts/SimObjPhysics.cs @@ -47,8 +47,8 @@ public class SimObjPhysics : MonoBehaviour, SimpleSimObj { [Header("State information Bools here")] #if UNITY_EDITOR public bool debugIsVisible = false; + public bool debugIsInteractable = false; #endif - public bool isInteractable = false; public bool isInAgentHand = false; // these collider references are used for switching physics materials for all colliders on this object @@ -925,7 +925,6 @@ public bool DoesThisObjectHaveThisSecondaryProperty(SimObjSecondaryProperty prop } // Update is called once per frame void Update() { - isInteractable = false; if (sceneManager.AllowDecayTemperature)// only do this if the scene is initialized to use Temperature decay over time { // if this object is either hot or col, begin a timer that counts until the object becomes room temperature again @@ -1089,7 +1088,7 @@ void OnDrawGizmos() { } // interactable drawn in magenta - if (isInteractable && gameObject.GetComponentInChildren()) { + if (debugIsInteractable && gameObject.GetComponentInChildren()) { MeshFilter mf = gameObject.GetComponentInChildren(false); Gizmos.color = Color.magenta; Gizmos.DrawWireMesh(mf.sharedMesh, -1, mf.transform.position, mf.transform.rotation, mf.transform.lossyScale); From b55a216d2b1fa2d112a4cac676a7a72f0e6c41e9 Mon Sep 17 00:00:00 2001 From: winthos Date: Fri, 10 Sep 2021 11:58:55 -0700 Subject: [PATCH 08/10] addressing changes -consolidates getTargetObjectFromId -adds || to short circuit visibility check -adds isInteractable to object meta in Drone agent -optimizing visibilty/interactable lists to hashsets -fixing some exception text syntax --- .../Assets/Scripts/BaseFPSAgentController.cs | 36 ++++++----------- .../Assets/Scripts/DroneFPSAgentController.cs | 6 ++- .../PhysicsRemoteFPSAgentController.cs | 40 +++++++++---------- 3 files changed, 37 insertions(+), 45 deletions(-) diff --git a/unity/Assets/Scripts/BaseFPSAgentController.cs b/unity/Assets/Scripts/BaseFPSAgentController.cs index 283703bdeb..7b91b3f0ef 100644 --- a/unity/Assets/Scripts/BaseFPSAgentController.cs +++ b/unity/Assets/Scripts/BaseFPSAgentController.cs @@ -2031,7 +2031,7 @@ public void Done() { // Helper method that parses objectId parameter to return the sim object that it target. // The action is halted if the objectId does not appear in the scene. - protected SimObjPhysics getTargetObject(string objectId, bool forceAction = false) { + protected SimObjPhysics getTargetObjectFromId(string objectId, bool forceAction = false) { // an objectId was given, so find that target in the scene if it exists if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(objectId)) { throw new ArgumentException($"objectId: {objectId} is not the objectId on any object in the scene!"); @@ -2039,7 +2039,7 @@ protected SimObjPhysics getTargetObject(string objectId, bool forceAction = fals SimObjPhysics sop = getSimObjectFromId(objectId); if (sop == null) { - throw new NullReferenceException("Object with id'" + objectId + "' is null"); + throw new NullReferenceException($"Object with id '{objectId}' is null"); } SimObjPhysics[] interactable; @@ -2059,7 +2059,7 @@ protected SimObjPhysics getTargetObject(string objectId, bool forceAction = fals // Helper method that parses (x and y) parameters to return the // sim object that they target. - protected SimObjPhysics getTargetObject(float x, float y, bool forceAction) { + protected SimObjPhysics getTargetObjectFromId(float x, float y, bool forceAction) { if (x < 0 || x > 1 || y < 0 || y > 1) { throw new ArgumentOutOfRangeException("x/y must be in [0:1]"); } @@ -2883,8 +2883,8 @@ protected SimObjPhysics[] GetAllVisibleSimObjPhysicsDistance( } private SimObjPhysics[] GetAllVisibleSimObjPhysicsCollider(Camera camera, float maxDistance, IEnumerable filterSimObjs, out SimObjPhysics[] interactable) { - List currentlyVisibleItems = new List(); - List interactableItems = new List(); + HashSet currentlyVisibleItems = new HashSet(); + HashSet interactableItems = new HashSet(); #if UNITY_EDITOR foreach (KeyValuePair pair in physicsSceneManager.ObjectIdToSimObjPhysics) { @@ -3008,10 +3008,14 @@ private SimObjPhysics[] GetAllVisibleSimObjPhysicsCollider(Camera camera, float updateAllAgentCollidersForVisibilityCheck(true); // populate array of visible items in order by distance - interactableItems.Sort((x, y) => Vector3.Distance(x.transform.position, agentCameraPos).CompareTo(Vector3.Distance(y.transform.position, agentCameraPos))); - currentlyVisibleItems.Sort((x, y) => Vector3.Distance(x.transform.position, agentCameraPos).CompareTo(Vector3.Distance(y.transform.position, agentCameraPos))); - interactable = interactableItems.ToArray(); - return currentlyVisibleItems.ToArray(); + List currentlyVisibleItemsToList = currentlyVisibleItems.ToList(); + List interactableItemsToList = interactableItems.ToList(); + + interactableItemsToList.Sort((x, y) => Vector3.Distance(x.transform.position, agentCameraPos).CompareTo(Vector3.Distance(y.transform.position, agentCameraPos))); + currentlyVisibleItemsToList.Sort((x, y) => Vector3.Distance(x.transform.position, agentCameraPos).CompareTo(Vector3.Distance(y.transform.position, agentCameraPos))); + + interactable = interactableItemsToList.ToArray(); + return currentlyVisibleItemsToList.ToArray(); } // check if the visibility point on a sim object, sop, is within the viewport @@ -3615,20 +3619,6 @@ public void ObjectTypeToObjectIds(string objectType) { } } - protected SimObjPhysics getInteractableSimObjectFromId(string objectId, bool forceVisible = false) { - SimObjPhysics sop = getSimObjectFromId(objectId); - if (sop == null) { - errorMessage = "Object with id '" + objectId + "' is null"; - return null; - } - - if (forceVisible || IsInteractable(sop)) { - return sop; - } - - return null; - } - protected SimObjPhysics getSimObjectFromId(string objectId) { if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(objectId)) { errorMessage = "Cannot find sim object with id '" + objectId + "'"; diff --git a/unity/Assets/Scripts/DroneFPSAgentController.cs b/unity/Assets/Scripts/DroneFPSAgentController.cs index eb7fb594fc..acb80a906a 100644 --- a/unity/Assets/Scripts/DroneFPSAgentController.cs +++ b/unity/Assets/Scripts/DroneFPSAgentController.cs @@ -181,8 +181,6 @@ public override ObjectMetadata ObjectMetadataFromSimObjPhysics(SimObjPhysics sim } } - - // can this object change others to hot? objMeta.isHeatSource = simObj.isHeatSource; @@ -213,6 +211,10 @@ public override ObjectMetadata ObjectMetadataFromSimObjPhysics(SimObjPhysics sim // in the multiagent setting, explicitly giving this information for now. objMeta.visible = isVisible; // simObj.isVisible; + //determines if the objects is unobstructed and interactable. Objects visible behind see-through geometry like glass will be isInteractable=False even if visible + //note using forceAction=True will ignore the isInteractable requirement + objMeta.isInteractable = isInteractable; + objMeta.isMoving = simObj.inMotion;// keep track of if this object is actively moving objMeta.objectOrientedBoundingBox = simObj.ObjectOrientedBoundingBox; diff --git a/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs b/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs index 5f7ff0dee5..b6df182604 100644 --- a/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs +++ b/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs @@ -70,7 +70,7 @@ public void SetTemperatureDecayTime(string objectId, float decayTime) { if (decayTime < 0) { throw new ArgumentOutOfRangeException("decayTime must be >= 0. You gave " + decayTime); } - SimObjPhysics sop = getTargetObject(objectId: objectId, forceAction: true); + SimObjPhysics sop = getTargetObjectFromId(objectId: objectId, forceAction: true); sop.SetHowManySecondsUntilRoomTemp(decayTime); actionFinished(true); } @@ -3010,7 +3010,7 @@ public void ScaleObject( ) { // if object is in the scene and visible, assign it to 'target' - SimObjPhysics target = getTargetObject(objectId: objectId, forceAction: forceAction); + SimObjPhysics target = getTargetObjectFromId(objectId: objectId, forceAction: forceAction); // neither objectId nor coordinates found an object if (target == null) { @@ -4023,7 +4023,7 @@ public void PlaceHeldObject(string objectId, float maxDistance, bool forceAction SimObjPhysics targetReceptacle = null; // if object is in the scene and visible, assign it to 'target' - targetReceptacle = getTargetObject(objectId: objectId, forceAction: forceAction); + targetReceptacle = getTargetObjectFromId(objectId: objectId, forceAction: forceAction); placeHeldObject( targetReceptacle: targetReceptacle, @@ -4301,12 +4301,12 @@ bool markActionFinished } public virtual void PickupObject(float x, float y, bool forceAction = false, bool manualInteract = false) { - SimObjPhysics target = getTargetObject(x: x, y: y, forceAction: forceAction); + SimObjPhysics target = getTargetObjectFromId(x: x, y: y, forceAction: forceAction); pickupObject(target: target, forceAction: forceAction, manualInteract: manualInteract, markActionFinished: true); } public virtual void PickupObject(string objectId, bool forceAction = false, bool manualInteract = false) { - SimObjPhysics target = getTargetObject(objectId: objectId, forceAction: forceAction); + SimObjPhysics target = getTargetObjectFromId(objectId: objectId, forceAction: forceAction); pickupObject(target: target, forceAction: forceAction, manualInteract: manualInteract, markActionFinished: true); } @@ -4809,7 +4809,7 @@ public void CookObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); + target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } @@ -4925,7 +4925,7 @@ private void toggleObject(string objectId, bool toggleOn, bool forceAction) { SimObjPhysics target = null; // if object is in the scene and visible, assign it to 'target' - target = getTargetObject(objectId: objectId, forceAction: forceAction); + target = getTargetObjectFromId(objectId: objectId, forceAction: forceAction); if (!target) { @@ -5117,7 +5117,7 @@ public void OpenObjectImmediate( string objectId, float openness = 1.0f ) { - SimObjPhysics target = getTargetObject(objectId: objectId, forceAction: true); + SimObjPhysics target = getTargetObjectFromId(objectId: objectId, forceAction: true); target.GetComponent().SetOpennessImmediate(openness); actionFinished(true); } @@ -5128,7 +5128,7 @@ public void OpenObject( float openness = 1, float? moveMagnitude = null // moveMagnitude is supported for backwards compatibility. It's new name is 'openness'. ) { - SimObjPhysics target = getTargetObject(objectId: objectId, forceAction: forceAction); + SimObjPhysics target = getTargetObjectFromId(objectId: objectId, forceAction: forceAction); openObject( target: target, openness: openness, @@ -5172,7 +5172,7 @@ public void Contains(ServerAction action) { return; } - SimObjPhysics target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); + SimObjPhysics target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); if (target) { List ids = target.GetAllSimObjectsInReceptacleTriggersByObjectID(); @@ -5876,8 +5876,8 @@ public bool objectIsCurrentlyVisible(SimObjPhysics sop, float maxDistance) { // Debug.Log(Vector3.Distance(tmp, transform.position)); if (Vector3.Distance(tmp, transform.position) < maxDistance) { // if this particular point is in view... - if ((CheckIfVisibilityPointInViewport(sop, point, m_Camera, false) | - CheckIfVisibilityPointInViewport(sop, point, m_Camera, true)).visible) { + if ((CheckIfVisibilityPointInViewport(sop, point, m_Camera, false).visible || + CheckIfVisibilityPointInViewport(sop, point, m_Camera, true).visible)) { updateAllAgentCollidersForVisibilityCheck(true); return true; } @@ -6086,7 +6086,7 @@ private List> getInteractablePoses( maxDistanceFloat = (float)maxDistance; } - SimObjPhysics theObject = getTargetObject(objectId: objectId, forceAction: true); + SimObjPhysics theObject = getTargetObjectFromId(objectId: objectId, forceAction: true); // Populate default standings. Note that these are boolean because that's // the most natural integration with Teleport @@ -7949,7 +7949,7 @@ public void SliceObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); + target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } // we found it! @@ -8005,7 +8005,7 @@ public void BreakObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); + target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } // we found it! @@ -8067,7 +8067,7 @@ public void DirtyObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); + target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } if (target) { @@ -8117,7 +8117,7 @@ public void CleanObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); + target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } if (target) { @@ -8168,7 +8168,7 @@ public void FillObjectWithLiquid(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); + target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } if (action.fillLiquid == null) { @@ -8225,7 +8225,7 @@ public void EmptyLiquidFromObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); + target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } if (target) { @@ -8276,7 +8276,7 @@ public void UseUpObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { - target = getTargetObject(objectId: action.objectId, forceAction: action.forceAction); + target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } if (target) { From 4ef41666b22c93771fd73db76d05d9587a0bcea4 Mon Sep 17 00:00:00 2001 From: winthos Date: Fri, 10 Sep 2021 15:28:50 -0700 Subject: [PATCH 09/10] addressing lgtm alerts -short circuit --- unity/Assets/Scripts/BaseFPSAgentController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unity/Assets/Scripts/BaseFPSAgentController.cs b/unity/Assets/Scripts/BaseFPSAgentController.cs index 7b91b3f0ef..e4441e7df4 100644 --- a/unity/Assets/Scripts/BaseFPSAgentController.cs +++ b/unity/Assets/Scripts/BaseFPSAgentController.cs @@ -4533,8 +4533,8 @@ public class VisibilityCheck { public static VisibilityCheck operator |(VisibilityCheck a, VisibilityCheck b) { VisibilityCheck c = new VisibilityCheck(); - c.interactable = a.interactable | b.interactable; - c.visible = a.visible | b.visible; + c.interactable = a.interactable || b.interactable; + c.visible = a.visible || b.visible; return c; } } From 98a1106db6575d96b573860fc5eaec69aedc25ff Mon Sep 17 00:00:00 2001 From: winthos Date: Mon, 20 Sep 2021 16:06:14 -0700 Subject: [PATCH 10/10] rename to `getInteractableSimObjectFromId` updating `getTargetObjectFromId` name to be more descriptive --- .../Assets/Scripts/BaseFPSAgentController.cs | 4 +-- .../PhysicsRemoteFPSAgentController.cs | 36 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/unity/Assets/Scripts/BaseFPSAgentController.cs b/unity/Assets/Scripts/BaseFPSAgentController.cs index e4441e7df4..76a5e25156 100644 --- a/unity/Assets/Scripts/BaseFPSAgentController.cs +++ b/unity/Assets/Scripts/BaseFPSAgentController.cs @@ -2031,7 +2031,7 @@ public void Done() { // Helper method that parses objectId parameter to return the sim object that it target. // The action is halted if the objectId does not appear in the scene. - protected SimObjPhysics getTargetObjectFromId(string objectId, bool forceAction = false) { + protected SimObjPhysics getInteractableSimObjectFromId(string objectId, bool forceAction = false) { // an objectId was given, so find that target in the scene if it exists if (!physicsSceneManager.ObjectIdToSimObjPhysics.ContainsKey(objectId)) { throw new ArgumentException($"objectId: {objectId} is not the objectId on any object in the scene!"); @@ -2059,7 +2059,7 @@ protected SimObjPhysics getTargetObjectFromId(string objectId, bool forceAction // Helper method that parses (x and y) parameters to return the // sim object that they target. - protected SimObjPhysics getTargetObjectFromId(float x, float y, bool forceAction) { + protected SimObjPhysics getInteractableSimObjectFromId(float x, float y, bool forceAction) { if (x < 0 || x > 1 || y < 0 || y > 1) { throw new ArgumentOutOfRangeException("x/y must be in [0:1]"); } diff --git a/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs b/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs index b6df182604..457446c947 100644 --- a/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs +++ b/unity/Assets/Scripts/PhysicsRemoteFPSAgentController.cs @@ -70,7 +70,7 @@ public void SetTemperatureDecayTime(string objectId, float decayTime) { if (decayTime < 0) { throw new ArgumentOutOfRangeException("decayTime must be >= 0. You gave " + decayTime); } - SimObjPhysics sop = getTargetObjectFromId(objectId: objectId, forceAction: true); + SimObjPhysics sop = getInteractableSimObjectFromId(objectId: objectId, forceAction: true); sop.SetHowManySecondsUntilRoomTemp(decayTime); actionFinished(true); } @@ -3010,7 +3010,7 @@ public void ScaleObject( ) { // if object is in the scene and visible, assign it to 'target' - SimObjPhysics target = getTargetObjectFromId(objectId: objectId, forceAction: forceAction); + SimObjPhysics target = getInteractableSimObjectFromId(objectId: objectId, forceAction: forceAction); // neither objectId nor coordinates found an object if (target == null) { @@ -4023,7 +4023,7 @@ public void PlaceHeldObject(string objectId, float maxDistance, bool forceAction SimObjPhysics targetReceptacle = null; // if object is in the scene and visible, assign it to 'target' - targetReceptacle = getTargetObjectFromId(objectId: objectId, forceAction: forceAction); + targetReceptacle = getInteractableSimObjectFromId(objectId: objectId, forceAction: forceAction); placeHeldObject( targetReceptacle: targetReceptacle, @@ -4301,12 +4301,12 @@ bool markActionFinished } public virtual void PickupObject(float x, float y, bool forceAction = false, bool manualInteract = false) { - SimObjPhysics target = getTargetObjectFromId(x: x, y: y, forceAction: forceAction); + SimObjPhysics target = getInteractableSimObjectFromId(x: x, y: y, forceAction: forceAction); pickupObject(target: target, forceAction: forceAction, manualInteract: manualInteract, markActionFinished: true); } public virtual void PickupObject(string objectId, bool forceAction = false, bool manualInteract = false) { - SimObjPhysics target = getTargetObjectFromId(objectId: objectId, forceAction: forceAction); + SimObjPhysics target = getInteractableSimObjectFromId(objectId: objectId, forceAction: forceAction); pickupObject(target: target, forceAction: forceAction, manualInteract: manualInteract, markActionFinished: true); } @@ -4809,7 +4809,7 @@ public void CookObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); + target = getInteractableSimObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } @@ -4925,7 +4925,7 @@ private void toggleObject(string objectId, bool toggleOn, bool forceAction) { SimObjPhysics target = null; // if object is in the scene and visible, assign it to 'target' - target = getTargetObjectFromId(objectId: objectId, forceAction: forceAction); + target = getInteractableSimObjectFromId(objectId: objectId, forceAction: forceAction); if (!target) { @@ -5117,7 +5117,7 @@ public void OpenObjectImmediate( string objectId, float openness = 1.0f ) { - SimObjPhysics target = getTargetObjectFromId(objectId: objectId, forceAction: true); + SimObjPhysics target = getInteractableSimObjectFromId(objectId: objectId, forceAction: true); target.GetComponent().SetOpennessImmediate(openness); actionFinished(true); } @@ -5128,7 +5128,7 @@ public void OpenObject( float openness = 1, float? moveMagnitude = null // moveMagnitude is supported for backwards compatibility. It's new name is 'openness'. ) { - SimObjPhysics target = getTargetObjectFromId(objectId: objectId, forceAction: forceAction); + SimObjPhysics target = getInteractableSimObjectFromId(objectId: objectId, forceAction: forceAction); openObject( target: target, openness: openness, @@ -5172,7 +5172,7 @@ public void Contains(ServerAction action) { return; } - SimObjPhysics target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); + SimObjPhysics target = getInteractableSimObjectFromId(objectId: action.objectId, forceAction: action.forceAction); if (target) { List ids = target.GetAllSimObjectsInReceptacleTriggersByObjectID(); @@ -6086,7 +6086,7 @@ private List> getInteractablePoses( maxDistanceFloat = (float)maxDistance; } - SimObjPhysics theObject = getTargetObjectFromId(objectId: objectId, forceAction: true); + SimObjPhysics theObject = getInteractableSimObjectFromId(objectId: objectId, forceAction: true); // Populate default standings. Note that these are boolean because that's // the most natural integration with Teleport @@ -7949,7 +7949,7 @@ public void SliceObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); + target = getInteractableSimObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } // we found it! @@ -8005,7 +8005,7 @@ public void BreakObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); + target = getInteractableSimObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } // we found it! @@ -8067,7 +8067,7 @@ public void DirtyObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); + target = getInteractableSimObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } if (target) { @@ -8117,7 +8117,7 @@ public void CleanObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); + target = getInteractableSimObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } if (target) { @@ -8168,7 +8168,7 @@ public void FillObjectWithLiquid(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); + target = getInteractableSimObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } if (action.fillLiquid == null) { @@ -8225,7 +8225,7 @@ public void EmptyLiquidFromObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { // if object is in the scene and visible, assign it to 'target' - target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); + target = getInteractableSimObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } if (target) { @@ -8276,7 +8276,7 @@ public void UseUpObject(ServerAction action) { // an objectId was given, so find that target in the scene if it exists else { - target = getTargetObjectFromId(objectId: action.objectId, forceAction: action.forceAction); + target = getInteractableSimObjectFromId(objectId: action.objectId, forceAction: action.forceAction); } if (target) {