androidplot background image shift - androidplot

I'm trying to separate the background of the graph grid in 3 areas using this code:
int[] data = {0xff000000, 0x80008000, 0xff000000};
bgBitmap = Bitmap.createBitmap(data, 1, 3, Bitmap.Config.ARGB_8888);
RectF rect = plot.getGraphWidget().getGridRect();
BitmapShader myShader = new BitmapShader(
Bitmap.createScaledBitmap(bgBitmap, 1, (int) rect.height(), false),
Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT);
plot.getGraphWidget().getGridBackgroundPaint().setShader(myShader);
So scaling a 3 pixel bitmap to the graph height and repeating it over the whole domain area.
However the resulting graph show that the background seems to be shifted up a bit.
It looks like the shift size is about equal to the domain label height.
How can I fix this?
Hm cannot post picture because of 'reputation' sigh.
Link to the example graph: http://marcel.mesa.nl/androidplot.png

I think you're running into the issue mentioned near the end of this thread. Essentially, the origin of the shader is the top-left corner of the screen, not the top-left corner of component for which the background is being drawn using the shader. The solution is to translate to the top-left point of the graphWidget like this:
RectF rect = plot.getGraphWidget().getGridRect();
Matrix m = new Matrix();
m.setTranslate(rect.left, rect.top);
shader.setLocalMatrix(m); // where shader is your shader instance

Related

Find original (x,y) new coordinates in fabric canvas

I am building a Warehouse map in 2D with fabricjs where I am displaying their racking systems as a series of rectangles.
As a first "layer/group", i add all bays as groups containing a rectangle and text, both positioned at the same (x,y). They also have both an angle set to fit their orientation in the space.
As a second "layer/group", i add groups containing a circle and text, representing the bay's number of issues. The (x,y) also fits the bays. This way, all my issues are always on top of the bays and the center of the group fits the rotated corner of the bay.
On the first paint, all is well aligned. Once they're shown on the page, the user can create new issues, so I am trying to position the issue group fitting the original (x,y), but since it can all be panned and zoomed, I am having a hard time positioning it where it should be.
I've been looking at their explanations about transforms, but I can't figure who the boss should be and thinking that having nested groups may also be why I am all mixed up.
By doing:
const gMatrix = matchingBay.group.calcTransformMatrix(false);
const targetToCanvas = fabric.util.transformPoint(matchingBay.aCoords.tl, gMatrix);
I am on the bay, but on the "group" corner, which is not what I am looking for. (x,y) will be one of the corners of the rectangle in the group, that may have been rotated.
By specifying the original (x,y) in this code will get me way off the actual painting zone.
So, my question is, how do I get the transformed (x,y) so I can add my issue group at those coordinates?
[EDIT]
As the suggestion of spring, it made me realize I can use the rotated rectangle's transforms to find its coordinates, so I tried:
const rect = matchingBay.getObjects()[BAY_RECTANGLE_INX];
const gMatrix = rect.calcTransformMatrix();
const targetToCanvas = fabric.util.transformPoint(rect.aCoords.bl, gMatrix);
Bottom left corner is where I wish to add the new Circle. After rotation, the bottom left is now the bottom right. But I am still off. As shown, the red circle should be on the corner. It looks like the rotation has not been applied.
qrDecompose gives me something that seems right:
{angle: -90, scaleX: 1, scaleY: -1, skewX: 0, skewY: 0, translateX: 6099.626027314769, translateY: 4785.016008065199 }
I realized that I was not thinking it the right way. Since I have the rectangle already in hands, I just had to get its own transformation and resolve the corner by my own, the following fixed my issue:
{
[...]
const rect = matchingBay.getObjects()[BAY_RECTANGLE_INX];
const gMatrix = rect.calcTransformMatrix();
const decomposed = fabric.util.qrDecompose(gMatrix);
const trans = fabric.util.transformPoint(new fabric.Point((decomposed.scaleX * -rect.width) / 2, (decomposed.scaleY * rect.height) / 2), gMatrix);
const top = trans.y;
const left = trans.x;
[...]
}
Since the matrix is bringing the center point of the rectangle, I can get the corner by substracting its width and height and then transforming the coordinates to find out where the matrix puts it.

Lego style split screen camera in godot

