The Mixed Reality Forums here are no longer being used or maintained.
There are a few other places we would like to direct you to for support, both from Microsoft and from the community.
The first way we want to connect with you is our mixed reality developer program, which you can sign up for at https://aka.ms/IWantMR.
For technical questions, please use Stack Overflow, and tag your questions using either hololens or windows-mixed-reality.
If you want to join in discussions, please do so in the HoloDevelopers Slack, which you can join by going to https://aka.ms/holodevelopers, or in our Microsoft Tech Communities forums at https://techcommunity.microsoft.com/t5/mixed-reality/ct-p/MicrosoftMixedReality.
And always feel free to hit us up on Twitter @MxdRealityDev.
Get the minimal distance to the walls
Hello, I'm discovering the spatial mapping/understanding and I'm trying to get the position of the nearest wall in order to be sure that an hologram is in the same room as the user.
I read most of the script and wrote this code.void CheckPlanes() { float minDist = 1000f; List<GameObject> walls = SurfaceMeshesToPlanes.Instance.GetActivePlanes(PlaneTypes.Wall); foreach (GameObject plane in walls) { if (Vector3.Distance(plane.transform.position - new Vector3(0, plane.transform.position.y, 0), camera1.position - new Vector3(0, camera1.position.y, 0)) < minDist) { minDist = Vector3.Distance(plane.transform.position - new Vector3(0, plane.transform.position.y, 0), camera1.position - new Vector3(0, camera1.position.y, 0)); Debug.Log(minDist); float cst = Mathf.Abs(character.position.x / character.position.z); character.position = new Vector3(minDist * cst / (Mathf.Sqrt(1 + cst)), character.position.y, minDist / (Mathf.Sqrt(1 + cst))); teleporteur.position = new Vector3(minDist * cst / (Mathf.Sqrt(1 + cst)), teleporteur.position.y, minDist / (Mathf.Sqrt(1 + cst))); } } }
But when I build it I get a nullreference on the walls list.
I use this function when the application launch so do I just have to wait for some time or did I do something wrong ?
Best Answers
-
keljed ✭✭
Yes, you have to wait for the surface mesh to be created. Try the Spatial Mapping and Understanding demos in the HoloToolkit. When you enable the rendering of the Surface Mesh you will see that it takes some time to have a (complete) model of the room.
5 -
trzy ✭✭✭
With ordinary spatial mapping, you have to:
1) Start scanning.
2) When the scan is complete enough (usually, the user decides and you can have them air tap or something), stop the scan.
3) Call MakePlanes() to actually extract the planar surfaces (this takes several frames to complete).
4) Wait for the callback from MakePlanes().I have only a complicated example (complicated because it also has support for spatial understanding) here: https://github.com/trzy/hololens/blob/master/Demo-Holocopter/Assets/Scripts/PlayspaceManager.cs
When reading the code, assume useSpatialUnderstanding == false. That's a separate pathway.
My main script is: https://github.com/trzy/hololens/blob/master/Demo-Holocopter/Assets/Scripts/PlayerGazeControlled.cs
You can see that I do the following there:
- Start up in the Scanning state. Call PlayspaceManager.Instance.StartScanning(). This is my function.
- I have an air tap handler that sets the state to State.Finalize.
- When State.Finalize is entered, I call PlayspaceManager.Instance.StopScanning().
What do these functions do? PlayspaceManager is the interesting part:
- In Start(), I first register a callback to the event that is fired when plane-making is complete:
SurfaceMeshesToPlanes.Instance.MakePlanesComplete += SurfaceMeshesToPlanes_MakePlanesComplete;
The Update() function does nothing (I have spatial understanding code in there, which is more complex -- ignore it).
PlayspaceManager.StartScanning(): this starts the observer if it has not already been started (usually it is configured to auto-start but it doesn't hurt to do this) and I also render spatial meshes during the scanning stage. So I do:
if (!m_spatialMappingManager.IsObserverRunning()) m_spatialMappingManager.StartObserver(); m_spatialMappingManager.DrawVisualMeshes = true; m_spatialMappingManager.SetSurfaceMaterial(renderingMaterial);
- PlayspaceManager.StopScanning(): When this is called from PlayerGazeControlled.cs (the main script) after the player air taps, it stops the scanning process (so we "freeze" the mesh) and constructs the planes.
`public void StopScanning()
{
if (m_spatialMappingManager.IsObserverRunning())
m_spatialMappingManager.StopObserver();
CreatePlanes();
m_scanningComplete = true;
}private void CreatePlanes()
{
// Generate planes based on the spatial map
SurfaceMeshesToPlanes surfaceToPlanes = SurfaceMeshesToPlanes.Instance;
if (surfaceToPlanes != null && surfaceToPlanes.enabled)
surfaceToPlanes.MakePlanes();
}`When MakePlanes() has finished, it will call my callback, which I installed at the very beginning:
private void SurfaceMeshesToPlanes_MakePlanesComplete(object source, System.EventArgs args) { if (!visualizeSpatialMeshes) m_spatialMappingManager.SetSurfaceMaterial(occlusionMaterial); SurfacePlaneDeformationManager.Instance.SetSpatialMeshFilters(m_spatialMappingManager.GetMeshFilters()); SetPlaneTags(Layers.Instance.surfacePlaneTag); if (OnScanComplete != null) OnScanComplete(); }
SurfacePlaneDeformationManager is my own code. You can see that I call GetMeshFilters() there.
I hope this helps you.
Bart
http://trzy.org5
Answers
Yes, you have to wait for the surface mesh to be created. Try the Spatial Mapping and Understanding demos in the HoloToolkit. When you enable the rendering of the Surface Mesh you will see that it takes some time to have a (complete) model of the room.
With ordinary spatial mapping, you have to:
1) Start scanning.
2) When the scan is complete enough (usually, the user decides and you can have them air tap or something), stop the scan.
3) Call MakePlanes() to actually extract the planar surfaces (this takes several frames to complete).
4) Wait for the callback from MakePlanes().
I have only a complicated example (complicated because it also has support for spatial understanding) here: https://github.com/trzy/hololens/blob/master/Demo-Holocopter/Assets/Scripts/PlayspaceManager.cs
When reading the code, assume useSpatialUnderstanding == false. That's a separate pathway.
My main script is: https://github.com/trzy/hololens/blob/master/Demo-Holocopter/Assets/Scripts/PlayerGazeControlled.cs
You can see that I do the following there:
What do these functions do? PlayspaceManager is the interesting part:
SurfaceMeshesToPlanes.Instance.MakePlanesComplete += SurfaceMeshesToPlanes_MakePlanesComplete;
The Update() function does nothing (I have spatial understanding code in there, which is more complex -- ignore it).
PlayspaceManager.StartScanning(): this starts the observer if it has not already been started (usually it is configured to auto-start but it doesn't hurt to do this) and I also render spatial meshes during the scanning stage. So I do:
if (!m_spatialMappingManager.IsObserverRunning()) m_spatialMappingManager.StartObserver(); m_spatialMappingManager.DrawVisualMeshes = true; m_spatialMappingManager.SetSurfaceMaterial(renderingMaterial);
`public void StopScanning()
{
if (m_spatialMappingManager.IsObserverRunning())
m_spatialMappingManager.StopObserver();
CreatePlanes();
m_scanningComplete = true;
}
private void CreatePlanes()
{
// Generate planes based on the spatial map
SurfaceMeshesToPlanes surfaceToPlanes = SurfaceMeshesToPlanes.Instance;
if (surfaceToPlanes != null && surfaceToPlanes.enabled)
surfaceToPlanes.MakePlanes();
}`
When MakePlanes() has finished, it will call my callback, which I installed at the very beginning:
private void SurfaceMeshesToPlanes_MakePlanesComplete(object source, System.EventArgs args) { if (!visualizeSpatialMeshes) m_spatialMappingManager.SetSurfaceMaterial(occlusionMaterial); SurfacePlaneDeformationManager.Instance.SetSpatialMeshFilters(m_spatialMappingManager.GetMeshFilters()); SetPlaneTags(Layers.Instance.surfacePlaneTag); if (OnScanComplete != null) OnScanComplete(); }
SurfacePlaneDeformationManager is my own code. You can see that I call GetMeshFilters() there.
I hope this helps you.
Bart
http://trzy.org
Argh. I wish these forums had a better markdown format.
Bart
http://trzy.org
Anyway, for object placement, consider using SpatialUnderstanding. It's much more complicated but you can perform interesting queries, including finding the largest wall, placing objects on a wall, and constraining them to be a certain distance from the user or other points, etc.
Bart
http://trzy.org
Thank you for your answers I'm going to see if I can make this work.