Skip to content

Codebase for Cuboid, XR (AR & VR) software for bringing spatial ideas into the real world. Built on top of Unity, written in C#

License

Notifications You must be signed in to change notification settings

ArjoNagelhout/cuboid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

51 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

⚠️ Discontinuation notice

Due to Unity's pricing changes, I made the decision to discontinue the development of this app, as I am no longer comfortable with spending significant time building on top of a foundation that could be pulled from under you at any point in time.

Some of the code and design decisions inside this repository might help someone develop something similar, which is why I have decided to publish the source code under the MIT license. Note that the project depends on one paid asset, Shapes by Freya HolmΓ©r. Luckily, this dependency could be replaced fairly trivially by something else.

Cuboid

Screenshot 2

Screenshot 1

Cuboid allows you to design for the real world, in the real world. Import high quality assets, and place and manipulate them at world-scale in your environment. Reimagine your living room, your house, or an entire city!

Supported Devices

  • Meta Quest 2
  • Meta Quest Pro

Key Features

  • Import any Unity Prefab or 3D model into the application via com.cuboid.unity-plugin (custom MonoBehaviour scripts excluded)
  • Place 3D objects in your environment on world-scale augmented reality using Passthrough.
  • Built-in asset library.
  • Cuboid is a local, standalone application. It does not require an internet connection or creating an account.
  • Translate, rotate and scale objects using gizmos and intuitive scale bounds handles, from a distance!
  • Select, cut, copy, paste, duplicate and delete objects via a context menu.
  • Full undo / redo support.
  • Save and load scenes to and from a local .json file.
  • Draw primitive shapes and change corner radius or their color via a full RGB / HSV color picker.

Dependencies

Unity Editor version: 2021.3.27f1

Packages

Notable packages:

See Packages/manifest.json for all packages. Other than those above, it only contains packages created and maintained by Unity.

Plugins

These are free and paid plugins retrieved from the Unity AssetStore and should be installed to the Plugins directory.

Oculus Package

The project depends on the Oculus Integration package > 57.0.0

Only the VR subdirectory of the package needs to be installed to the Oculus subdirectory.

⚠️ Note that the Oculus Integration package has since been deprecated. Please refer to Meta's guide for upgrading your project to the new packages.

Codebase Architecture

Unity Scenes and Prefabs

There are two main Unity Scenes that compose the app. These are the main entrypoints of the application:

  1. AppEditor The main scene for testing the application directly inside the Editor with the XR Device Simulator.
  2. AppRuntime The main scene that gets run on the XR device, which does not contain the simulator.

Both scenes contain the App prefab, which contain prefabs for each controller described below (e.g. UndoRedoController, RealitySceneController and ToolController).

The only difference is that the AppEditor scene contains the EditorXRRig, and AppRuntime contains the RuntimeXRRig.

Scripts

All code is located in the following directories:

πŸ“ app/
└── πŸ“ Assets/
    └── πŸ“ Scripts/
        β”œβ”€β”€ πŸ“ Editor/
        └── πŸ“ Runtime/
            β”œβ”€β”€ πŸ“ Commands/
            β”œβ”€β”€ πŸ“ Document/
            β”œβ”€β”€ πŸ“ Input/
            β”œβ”€β”€ πŸ“ Rendering/
            β”œβ”€β”€ πŸ“ SpatialUI/
            β”œβ”€β”€ πŸ“ Tools/
            β”œβ”€β”€ πŸ“ UI/
            └── πŸ“ Utils/

Top level scripts inside πŸ“ Runtime:

  • Binding.cs Utility class for binding a value to a UI element to keep the UI and data model in sync.
  • CacheController.cs Enables the user to clear the cache and to inspect its size
  • ColorsController.cs Global controller for changing the color of all selected objects

πŸ“ Commands

For storing the editing history to enable fully undoing and redoing all edits made by the user. This employs the command pattern. Commands can be nested and/or combined to create compound commands, e.g. for selecting and moving objects on click and drag.

Commands

πŸ“ Document

Serializable and editable data model of a 3D scene. A RealityDocument is the data model that gets saved and loaded to and from disk. A RealityDocument contains a RealityScene, which in its turn contains a set of RealityObjects. These RealityObjects can have different types, such as a 3D asset, or a primitive shape.

3D assets are not stored inside the RealityDocument but stored as a reference to a RealityAssetCollection, which wraps a Unity AssetBundle. These RealityAssetCollections are created with com.cuboid.unity-plugin.

Data model

Controllers

πŸ“ Input

Handling of spatial input events from XR controllers. Part of this is adopted and modified from the XR Interaction Toolkit, as the XR Interaction Toolkit proved insufficient for achieving the exact interactions expected in a design application.

There are three different types of interactables in the scene. They are interacted with in the following order: UI is always on top of SpatialUI, which on its turn is always above the scene.

  1. UI 2D UI such as buttons and a colorpicker
  2. SpatialUI 3D handles and UI elements that should be moved in 3D space to perform the action, e.g. a translate along axis handle
  3. OutsideUI Anywhere outside UI or SpatialUI, can be digital objects or the physical world

πŸ“ Core

πŸ“ Keyboard

Custom VR keyboard implementation with numeric support.

πŸ“ XRController

Handling buttons and rendering of controller.

