New Features in 3D Wayfinder

January 15, 2016

With the end of 2015 and the beginning of this year there are many new features added to 3D Wayfinder. The goal of these changes was to add flexibility to customizing the behavior of the 3D map and wayfinding. Custom models for path, path types, POI options and many more.

In parallel with large customer projects, we have added many new features to 3D Wayfinder. Most of them were requested by our customers and we have added them as features/settings for all our users. Below are listed the most important ones.

Custom models for path visualizationcustom_path_models_wayfinding

It is now possible to choose your own custom models for path visualization. Path models can be different kind of arrows, footprints or simple tubes/lines. Changing path visualization models can be done under settings.

In near future we’ll add some sample path models also to our blog.

Path types and accessibility paths

It is now possible to add different kind of inaccessibility attributes to the path . This can be used for defining paths  that are also accessible with wheelchairs and/or baby strollers. This also enables defining other kinds of areas, like paths for service personnel etc.

Currently it has to be entered to the node attributes in json object format:

{

“inaccessibility”: [

 “wheelchair”

]

}

wheelchair_wayfinding_inaccessibility_Path_types_and_accessibility_paths

The nodes with these kind of restrictions cannot be used for path finding with “wheelchair” option. It is useful to set these restrictions for stairs or doors.

To use the inaccessibility in user interface, you have to change the accessibility option first:

this.wayfinder.accessibility = “wheelchair”;

Then it is possible to use the same show path method:

this.wayfinder.showPath(poi.node, poi);

And after showing path, just change the accessibility option back to blank:

this.wayfinder.accessibility = “”;

Also check out our blog post about how to set up time dependent navigation rules.

POI specific options

Advanced_POI_settings_specific_options

It is now possible to create special settings for each POI (location). These settings can be chosen from the list of all POI settings, like the size of the billboard image or billboard text size, highlight color, activation radius, billboard height etc.

This feature allows to customize the map by locations, for examples larger shops can have larger texts or text colors can be set by each shop. Also it makes easier to use logos or icons on the map, as the billboard images don’t have to be the same size anymore.

In the future it is possible to add new settings that can be used when developing your own template.

Top-down view for Path showing

path-top-down-view-for-path-showing

Now there is a simple option under settings to turn the map to top-down view when showing the path.

In general it is not a good idea to show the “You are here” location from top-down view, but rather  from certain angle (especially when it is possible with real 3D models as in 3D Wayfinder), which provides a better overview of the map and also makes the map look better.

Now when using the same angle, as displaying the “You are here” location, and visualizing the path, it may happen that the visualized path might not be visible. This is due to tall objects like walls that might block the view of the path. Using the top-down view during path visualization solves this problem.

Pause options between changing floors

According to valuable customer feedback, the transition of switching floors happens too quickly , which might be a bit confusing for the end-users. We solved this issue by adding the “pause-time” option to the settings. With this option it is possible to adjust the duration of the pause before switching to the next floor. The pause duration can be defined in seconds,  which makes it easiest to find  the proper delay that helps  all wayfinder users to understand, which floor they have to go to.

Kiosk view enhancements

In addition to being able to save the view angle, it is now possible to save the zoom factor for “kiosk view”. By clicking the “You are here” button, the map assumes the “kiosk view” saved in the editor.

In the future we will add this view option as a separate object so the view can be linked with any location or node.

« »

New Reflection Feature in Our 3D Engine

December 18, 2015

FRAK WebGL engine has now built in Cubemaps and reflection shader. This gives 3D Wayfinder access to use reflections of surrounding area.

We have added built in cubemaps and cubemap reflection shader to FRAK WebGL engine. In addition reflection with cubemaps is efficient way to create reflective surfaces like glass or mirrors.
Also cubemap reflection is a rendering method. It means that reflective surfaces reflect the cubemap textures.

Cubemaps_and_reflection_shader_frak_reflections_webGL

It will be available for 3D Wayfinder in near future. This will be the effective way to create large glass walls or buildings. It make them more realistic. It might be used also for expensive shopping mall floors.

