Spatial Understanding Queries Return Empty Array

Hello!
Does anyone have the issue of spatial understanding queries returning a null array. This happens with the topology query and the shape query. I want to place objects randomly on the floor, and I know it identifies the floor correctly (I print the values of the scan during gameplay). I also know it stores the values correctly because I've had it read numFloors from UnderstandingDLL.GetStaticPlayspaceStats() to me immediately before the query, and it's a nonzero value. However, it never places my objects because the return value of the query (which is supposed to return the number of matches found) is always zero. At this point, my code is copied from SpatialVisualizer.cs.
Is this a common problem? Any known fixes?
I can provide my code, if needed. In case it matters, I'm on Unity 5.5 and I'm working with a HoloToolkit from February.
Thank you so much!

Best Answer

  • trzytrzy ✭✭✭
    Accepted Answer
    You need to perform a number of steps to finalize the scan and generate the data that is used by the query solver:

    1. Call RequestFinishScan()
    2. (Possibly optional depending on whether you want to visualize the understanding mesh or use it for occlusion): wait for mesh import by checking the UnderstandingCustomMesh.IsImportActive flag.
    3. Initialize the placement solver: call Solver_Init().

    I implement this procedure as a state machine that takes several frames to complete. At minimum, step 1 will take a few frames and will trigger a callback that you need to listen to. Then, you can proceed to step 3 and perform queries afterwards.

    Here is my code: https://github.com/trzy/hololens/blob/master/Demo-Platformer/Assets/Scripts/PlayspaceManager.cs

    It's more complex than you need but take a look at Update(), OnScanStateChange(), StartScanning(), and StopScanning() to understand how the complete flow works.

    By the way, I notice many people have trouble getting started with this API -- does anyone think it would be useful for me to write a blog post/tutorial or record a YouTube walk-through?

Answers

  • trzytrzy ✭✭✭
    Accepted Answer
    You need to perform a number of steps to finalize the scan and generate the data that is used by the query solver:

    1. Call RequestFinishScan()
    2. (Possibly optional depending on whether you want to visualize the understanding mesh or use it for occlusion): wait for mesh import by checking the UnderstandingCustomMesh.IsImportActive flag.
    3. Initialize the placement solver: call Solver_Init().

    I implement this procedure as a state machine that takes several frames to complete. At minimum, step 1 will take a few frames and will trigger a callback that you need to listen to. Then, you can proceed to step 3 and perform queries afterwards.

    Here is my code: https://github.com/trzy/hololens/blob/master/Demo-Platformer/Assets/Scripts/PlayspaceManager.cs

    It's more complex than you need but take a look at Update(), OnScanStateChange(), StartScanning(), and StopScanning() to understand how the complete flow works.

    By the way, I notice many people have trouble getting started with this API -- does anyone think it would be useful for me to write a blog post/tutorial or record a YouTube walk-through?
  • Fantastic! I was missing SpatialUnderstandingDllObjectPlacement.Solver_Init(). Do you by chance know what ClearGeometry() does in SpaceVisualizer and LevelSolver. I copied my query from SpaceVisualizer and modified it to place GameObjects instead of drawing boxes, and ClearGeometry() seems to permanently disable the ability to instantiate or move GameObjects.
    A tutorial is a wonderful idea! I struggled with this very much, so a simple, straightforward tutorial that actually explains what each piece of code is doing would be helpful to many people.

  • trzytrzy ✭✭✭

    I haven't used their ClearGeometry() function but all it appears to be doing is removing the line drawings that the demo generates and, more importantly, calling Solver_RemoveAllObjects(). My understanding of this function (although I have not used it) is that it will discard all the placements that the solver is keeping track of.

    When you use the solver to obtain a placement position, you pass in the size of the volume you want to place (via the placement definition object). The solver is supposed to keep track of these so that subsequent placement requests do not create overlapping placements.

    I'm not sure how you're moving game objects around but calling ClearGeometry() should do nothing more than remove the placement visualizations and then allow you to place new objects even where existing ones have already been placed.

  • That's odd. I tried:
    Instantiate(floorObject, resultsTopology[0].position, Quaternion.identity);
    and
    floorObject.transform.position = new Vector3(resultsTopology[0].position.x, .5f, resultsTopology[0].position.z);

    as well as hard coded values for both methods instead of resultsTopology, and both failed until I commented out ClearGeometry. Hard to tell if it's something I did wrong or a bug with ClearGeometry. I'm just glad it's finally working!

  • trzytrzy ✭✭✭
    Don't reuse resultsTopology[] in between calls to the spatial understanding library. My guess is that the results also get cleared. That memory is managed by the DLL, it is *not* an array that is copied over to the .NET world.

    To move the object, use its own transform to get the current position rather than going back to the topology results. My guess is that if you ClearGeometry(), it will work just fine.
  • MaryamSMaryamS
    edited May 3

    @trzy hope you can make a tutorial about the spatial understanding dll on YouTube or a blog it would be really useful (y)

Sign In or Register to comment.