Hello everyone.

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.

Is there a 'world up' vector (Unity)?

edited May 2016 in Questions And Answers

I can see that the spatial mesh I create is not axis-aligned in Unity. The mapped floor is not parallel to the Y plane. Is there a handy way to tell what the mapped world Y axis is? I can sample some triangles to get normals, but it's an extra step for the user I'd rather not have to force on them. Would the accelerometer help me here?

Answers

  • ahillierahillier mod
    edited May 2016

    Unity has Vector3.up. You can also use transform.up, if you're interested in getting the Y axis of the object itself. This forum post might be helpful.

    If the spatial mapping mesh normals do not appear correct when rendered, then you will need to call RecalculateNormals when the mesh is updated. The spatial mapping course will use the following code in SurfaceObserver_OnDataReady to fix the normals:

    if (renderer.enabled)
    {
        MeshFilter filter = surface.GetComponent<MeshFilter>();
        if (filter != null && filter.sharedMesh != null)
        {
            filter.sharedMesh.RecalculateNormals();
        }
    }
    
  • @ahillier said:
    Unity has Vector3.up. You can also use transform.up, if you're interested in getting the Y axis of the object itself. This forum post might be helpful.

    If the spatial mapping mesh normals do not appear correct when rendered, then you will need to call RecalculateNormals when the mesh is updated. The spatial mapping course will use the following code in SurfaceObserver_OnDataReady to fix the normals:

    if (renderer.enabled)
    {
        MeshFilter filter = surface.GetComponent<MeshFilter>();
        if (filter != null && filter.sharedMesh != null)
        {
            filter.sharedMesh.RecalculateNormals();
        }
    }
    

    I don't think this is what I need. As I understand it, RecalculateNormals will fix the normals given the local coords of the mesh, not the real world. I need a real-world Up vector. I think it would be opposite a Gravity vector, from the Accelerometer (assuming I can get at that).

    It just appears that the scanned floor mesh (looks like it's right on the real floor), has Up vectors that are not real-world up (can be off by 45 degrees sometimes)

  • How do you want to use this up vector? If you are trying to make a hologram move 'up' in the world, the correct vector is 0,1,0.

    ===
    This post provided as-is with no warranties and confers no rights. Using information provided is done at own risk.

    (Daddy, what does 'now formatting drive C:' mean?)

  • Jarrod1937Jarrod1937 ✭✭✭

    If the normal associated with a vertex point is not perfectly flat with those around it, it very well may be 45 degrees off. What are you trying to achieve? A simple Vector3.up will give you a direct Y up vector (0, 1, 0), an objects transform.up will give you the up vector in worldspace relative to the objects orientation.

  • @Jarrod1937 said:
    If the normal associated with a vertex point is not perfectly flat with those around it, it very well may be 45 degrees off. What are you trying to achieve? A simple Vector3.up will give you a direct Y up vector (0, 1, 0), an objects transform.up will give you the up vector in worldspace relative to the objects orientation.

    I may need to put up a screen shot. Let me see if I can describe the problem:

    I use the Spatial Mapping prefab to display the room. I see the mesh hugging the real world fine. I put a sphere at the Basic Cursor position. Then, I use Vector.up to put something .2 meters above it. It does not appear above it, but at an angle. And as I move the cursor around, the object floating .2m 'above' will retain that angle. Let's say it's tilted 10 degrees off-axis toward me. If I move around to the other side of the cursor (cursor at same position), I see the object tilted off-axis 10 degrees away from me. So I know it's not relative to me (the camera), it's relative to the world. And it's not 'up' in the real world, it's up in the virtual world surely. I need real-world.
    To get around this, I can use the cursor's Normal (derived from the mesh where it hit). Now it appears above the cursor as I expect. But it's not 0,.2,0 offset, it's along the Normal of the Hit.
    Because I need to always keep my object directly above the cursor, I cannot depend on the Hit, as you say, it can be very off axis.
    I'm going to try Input.accelerometer and see if that helps.

  • PatrickPatrick mod
    edited May 2016

    The accelerometer isn't exposed, so that's not going to help you. Even if it were exposed, you are working in world space as the Unity engine sees it. In Unity for HoloLens real world up is virtual world up unless you've done something unusual.

    Let me see if I understand you correctly-you are making a sphere for your cursor and you want some sort of gizmo that stays .2m above your cursor? If so, I'm pretty sure I know what your problem is. Check the transforms of your objects very carefully, especially if you are making the gizmo a child of the cursor.
    Here's a little script I just attached to a gizmo of my own that keeps it above the cursor:

    void Update () {
            if (objectToStayOver != null)
            {
                transform.position = objectToStayOver.transform.position + Vector3.up * 0.2f;
            }
        }
    

    ===
    This post provided as-is with no warranties and confers no rights. Using information provided is done at own risk.

    (Daddy, what does 'now formatting drive C:' mean?)

  • @Patrick said:
    The accelerometer isn't exposed, so that's not going to help you. Even if it were exposed, you are working in world space as the Unity engine sees it. In Unity for HoloLens real world up is virtual world up unless you've done something unusual.

    Let me see if I understand you correctly-you are making a sphere for your cursor and you want some sort of gizmo that stays .2m above your cursor? If so, I'm pretty sure I know what your problem is. Check the transforms of your objects very carefully, especially if you are making the gizmo a child of the cursor.
    Here's a little script I just attached to a gizmo of my own that keeps it above the cursor:

    void Update () {
          if (objectToStayOver != null)
            {
                transform.position = objectToStayOver.transform.position + Vector3.up * 0.2f;
            }
      }
    

    This is precisely what I tried, and saw the tilt. If I do this, AND the floor is pretty flat, it looks right:

    transform.position = objectToStayOver.transform.position + GazeManager.Instance.Normal * .2f;

  • Is the object a child of another object? My hypothesis is that the rotation of the parent object is impacting the child object.

    ===
    This post provided as-is with no warranties and confers no rights. Using information provided is done at own risk.

    (Daddy, what does 'now formatting drive C:' mean?)

  • @Patrick said:
    Is the object a child of another object? My hypothesis is that the rotation of the parent object is impacting the child object.

    It is, will look into that

  • edited May 2016

    Ok, here is a screen shot. Please note the areas I circled in red. The bottom left shows that the mesh is flush with the floor as expected. The Unity screen shows the cylinder perpendicular to the floor in Unity world space. The rendered live view shows that cylinder tilted about 30 degrees off axis. The cylinder is not a child of anything.

  • edited May 2016

    Well position and rotation are 2 separate things. Are you instantiating the cylinder or just moving it in the scene to different positions? How are you setting it's rotation?

    After setting it's position try setting it's transform.localRotation = Vector3.zero and see if it is upright, or set the transform.rotation = Quaternion.identity;

  • edited May 2016

    This is not set by anything but the editor. At 0,0,0 rotated 0,0,0. For kicks, I try Instantiating one well into the run, shows up the same place. And, for added fun, I put one (with a cone on top to make an arrow) at the local origin and rotation of each surface object (MeshRenderer's gameObject). Arrowhead (green) is pointing at Y = 1.

    Appears the Y axes are pointing along the XZ plane, at an interesting angle, and WAY different from the Unity world Up (seen here surrounded a bit by a red capsule, also 'along world Y up'

  • Here I've shortened the arrows and added X and Z arrows. Looks like the -Z direction for any mesh object will do for my purpose.

Sign In or Register to comment.