Next feature in FRAK will be specular map to mark efficiently reflective areas.

Cubemap demo can be found under FRAK repository.

« »

3D Wayfinder is Sponsoring CG Architecture Challenge

October 29, 2015

CGTrader is organizing challenge called “CG Architecture Challenge”. More than 240 thousand 3D enthusiasts and designers have been invited to participate. 3D Wayfinder has set awards for each challenge subcategory. Award will be given for the best 3D CG model or visualization uploaded during the challenge period.

The challenge will take 3 months and there will be 3 individual winners in each architectural category. Categories are: Best Architectural Interior Model; Best Architectural Exterior Model; Best Architectural Details Model and Best Architectural portfolio. Read more from cgtrader.com. In addition winner in each category will get 3D Wayfinder Pro account for a year.

CGTrader is a 3D model marketplace for computer graphics and 3D printing. For example 3D artists and designers share and sell their models. Then they get valuable feedback, learn from peers, and interact in a designer-friendly environment.

Here are 2 winning works from last year challenge:

Best 3D Architectural Exterior model 2014
Best 3D Architectural Exterior model 2014.

1st Runner-up in Best 3D Architectural Exterior model 2014
1st Runner-up in Best 3D Architectural Exterior model 2014.

« »

Towards Rule-Base Wayfinding

September 25, 2015

Future in wayfinding includes definitely possibility to create complex rules for path finding. Now there are also node restrictions in 3D Wayfinder to specify working days etc.

One of the last addition to 3D Wayfinder was node weights for calculating optimal paths. This made possible to guide visitors in some recommended way. Now there is also possible to restrict some nodes based on time and day.node_restrictions_wayfinding_paths_by_date_and_time

In many public buildings, there are rules for locking doors, elevators or gates. There can be different areas open during working hours than weekends or night times. This is common for shopping malls, train stations, university campuses etc. Even large office buildings are keeping some doors open during the weekends as there might be service providers like dentists, children playrooms etc. When providing wayfinding to your visitors, it is important to follow the same rules.

With 3D Wayfinder, it is possible now to create path restrictions according to work-day and time. To create this kind of restrictions, just open node attributes under editor.
Under Node attributes in 3D Wayfinder Editor, there can be entered JSON. In future we will provide also special UI for that.

Here is the example that will allow to pass the navigation node from 10AM to wayfinding_paths_restriction_node_attributes9PM:

{
“allowedTimes”: [
[
10,
21
]
]
}

Adding other blocks, you can also specify by days.

We are currently developing also other rule types, like security or accessibility. These rules help to create adaptable and user-friendly way-finding applications which are useful and finally elementary for large buildings.

« »

3D Interactive Floor Plan Demo

September 8, 2015

Check out our new 3D Wayfinder platform demo. This will give you short overview of what you can do with 3D Wayfinder and what are our API capabilities.

The demo has following topics:

  1. Moving 3D map with mouse cursor or touch screen.
  2. Clicking on the map and getting location name and description.
  3. Changing floors of the building.
  4. Showing path between 2 locations.

Demo is accessible from the 3D wayfinder home page and can be opened also from this link:

[xyz-ihs snippet=”3D-demo”]

Demo is based on following javascript code. You are welcome to use it in your projects, your HTML should contain canvas with ID “map”. For more info please see 3D Wayfinder embedding tutorial.

var wayfinder;
var map;
var mapContainer;
var poiInfo;
var tutorialArea;
var currentStep = 0;
var STEPCOUNT = 3;
var originals = {};
var floors = {};

function mapResize(){
	if(wayfinder){
		cont = mapContainer.find(".map-area");
		map.attr("width", cont.css("width"));
		map.attr("height", cont.css("height"));
		wayfinder.resize();
	}
}

