Unity is great for creating primitive objects, and the asset store is a great repository for finding prefabricated objects to use in your project. But what if you’ve got your own object that you’d like to see and share in a mixed reality world?
I’ve certainly done a lot of work using Autodesk 123d with my 3d printing projects, and I was interested to see if I could get some of my historical projects to display in the HoloLens – specifically my 3d printed prosthetic robot hand project.
So how can I get from Autodesk 123d to Unity, and render it as a static object in the HoloLens?
Starting with Autodesk 123d
This is just my CAD tool of choice – this isn’t a mandatory tool. This package creates files which have extension “123dx”, which is a proprietary Autodesk format.
However, you can export these to an open format of STL – I use this format commonly for 3d printing.
I located a 123d file of part of the robot hand I referred to earlier, and loaded it up in Autodesk 123d.
It’s worth noting that I’ve orientated this to be centred on the origin of the blue grid, and also that the front of the 3 fingers is orientated to align with Autodesk’s front view also.
Next, I exported this to the STL format, using the menu item below:
Converting the STL to OBJ format
I’m sure there are a bunch of ways to do this – I chose to use an online conversion tool. This allowed me to upload an STL, and then download a OBJ file.
The tool I use is http://www.greentoken.de/onlineconv/.
There are lots of options – another is: http://www.meshconvert.com/
From here, it’s a simple step into Unity.
Creating a Unity Prefab
I created a new project in Unity, and configured it for mixed reality. I’ve described the steps for this before, but basically to re-itereate:
- Create the project;
- First, I changed the position of the camera to (0, 0, 0), meaning X = 0, Y = 0, and Z = 0;
- Next, in the Camera section, I changed the Clear Flags dropdown value to Solid Color.
- Finally, I change the Background property to Black (R = 0, G = 0, B = 0, A = 0).
Once the base project was set up, I dragged the OBJ file from where I saved it on my hard-drive to the Assets folder in Unity. This showed a little preview icon of the hand, which showed me I was on the right track.
Then I dragged this prefab object into the Hierarchy view as a static object, and moved it to be 1m in front of my field of view (i.e. I changed the Z-position to have value 1).
I then built the app, and deployed it to the HoloLens emulator. But there were a couple of immediate and obvious problems.
- The object was many times bigger than I expected, and
- The object was rotated by 90 degrees anti-clockwise around the X-axis, and 90 degrees anti-clockwise around the Y-axis.
Fixing Scaling and Rotation
There’s an element of guesswork here, but I think that the default unit in Autodesk 123d is millimetres. When I export to STL and convert to OBJ, it doesn’t store the measurement of the unit – and when I load it up in Unity, since the default unit is metres, then every 1mm in Autodesk 123d is seen as 1m in Unity. Therefore the object is 1000 times too big, and I need to scale by 0.001.
Regarding rotation, different CAD packages have different ideas of what “up” means. For me, it was pretty straightforward to rotate by -90 degrees in the X and Y axis to make the object render correctly.
Once I implemented the scaling and rotations shown above, Unity showed the scene below:
When I run this program in the emulator with the modified values, I see the hologram below:
Finally, I loaded this app into the physical HoloLens to look at it – it rendered pretty much perfectly, and identical to how it rendered in the HoloLens Emulator.
This opens up a new world of possibilities for me with the HoloLens – I’m not restricted to primitive objects within Unity, or using other people’s prefabs from the Unity Asset Store.
This is an incredibly powerful technique – you can create your own complex 3d objects, export them to a standard format like STL or OBJ files, and then import into Unity for display. Some post processing was necessary – I found that I needed to scale the object down by 1000 times, and rotate in a couple of different axis, but this is a pretty trivial modification to make. I chose to display this as a static object – but as I’ve discussed before, there’s no reason why this couldn’t be a dynamically generated object.