public static IEnumerator rotate( PhysicsRemoteFPSAgentController controller, CollisionListener collisionListener, Transform moveTransform, Quaternion targetRotation, float fixedDeltaTime, float radiansPerSecond, bool returnToStartPropIfFailed = false ) { float degreesPerSecond = radiansPerSecond * 180.0f / Mathf.PI; return(updateTransformPropertyFixedUpdate( controller, collisionListener, moveTransform, targetRotation, // Get (t) => t.rotation, // Set (t, target) => t.rotation = target, // Next (t, target) => Quaternion.RotateTowards(t.rotation, target, fixedDeltaTime * degreesPerSecond), // Direction function for quaternion should just output target quaternion, since RotateTowards is used for addToProp (target, current) => target, // Distance Metric (target, current) => Quaternion.Angle(current, target), fixedDeltaTime, returnToStartPropIfFailed )); }
public bool SetObjectToggles(ObjectToggle[] objectToggles) { bool shouldFail = false; if (objectToggles != null && objectToggles.Length > 0) { // Perform object toggle state sets. SimObjPhysics[] simObjs = GameObject.FindObjectsOfType(typeof(SimObjPhysics)) as SimObjPhysics[]; Dictionary <SimObjType, bool> toggles = new Dictionary <SimObjType, bool>(); foreach (ObjectToggle objectToggle in objectToggles) { SimObjType objType = (SimObjType)System.Enum.Parse(typeof(SimObjType), objectToggle.objectType); toggles[objType] = objectToggle.isOn; } PhysicsRemoteFPSAgentController fpsController = GameObject.Find("FPSController").GetComponent <PhysicsRemoteFPSAgentController>(); foreach (SimObjPhysics sop in simObjs) { if (toggles.ContainsKey(sop.ObjType)) { bool success = fpsController.ToggleObject(sop, toggles[sop.ObjType], true); if (!success) { shouldFail = true; } } } } return(!shouldFail); }
private void Start() { m_CharacterController = GetComponent <CharacterController>(); m_Camera = Camera.main; m_MouseLook.Init(transform, m_Camera.transform); // find debug canvas related objects Debug_Canvas = GameObject.Find("DebugCanvasPhysics"); InputMode_Text = GameObject.Find("DebugCanvasPhysics/InputModeText"); InputFieldObj = GameObject.Find("DebugCanvasPhysics/InputField"); PhysicsController = gameObject.GetComponent <PhysicsRemoteFPSAgentController>(); highlightController = new ObjectHighlightController(PhysicsController, MaxViewDistance, enableHighlightShader, true, MaxThrowForce, MaxChargeThrowSeconds); // if this component is enabled, turn on the targeting reticle and target text if (this.isActiveAndEnabled) { Debug_Canvas.GetComponent <Canvas>().enabled = true; Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; } // FlightMode = PhysicsController.FlightMode; #if UNITY_WEBGL FPSEnabled = false; Cursor.visible = true; Cursor.lockState = CursorLockMode.None; HideHUD(); #endif }
private void UpdateOpenOrCloseBoundingBox() { if (ResetPositionIfPickupableAndOpenable.Contains(gameObject.GetComponent <SimObjPhysics>().Type)) { if (ClosedBoundingBox != null && OpenBoundingBox != null) { SimObjPhysics sop = gameObject.GetComponent <SimObjPhysics>(); if (isOpen) { sop.BoundingBox = OpenBoundingBox; } else { sop.BoundingBox = ClosedBoundingBox; } PhysicsRemoteFPSAgentController agent = GameObject.Find("FPSController").GetComponent <PhysicsRemoteFPSAgentController>(); //if the agent is holding this object RIGHT NOW, then update the rotation box checkers if (agent.WhatAmIHolding() == gameObject) { agent.SetUpRotationBoxChecks(); } } else { Debug.Log("Closed/Open Bounding box references are null!"); } } //check if this object is in the ResetPositionIfPickupableAndOpenable list //also check if the ClosedBoundingBox and OpenBoundingBox fields are null or not }
public void GatherSimObjPhysInScene() { //PhysObjectsInScene.Clear(); PhysObjectsInScene = new List <SimObjPhysics>(); PhysObjectsInScene.AddRange(FindObjectsOfType <SimObjPhysics>()); PhysObjectsInScene.Sort((x, y) => (x.Type.ToString().CompareTo(y.Type.ToString()))); foreach (SimObjPhysics o in PhysObjectsInScene) { Generate_UniqueID(o); ///debug in editor, make sure no two object share ids for some reason #if UNITY_EDITOR if (CheckForDuplicateUniqueIDs(o)) { Debug.Log("Yo there are duplicate UniqueIDs! Check" + o.UniqueID); } else #endif UniqueIDsInScene.Add(o.UniqueID); } PhysicsRemoteFPSAgentController fpsController = GameObject.Find("FPSController").GetComponent <PhysicsRemoteFPSAgentController>(); if (fpsController.imageSynthesis != null) { fpsController.imageSynthesis.OnSceneChange(); } }
public void rotateHand( PhysicsRemoteFPSAgentController controller, Quaternion targetQuat, float degreesPerSecond, bool disableRendering = false, float fixedDeltaTime = 0.02f, bool returnToStartPositionIfFailed = false ) { collisionListener.Reset(); IEnumerator rotate = ContinuousMovement.rotate( controller, collisionListener, armTarget.transform, armTarget.transform.rotation * targetQuat, disableRendering ? fixedDeltaTime : Time.fixedDeltaTime, degreesPerSecond, returnToStartPositionIfFailed ); if (disableRendering) { controller.unrollSimulatePhysics( rotate, fixedDeltaTime ); } else { StartCoroutine(rotate); } }
public ObjectHighlightController( PhysicsRemoteFPSAgentController physicsController, float minHighlightDistance, bool highlightEnabled = true, bool throwEnabled = true, float maxThrowForce = 1000.0f, float maxChargeThrowSeconds = 1.4f, bool highlightWhileHolding = false, HighlightConfig highlightConfig = null ) { this.PhysicsController = physicsController; this.MinHighlightDistance = minHighlightDistance; this.MaxThrowForce = maxThrowForce; this.withHighlightShader = highlightEnabled; this.MaxChargeThrowSeconds = maxChargeThrowSeconds; this.highlightWhileHolding = highlightWhileHolding; if (highlightConfig != null) { this.HighlightParams = highlightConfig; } m_Camera = Camera.main; TargetText = GameObject.Find("DebugCanvasPhysics/TargetText").GetComponent <Text>(); CrosshairText = GameObject.Find("DebugCanvasPhysics/Crosshair").GetComponent <Text>(); var throwForceBar = GameObject.Find("DebugCanvasPhysics/ThrowForceBar"); if (throwForceBar) { ThrowForceBarSlider = throwForceBar.GetComponent <Slider>(); } this.throwEnabled = throwEnabled; this.highlightShader = Shader.Find("Custom/TransparentOutline"); }
void Start() { PhysicsController = gameObject.GetComponent <PhysicsRemoteFPSAgentController>(); inputField = GameObject.Find("DebugCanvasPhysics").GetComponentInChildren <DebugInputField>();//FindObjectOfType<DebugInputField>(); //GameObject.Find("DebugCanvas").GetComponentInChildren<AgentManager>(); Init(); Debug.Log("Calling store data"); }
private void initializePrimaryAgent() { GameObject fpsController = GameObject.Find("FPSController"); PhysicsRemoteFPSAgentController physicsAgent = fpsController.GetComponent <PhysicsRemoteFPSAgentController>(); primaryAgent = physicsAgent; primaryAgent.agentManager = this; primaryAgent.enabled = true; primaryAgent.actionComplete = true; }
void Start() { var Debug_Canvas = GameObject.Find("DebugCanvasPhysics"); PhysicsController = gameObject.GetComponent <PhysicsRemoteFPSAgentController>(); Cursor.visible = true; Cursor.lockState = CursorLockMode.None; Debug_Canvas.GetComponent <Canvas>().enabled = true; highlightController = new ObjectHighlightController(PhysicsController, PhysicsController.maxVisibleDistance, true, false); }
//additional checks if the point is valid. Return true if it's valid public bool NarrowDownValidSpawnPoints(Vector3 point) { //check if the point is in range of the agent at all GameObject agent = GameObject.Find("FPSController"); PhysicsRemoteFPSAgentController agentController = agent.GetComponent <PhysicsRemoteFPSAgentController>(); //get agent's camera point, get point to check, find the distance from agent camera point to point to check float maxvisdist = agentController.WhatIsAgentsMaxVisibleDistance(); //set the distance so that it is within the radius maxvisdist from the agent Vector3 tmpForCamera = agent.GetComponent <PhysicsRemoteFPSAgentController>().m_Camera.transform.position; tmpForCamera.y = point.y; //automatically rule out a point if it's beyond our max distance of visibility if (Vector3.Distance(point, tmpForCamera) >= maxvisdist) { return(false); } //ok cool, it's within distance to the agent, now let's check //if the point is within the viewport of the agent as well Camera agentCam = agent.GetComponent <PhysicsRemoteFPSAgentController>().m_Camera; //no offset if the object is below the camera position - a slight offset to account for objects equal in y distance to the camera if (point.y < agentCam.transform.position.y - 0.05f) { //do this check if the point's y value is below the camera's y value //this check will be a raycast vision check from the camera to the point exactly if (agentController.CheckIfPointIsInViewport(point)) { return(true); } } else { //do this check if the point's y value is above the agent camera. This means we are //trying to place an object on a shelf or something high up that we can't quite reach //in this case, modify the point that is checked for visibility by adding a little bit to the y //might want to adjust this offset amount, or even move this check to ensure object visibility after the //checkspawnarea corners are generated? if (agentController.CheckIfPointIsInViewport(point + new Vector3(0, 0.05f, 0))) { return(true); } } return(false); }
public IEnumerator ReturnObjectsInMagnetAfterPhysicsUpdate(PhysicsRemoteFPSAgentController controller) { yield return(new WaitForFixedUpdate()); List <string> listOfSOP = new List <string>(); foreach (string oid in this.WhatObjectsAreInsideMagnetSphereAsObjectID()) { listOfSOP.Add(oid); } Debug.Log("objs: " + string.Join(", ", listOfSOP)); controller.actionFinished(true, listOfSOP); }
void Start() { var Debug_Canvas = GameObject.Find("DebugCanvasPhysics"); PhysicsController = gameObject.GetComponent <PhysicsRemoteFPSAgentController>(); Cursor.visible = true; Cursor.lockState = CursorLockMode.None; Debug_Canvas.GetComponent <Canvas>().enabled = true; highlightController = new ObjectHighlightController(PhysicsController, PhysicsController.maxVisibleDistance, true, false, 0, 0, true); highlightController.SetDisplayTargetText(false); // SpawnObjectToHide("{\"objectType\": \"Plunger\", \"objectVariation\": 1}"); }
public void moveArmBase( PhysicsRemoteFPSAgentController controller, float height, float unitsPerSecond, float fixedDeltaTime = 0.02f, bool returnToStartPositionIfFailed = false, bool disableRendering = false ) { // clearing out colliders here since OnTriggerExit is not consistently called in Editor collisionListener.Reset(); // first check if the target position is within bounds of the agent's capsule center/height extents // if not, actionFinished false with error message listing valid range defined by extents CapsuleCollider cc = controller.GetComponent <CapsuleCollider>(); Vector3 cc_center = cc.center; Vector3 cc_maxY = cc.center + new Vector3(0, cc.height / 2f, 0); Vector3 cc_minY = cc.center + new Vector3(0, (-cc.height / 2f) / 2f, 0); // this is halved to prevent arm clipping into floor // linear function that take height and adjusts targetY relative to min/max extents float targetY = ((cc_maxY.y - cc_minY.y) * (height)) + cc_minY.y; Vector3 target = new Vector3(this.transform.localPosition.x, targetY, 0); IEnumerator moveCall = ContinuousMovement.move( controller: controller, collisionListener: collisionListener, moveTransform: this.transform, targetPosition: target, fixedDeltaTime: disableRendering ? fixedDeltaTime : Time.fixedDeltaTime, unitsPerSecond: unitsPerSecond, returnToStartPropIfFailed: returnToStartPositionIfFailed, localPosition: true ); if (disableRendering) { controller.unrollSimulatePhysics( enumerator: moveCall, fixedDeltaTime: fixedDeltaTime ); } else { StartCoroutine(moveCall); } }
// Start is called before the first frame update void Start() { InputFieldObj = GameObject.Find("DebugCanvasPhysics/InputField"); var Debug_Canvas = GameObject.Find("DebugCanvasPhysics"); inputField = InputFieldObj.GetComponent <InputField>(); PhysicsController = gameObject.GetComponent <PhysicsRemoteFPSAgentController>(); Cursor.visible = true; Cursor.lockState = CursorLockMode.None; if (this.isActiveAndEnabled) { Debug_Canvas.GetComponent <Canvas>().enabled = true; Cursor.visible = true; Cursor.lockState = CursorLockMode.None; } }
public static IEnumerator move( PhysicsRemoteFPSAgentController controller, CollisionListener collisionListener, Transform moveTransform, Vector3 targetPosition, float fixedDeltaTime, float unitsPerSecond, bool returnToStartPropIfFailed = false, bool localPosition = false ) { Func <Func <Transform, Vector3>, Action <Transform, Vector3>, Func <Transform, Vector3, Vector3>, IEnumerator> moveClosure = (get, set, next) => updateTransformPropertyFixedUpdate( controller, collisionListener, moveTransform, targetPosition, get, set, next, (target, current) => (target - current).normalized, (target, current) => Vector3.SqrMagnitude(target - current), fixedDeltaTime, returnToStartPropIfFailed ); if (localPosition) { return(moveClosure( (t) => t.localPosition, (t, pos) => t.localPosition = pos, (t, direction) => t.localPosition + direction * unitsPerSecond * fixedDeltaTime )); } else { return(moveClosure( (t) => t.position, (t, pos) => t.position = pos, (t, direction) => t.position + direction * unitsPerSecond * fixedDeltaTime )); } }
private static void continuousMoveFinish <T>( PhysicsRemoteFPSAgentController controller, CollisionListener collisionListener, Transform moveTransform, System.Action <Transform, T> setProp, T target, T resetProp ) { bool actionSuccess = true; string debugMessage = ""; IK_Robot_Arm_Controller arm = controller.GetComponentInChildren <IK_Robot_Arm_Controller>(); var staticCollisions = collisionListener.StaticCollisions(); if (staticCollisions.Count > 0) { var sc = staticCollisions[0]; // decide if we want to return to original property or last known property before collision setProp(moveTransform, resetProp); // if we hit a sim object if (sc.isSimObj) { debugMessage = "Collided with static sim object: '" + sc.simObjPhysics.name + "', could not reach target: '" + target + "'."; } // if we hit a structural object that isn't a sim object but still has static collision if (!sc.isSimObj) { debugMessage = "Collided with static structure in scene: '" + sc.gameObject.name + "', could not reach target: '" + target + "'."; } actionSuccess = false; } controller.errorMessage = debugMessage; controller.actionFinished(actionSuccess, debugMessage); }
private void Start() { m_CharacterController = GetComponent <CharacterController>(); m_Camera = Camera.main; m_MouseLook.Init(transform, m_Camera.transform); //find debug canvas related objects Debug_Canvas = GameObject.Find("DebugCanvasPhysics"); InputMode_Text = GameObject.Find("DebugCanvasPhysics/InputModeText"); TargetText = GameObject.Find("DebugCanvasPhysics/TargetText").GetComponent <Text>(); InputFieldObj = GameObject.Find("DebugCanvasPhysics/InputField"); CrosshairText = GameObject.Find("DebugCanvasPhysics/Crosshair").GetComponent <Text>(); var throwForceBar = GameObject.Find("DebugCanvasPhysics/ThrowForceBar"); ThrowForceBarSlider = throwForceBar.GetComponent <Slider>(); //if this component is enabled, turn on the targeting reticle and target text if (this.isActiveAndEnabled) { Debug_Canvas.GetComponent <Canvas>().enabled = true; Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; } PhysicsController = gameObject.GetComponent <PhysicsRemoteFPSAgentController>(); FlightMode = PhysicsController.FlightMode; this.highlightShader = Shader.Find("Custom/TransparentOutline"); #if UNITY_WEBGL Cursor.visible = true; Cursor.lockState = CursorLockMode.None; HideHUD(); #endif }
//return spawn coordinates above the <receptacleObjectId> that the <objectId> will fit at a given rotation <yRot> //excludes coordinates that would cause object <objectId> to fall off the table public List <Vector3> ReturnValidSpawns(string objType, int variation, SimObjPhysics targetReceptacle, float yRot = 0) { toSpawn = null; if (objType == "screen") { toSpawn = screensToSpawn[variation].GetComponent <SimObjPhysics>(); } if (objType == "receptacle") { toSpawn = receptaclesToSpawn[variation].GetComponent <SimObjPhysics>(); } SimObjPhysics spawned = GameObject.Instantiate(toSpawn, initialSpawnPosition, Quaternion.identity); Rigidbody rb = spawned.GetComponent <Rigidbody>(); //apply rotation to object, default quaternion.identity spawned.transform.Rotate(new Vector3(0, yRot, 0), Space.Self); //generate grid of potential spawn points //GetSpawnCoordinatesAboveReceptacle List <Vector3> spawnCoordinates = new List <Vector3>(); PhysicsRemoteFPSAgentController fpsAgent = agentManager.ReturnPrimaryAgent().GetComponent <PhysicsRemoteFPSAgentController>(); spawnCoordinates = fpsAgent.GetSpawnCoordinatesAboveReceptacle(targetReceptacle); List <Vector3> returnCoordinates = new List <Vector3>(); //try and place object at every spawn coordinate and if it works, add it to the valid coords to return for (int i = 0; i < spawnCoordinates.Count; i++) { //place object at the given point, then check if the corners are ok fpsAgent.PlaceObjectAtPoint(toSpawn, spawnCoordinates[i]); List <Vector3> corners = GetCorners(spawned); Contains con = targetReceptacle.ReceptacleTriggerBoxes[0].GetComponent <Contains>(); bool cornerCheck = true; foreach (Vector3 p in corners) { if (!con.CheckIfPointIsAboveReceptacleTriggerBox(p)) { cornerCheck = false; //this position would cause object to fall off table //double back and reset object to try again with another point spawned.transform.position = initialSpawnPosition; break; } } if (cornerCheck) { returnCoordinates.Add(spawnCoordinates[i]); //all corners were ok, so add it to the points that are valid } spawned.transform.position = initialSpawnPosition; } #if UNITY_EDITOR //debug draw debugCoords = returnCoordinates; #endif Destroy(spawned.transform.gameObject); return(returnCoordinates); }
// Use this for initialization void Start() { AgentRef = gameObject.GetComponentInParent <PhysicsRemoteFPSAgentController>(); }
public bool PlaceObject(SimObjPhysics sop, ReceptacleSpawnPoint rsp, bool PlaceStationary, int degreeIncrement, bool AlwaysPlaceUpright) { if (rsp.ParentSimObjPhys == sop) { #if UNITY_EDITOR Debug.Log("Can't place object inside itself!"); #endif return(false); } //remember the original rotation of the sim object if we need to reset it //Quaternion originalRot = sop.transform.rotation; Vector3 originalPos = sop.transform.position; Quaternion originalRot = sop.transform.rotation; //get the bounding box of the sim object we are trying to place BoxCollider oabb = sop.BoundingBox.GetComponent <BoxCollider>(); //zero out rotation and velocity/angular velocity, then match the target receptacle's rotation sop.transform.rotation = rsp.ReceptacleBox.transform.rotation; Rigidbody sopRB = sop.GetComponent <Rigidbody>(); sopRB.velocity = Vector3.zero; sopRB.angularVelocity = Vector3.zero; //set 360 degree increment to only check one angle, set smaller increments to check more angles when trying to place (warning THIS WILL GET SLOWER) int HowManyRotationsToCheck = 360 / degreeIncrement; Plane BoxBottom; float DistanceFromBoxBottomTosop; List <RotationAndDistanceValues> ToCheck = new List <RotationAndDistanceValues>(); //we'll check 8 rotations for now, replace the 45 later if we want to adjust the amount of checks //get rotations and distance values for 360/increment number of rotations around just the Y axis //we want to check all of these first so that the object is prioritized to be placed "upright" for (int i = 0; i < HowManyRotationsToCheck; i++) { oabb.enabled = true; if (i > 0) { sop.transform.Rotate(new Vector3(0, degreeIncrement, 0), Space.Self); //ToCheck[i].rotation = sop.transform.rotation; Vector3 Offset = oabb.ClosestPoint(oabb.transform.TransformPoint(oabb.center) + -rsp.ReceptacleBox.transform.up * 10); BoxBottom = new Plane(rsp.ReceptacleBox.transform.up, Offset); DistanceFromBoxBottomTosop = Math.Abs(BoxBottom.GetDistanceToPoint(sop.transform.position)); ToCheck.Add(new RotationAndDistanceValues(DistanceFromBoxBottomTosop, sop.transform.rotation)); } else { //no rotate change just yet, check the first position Vector3 Offset = oabb.ClosestPoint(oabb.transform.TransformPoint(oabb.center) + -rsp.ReceptacleBox.transform.up * 10); //was using rsp.point BoxBottom = new Plane(rsp.ReceptacleBox.transform.up, Offset); DistanceFromBoxBottomTosop = BoxBottom.GetDistanceToPoint(sop.transform.position); ToCheck.Add(new RotationAndDistanceValues(DistanceFromBoxBottomTosop, sop.transform.rotation)); } oabb.enabled = false; } //continue to check rotations about the X and Z axes if the object doesn't have to be placed upright if (!AlwaysPlaceUpright) { //ok now try if the X and Z local axis are rotated if it'll fit //these values can cause the object to be placed at crazy angles, so we'll check these last for (int i = 0; i < HowManyRotationsToCheck; i++) { oabb.enabled = true; if (i > 0) { sop.transform.Rotate(new Vector3(0, degreeIncrement, 0), Space.Self); Quaternion oldRotation = sop.transform.rotation; //now add more points by rotating the x axis at this current y rotation for (int j = 0; j < HowManyRotationsToCheck; j++) { sop.transform.Rotate(new Vector3(degreeIncrement, 0, 0), Space.Self); Vector3 Offset = oabb.ClosestPoint(oabb.transform.TransformPoint(oabb.center) + -rsp.ReceptacleBox.transform.up * 10); BoxBottom = new Plane(rsp.ReceptacleBox.transform.up, Offset); DistanceFromBoxBottomTosop = Math.Abs(BoxBottom.GetDistanceToPoint(sop.transform.position)); ToCheck.Add(new RotationAndDistanceValues(DistanceFromBoxBottomTosop, sop.transform.rotation)); } sop.transform.rotation = oldRotation; //now add EVEN more points by rotating the z axis at this current y rotation for (int j = 0; j < HowManyRotationsToCheck; j++) { sop.transform.Rotate(new Vector3(0, 0, degreeIncrement), Space.Self); Vector3 Offset = oabb.ClosestPoint(oabb.transform.TransformPoint(oabb.center) + -rsp.ReceptacleBox.transform.up * 10); BoxBottom = new Plane(rsp.ReceptacleBox.transform.up, Offset); DistanceFromBoxBottomTosop = Math.Abs(BoxBottom.GetDistanceToPoint(sop.transform.position)); ToCheck.Add(new RotationAndDistanceValues(DistanceFromBoxBottomTosop, sop.transform.rotation)); } sop.transform.rotation = oldRotation; } oabb.enabled = false; } } foreach (RotationAndDistanceValues quat in ToCheck) { //if spawn area is clear, spawn it and return true that we spawned it if (CheckSpawnArea(sop, rsp.Point + rsp.ParentSimObjPhys.transform.up * (quat.distance + yoffset), quat.rotation, false)) { //translate position of the target sim object to the rsp.Point and offset in local y up sop.transform.position = rsp.Point + rsp.ReceptacleBox.transform.up * (quat.distance + yoffset);//rsp.Point + sop.transform.up * DistanceFromBottomOfBoxToTransform; sop.transform.rotation = quat.rotation; //now to do a check to make sure the sim object is contained within the Receptacle box, and doesn't have //bits of it hanging out //Check the ReceptacleBox's Sim Object component to see what Type it is. Then check to //see if the type is the kind where the Object placed must be completely contained or just the bottom 4 corners contained int HowManyCornersToCheck = 0; if (ReceptacleRestrictions.OnReceptacles.Contains(rsp.ParentSimObjPhys.ObjType)) { //check that only the bottom 4 corners are in bounds HowManyCornersToCheck = 4; } if (ReceptacleRestrictions.InReceptacles.Contains(rsp.ParentSimObjPhys.ObjType)) { //check that all 8 corners are within bounds HowManyCornersToCheck = 8; } if (ReceptacleRestrictions.InReceptaclesThatOnlyCheckBottomFourCorners.Contains(rsp.ParentSimObjPhys.ObjType)) { //only check bottom 4 corners even though the action is PlaceIn HowManyCornersToCheck = 4; } int CornerCount = 0; //Plane rspPlane = new Plane(rsp.Point, rsp.ParentSimObjPhys.transform.up); //now check the corner count for either the 4 lowest corners, or all 8 corners depending on Corner Count //attmpt to sort corners so that first four corners are the corners closest to the spawn point we are checking against SpawnCorners.Sort(delegate(Vector3 p1, Vector3 p2) { //sort by making a plane where rsp.point is, find the four corners closest to that point //return rspPlane.GetDistanceToPoint(p1).CompareTo(rspPlane.GetDistanceToPoint(p2)); //^ this ended up not working because if something is placed at an angle this no longer makes sense... return(Vector3.Distance(p1, rsp.Point).CompareTo(Vector3.Distance(p2, rsp.Point))); // return Vector3.Distance(new Vector3(0, p1.y, 0), new Vector3(0, rsp.Point.y, 0)).CompareTo( // Vector3.Distance(new Vector3(0, p2.y, 0), new Vector3(0, rsp.Point.y, 0))); }); //ok so this is just checking if there are enough corners in the Receptacle Zone to consider it placed correctly. //originally this looped up to i < HowManyCornersToCheck, but if we just check all the corners, regardless of //sort order, it seems to bypass the issue above of how to sort the corners to find the "bottom" 4 corners, so uh // i guess this might just work without fancy sorting to determine the bottom 4 corners... especially since the "bottom corners" starts to lose meaning as objects are rotated for (int i = 0; i < 8; i++) { if (rsp.Script.CheckIfPointIsInsideReceptacleTriggerBox(SpawnCorners[i])) { CornerCount++; } } //if not enough corners are inside the receptacle, abort if (CornerCount < HowManyCornersToCheck) { sop.transform.rotation = originalRot; sop.transform.position = originalPos; return(false); } //one final check, make sure all corners of object are "above" the receptacle box in question, so we //dont spawn stuff half on a table and it falls over foreach (Vector3 v in SpawnCorners) { if (!rsp.Script.CheckIfPointIsAboveReceptacleTriggerBox(v)) { sop.transform.rotation = originalRot; sop.transform.position = originalPos; return(false); } } //set true if we want objects to be stationary when placed. (if placed on uneven surface, object remains stationary) //if false, once placed the object will resolve with physics (if placed on uneven surface object might slide or roll) if (PlaceStationary == true) { //make object being placed kinematic true sop.GetComponent <Rigidbody>().collisionDetectionMode = CollisionDetectionMode.Discrete; sop.GetComponent <Rigidbody>().isKinematic = true; //check if the parent sim object is one that moves like a drawer - and would require this to be parented //if(rsp.ParentSimObjPhys.DoesThisObjectHaveThisSecondaryProperty(SimObjSecondaryProperty.CanOpen)) sop.transform.SetParent(rsp.ParentSimObjPhys.transform); //if this object is a receptacle and it has other objects inside it, drop them all together if (sop.DoesThisObjectHaveThisSecondaryProperty(SimObjSecondaryProperty.Receptacle)) { PhysicsRemoteFPSAgentController agent = GameObject.Find("FPSController").GetComponent <PhysicsRemoteFPSAgentController>(); agent.DropContainedObjectsStationary(sop);//use stationary version so that colliders are turned back on, but kinematics remain true } //if the target receptacle is a pickupable receptacle, set it to kinematic true as will sence we are placing stationary if (rsp.ParentSimObjPhys.PrimaryProperty == SimObjPrimaryProperty.CanPickup) { rsp.ParentSimObjPhys.GetComponent <Rigidbody>().isKinematic = true; } } //place stationary false, let physics drop everything too else { //if not placing stationary, put all objects under Objects game object GameObject topObject = GameObject.Find("Objects"); //parent to the Objects transform sop.transform.SetParent(topObject.transform); Rigidbody rb = sop.GetComponent <Rigidbody>(); rb.isKinematic = false; rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic; //if this object is a receptacle and it has other objects inside it, drop them all together if (sop.DoesThisObjectHaveThisSecondaryProperty(SimObjSecondaryProperty.Receptacle)) { PhysicsRemoteFPSAgentController agent = GameObject.Find("FPSController").GetComponent <PhysicsRemoteFPSAgentController>(); agent.DropContainedObjects(sop); } } sop.isInAgentHand = false;//set agent hand flag // #if UNITY_EDITOR // Debug.Log(sop.name + " succesfully spawned in " +rsp.ParentSimObjPhys.name + " at coordinate " + rsp.Point); // #endif return(true); } } //reset rotation if no valid spawns found //oh now we couldn't spawn it, all the spawn areas were not clear sop.transform.rotation = originalRot; sop.transform.position = originalPos; return(false); }
public void moveArmTarget( PhysicsRemoteFPSAgentController controller, Vector3 target, float unitsPerSecond, float fixedDeltaTime = 0.02f, bool returnToStart = false, string coordinateSpace = "arm", bool restrictTargetPosition = false, bool disableRendering = false ) { // clearing out colliders here since OnTriggerExit is not consistently called in Editor collisionListener.Reset(); IK_Robot_Arm_Controller arm = this; // Move arm based on hand space or arm origin space // Vector3 targetWorldPos = handCameraSpace ? handCameraTransform.TransformPoint(target) : arm.transform.TransformPoint(target); Vector3 targetWorldPos = Vector3.zero; switch (coordinateSpace) { case "world": // world space, can be used to move directly toward positions // returned by sim objects targetWorldPos = target; break; case "wrist": // space relative to base of the wrist, where the camera is targetWorldPos = handCameraTransform.TransformPoint(target); break; case "armBase": // space relative to the root of the arm, joint 1 targetWorldPos = arm.transform.TransformPoint(target); break; default: throw new ArgumentException("Invalid coordinateSpace: " + coordinateSpace); } // TODO Remove this after restrict movement is finalized Vector3 targetShoulderSpace = (this.transform.InverseTransformPoint(targetWorldPos) - new Vector3(0, 0, originToShoulderLength)); #if UNITY_EDITOR Debug.Log( $"pos target {target} world {targetWorldPos} remaining {targetShoulderSpace.z}\n" + $"magnitude {targetShoulderSpace.magnitude} extendedArmLength {extendedArmLength}" ); #endif if (restrictTargetPosition && !validArmTargetPosition(targetWorldPos)) { targetShoulderSpace = ( this.transform.InverseTransformPoint(targetWorldPos) - new Vector3(0, 0, originToShoulderLength) ); throw new InvalidOperationException( $"Invalid target: Position '{target}' in space '{coordinateSpace}' is behind shoulder." ); } Vector3 originalPos = armTarget.position; Vector3 targetDirectionWorld = (targetWorldPos - originalPos).normalized; IEnumerator moveCall = ContinuousMovement.move( controller, collisionListener, armTarget, targetWorldPos, disableRendering ? fixedDeltaTime : Time.fixedDeltaTime, unitsPerSecond, returnToStart, false ); if (disableRendering) { controller.unrollSimulatePhysics( moveCall, fixedDeltaTime ); } else { StartCoroutine( moveCall ); } }
public static IEnumerator updateTransformPropertyFixedUpdate <T>( PhysicsRemoteFPSAgentController controller, CollisionListener collisionListener, Transform moveTransform, T target, Func <Transform, T> getProp, Action <Transform, T> setProp, Func <Transform, T, T> nextProp, // We could remove this one, but it is a speedup to not compute direction for position update calls at every addToProp call and just outside while Func <T, T, T> getDirection, Func <T, T, float> distanceMetric, float fixedDeltaTime, bool returnToStartPropIfFailed, double epsilon = 1e-3 ) { T originalProperty = getProp(moveTransform); var previousProperty = originalProperty; var arm = controller.GetComponentInChildren <IK_Robot_Arm_Controller>(); var ikSolver = arm.gameObject.GetComponentInChildren <FK_IK_Solver>(); // commenting out the WaitForEndOfFrame here since we shoudn't need // this as we already wait for a frame to pass when we execute each action // yield return yieldInstruction; var currentProperty = getProp(moveTransform); float currentDistance = distanceMetric(target, currentProperty); T directionToTarget = getDirection(target, currentProperty); while (currentDistance > epsilon && collisionListener.StaticCollisions().Count == 0) { previousProperty = getProp(moveTransform); T next = nextProp(moveTransform, directionToTarget); float nextDistance = distanceMetric(target, next); // allows for snapping behaviour to target when the target is close // if nextDistance is too large then it will overshoot, in this case we snap to the target // this can happen if the speed it set high if ( nextDistance <= epsilon || nextDistance > distanceMetric(target, getProp(moveTransform)) ) { setProp(moveTransform, target); } else { setProp(moveTransform, next); } // this will be a NOOP for Rotate/Move/Height actions ikSolver.ManipulateArm(); if (!Physics.autoSimulation) { Physics.Simulate(fixedDeltaTime); } yield return(new WaitForFixedUpdate()); currentDistance = distanceMetric(target, getProp(moveTransform)); } T resetProp = previousProperty; if (returnToStartPropIfFailed) { resetProp = originalProperty; } continuousMoveFinish( controller, collisionListener, moveTransform, setProp, target, resetProp ); // we call this one more time in the event that the arm collided and was reset ikSolver.ManipulateArm(); if (!Physics.autoSimulation) { Physics.Simulate(fixedDeltaTime); } }
//spawn receptacle/screen <objType> of index [variation] on <targetReceptacle> table object using random seed to pick which spawn coordinate used public bool SpawnExperimentObjAtRandom(string objType, int variation, int seed, SimObjPhysics targetReceptacle, float yRot = 0) { toSpawn = null; bool success = false; //init random state UnityEngine.Random.InitState(seed); if (objType == "screen") { toSpawn = screensToSpawn[variation].GetComponent <SimObjPhysics>(); } if (objType == "receptacle") { toSpawn = receptaclesToSpawn[variation].GetComponent <SimObjPhysics>(); } List <Vector3> spawnCoordinates = new List <Vector3>(); PhysicsRemoteFPSAgentController fpsAgent = agentManager.ReturnPrimaryAgent().GetComponent <PhysicsRemoteFPSAgentController>(); spawnCoordinates = fpsAgent.GetSpawnCoordinatesAboveReceptacle(targetReceptacle); spawnCoordinates.Shuffle_(seed); //instantiate the prefab toSpawn away from every other object SimObjPhysics spawned = GameObject.Instantiate(toSpawn, initialSpawnPosition, Quaternion.identity); Rigidbody rb = spawned.GetComponent <Rigidbody>(); //make sure object doesn't fall until we are done preparing to reposition it on the target receptacle rb.isKinematic = true; //apply rotation to object, default quaternion.identity spawned.transform.Rotate(new Vector3(0, yRot, 0), Space.Self); for (int i = 0; i < spawnCoordinates.Count; i++) { //place object at the given point, this also checks the spawn area to see if its clear //if not clear, it will return false if (fpsAgent.PlaceObjectAtPoint(toSpawn, spawnCoordinates[i])) { //we set success to true, if one of the corners doesn't fit on the table //this will be switched to false and will be returned at the end success = true; //double check if all corners of spawned object's bounding box are //above the targetReceptacle table //note this only accesses the very first receptacle trigger box, so //for EXPERIMENT ROOM TABLES make sure there is only one //receptacle trigger box on the square table List <Vector3> corners = GetCorners(spawned); Contains con = targetReceptacle.ReceptacleTriggerBoxes[0].GetComponent <Contains>(); bool cornerCheck = true; foreach (Vector3 p in corners) { if (!con.CheckIfPointIsAboveReceptacleTriggerBox(p)) { cornerCheck = false; //this position would cause object to fall off table //double back and reset object to try again with another point spawned.transform.position = initialSpawnPosition; break; } } if (!cornerCheck) { success = false; continue; } } //if all corners were succesful, break out of this loop, don't keep trying if (success) { rb.isKinematic = false; //run scene setup to grab reference to object and give it objectId sceneManager.SetupScene(); sceneManager.ResetObjectIdToSimObjPhysics(); break; } } //no objects could be spawned at any of the spawn points //destroy the thing we tried to place on target receptacle if (!success) { Destroy(spawned.transform.gameObject); } return(success); }