ARCORE: remove a specific renderable by clicking on this renderable - arcore

I'm working on a project using Sceneform from ARCore. I develop it base on HelloSceneform example provided by ARCore.
What I wanna do is adding a renderable object by a hit and then delete it when I click on the specific renderable on the screen.
I've tried method AnchorNode.setOnTapListener as following, but it didn't work(no response):
anchorNode.setOnTapListener(new Node.OnTapListener() {
#Override
public void onTap(HitTestResult hitTestResult, MotionEvent motionEvent) {
if(anchorNode.getAnchor()!=null){
arFragment.getArSceneView().getScene().removeChild(anchorNode);
anchorNode.getAnchor().detach();
anchorNode.setParent(null);
}
}
});
I also tried the following method, which causes unexpected close:
Scene scene = arFragment.getArSceneView().getScene();
scene.addOnPeekTouchListener(new Scene.OnPeekTouchListener() {
#Override
public void onPeekTouch(HitTestResult hitTestResult, MotionEvent motionEvent) {
Node node = hitTestResult.getNode();
node.setParent(null);
}
});
Is there any method could achieve this feature?

The code below should detect the touch and delete the node.
If you want to have a separate button to delete a selected node you can add a regular button and listener and just use the 'touch' event to select the node you want to delete.
private void handleOnTouch(HitTestResult hitTestResult, MotionEvent motionEvent) {
Log.d(TAG,"handleOnTouch");
// First call ArFragment's listener to handle TransformableNodes.
arFragment.onPeekTouch(hitTestResult, motionEvent);
//We are only interested in the ACTION_UP events - anything else just return
if (motionEvent.getAction() != MotionEvent.ACTION_UP) {
return;
}
// Check for touching a Sceneform node
if (hitTestResult.getNode() != null) {
Log.d(TAG,"handleOnTouch hitTestResult.getNode() != null");
Node hitNode = hitTestResult.getNode();
if (hitNode.getRenderable() == andyRenderable) {
Toast.makeText(LineViewMainActivity.this, "We've hit Andy!!", Toast.LENGTH_SHORT).show();
arFragment.getArSceneView().getScene().removeChild(hitNode);
AnchorNode hitNodeAnchor = (AnchorNode) hitNode;
if (hitNodeAnchor != null) {
hitNode.getAnchor().detach();
}
hitNode.setParent(null);
hitNode = null;
}
}
}
The above is extracted from various parts of a VR test application and combined here for a concise example - the full working application source is available here: https://github.com/mickod/LineView
Update - Kotlin version (tested April 2020):
private fun removeAnchorNode(nodeToRemove: AnchorNode) {
//Remove an Anchor node
arFragment.getArSceneView().getScene().removeChild(nodeToRemove);
nodeToRemove.getAnchor()?.detach();
nodeToRemove.setParent(null);
nodeToRemove.renderable = null
}

I know i am late but it may be helpful for someone.
Node you want to remove, first of you have to select that Transferable node by click or touch that node.
TransfarableNode.setOnTapListener this bulit in method serve purpose for us.
After that get node from HitTestResult and than detach node.
Here is the code you can use for selecting and removing node.
transformableNode.setParent(anchorNode );
transformableNode.setRenderable(model_nodeRenderable);
transformableNode.select();
transformableNode.setOnTapListener((HitTestResult hitTestResult, MotionEvent Event) ->
{
Node nodeToRemove = hitTestResult.getNode();
anchorNode.removeChild(nodeToRemove );
});

Related

How to add a marker in a map? i using SupportMapFragment

