cancel
Showing results for 
Search instead for 
Did you mean: 

How to geometrically align a 3D model to real furniture?

evb7928
Honored Guest

For my video-see-through AR application I want a model to automatically be placed on the biggest found table surface. I achieved the first step: The model is correctly positioned at the table center. However, the orientationis not correct. I want the model to "lie down" on the table, means laying on the back, facing up, while the longest side of the model is orientated just as the longest side of the table - see the following pictures: 

Screenshot 2024-11-12 154716.pngScreenshot 2024-11-12 154644.png

 After a very long time trying, I could not figure out how to align the model correctly. If you have any idea/hint/ or clue I could try, please let me know.

Used Asset for testing:

I added an Empty (called ModelPlacer) where I added the script (see below) and pulled this asset in the modelInstance field.

Used Meta XR Building Blocks:

  • Camera Rig
  • Passthrough
  • MR Utility Kit
  • Scene Debugger
  • Effect Mesh
  • Hand Tracking
  • Controller Tracking

Technical Specifications:

  • Unity 2022.3.50f1
  • VR-Glasses: Meta Quest 3
  • Meta MR Utility Kit

Code: 

 

using Meta.XR.MRUtilityKit;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ModelPlacer : MonoBehaviour
{
    public GameObject modelPrefab;
    private GameObject modelInstance;

    void Start()
    {
        MRUK.Instance?.RegisterSceneLoadedCallback(OnSceneLoaded);
    }

    private void OnSceneLoaded()
    {
        SpawnModel();
        AlignModelWithSurface();
    }

    public void SpawnModel()
    {
        Vector3 spawnPosition = new Vector3(0.0f, 1.0f, -1.0f);
        modelInstance = Instantiate(modelPrefab, spawnPosition, Quaternion.identity);
    }

    public void AlignModelWithSurface()
    {
        var largestSurface = MRUK.Instance?.GetCurrentRoom()?.FindLargestSurface(MRUKAnchor.SceneLabels.TABLE);

        if (modelInstance != null)
        {
            if (largestSurface != null)
            {
                modelInstance.transform.SetParent(largestSurface.transform);

                Renderer modelRenderer = modelInstance.GetComponent<Renderer>();

                modelInstance.transform.rotation = Quaternion.Euler(-90, 0, 0);

                Vector3 modelCenter = modelRenderer.bounds.center;
                Vector3 surfaceCenter = largestSurface.transform.position;

                Vector3 positionOffset = surfaceCenter - modelCenter;
                Vector3 adjustedPosition = modelInstance.transform.position + positionOffset;

                modelInstance.transform.position = adjustedPosition;
            }
            else
            {
                Debug.LogWarning("No surface found.");
            }
        }
        else
        {
            Debug.LogWarning("modelInstance is null.");
        }
    }
}

 

 

3 REPLIES 3

evb7928
Honored Guest

Hi @ModeratorTeam,

I posted this in the wrong section, and I think the Unity Development forum would be a better fit for my topic. According to this post about deleting forum posts , I understand I can request help from moderators in such cases.

Could you please help move it, or let me know if there’s anything further I should do?

Thank you very much for your assistance!

4vit
Explorer

May be you can try the below ones

  • Attach the script to an empty GameObject in your scene
  • Assign your model prefab in the Inspector
  • Adjust the alignment settings as needed
  • Use the events to respond to alignment success/failure

Hello @4vit , thank you for reaching out. 

Your first two suggestions are a given. I thought mentioning that my script works at positioning implies that I already attached the script to an Empty in my Scene and assigned the Model Prefab. 

Your advice to "Adjust the alignment settings as needed" is not helpful for me, as that is literally my question how to.

I have already tried different lines of code to do that but didn't succeed (it didn't align the model to the table). I had hoped for any links to similar cases (that I haven't found) with code examples, or lines of code I could try out. 
I have already tried things like ...

 

modelInstance.transform.rotation = largestTableSurface.transform.rotation;

 

However that didn't work.