function runDemo(){
	map = $('#map');
	poiInfo = mapContainer.find("#poiInfo");
	tutorialArea = mapContainer.find(".tutorial-box");
	wayfinder = new Wayfinder3D();
	wayfinder.options.assetsLocation = '//static.3dwayfinder.com/shared/';
	wayfinder.open("1a07bdc53edb3828f390bc9af7281585");
	setTimeout(mapResize, 150);

	wayfinder.cbOnProgress = function(percentage){
		$("#progression").css('width', percentage * 100+'%');
	};

	wayfinder.cbOnDataLoaded = function(){
	    mapContainer.find(".loading-screen").hide(100);
	};

	wayfinder.cbOnMapReady = function(){
		removeAllFunctionality();
		setText(0);
		stepTutorialButtons(0);
	};
}

function stepTutorialButtons(step) {
	var prev = tutorialArea.find(".tutorial-prev");
	var next = tutorialArea.find(".tutorial-next");

	if (prev.text() && step === 0)
		prev.text("").off("click").css("cursor", "auto");
	else if (!(prev.text()) && step !== 0)
		prev.text("<").click(previousStep).css("cursor", "pointer");

	if (next.text() && step === STEPCOUNT)
		next.text("").off("click").css("cursor", "auto");
	else if (!(next.text()) && step !== STEPCOUNT)
		next.text(">").click(nextStep).css("cursor", "pointer");
}

function removeAllFunctionality() {
	if (wayfinder) {
		if (wayfinder.poiController) {
			originals.onPOIClick = wayfinder.poiController.onPOIClick;
			wayfinder.poiController.onPOIClick = function(poi, position, event) {};
		}
		originals.cbOnPOIClick = wayfinder.cbOnPOIClick;
		wayfinder.cbOnPOIClick = function(poi) {};
	}
}

function setText(step) {
	var keep = tutorialArea.find(".tutorial-text").find(".keep");
	if (keep.length)
		keep = keep.detach();
	switch (step) {
		case 0:
			tutorialArea.find(".tutorial-text").text("Click and drag on the map to move or rotate.");
			break;

		case 1:
			tutorialArea.find(".tutorial-text").text("Click on a location for more info.");
			break;

		case 2:
			tutorialArea.find(".tutorial-text").text("Click on a button to show that floor.");
			break;

		case 3:
			tutorialArea.find(".tutorial-text").text("Click on the button to show the path between two random locations.");
			break;

		default:
			break;
	}
	if (keep.length)
		tutorialArea.find(".tutorial-text").append(keep);
	stepTutorialButtons(step);
}

function addFunctionality(step) {
	switch (step) {
		case 1:
			if (wayfinder && wayfinder.poiController) {
				wayfinder.poiController.onPOIClick = originals.onPOIClick;
				wayfinder.cbOnPOIClick = function(poi) {
					poiInfo.show(100);
					poiInfo.find(".title").text(poi.getName("en"));
					var poiDescription = poi.getDescription("en");
					if (poiDescription)
						poiInfo.find(".description").text(poi.getDescription("en"));
					else
						poiInfo.find(".description").text("");
				};
			}
			break;

		case 2:
			poiInfo.hide(100);
			poiInfo.find(".title").text("");
			poiInfo.find(".description").text("");

			if (wayfinder) {
				var showFloor = function() {
					var f = $(this).attr("data-floor");
					if (f in floors)
						wayfinder.showFloor(floors[f]);
				};
				var fs = wayfinder.building.getFloors();
				tutorialArea.find(".tutorial-text").html("<div class='keep'></div>");
				var floorsMenu = tutorialArea.find(".tutorial-text").find(".keep");
				for (var i in fs) {
					if (fs[i] && fs[i].showInMenu) {
						floors[i] = fs[i];
						var button = $("<button data-floor='"+i+"'>"+fs[i].getName("en")+"</button>").click(showFloor);
						floorsMenu.append(button);
					}
				}
			}
			break;

		case 3:
			if (wayfinder && wayfinder.logic) {
				var randomPath = function(times) {
					if (typeof times !== 'number')
						times = 1;
					if (times > 9)
						return;
					var poiList = wayfinder.pois;
					var poiIDs = [];
					for (var i in poiList) {
						poiIDs.push(i);
					}
					var rand1, rand2;
					while (!rand1 || !(poiList[rand1].getNode())) {
						rand1 = rand2 = poiIDs[Math.floor(Math.random() * poiIDs.length)];
					}
					while (rand2 == rand1 || !(poiList[rand2].getNode())) {
						rand2 = poiIDs[Math.floor(Math.random() * poiIDs.length)];
					}
					rand1 = poiList[rand1].getNode();
					rand2 = poiList[rand2].getNode();
					try {
						wayfinder.logic.showPath(rand1.id, rand2.id);
					}
					catch (e) {
						// Try again
						randomPath(times + 1);
					}
				};
				tutorialArea.find(".tutorial-text").html("<div class='keep'></div>");
				var area = tutorialArea.find(".tutorial-text").find(".keep");
				var pathButton = $("<button>Show random path</button>").click(randomPath);
				area.append(pathButton);
			}
			break;

		default:
			break;
	}
}