This is my code,
I am trying to add a bookmark to google maps, and also to initialize the map in a specific place, but I can not understand how SupporMapFragment works, if someone could help me explaining how to do it, thanks
internal class DetailMapFragment : BaseFragment , IOnMapReadyCallback
{
private GoogleMap GoogleMap;
private SupportMapFragment _mapFragment;
public override int LayoutId => Resource.Layout.map_page;
protected override void InitViews()
{
//var mapView = mView.FindViewById<MapView>(Resource.Id.mapView);
//mapView.GetMapAsync(this);
try
{
_mapFragment = Activity.SupportFragmentManager.FindFragmentByTag("map") as SupportMapFragment;
if (_mapFragment == null)
{
GoogleMapOptions mapOptions = new GoogleMapOptions()
.InvokeMapType(GoogleMap.MapTypeNormal)
.InvokeZoomControlsEnabled(false)
.InvokeMaxZoomPreference(20)
.InvokeCompassEnabled(true);
FragmentTransaction fragTx = FragmentManager.BeginTransaction();
_mapFragment = SupportMapFragment.NewInstance(mapOptions);
fragTx.Add(Resource.Id.mapView, _mapFragment, "map");
fragTx.Commit();
LatLng latlong = new LatLng(40.776408,-73.970755);
MarkerOptions mark = new MarkerOptions()
.SetPosition(latlong)
.SetTitle("New York")
.SetSnippet("Apple");
_mapFragment.AddMarker(mark);
}
_mapFragment.GetMapAsync(this);
}
catch (System.Exception ex)
{
ex.Message.ToString();
}
public void OnMapReady(GoogleMap googleMap)
{
//this.GoogleMap = googleMap;
}
void IOnMapReadyCallback.OnMapReady(GoogleMap googleMap)
{
//try
//{
// this.GoogleMap = googleMap;
// if (googleMap != null)
// {
// googleMap.AnimateCamera(CameraUpdateFactory.NewLatLng(new LatLng(-11.083271, -76.207374)));
// }
//}
//catch (System.Exception ex)
//{
// ex.Message.ToString();
//}
}
}
i new in xamarin android, i cant achieved understand how add de marker to map
Its very easy actually all you have to do is the following:
In your variable of type, Google maps in your case this private GoogleMap GoogleMap;you need to add the markers
Now adding markers can be tricky as you need to add them not when your google map object is null and this object gets its value runtime, so you need to be sure that it's not null because if it is then your app will crash for sure
(If not handled).
What i do for this case is always null check before adding a marker, and since it is bitmap(Which is the main reason for a thousand types of memory leaks in Android usually),On destroy of my map fragment i call the garbage collector and i clear my google maps object by calling GoogleMap.Clear(); whenever i leave the maps page.
Coming to the point the code for adding markers is as follows:
LatLng latlngall = new LatLng(double.Parse(point.Latitude), double.Parse(point.Loungitude));
MarkerOptions options = new MarkerOptions().SetPosition(latlngall).SetTitle(point.Landmark);
options.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.marker));
Marker marker = GMap.AddMarker(options);
marker.Tag = point.Id.ToString();
Here you need latitude, longitude and a title for your marker, also if you want to provide your custom marker then you can put it in place of the Drawable.marker also lat and long are mandatory here.
In case you have any other problems revert here.
Goodluck!
Happy coding

Vaadin Grid ItemClickListener fails to register clicks on column with ImageRenderer

I have the following code which is supposed to show a clickable icon which opens a popup dialog reading out a lengthy note.
this.capacityCommentColumn = this.facilityGrid.addColumn(
p -> {
if (Strings.isNullOrEmpty(p.getCapacityComment())) {
return null;
} else {
return new ThemeResource("img/note.svg");
}
},
new ImageRenderer<>())
.setWidth(80)
.setCaption("Note");
this.facilityGrid.addItemClickListener(new ItemClickListener<MapQueryService.RowResult>() {
#Override
public void itemClick(Grid.ItemClick<MapQueryService.RowResult> event) {
if (event.getColumn() == capacityCommentColumn && !Strings.isNullOrEmpty(event.getItem().getCapacityComment())) {
final NoteWindow noteWindow = new NoteWindow();
noteWindow.txtDescription.setValue("test");
noteWindow.show();
}
}
});
The problem is the code does not respond to clicks on the actual image, only on the outside. You can see this below. Any idea if its possible to make the image clickable?
You need to add a click listener to the Renderer as well. For example:
Grid<Integer> grid = new Grid();
private void addIconColumn() {
ImageRenderer<Integer> renderer = new ImageRenderer<>();
renderer.addClickListener(e -> iconClicked(e.getItem())); // allow clicks on the image
Grid.Column<Integer, ThemeResource> iconColumn = grid.addColumn(i -> new ThemeResource("img/icon.svg"), renderer)
.setCaption("Icon");
grid.addItemClickListener(e -> { // allow clicks on the cell
if (iconColumn.equals(e.getColumn())) {
iconClicked(e.getItem());
}
});
}
private void iconClicked(Integer i) {
... your UI logic here ...
}
You can see a working example here: https://github.com/alejandro-du/community-answers/tree/master/click-image-in-grid

How to listen for a keyboard event in dart programming

