/// <summary> /// Returs the GameObject (instantiated from boundingBoxPrefab) that represents the provided DetectedObject. /// If none exists, it retrieves one from the pool (or instantiates a new one if none is available) and /// sets it up with the proper ID and colors. /// </summary> private GameObject GetBBoxForObject(DetectedObject dobj) { if (!liveBBoxes.ContainsKey(dobj.id)) { GameObject newbox = GetAvailableBBox(); newbox.name = "Object #" + dobj.id; BBox3DHandler boxhandler = newbox.GetComponent <BBox3DHandler>(); Color col; if (idColorDict.ContainsKey(dobj.id)) { col = idColorDict[dobj.id]; } else { col = GetNextColor(); idColorDict.Add(dobj.id, col); } if (boxhandler) { boxhandler.SetColor(col); boxhandler.SetID(dobj.id); } liveBBoxes[dobj.id] = newbox; return(newbox); } else { return(liveBBoxes[dobj.id]); } }
/// <summary> /// Given a frame of object detections, positions a GameObject to represent every visible object /// in that object's actual 3D location within the world. /// <para>Called from ZEDManager.OnObjectDetection each time there's a new detection frame available.</para> /// </summary> private void Visualize3DBoundingBoxes(DetectionFrame dframe) { //Get a list of all active IDs from last frame, and we'll remove each box that's visible this frame. //At the end, we'll clear the remaining boxes, as those are objects no longer visible to the ZED. List <int> activeids = liveBBoxes.Keys.ToList(); List <DetectedObject> newobjects = dframe.GetFilteredObjectList(showONTracked, showSEARCHINGTracked, showOFFTracked); foreach (DetectedObject dobj in newobjects) { Bounds objbounds = dobj.Get3DWorldBounds(); //Make sure the object is big enough to count. We filter out very small boxes. if (objbounds.size.x < minimumWidthToDisplay) { continue; } //Remove the ID from the list we'll use to clear no-longer-visible boxes. if (activeids.Contains(dobj.id)) { activeids.Remove(dobj.id); } //Get the box and update its distance value. GameObject bbox = GetBBoxForObject(dobj); //Move the box into position. bbox.transform.position = dobj.Get3DWorldPosition(); if (floorBBoxPosition) { bbox.transform.position = new Vector3(bbox.transform.position.x, 0, bbox.transform.position.z); } bbox.transform.rotation = dobj.Get3DWorldRotation(boxesFaceCamera); //Rotate them. //Transform the box if desired. if (transformBoxScale) { //We'll scale the object assuming that it's mesh is the default Unity cube, or something sized equally. if (transformBoxToTouchFloor) { Vector3 startscale = objbounds.size; float distfromfloor = bbox.transform.position.y - (objbounds.size.y / 2f); bbox.transform.localScale = new Vector3(objbounds.size.x, objbounds.size.y + distfromfloor, objbounds.size.z); Vector3 newpos = bbox.transform.position; newpos.y -= (distfromfloor / 2f); bbox.transform.position = newpos; } else { bbox.transform.localScale = objbounds.size; } } //Now that we've adjusted position, tell the handler on the prefab to adjust distance display.. BBox3DHandler boxhandler = bbox.GetComponent <BBox3DHandler>(); if (boxhandler) { float disttobox = Vector3.Distance(dobj.detectingZEDManager.GetLeftCameraTransform().position, dobj.Get3DWorldPosition()); boxhandler.SetDistance(disttobox); boxhandler.UpdateBoxUVScales(); boxhandler.UpdateLabelScaleAndPosition(); } //DrawDebugBox(dobj); } //Remove boxes for objects that the ZED can no longer see. foreach (int id in activeids) { ReturnBoxToPool(id, liveBBoxes[id]); } }