Advanced Models

Snapping

When inserting a model in a scene, it is sometimes more useful to use another model as a reference about the new model position, than using 3D space coordinates.

Imagine a product visualisation application, where a user is allowed to choose between different table tops. Every table top has not only different set of materials provided, but also a distinct shape and dimensions. Moreover, table legs on which those tops are to be placed also have their individual heights and shapes. Normally, in such a case, every time a switch of a table element was to be made, a set of information about the current properties of all elements would have to be retrieved and processed before a new element would be inserted. Even worse - what if the container with the table elements was moved? Or if we were to replace 20 table tops at once?

It would be helpful to make the models pull to one another. Furthermore, it would be even better to have them pull one another just in one direction, so that the table remained on the ground with the table top laying peacefully on it, instead of floating in the thin air, if a shorter leg was introduced.

In order serve such scenarios, a Snapping functionality was introduced.

In order for this functionality to work, a pair of matching s_nappoints _must be introduced in both models to be snapped. Snappoints are generated automatically by the ViewAR system converter on the basis of cubes inserted in the models. The user must pay attention to the following properties of the cubes:

  • point of origin (translation) - defines the point of the created snappoint
  • orientation (rotation) - defines orientation of the created snappoint
  • name - defines functionality of the created snappoint

The name should follow the pattern below:

SNAPPOINT__PLUG1_PLUG2__SOCKET1__SNAPPOINTNAME
Explanation: (1)__(2)__(3)__(4)

(1) SNAPPOINT - a prefix informing the converter that the mesh is a snappoint
(2) PLUGS - separated with a single underscore ("_") names defining snappoint's plugs. If a snappoint has no plug, "dummyplug" should be inserted.
(3) SOCKETS - separated with a single underscore ("_") names defining snappoint's sockets. If a snappoint has no sockets, "dummysocket" should be inserted.
(4) SNAPPOINTNAME - a suffix defining a snappoint's name. It is not an active part of the name, just a note for 3D designers and developers.

Notes:

  • Numbers of plugs and sockets don't have to match 1:1. It is absolutely fine, if one socket serves multiple plugs (e.g. multiple table tops may be placed on one table leg).
  • However, one plug may only serve one socket at a time.
  • Therefore, defining multiple plugs in one snappoint is necessary to prevent snapping objects in objects.
  • There is no specific maximum of snappoints, plugs, sockets, however try to keep the naming short.

HowTo:
In a 3D software, open your model and create a small cube (the cube will not be removed from the scene, therefore keep it as small as possible e.g. 1x1x1 units). Move it to the position where the snappoint is supposed to be. Then, rotate it so that the front of the cube points in the direction where other object should be snapped. Snappoints need to face each other and their tops need to point in the same direction. Scaling of the snappoint does not affect it's functionality. Name the cube according to the above naming convention.

IMPORTANT: DO NOT freeze the transformation or delete history of cubes. This information is needed for our converter and are essential!

You can also download a prepared snappoint here: Snappoint.fbx

Parametric Models

Sometimes a fixed object geometry is not enough. For example, in order to create a product customisation application where not only material finishings but also product dimensions may be adjusted, so-called Parametric Models would be needed.

Parametric models are 3D objects which geometric characteristics may be algorithmically adjusted. This may relate to overall characteristics of the object (e.g. it’s length and width) or properties of its elements (e.g. radius of corners curvature).

Let’s take an example of a plain cube with following properties:

  • a point of origin: [0, 0, 0]

  • xdimension: [int], x∈ <1, 20>

  • ydimension: [int], y∈ <1, 20>

  • zdimension: [int], z∈ <1, 20>

Let’s additionally add a numerical property describing a radius of curvature of its corners. We assume that the curvature is symmetrical, identical in all directions and same for all corners.

  • cornerRadius: [int], cornerRadius∈ <0, 90>

Even with such limited scopes of parameters, we may achieve multiple combinations using just one model.

From a technical standpoint, such an object need to be created in a 3D software (e.g. Autodesk Maya) and must then be enriched with a layer of code connecting the model elements with the ViewAR Core, handling such entities.

In order to provide an appropriate texturing outcome, there is an additional real-time UV layout updating process implemented. Depending on which parts of the model would be stretched, the 3D object gets divided in sections with UV layouts applied accordingly. When parameters are changed, the UV layout of static parts remains untouched, while the layout of the altered elements gets regenerated in real-time. In this way it is ensured that changes in geometry are followed by appropriate changes in the UV layout.

Development and integration of parametric models is a complex issue, therefore we strongly encourage you to use our support on that matter. Custom 3D objects may be requested via this form: Request 3D Model

IMPORTANT: Parametric models may not be previewed through the web preview icon in the Content tab.

Configurations

In order to create complex scenes with model interdependencies encoded, we use Configurations.

Configuration is a JSON defining logical rules of model properties or possibilities of loading models in the scene.

Below an example of a portion of configuration defining geometry options for a table top:

{
    "configuration": {
        "properties": [{
            "name": "Table_top",
            "type": "part",
            "valueType": "enumerated",
            "values": [{
                    "name": "Table top - Round",
                    "foreignKey": "table-top-round"
                },
                {
                    "name": "Table top - Rectangular",
                    "foreignKey": "table-top-rectangular"
                },
                {
                    "name": "Table top - Square",
                    "foreignKey": "table-top-square"
                }

            ]
        }]
    }
}

and a portion of configuration defining material options for that table top:

{
    "configuration": {
        "properties": [{
            "name": "Table_top",
            "type": "material",
            "valueType": "enumerated",
            "values": [{
                    "name": "White Marble"
                },
                {
                    "name": "Pink Marble"
                },
                {
                    "name": "Decorative Concrete"
                }
            ]
        }]
    }
}

Reference Models

When creating complex objects taking up a lot of memory, it is a good idea to divide a model into lighter portions and, instead of inserting them all in one model file, provide a list of references to the group of smaller models. Such an entity is called a Reference Model.

Technically, a Reference Model is a JSON file providing references to models which are to be downloaded. It is done by their unique ID (UID). Good to keep in mind that the order of the list is used as an order of download.

{
    "converter": {...},
    "meshes": {
        "mesh_1": [],
        "mesh_2": [],
        "mesh_3": []
},
    "references": [
    {
        "UID": "1",
        "name": "mesh_1",
        "pose": {
            "orientation": {
                "w": 1,
                "x": 0,
                "y": 0,
                "z": 0
            },
            "position": {
                "x": 0,
                "y": 0,
                "z": 100.0
            },
            "scale": {
                "x": 1,
                "y": 1,
                "z": 1
            }
        },
        "version": "1",
        "type": "environment",
        "foreign_key": ""
    },
    {...},
    {...}
]
}