Wrong TileMap coordinates on zoom with InputEventScreenTouch - godot

The goal is to enable the player to drow the patch for the character.
So I start with simple think, set value for cell(0, 0) in tilemap
and replace the value when the user clicks on it
and it works as expected.
But when I change the camera zoom and try it again it set value in another cell:
I was trying to multiple/divide the click position by the zoom value but it also not resolve the problem
Can anyone give me the hint on how should I handle that?
repo: Github

Once you zoom, the coordinates you get from the input event (screen coordinates) do not match the world.
If you have an input event, the recommended way to do this is with make_input_local:
tilemap.world_to_map(tilemap.make_input_local(event).position)
However, if you don't, but you have screen coordinates, you can do this:
var transform = tilemap.get_canvas_transform() * tilemap.get_global_transform()
tilemap.world_to_map(transform.affine_inverse() * screen_coordinates)

Related

How to detect if a custom shape has been clicked in godot?

Is it possible to check if a custom shape has been clicked. For instance, how would I check if a piano key, which is not a regular shape, has been clicked. I would assume that you would make an area 2D and make a Collision Polygon 2D, which has your shape, as a child, Then you would send a signal to a script if their was input, and the script would check if it was a click and respond accordingly. I tried this but it is not working. Below is my code. Any help is much appreciated!
func _on_Collision_input_event(viewport, event, shape_idx):
if event is InputEventMouseButton:
if event.is_pressed:
$"RadioCPressed".show()
print("Object Clicked")
else:
$"RadioCPressed".hide()
You have a typo, it should be event.is_pressed() not event.is_pressed. It must be giving you an error on run time.
Assuming it is not giving you an error, it probably means the method is not running at all (You can use a print or breakpoint at the start of the method to confirm). Also, double check you connected the signal. And make sure the Area has input_pickable set to true.
Something else you need to consider if whether or not there is something else getting the input. A common case is that people will use a ColorRect or TextureRect for background, and leave it with mouse_filter set to Stop (which is the default). Even if it is in the background, you need to set mouse_filter to Ignore, because Controls take priority over other nodes for input. See Using InputEvent.

Mplcursor hover showing _line0 on data points

Does anybody know why I would be getting "_line0" on certain points when using mplcursor hover on rectangles? I created a bunch of rectangles in a subplot and used the following code to create a cursor to show annotation when hovering over them:
def update_annotation(sel):
""" update the annotation belonging to the current selected item (sel) """
# get the label of the graphical element that is selected
label = sel.artist.get_label()
#point = sel.artist[sel.target.index]
# change the text of the annotation
sel.annotation.set_text(label)
sel.annotation.set(position=(1, 10), anncoords="offset points")
sel.annotation.get_bbox_patch().set(fc="yellow", alpha = 1)
sel.annotation.arrow_patch.set(arrowstyle="simple", fc="yellow", alpha=.5)
# create an mplcursor object that shows an annotation while hovering
cursor = mplcursors.cursor(axs[1], hover=True)
# call the function "update_annotation" each time a new element gets hovered over
cursor.connect("add", update_annotation)
However, when I hover over certain datapoint, not only is it REALLY slow to go to where I'm hovering over but it also shows me this:
My guess is that there are too many overlapping data points? If so, does anybody know a way around that and also can somebody explain to me what _line0 even means?
I realize the cursor is hovering over an empty space in the plot but it also shows _line0 when I hover over rectangles. Sometimes it will even show the label and then go back to _line0.

New to Coding Very confused

I'm new to coding in general and I'm trying to make a sprite change texture so it has a walking animation but I can't seem to figure out how to apply a wait() or something to my code.
if Input.is_action_pressed("move_up"):
vel.y -= 1
facingDir = Vector2(0, -1)
$LilBoiTexture.texture = load("res://LilBoiAssets/LilBoiBackward.png")
$LilBoiTexture.texture = load("res://LilBoiAssets/LilBoiBackward2.png")
Any help is appreciated. I'm trying to change from the first texture to the second one within idk 0.5, or something ill mess with it if i can figure out what to do.
There is an easier way of doing this instead of changing sprite image manually. You can use "AnimatedSprite" node as shown in the tutorial. Here are the steps:
1- Add an AnimatedSprite node to your character.
2- In properties of AnimatedSprite, Frames-> select new SpriteFrames.
3- Click SpriteFrames you just created, another menu will appear at the bottom of editor. Drag and drop your animation images to center of this menu.
4- Change animation name from default to something else (for example walkback).
5- In your code you just need to do this:
if Input.is_action_pressed("move_up"):
$AnimatedSprite.play("walkback")
else:
# you can also play an idle animation if you have one
$AnimatedSprite.stop()

