Connecting to BlenderLIVE

We will communicate with the BlenderLIVE service using the BlenderServiceManager class via the SceneManager class. So, jump into the SceneManager script, which you can quickly locate by entering SceneManager into the search field of the Project panel. Once it's visible, double-click it to open it in Visual Studio.  

Once opened, navigate to the Start method and make the following amendments: 

void Start ()
{
BlenderServiceManager.Instance.OnBlenderServiceStateChanged +=
BSM_OnBlenderServiceStateChanged;
BlenderServiceManager.Instance.OnBlenderGameObjectCreated +=
BSM_OnBlenderGameObjectCreated;
BlenderServiceManager.Instance.OnBlenderGameObjectUpdated +=
BSM_OnBlenderGameObjectUpdated;
BlenderServiceManager.Instance.OnBlenderGameObjectDestoryed +=
BSM_OnBlenderGameObjectDestoryed;

SceneStatus.Instance.SetText("Scanning room", 3.0f);
}

Because of the asynchronous nature of the service, we will be interacting with the BlenderServiceManager class via events. The following list briefly describes each event that we have subscribed before:

  •  BSM_OnBlenderServiceStateChanged is called when the state of the connection changes. We can use this to monitor when the service is discovered, connected, and disconnected. 
  • BSM_OnBlenderGameObjectCreated is called when a shared model is first created, BSM_OnBlenderGameObjectUpdated is called when the model is updated, and BSM_OnBlenderGameObjectDestoryed is called when unshared within Blender. 

The last statement, SceneStatus.Instance.SetText("Scanning room", 3.0f), is used to set our tag-along status label, which we are using to keep the user informed of the application's state. Let's now stub out those delegates to remove the errors. Add the following code to the SceneManager class: 

 private void BSM_OnBlenderGameObjectDestoryed(string name) { }

private void BSM_OnBlenderGameObjectCreated(BaseBlenderGameObject bgo)
{ }

private void BSM_OnBlenderGameObjectUpdated(BaseBlenderGameObject bgo)
{ }

private void
BSM_OnBlenderServiceStateChanged(BlenderServiceManager.ServiceStates
state) { }

We now have the methods the BlenderServiceManager will use to communicate with us. All we need to do now is ask it to start, but before we do just that, let's quickly review what starting this service will actually do.
As mentioned earlier, the BlenderServiceManager  interfaces between BlenderService and Unity. Its first task is to discover the service (if active on the local network). Discovery is achieved by listening to a UDP emitted by the BlenderLIVE service every once in a while. Once it is discovered, BlenderServiceManager will automatically connect by establishing a TCP connection and proceed to download any shared models. BlenderServiceManager also takes care of constructing the shared GameObjects and making the application aware via the event BSM_OnBlenderGameObjectCreated (when created). After this, it will be the responsibility of the application to place and display the model. But before starting the service, it makes sense that we have scanned enough of the room that there is sufficient surface to place the model onto when it has been downloaded. More importantly, when downloading with an accompanying WorldAnchor, it's important that the scanning has been sufficiently comprehensive such that the HoloLens has enough understanding of the environment to be able to recognize where the shared WorldAnchor belongs. But that's getting a little ahead of ourselves. More on this later.

As discussed in the previous chapters, WorldAnchor describes a physical position and rotation in the real world and how it relates to the position and rotation of the application's frame of reference. In Unity, attaching a WorldAnchor locks a GameObject's position to the physical space.

As we have done in the previous chapters, we will take the simplest approach and assume the user has sufficiently scanned the area after a certain time and, once this time has lapsed, we will ask BlenderServiceManager to discover and connect to the BlenderLIVE service. Head back to the top of the class and add the following variable to determine this time threshold:

    public float initialScanningTime = 10.0f; 

The most convenient place to monitor whether this time has elapsed is in the Update method, so head back down and make the following amendments:

void Update () 
{
if (BlenderServiceManager.Instance.ServiceState ==
BlenderServiceManager.ServiceStates.Stopped)

{
if (Time.time - SpatialMappingManager.Instance.StartTime >
initialScanningTime)

{
SceneStatus.Instance.SetText("Searching for BlenderLIVE Service");

BlenderServiceManager.Instance.SearchAndConnectToService();
}
}
}

Here, we are testing the state of BlenderServiceManager. If stopped and sufficient time has lapsed, we will call SearchAndConnectToService which, as the name suggests, listens out for the service and, once found, will establish a connection. 
As mentioned previously, BlenderServiceManager communicates via events. One such event notifies us of the state of the service. Let's fill this in; here, we will just pass those state changes to the user, keeping them informed of the state of the application. Scroll down to the method BSM_OnBlenderServiceStateChanged and make the following amendments:

private void BlenderServiceManager_OnBlenderServiceStateChanged(BlenderServiceManager.ServiceStates state)
{
switch (state)
{
case BlenderServiceManager.ServiceStates.Discovered:
SceneStatus.Instance.SetText("Found BlenderLIVE service", SHORT);
break;
case BlenderServiceManager.ServiceStates.Connecting:
SceneStatus.Instance.SetText("Connecting to BlenderLIVE service",
SHORT);
break;
case BlenderServiceManager.ServiceStates.Connected:
SceneStatus.Instance.SetText("Connected to BlenderLIVE service",
SHORT);
break;
case BlenderServiceManager.ServiceStates.Disconnected:
SceneStatus.Instance.SetText("Disconnected from BlenderLIVE
service", LONG);
break;
case BlenderServiceManager.ServiceStates.Failed:
SceneStatus.Instance.SetText("BlenderLIVE connection failednPlease
restart everything and try again.", LONG);
break;
}
}

Here, we are simply updating the status text with the current state of the service. Similarly, we want to notify the user when an object has been unshared; find the method BSM_OnBlenderGameObjectDestoryed and make the following amendments: 

 private void BlenderServiceManager_OnBlenderGameObjectDestoryed(string name)
{
SceneStatus.Instance.SetText(string.Format("{0} removed", name), MEDIUM);
}

The last two delegates remaining are concerned with when an object is created (first retrieved) and when the object is updated. When an object is created, we will pass it onto PlacementManager, whose responsibility it is to assist the user in placing the object and notified via the OnObjectPlaced event once the object has been placed. By contrast, when the object is updated, we will simply clear the status text.

Let's make those amendments to the BSM_OnBlenderGameObjectCreated and BSM_OnBlenderGameObjectUpdated methods: 

 private void BSM_OnBlenderGameObjectUpdated(BaseBlenderGameObject bgo)
{
SceneStatus.Instance.SetText("");
}
 private void BSM_OnBlenderGameObjectCreated(BaseBlenderGameObject bgo)
{
SceneStatus.Instance.SetText("Blender object ready for
placementnAir-tap on a suitable surface to place", MEDIUM);
PlacementManager.Instance.AddObjectForPlacement(bgo);
}

Our final task is to listen out for when the object has been placed; head back to the Start method and make the following amendment:

 ...
PlacementManager.Instance.OnObjectPlaced +=
PlacementManager_OnObjectPlaced;
SceneStatus.Instance.SetText("Scanning room", 3.0f);

And now add in the delegate method: 

 private void PlacementManager_OnObjectPlaced(BaseBlenderGameObject  
bgo)
{
SceneStatus.Instance.SetText("");
}

With that implemented, we can pull models from Blender into the real world. Now is a good time to build and deploy, testing whether everything is working before we continue.

Remember that you will need to have Blender and the BlenderLIVE service running with at least one object shared. See the preceding section for details. If you do run into trouble, check that you have opened the ports discussed earlier. 

The following image shows a live link between Blender and HoloLens: 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.44.23