Project wide functionalities - HU-ICT-LAB/WebVR-Demo GitHub Wiki

Global Functionalities

In the project we also have some functionalities which each game can use. These functionalities can be found in the top level scripts folder. On this page we will describe these functionalities.

Deployment

To run our project there are two things you need:

  • active internet connection on the headset and pc
  • connection to local area network on the headset and pc
  • python

step 1: Clone our project to your computer using git

step 2: Find the local ip adress of your computer

step 3: run python server.py from the main directory

step 4: Navigate to https://<<local ip>>:8000/ on your vr headset

step 5: Enjoy

Deployment diagram

DeploymentDiagram

Camera Rig

In VR we are not allowed to move the camera entity around. As this entity is controlled by the headset it does not allow you to control it with code. to solve this problem we use an camera rig. A camera rig is an entity that encapsulates the headset and controllers. We can then programmatically change the position of the camera rig. As the camera and controllers move relative to the rig, they will also move thru the world if we move the rig.

Using a camera rig also makes it easier to write components that use the headset and controllers. You can attach the component to the camera rig to have control over the rig, controllers and headset.

MQTT

To enable communication between multiple devices we make use of the MQTT protocol. The MQTT protocol is a lightweight communication protocol based on TCP but can be implemented on many forms of data transportation.
Our MQTT client is based on 2 JavaScript files:

  • scripts/browserMqtt.js
  • scripts/mqtt_client.js

browserMqtt.js is the library that allows us to create websocket MQTT connections. browserMqtt.js is a browserified version of the MQTT library that can be used by NODE.js. In mqtt_client.js we initialize our MQTT client and connect to the MQTT broker. This file also defines some functions that add some helpful abilities to the client. The client connects with the following MQTT broker:

host: wss://broker.emqx.io
port: 8084
This is a public broker from emqx that can be freely used without subscriptions. But they advise to not use it for applications in production.

For the user the following methods are available:
Client.subscribe(<<topic>>)
This function allows the user to subscribe to a specified topic wich will notify the broker that the user wants to receive messages send to that topic
Client.publish(<<topic>>, <<message>>)
This function allows the user to publish messages to a specified topic.
mqtt_add_topic_callback(<<topic>>, callback(<<topic>>, <<message>>)
This function allows the user to add a callback function to a topic. If a message is received all callbacks linked to this topic will be executed.

The MQTT client uses a TLS connection because browsers do not allow to connect to a non-secure connection over a HTTPS connection. This is also why we use a public broker. It is possible to create a local broker that uses SSL/TLS. But it makes use of self-signed certificates and some browsers do not accept TLS/SSL WebSocket connections to servers that use self-signed certificates.

Player Clone

For a nice visualization of the player in the game we created a digital clone. The clone is made out of two parts. A logger and a visualizer. The logger is a component in A-Frame that can be attached to the camera rig. It will then send the positions and rotations of the headset and controllers over MQTT to the hbo_ict_vr_game_player_stats topic.

These values are recieved by the visualiser. The visualiser is a simple A-Frame scene with 3 cubes. 2 cubes represent the controllers and one cube represents the headset. These cubes move in the scene just like the player moves in real life, the controllers and headset match the positions and rotations of the cubes.

Physics

The way we implement physics is through the library aframe-physics-system, this library uses a JavaScript called Ammo Driver. This driver makes it easy to assign physics to scenes, objects and the player itself. Every object is required to have an ammo-body, this means that the object gets assigned to a certain category, here are the 3 ammo-body types:

  • Static: A fixed-position object. Other bodies may collide with static bodies, but static bodies themselves are unaffected by gravity and collisions. These bodies should typically not be moved after initialization as they cannot impart forces on dynamic bodies.
  • Dynamic: A freely-moving object. Dynamic bodies have mass, collide with other bodies, bounce or slow during collisions, and fall if gravity is enabled.
  • Kinematic: Like a static body, except that they can be moved via updating the position of the entity. Unlike a static body, they impart forces on dynamic bodies when moved. Useful for animated or remote (networked) objects.

The second thing to do is to assign the object to a certain shape, this will become the colliding hitbox for the given object. There are 5 different primitive ammo-shapes:

  • Box
  • Cylinder
  • Sphere
  • Capsule
  • Cone

We currently don't need any other shapes for hitboxes, but there are ways to make a perfect hitbox for 3D models in the Ammo driver such as the shape "hull". As long as both the shape and body type are assigned to an object, the gravity will be automated to the object by including the script in the scene. The player itself needs an ammo-body type and ammo-shape. We use the cylinder shape to produce collision with other objects, this shape made the most sense on our eyes. Here is an example of how to use the Ammo driver.

⚠️ **GitHub.com Fallback** ⚠️