vtk render window GetZbufferData method

As I understand it, if I create a vtk render window, then I can add different renderers to it and for each renderer renders from a different perspective. No to actually render the scene I use the vtk render window method render() to render all renderers in parallel. Now there is a vtk render window method called GetZbufferData which apparently returns an array containing the zbuffer. So my question is, to which renderer does this zbuffer correspond to?
Thanks for any clarification.
If you have all renderers in the same window, then they will share the same framebuffer, so also the same z-buffer. So a simple answer to your question is "to all of them". To get the individual z-values, it depends on what you are exactly doing with the renderers.
If you are doing some kind of a "tiled view", you want to assign different viewports (vtkRenderer::SetViewport(), like here) to each of the renderers. Then you can access the z data for a given "tile" (renderer) by passing appropriate x,y coordinates to the GetZBufferData function. For example, to get the whole part of the z buffer that belongs to renderer ren1 of vtkRenderWindow renWin:
double x1 = ren1->GetViewport()[0] * (renWin->GetSize()[0] - 1);
double y1 = ren1->GetViewport()[1] * (renWin->GetSize()[1] - 1);
double x2 = ren1->GetViewport()[2] * (renWin->GetSize()[0] - 1);
double y2 = ren1->GetViewport()[3] * (renWin->GetSize()[1] - 1);
float *ren1Z = renWin->GetZbufferData(
static_cast<int>(x1),static_cast<int>(y1),static_cast<int>(x2),
static_cast<int>(y2));
If you have the same viewport, it would be more complicated. You can have a renderwindow with multiple "layers", by setting vtkRenderWindow::SetNumberOfLayers(int) and then you can assign each renderer to a different layer (vtkRenderer::SetLayer(0-based layer index)). The window then renders from layer 0 to the last layer over each other. If you are interested in getting only one specific renderer's z-data, you should get it if you have it render in the last layer. However, I am not sure if the z-buffer is cleaned in between individual renderer's renders, I would actually bet on that it is not, so you might also get some inconsistent mess.
I would like to complement tomj answer:
Any of the vtkRenderWindow::GetZbufferData() methods query the framebuffer for Z-values, which is contained in the vtkRenderWindow, but there is a slight remark:
You need to set this in your renderers: vtkRenderer::PreserveDepthBufferOn(). This is because as the documentation says:
"By default, the depth buffer is reset for each renderer.
If this flag is true, this renderer will use the existing depth buffer for its rendering."
So, that bring us to the vtkRenderers. There is a layering of vtkRenderers, which tells which "chain" or "precedence order" to make the drawing. Check the method vtkRenderer::SetLayer().
So, you first need to set up your layered vtkRenderers, attach them to the vtkRenderWindow, and then set up correctly if you want to preserve some depth buffers or not.
Notice that if the z-buffer has not been set (first draw of the first vtkRenderer), it will return 1.0. I'm still figuring out why, but currently that is the situation.

How to determine which (object) control has been clicked?

I'm after some advice re "how to determine which (object) control has been clicked"?
On mouse:over I hide the corner controls (and the border):
Image -> https://github.com/Robinyo/my-2d-diagram-editor/blob/master/client/content/images/my-2d-diagram-editor-with-ports.png
On mouse:down I use getCenterPoint() (of the mouse:over target) to start drawing a line:
Image -> https://github.com/Robinyo/my-2d-diagram-editor/blob/master/client/content/images/my-2d-diagram-editor-with-connections.png
On mouse:move I update the (connector) lines x2 and y2, and on mouse:up I use getCenterPoint() (of the mouse:over target) as the line's end point.
What I would like to do is use the nearest connect point (ml, mt, mr, mb) rather than getCenterPoint().
update to latest fabric js if your application allows it, because this fix is recent.
then on mouse up you can check for:
object.__corner
That should have value 'mt', 'mr'... and so on.
Be carefull that if i'm not wrong fabricjs check first for object, and then if it fails it check for corner click.
(target.containsPoint(xy) || target._findTargetCorner(pointer))
It means that it will first check for the bounding box and then for the corners. In other words the corner targeting will work just in the outer part of the corner.

Resources