Correct language:
How do I use your Combine Image Recognition and POIs example to modify it to Auto Reloading POI Data? Can I add a POI title to jump out of the transparent video? I cannot change it when I try to change it.
Hope for help, thank you!
Hi,
Please have a look at the following sample - Demos > 2D Tracking and Geo. This shows a sample on how to use 2D Image Recognition and Geo AR in one experience. I'm not sure I understand the requirement 'POI title to jump our of the transparent video' - can you please provide further details on this one. If you refer to displaying a transparent video on a specific location then this is possible - we provide a sample which displays a 3D model at a location (sample section 3D models > 3D model at Geo Location).
Greetings
Nicola
That's right, I just want to display a transparent video at a specific location.
However, I follow the 3D model paradigm that you provided,Can't change to transparent video?
What is the problem?
This is a program that I have modified so I can't run video effects:
var World = { loaded: false, rotating: false, init: function initFn() { this.createModelAtLocation(); }, createModelAtLocation: function createModelAtLocationFn() { /* First a location where the model should be displayed will be defined. This location will be relativ to the user. */ var location = new AR.GeoLocation(47.805634, 13.045209); var altitude = location.altitude; /* Next the model object is loaded. */ var video = new AR.VideoDrawable("assets/transparentVideo.mp4", 0.7, { translate: { x: -0.2, y: -0.12 }, isTransparent: true }); var indicatorImage = new AR.ImageResource("assets/indi.png"); var indicatorDrawable = new AR.ImageDrawable(indicatorImage, 0.1, { verticalAnchor: AR.CONST.VERTICAL_ANCHOR.TOP }); video.play(-1); video.pause(); /* Putting it all together the location and 3D model is added to an AR.GeoObject. */ var obj = new AR.GeoObject(location, { drawables: { cam: [video], indicator: [indicatorDrawable] } }); }, worldLoaded: function worldLoadedFn() { World.loaded = true; var e = document.getElementById('loadingMessage'); e.parentElement.removeChild(e); } }; /* Set a custom function where location changes are forwarded to. There is also a possibility to set AR.context.onLocationChanged to null. In this case the function will not be called anymore and no further location updates will be received. */ AR.context.onLocationChanged = World.locationChanged; World.init();
There is also a POI. After pressing the totem tag, it will jump out of the transparent video. Can this be done?
Please note that the location you're using above is Salzburg - so it might very well be that you don't see the video, as it's too far away.
As a starting point I also recommend to have detailed look at the transparent video sample to see how the video handling is working and then combine the this with the 3D model at Geolocation.
You can also recact on the 'POI marker click' and display the video then -> we don't have special sample for this functionality though.
Greetings
Nicola
I adjusted the location of the area.
Still the same did not appear!
I also tried various possibilities.
I continue to try it!
Thank you
// information about server communication. This sample webservice is provided by Wikitude and returns random dummy places near given location var ServerInformation = { POIDATA_SERVER: "http://120.101.58.70/storeblog/content-data.js", POIDATA_SERVER_ARG_LAT: "lat", POIDATA_SERVER_ARG_LON: "lon", POIDATA_SERVER_ARG_NR_POIS: "nrPois" }; // implementation of AR-Experience (aka "World") var World = { // user's latest known location, accessible via userLocation.latitude, userLocation.longitude, userLocation.altitude userLocation: null, // you may request new data from server periodically, however: in this sample data is only requested once isRequestingData: false, // true once data was fetched initiallyLoadedData: false, // different POI-Marker assets markerDrawable_idle: null, markerDrawable_selected: null, markerDrawable_directionIndicator: null, // list of AR.GeoObjects that are currently shown in the scene / World markerList: [], // The last selected marker currentMarker: null, locationUpdateCounter: 0, updatePlacemarkDistancesEveryXLocationUpdates: 10, // called to inject new POI data loadPoisFromJsonData: function loadPoisFromJsonDataFn(poiData) { // destroys all existing AR-Objects (markers & radar) AR.context.destroyAll(); // show radar & set click-listener PoiRadar.show(); $('#radarContainer').unbind('click'); $("#radarContainer").click(PoiRadar.clickedRadar); // empty list of visible markers World.markerList = []; // start loading marker assets World.markerDrawable_idle = new AR.ImageResource("assets/marker_idle.png"); World.markerDrawable_selected = new AR.ImageResource("assets/marker_selected.png"); World.markerDrawable_directionIndicator = new AR.ImageResource("assets/indi.png"); // loop through POI-information and create an AR.GeoObject (=Marker) per POI for (var currentPlaceNr = 0; currentPlaceNr < poiData.length; currentPlaceNr++) { var singlePoi = { "id": poiData[currentPlaceNr].id, "latitude": parseFloat(poiData[currentPlaceNr].latitude), "longitude": parseFloat(poiData[currentPlaceNr].longitude), "altitude": parseFloat(poiData[currentPlaceNr].altitude), "title": poiData[currentPlaceNr].name, "description": poiData[currentPlaceNr].description, "website": poiData[currentPlaceNr].website, }; World.markerList.push(new Marker(singlePoi)); } // updates distance information of all placemarks World.updateDistanceToUserValues(); World.updateStatusMessage(currentPlaceNr + ' places loaded'); // set distance slider to 100% $("#panel-distance-range").val(100); $("#panel-distance-range").slider("refresh"); }, // sets/updates distances of all makers so they are available way faster than calling (time-consuming) distanceToUser() method all the time updateDistanceToUserValues: function updateDistanceToUserValuesFn() { for (var i = 0; i < World.markerList.length; i++) { World.markerList[i].distanceToUser = World.markerList[i].markerObject.locations[0].distanceToUser(); } }, // updates status message shown in small "i"-button aligned bottom center updateStatusMessage: function updateStatusMessageFn(message, isWarning) { var themeToUse = isWarning ? "e" : "c"; var iconToUse = isWarning ? "alert" : "info"; $("#status-message").html(message); $("#popupInfoButton").buttonMarkup({ theme: themeToUse }); $("#popupInfoButton").buttonMarkup({ icon: iconToUse }); }, /* It may make sense to display POI details in your native style. In this sample a very simple native screen opens when user presses the 'More' button in HTML. This demoes the interaction between JavaScript and native code. */ // user clicked "More" button in POI-detail panel -> fire event to open native screen onPoiDetailMoreButtonClicked: function onPoiDetailMoreButtonClickedFn() { var currentMarker = World.currentMarker; var markerSelectedJSON = { action: "present_poi_details", id: currentMarker.poiData.id, title: currentMarker.poiData.title, description: currentMarker.poiData.description, website: currentMarker.poiData.website }; /* The sendJSONObject method can be used to send data from javascript to the native code. */ AR.platform.sendJSONObject(markerSelectedJSON); }, // location updates, fired every time you call architectView.setLocation() in native environment locationChanged: function locationChangedFn(lat, lon, alt, acc) { // store user's current location in World.userLocation, so you always know where user is World.userLocation = { 'latitude': lat, 'longitude': lon, 'altitude': alt, 'accuracy': acc }; // request data if not already present if (!World.initiallyLoadedData) { World.requestDataFromServer(lat, lon); World.initiallyLoadedData = true; } else if (World.locationUpdateCounter === 0) { // update placemark distance information frequently, you max also update distances only every 10m with some more effort World.updateDistanceToUserValues(); } // helper used to update placemark information every now and then (e.g. every 10 location upadtes fired) World.locationUpdateCounter = (++World.locationUpdateCounter % World.updatePlacemarkDistancesEveryXLocationUpdates); }, // fired when user pressed maker in cam onMarkerSelected: function onMarkerSelectedFn(marker) { World.currentMarker = marker; // update panel values $("#poi-detail-title").html(marker.poiData.title); $("#poi-detail-description").html(marker.poiData.description); $("#poi-detail-website").html(marker.poiData.website); /* It's ok for AR.Location subclass objects to return a distance of `undefined`. In case such a distance was calculated when all distances were queried in `updateDistanceToUserValues`, we recalcualte this specific distance before we update the UI. */ if( undefined == marker.distanceToUser ) { marker.distanceToUser = marker.markerObject.locations[0].distanceToUser(); } var distanceToUserValue = (marker.distanceToUser > 999) ? ((marker.distanceToUser / 1000).toFixed(2) + " km") : (Math.round(marker.distanceToUser) + " m"); $("#poi-detail-distance").html(distanceToUserValue); // show panel $("#panel-poidetail").panel("open", 123); $(".ui-panel-dismiss").unbind("mousedown"); $("#panel-poidetail").on("panelbeforeclose", function(event, ui) { World.currentMarker.setDeselected(World.currentMarker); }); }, // screen was clicked but no geo-object was hit onScreenClick: function onScreenClickFn() { // you may handle clicks on empty AR space too }, // returns distance in meters of placemark with maxdistance * 1.1 getMaxDistance: function getMaxDistanceFn() { // sort places by distance so the first entry is the one with the maximum distance World.markerList.sort(World.sortByDistanceSortingDescending); // use distanceToUser to get max-distance var maxDistanceMeters = World.markerList[0].distanceToUser; // return maximum distance times some factor >1.0 so ther is some room left and small movements of user don't cause places far away to disappear return maxDistanceMeters * 1.1; }, // udpates values show in "range panel" updateRangeValues: function updateRangeValuesFn() { // get current slider value (0..100); var slider_value = $("#panel-distance-range").val(); // max range relative to the maximum distance of all visible places var maxRangeMeters = Math.round(World.getMaxDistance() * (slider_value / 100)); // range in meters including metric m/km var maxRangeValue = (maxRangeMeters > 999) ? ((maxRangeMeters / 1000).toFixed(2) + " km") : (Math.round(maxRangeMeters) + " m"); // number of places within max-range var placesInRange = World.getNumberOfVisiblePlacesInRange(maxRangeMeters); // update UI labels accordingly $("#panel-distance-value").html(maxRangeValue); $("#panel-distance-places").html((placesInRange != 1) ? (placesInRange + " Places") : (placesInRange + " Place")); // update culling distance, so only places within given range are rendered AR.context.scene.cullingDistance = Math.max(maxRangeMeters, 1); // update radar's maxDistance so radius of radar is updated too PoiRadar.setMaxDistance(Math.max(maxRangeMeters, 1)); }, // returns number of places with same or lower distance than given range getNumberOfVisiblePlacesInRange: function getNumberOfVisiblePlacesInRangeFn(maxRangeMeters) { // sort markers by distance World.markerList.sort(World.sortByDistanceSorting); // loop through list and stop once a placemark is out of range ( -> very basic implementation ) for (var i = 0; i < World.markerList.length; i++) { if (World.markerList[i].distanceToUser > maxRangeMeters) { return i; } }; // in case no placemark is out of range -> all are visible return World.markerList.length; }, handlePanelMovements: function handlePanelMovementsFn() { $("#panel-distance").on("panelclose", function(event, ui) { $("#radarContainer").addClass("radarContainer_left"); $("#radarContainer").removeClass("radarContainer_right"); PoiRadar.updatePosition(); }); $("#panel-distance").on("panelopen", function(event, ui) { $("#radarContainer").removeClass("radarContainer_left"); $("#radarContainer").addClass("radarContainer_right"); PoiRadar.updatePosition(); }); }, // display range slider showRange: function showRangeFn() { if (World.markerList.length > 0) { // update labels on every range movement $('#panel-distance-range').change(function() { World.updateRangeValues(); }); World.updateRangeValues(); World.handlePanelMovements(); // open panel $("#panel-distance").trigger("updatelayout"); $("#panel-distance").panel("open", 1234); } else { // no places are visible, because the are not loaded yet World.updateStatusMessage('No places available yet', true); } }, // reload places from content source reloadPlaces: function reloadPlacesFn() { if (!World.isRequestingData) { if (World.userLocation) { World.requestDataFromServer(World.userLocation.latitude, World.userLocation.longitude); } else { World.updateStatusMessage('Unknown user-location.', true); } } else { World.updateStatusMessage('Already requesing places...', true); } }, // request POI data requestDataFromServer: function requestDataFromServerFn(lat, lon) { // set helper var to avoid requesting places while loading World.isRequestingData = true; World.updateStatusMessage('Requesting places from web-service'); // server-url to JSON content provider var serverUrl = ServerInformation.POIDATA_SERVER + "?" + ServerInformation.POIDATA_SERVER_ARG_LAT + "=" + lat + "&" + ServerInformation.POIDATA_SERVER_ARG_LON + "=" + lon + "&" + ServerInformation.POIDATA_SERVER_ARG_NR_POIS + "=20"; var jqxhr = $.getJSON(serverUrl, function(data) { World.loadPoisFromJsonData(data); }) .error(function(err) { /* In certain circumstances your web service may not be available or other connection issues can occur. To notify the user about connection problems a status message is updated. In your own implementation you may e.g. use an info popup or similar. */ World.updateStatusMessage("Invalid web-service response.", true); World.isRequestingData = false; }) .complete(function() { World.isRequestingData = false; }); }, // helper to sort places by distance sortByDistanceSorting: function(a, b) { return a.distanceToUser - b.distanceToUser; }, // helper to sort places by distance, descending sortByDistanceSortingDescending: function(a, b) { return b.distanceToUser - a.distanceToUser; }, loaded: false, init: function initFn() { this.createOverlays(); }, createOverlays: function createOverlaysFn() { /* Initialize ClientTracker */ this.targetCollectionResource = new AR.TargetCollectionResource("assets/magazine.wtc", { onError: function(errorMessage) { alert(errorMessage); } }); this.tracker = new AR.ImageTracker(this.targetCollectionResource, { onTargetsLoaded: this.worldLoaded, onError: function(errorMessage) { alert(errorMessage); } }); var video = new AR.VideoDrawable("assets/transparentVideo.mp4", 0.7, { translate: { x: -0.2, y: -0.12 }, isTransparent: true }); this.imgButton = new AR.ImageResource("assets/wwwButton.jpg"); var pageOneButton = this.createWwwButton("https://www.blue-tomato.com/en-US/products/?q=sup", 0.1, { translate: { x: -0.05, y: 0.2 }, zOrder: 1 }); video.play(-1); video.pause(); var pageOne = new AR.ImageTrackable(this.tracker, "*", { drawables: { cam: [video, pageOneButton] }, onImageRecognized: function onImageRecognizedFn() { video.resume(); World.removeLoadingBar(); }, onImageLost: function onImageLostFn() { video.pause(); }, onError: function(errorMessage) { alert(errorMessage); } }); }, createWwwButton: function createWwwButtonFn(url, size, options) { options.onClick = function() { // this call opens a url in a browser window AR.context.openInBrowser(url); }; return new AR.ImageDrawable(this.imgButton, size, options); }, removeLoadingBar: function() { if (!World.loaded) { var e = document.getElementById('loadingMessage'); e.parentElement.removeChild(e); World.loaded = true; } }, worldLoaded: function worldLoadedFn() { var cssDivInstructions = " style='display: table-cell;vertical-align: middle; text-align: right; width: 50%; padding-right: 15px;'"; var cssDivSurfer = " style='display: table-cell;vertical-align: middle; text-align: left; padding-right: 15px; width: 38px'"; var cssDivBiker = " style='display: table-cell;vertical-align: middle; text-align: left; padding-right: 15px;'"; document.getElementById('loadingMessage').innerHTML = "<div" + cssDivInstructions + ">Scan Target #1 (surfer) or #2 (biker):</div>" + "<div" + cssDivSurfer + "><img src='assets/surfer.png'></img></div>" + "<div" + cssDivBiker + "><img src='assets/bike.png'></img></div>"; } }; /* forward locationChanges to custom function */ AR.context.onLocationChanged = World.locationChanged; /* forward clicks in empty area to World */ AR.context.onScreenClick = World.onScreenClick; World.init();
I would like to ask I have successfully combined Overlay Videos with alpha channel and POI, but video will only appear at the beginning of loading, but can not be combined with POI. Where can I make a mistake?
Hi,
Please send your complete AR experience (.html, .js, .css files, assets, etc.) this experience needs to run independently from your app, so we can test. Please also note that we can't implement the experience for you and can only provide guidelines. This is why I would also like you to check if the transparent video sample is working as expected with your video - if this works, concentrate on the 3D at Geo location sample and make sure you understand all concepts.
Thx and greetings
Nicola
This is my program file.
sorry to bother you
sudo fgu
如何使用組合圖像識別和POI示例將其修改為自動重新加載POI數據?我可以添加POI標題跳出透明視頻嗎?當我嘗試改變它時,我無法改變它。
希望有所幫助,謝謝!