function removeFunctionality(step) {
	switch (step) {
		case 1:
			if (wayfinder && wayfinder.poiController) {
				wayfinder.poiController.clearHighlights();
				poiInfo.hide(100);
				poiInfo.find(".title").text("");
				poiInfo.find(".description").text("");
				wayfinder.poiController.onPOIClick = function(poi, position, event) {};
				wayfinder.cbOnPOIClick = function(poi) {};
			}
			break;

		case 2:
			tutorialArea.find(".tutorial-text").find(".keep").remove();
			break;

		case 3:
			addFunctionality(2);
			break;

		default:
			break;
	}
}

function previousStep() {
	if (currentStep === 0)
		return;
	removeFunctionality(currentStep);
	currentStep--;
	setText(currentStep);
}

function nextStep() {
	if (currentStep === STEPCOUNT)
		return;
	currentStep++;
	addFunctionality(currentStep);
	setText(currentStep);
}

$(function(){
	mapContainer = $("#demoMap");
	$(".home-video").click(function () {
		mapContainer.show(100);

		if(!wayfinder)
			runDemo();
		else
			wayfinder.engine.run();

		$(window).resize(mapResize);
	});
});

« »

WebGL Broken in Android 5.1.1 (updates)

August 27, 2015

We have made some additional testing for Android Lollipop 5.1.1 WebGL problems. 

Android Lollipop 5.1.1 (right now available for Google Nexus devices) has problems with WebGL (see our previous post about Android WebGL problems). Following extensions are not working properly:

  • OES_vertex_array_object
  • OES_texture_float
  • OES_texture_half_float

First one gives GL errrors to random GL call. The other ones fail silently.

Hoping to get the fixes from Android soon.

 

 

« »

Node Weights in Path Calculation

August 21, 2015

We have updated path finding functionality and path calculation. Now it is possible to change the weights of navigation nodes in 3D Wayfinder floor plan editor.

Path-finding application calculates automatically the shortest route from the starting node to the required location. In mobile applications, the Kiosk node can be your position inside the building. With 3D Wayfinder, the shortest route is calculated in a 3 dimensional room. It means the shortest path through all the floors.

Now it is possible to change the weights of the connection nodes. With this wayfinding application calculates optimal route, which doesn’t have to be the shortest. For example when you would like to guide your visitors to use the path inside the building instead of going around the building. Then you can set the weight for outdoor nodes higher. The weight is basically virtual length that will be added to the route, when passing the navigation node with a weight.

path_finding_functionality_in_3D_WayfinderTo use the weights you have to select the navigation node in 3D Wayfinder floor plan editor and change the node weight from the text box. By default all the weights are 0.

For example lets, say that waiting for the elevator takes usually 3 minutes. Lets assume, that visitors are moving with a speed of 3 km per hour, which is 50 meters per minute. So with waiting the elevator, visitor can pass 150 meters (3*50). If we would like to take account this in path calculation. Then we can add weight of 150 to the navigation node, that is marked as elevator.

Pathfinding functionality comes bundled in an add-on you can order from 3D Wayfinder Administration panel. It is also included in the Pro plan.

Read more about 3D Wayfinder’s path-finding capabilities.

« »