I want to have lego style splitscreen camera with seamless transitions.
Anyone has any experience creating something like this? I thought of creating one normal camera and then another camera for second player that by default wouldn't be visible. Then, when i would want to show it, i would draw a triangle to split the screen and set it texture as camera #2 view.
I found this Unity implementation but i couldn't implement it in Godot. I've managed to create second viewport with it's own camera, but for some reason the view of the second camera is not showing anything. I'm thinking that the problem is that the world of the second viewport is different than the main viewport.
Source code can be found here.
I just setup a toy project to test this out and it turned out to be simpler than expected.
Here is an overview of the process and then code examples will follow.
Add one main camera
And a secondary camera with tree: Control > Viewport > Camera
Draw the shape of the split screen with Control using the draw_* api
Add a shader to Control that takes a texture and draws it at SCREEN_UV
Get the viewport texture from Viewport
Pass the viewport texture to the Control shader every frame.
Animate the split by animating and redrawing the Control shape.
I'm not sure how to do the border.
To make the split join you'll probably have to shift the Control shape by the thickness of border and then shrink that border as the cameras go towards each other. Use that distance between the players to calculate the border width.
The split border is also at an angle between the two players so when animating the shape you'll want to use that angle. This will make the joining of the viewport look smoother.
Control code:
extends Control
func _draw():
# in this case animate tl and bml to get the
# rotating split like effect in the lego game
var tl = Vector2()
var tr = rect_size
tr.y = 0
var br = rect_size
var bml = rect_size
bml.x /= 2.0
draw_polygon([tl, tr, br, bml, tl], [Color(), Color(), Color(), Color(), Color()], [])
func _process(d):
material.set_shader_param('viewport', $Viewport.get_texture())
Shader Code:
shader_type canvas_item;
uniform sampler2D viewport;
void fragment(){
COLOR=texture(viewport, SCREEN_UV);
}
I hope this helps get you started!
It is a complex effect with many parts so be warned.
I found that the easiest way is to create a separate scene with your viewports and cameras which will be your main scene and then add your game scene under it like this:
Spatial
Viewport1
Camera1
Viewport2
Camera2
GameScene
You should then be able to make a ColorRect with a shader material and send in the textures from each viewport:
shader_type canvas_item;
render_mode unshaded, cull_disabled;
uniform sampler2D viewport1;
uniform sampler2D viewport2;
void fragment() {
vec3 view1 = texture(viewport1, UV).rgb;
vec3 view2 = texture(viewport2, UV).rgb;
vec3 col = vec3(0);
// mix them in a satisfying way depending on distance and angle between cameras
// float mixVal = <your formula here>
// col = mix(view1, view2, mixVal)
COLOR = vec4(col, 0.0); // this may not work in Godot shaders
}
This is a great guide to get you started:
https://docs.godotengine.org/en/3.1/tutorials/viewports/using_viewport_as_texture.html

How to set relative position (oCoords) in FabricJs?

I have a Text in fabricJs. I set top and left.
This sets the aCoords properly to those values.
However the oCoords dont match. And the Text is not displayed at the right position.
I suspect that I need to set to oCoords somehow. So that the Text is displayed at the right pixel coordinates (top & left) on the canvas.
aCoords and oCoords are two different things and should not be in sync.
In your comment you speak about scaled canvas.
Top and Left are 2 absolute values that represent the position of the object on the canvas. This position match with the canvas pixels when the canvas has a identity transform matrix.
If you apply a zoom, this coordinates diverge.
To get the position of pixel 300,100 of the scaled canvas on the unscaled canvas, you need to apply some basic math.
1) get the transform applied to the canvas
canvas.viewportTransform
2) invert it
var iM = fabric.util.invertTransform(canvas.viewportTransform)
3) multiply the wanted point by this matrix
var point = new fabric.Point(myX, myY);
var transformedPoint = fabric.util.transformPoint(point, iM)
4) set the object at that point.

How to isolate a Phaser shader to a specific object/shape?

I'm using the Phaser framework. Here is the jsfiddle:
http://jsfiddle.net/Dillybob/u3mGL/13/
Here is where the filter is getting populated:
background = game.add.sprite(0, 0);
background.width = 800;
background.height = 600;
filter = game.add.filter('Fire', 800, 600);
filter.alpha = 0.0;
background.filters = [filter];
My line object is assigned to the variable drawnObject
So I assign that object to receive the filter like so:
drawnObject.filters = [filter];
But my line is now a red fiery square instead of being a line with a fiery background, why?
Firstly, be aware that drawnObject is actually a bitmap, which is rectangular shaped. It consists of white pixels, which build your line, and transparent pixels, which are taking the rest of bitmap space.
The filter you use is a pixel shader. Pixel shader describes instructions that GPU invokes for each pixel of a provided bitmap. In case of this shader, it creates fire effect based on some noise functions, but it doesn't take original bitmap into account. The original color of pixels is not preserved, it doesn't add to final effect in any way.
To achieve your expected result, you have to amend fragmentSrc in Fire.js, so that shader uses and mixes/blends original color into final pixel color and/or doesn't change pixel transparency.

How to avoid fade-out on scaled CCSprite without cancelling anti-aliasing?

I have 3 sprites. Left edge, right edge, and repeating center which has 1 pixel width but is scaled up. The problem is that the scaled sprite fades out the farther away it is from the center:
I've tried using CCTexture's setAliasTexParameters but the result doesn't look good:
How do I get the antialiased looks in the first picture but without the fade out problem?
You could try this on the sprite:
// These parameters set the texture properties:
// minifying filter - linear interpolation,
// magnification filter - linear interpolation,
// texture repeat in S direction,
// texture repeat in T direction (*)
ccTexParams params = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT};
[sprite.texture setTexParams:&params];
// This explicitly sets the contentSize of the sprite to (10, 200),
// but also sets the "window to the texture" to this rectangle:
[sprite setTextureRect:CGRectMake(0, 0, 10, 200)];
You have to tweak these settings, but hope you get it.
You don't have to scale the sprite.
(*) For S and T check this: Difference between U V and S T texture coordinates

Resources