Mapping buttons to high level actions.

πŸ“ Rendering

Not much to see here, as Unity handles all rendering.

πŸ“ SpatialUI

Handles

The handles defined in SpatialUI purely contain data and implement the interfaces defined in SpatialPointerEvents.cs in πŸ“ Input.

Calculating the new position of the handle on moving the spatial pointer is performed by the tools in πŸ“ Tools. These tools are also responsible for instantiating these handles.

Miscellaneous

πŸ“ Tools

  • ToolController.cs Instantiates the tool prefab based on the selected tool
  • ToolSwitcher.cs A quick switcher that enables the user to switch with the joystick between the most commonly used tools.
  • ModifiersController.cs Listens to buttons on the non-dominant hand to activate the Shift or Option modifiers
  • OutsideUIBehaviour.cs Registers listening to events (e.g. when the user clicks or drags) for outside the UI and outside spatial UI.

Selection

  • DefaultSelectBehaviour.cs Behaviour for selecting and moving objects when clicking and dragging an object. Depends on OutsideUIBehaviour. All handle tools use this behaviour.
  • SelectTool.cs Uses DefaultSelectBehaviour.

Handle tools

  • AxisHandleTool.cs Base class for a tool that instantiates handles. Uses DefaultSelectBehaviour
  • TranslateTool.cs Translate the selected objects along their local x, y or z axis, or their x, y or z plane.
  • RotateTool.cs Rotate the selected objects around their local x, y or z axis.
  • ScaleTool.cs Scale the selected objects along their local x, y or z axis
  • SelectionBoundsTool.cs Scale the selected objects by dragging the corners, edges or faces of the selection bounds, similar to how Adobe Photoshop or Adobe Illustrator has a selection box around the selected items.

Draw tools

πŸ“ UI

πŸ“ Binding

Contains UI components that are bound to specific data or data types inside the application. Ideally, only the generic versions of these UI Binding classes exist, but as UI is still sometimes defined inside Prefabs, specialized versions need to exist. These are ommitted for brevity.

πŸ“ Core

Contains custom UI components that are data driven and better than Unity UI's built in components, such as scroll views, sliders and more.

Elements
  • Button.cs A data driven button
  • PopupButton.cs A button for an enum value that on press shows a list of all enum values to pick from.
  • Slider.cs A data driven slider
  • Slider2D.cs A data driven 2D slider (used by the color picker)
  • Toggle.cs A data driven toggle
  • InputField.cs An input field, adapted from TextMeshPro as that one was broken with text selection and editing in VR. Instantiates the correct keyboard popup based on its value type (e.g. numeric or text).
  • ValueField.cs Depends on InputField, binds to a binding that contains a float value.
  • Vector2Field.cs Contains two ValueFields
  • Vector3Field.cs Contains three ValueFields
Containers
  • NavigationStack.cs A stack of views similar to UIKit's NavigationStack.
  • ScrollView.cs A scroll view that keeps focus during dragging, even when the pointer exits the scroll view bounds.
  • ScrollViewPool.cs A performant data driven grid or list view that pools UI elements and only renders the amount of UI elements that are visible.
Menus
  • ContextMenu.cs A data driven context menu that contains a set of actions that can be performed.
  • DialogBox.cs Similar to a ContextMenu, but with a description and icon for the actions that are to be performed (used for a save file dialog for example)
Miscellaneous
  • ColorPicker.cs ColorPicker with HSV and RGB sliders with value field and and a 2D area for setting for example Hue and Value at the same time.
  • LoadingSpinner.cs A rotating spinner for indicating that something is loading
  • Notification.cs A notification that hides after a set duration
  • Tooltip.cs A tooltip that shows when hovering over a UI element. Hides after a set duration.

πŸ“ Properties

Contains property UI elements. Property UI elements get instantiated by the PropertiesController (see πŸ“ Document/PropertiesController.cs).

The state of the UI elements referenced by the property UI elements reflects the state of the document. Changes are propagated to the document when changed in the UI, and when the document changes, the UI changes (e.g. when performing Undo or Redo).

Another unique property of properties (he), is that they can update the document live while for example dragging the slider, but only register the set property command on release.

In addition, it works with multiple objects selected at the same time.

πŸ“ Views

Contains implementation for the UI for each specific view (i.e. panel). These panels can be selected in the interface via the panel buttons.

  • πŸ“ AssetsView Display asset collections and handle dragging and dropping RealityAssets into the scene
  • πŸ“ DocumentsView Display the currently opened document, and other documents that the user has created that they could open, rename or delete.
  • ColorsViewController.cs Display a colors panel with the currently active
  • CreditsViewController.cs Display credits and links to license and website
  • PropertiesViewController.cs Display properties of the currently selected objects
  • SettingsViewController.cs Display settings
  • ToolsViewController.cs Display tools, and the properties of the selected tool, if any.
  • TransformProperties.cs Display transform properties of selected objects (translation, rotation and scale) using Vector3Fields

πŸ“ Utils

General utility functions that extend Unity's classes or mitigate some ommision in Unity.

About

Codebase for Cuboid, XR (AR & VR) software for bringing spatial ideas into the real world. Built on top of Unity, written in C#

Topics

Resources

License

Stars

Watchers

Forks