I'm new to google dart and been trying to learn it for a day now. I'm pretty novice to programming in general and I'm trying to read the documentation; however, I feel a bit overwhelmed.
I would like to know the most proper method of creating a interaction for spacebar here key. When one would push spacebar, it would toggle between function void startwatch() , void resetwatch()
I believe this is the correct documentation page also documentation for keyboardEventController
void main() {
}
void startwatch() {
mywatch.start();
var oneSecond = new Duration(milliseconds:1);
var timer = new Timer.repeating(oneSecond, updateTime);
}
void resetwatch() {
mywatch.reset();
counter = '00:00:00';
}
Any further information needed I'll try to respond immediately. Thnk you so much for your help.
To listen to keyboard events and toggle between startwatch() and resetwatch():
void main() {
var started = false;
window.onKeyUp.listen((KeyboardEvent e) {
print('pressed a key');
if (e.keyCode == KeyCode.SPACE) {
print('pressed space');
if (started) {
resetwatch();
} else {
startwatch();
}
started = !started; // A quick way to switch between true and false.
}
});
}
window is an instance of Window class. It's automatically provided for you.
There's also a handy class called KeyEvent, which attempts to eliminate cross-browser inconsistencies. These inconsistencies are usually related to special keys.

Problems handling KeyboardEvents on DartFlash

I'm having trouble to handle KeyboardEvents on DartFlash.
I don't know what I'm doing wrong here. Could someone help me?
My intention is to just create a very simple walking character and every time I hit a key, it moves in the x and y, only to start understanding DartFlash API.
Here is the full source code:
class Character extends Sprite
{
TextureAtlas _atlas;
Bitmap _currentBitmap;
int _direction;
String _name;
Character(this._name, this._atlas)
{
this._direction=Direction.down;
this._currentBitmap=this.getBitmap("stand", this._direction);
addChild(this._currentBitmap);
}
String get name => this._name;
Bitmap getBitmap(String name, [int direction, int number])
{
if(direction == null)
{
return new Bitmap(this._atlas.getBitmapData(name));
} else if (number == null)
{
return new Bitmap(this._atlas.getBitmapData("${name}-${Direction.getDirectionName(direction)}"));
}
return new Bitmap(this._atlas.getBitmapData("${name}-${Direction.getDirectionName(direction)}-${number}"));
}
}
Character dk;
void keyboardListener(KeyboardEvent ke) {
print("Key code: ${ke.keyCode}");
dk.x+=1;
dk.y+=1;
}
void main()
{
Stage mainStage = new Stage("mainStage", html.document.query("#mainStage"));
RenderLoop renderLoop = new RenderLoop();
renderLoop.addStage(mainStage);
Resource resource=new Resource();
resource.addTextureAtlas("DarkKnight", "resources/DarkKnight.json", TextureAtlasFormat.JSONARRAY);
resource.load().then((res)
{
print(resource.toString());
dk=new Character("DarkKnight", resource.getTextureAtlas("DarkKnight"));
dk.x=10;
dk.y=10;
mainStage.addChild(dk);
dk.addEventListener(KeyboardEvent.KEY_DOWN, keyboardListener, false);
mainStage.focus=dk;
print("${mainStage.focus.name}");
});
}
There is an easy workaround. Just add an "tabindex" attribute to the canvas element and afterwards you will received KeyboardEvents. If the "tabindex" is not set, then the canvas does not receive keyboard events.
<canvas id="stage" width="800" height="600" tabindex="1"></canvas>
The canvas also needs the focus. You can get the focus by clicking on the canvas or problematically set the focus:
query('#stage').focus();

problem in starting camera?

hie i am using jde 4.5 want to use camera through my app.
i write the code and getting runtime excepetion Pushmodelscreen caaled by non event thread
tell me what the problem in it?
public void start Camera()
{
try {
// Create a player for the Blackberry's camera
Player player= Manager.createPlayer( "capture://video" );
// Set the player to the REALIZED state (see Player javadoc)
player.realize();
// Grab the video control and set it to the current display
_videoControl = (VideoControl)player.getControl( "VideoControl" );
if (_videoControl != null)
{
// Create the video field as a GUI primitive (as opposed to a
// direct video, which can only be used on platforms with
// LCDUI support.)
_videoField = (Field) _videoControl.initDisplayMode (VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field");
_videoControl.setDisplayFullScreen(true);
_videoControl.setVisible(true);
}
player.start();
if(_videoField!=null)
{
add(_videoField);
}
} catch (Exception e) {
// TODO: handle exception
Dialog.alert(e.getMessage());
}
}
`
thnaks alot
Amit
The code that involved in UI changes should be called from within the UI thread. So most likely some part of your code should be called in a way:
UIApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
// do your UI related staff here
// e.g. push a Screen or call Dialog.alert(), etc.
}
});
Also, you may find this info interesting.

Resources