I'm developing a Windows Phone 8 application with GART SDK.
But I don't like because it overlaps the places' names and all has the same font size. I was using ARToolkit for iPhone and it changes the font size it the places are near or far, and it doesn't overlap them.
Do you know another SDK like GART for Windows Phone 8?
I encountered the same problem a while ago, and I solved it by modifying OnAttitudeChanged method of WorldView class.
This is the code I have inside the else block of that method:
else
{
// In range so show
wvItem.Visibility = Visibility.Visible;
// Create a CompositeTransform to position and scale the WorldViewItem
CompositeTransform ct = new CompositeTransform();
// Offset by half of the WorldViewItems size to center it on the point
ct.TranslateX = projected.X - (wvItem.ActualWidth / 2);
ct.TranslateY = projected.Y - (wvItem.ActualHeight / 2);
// Scale should be 100% at near clipping plane and 10% at far clipping plane
//double scale = (double)(MathHelper.Lerp(0.1f, 1.0f, (FarClippingPlane - Math.Abs(arItem.WorldLocation.Z)) / FarClippingPlane));
// Added to use distance
double scale = (double)(MathHelper.Lerp(0.1f, 1.0f, (FarClippingPlane - (float)Math.Round(arItem.GeoLocation.GetDistanceTo(this.Location))) / FarClippingPlane));
// This makes the items that are far to appear higher on screen. Values are that best fit my project, so, it should be calibrated.
ct.TranslateY = ct.TranslateY - (int)((1-scale) * 63);
ct.ScaleX = scale;
ct.ScaleY = scale;
// Set the transform, which moves the item
wvItem.RenderTransform = ct;
// Set the items z-index so that the closest item is always rendered on top
Canvas.SetZIndex(wvItem, (int)(scale * 255));
}
Related
This video will show my current situation, and I currently can't find any answers to it online.
https://www.youtube.com/watch?v=O8Mh-1Emoc8&feature=youtu.be
My Code:
public Vector3D pickBlock() {
glDisable(GL_TEXTURE);
IntBuffer viewport = BufferUtils.createIntBuffer(16);
FloatBuffer modelview = BufferUtils.createFloatBuffer(16);
FloatBuffer projection = BufferUtils.createFloatBuffer(16);
FloatBuffer winZ = BufferUtils.createFloatBuffer(1);
float winX, winY;
FloatBuffer position = BufferUtils.createFloatBuffer(3);
glGetFloat(GL_MODELVIEW_MATRIX, modelview);
glGetFloat(GL_PROJECTION_MATRIX, projection);
glGetInteger(GL_VIEWPORT, viewport);
winX = (float)Display.getWidth() / 2;
winY = (float)viewport.get(3) - (float)Display.getHeight() / 2;
glReadPixels(Display.getWidth() / 2, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, winZ);
gluUnProject(winX, winY, winZ.get(), modelview, projection, viewport, position);
glEnable(GL_TEXTURE);
return new Vector3D(position.get(0) / 2 + 0.5f, position.get(1) / 2 + 0.5f, position.get(2) / 2 + 0.5f);
}
It returns "/ 2 + 0.5f" because that is needed because of the offsets I have for the blocks (if I removed the 0.5f, the offset would be in the center instead of the corner)
I seams to me that the error, based on the video, comes from when you are facing in the positive z direction (or whatever your back direction is). My guess is that you aren't taking the facing direction into account as I see in your code that you are just adding a constant 0.5F to the position of your cursor.
Therfore, when you are facing backwards, it adds 0.5 which makes it be behind the wall (since back is negative Z). one simple check would be weather the Z component of your forward vector is positive or negative, and deciding the factor added to the cursor based on that, then doing the same for the X.
Depending on how you implemented your camera (IE: if you used Euler angles (rx, ry, rz) or if you used Quaternions / forward vectors), the way you would do that check would vary, feel free to ask me for examples based on your system if you need.
hope this helped!
PS: if you're using angles, you can either check for the range of the y-axis rotation value and determine which direction you are facing and thus weather to add or subtract, OR you can calculate the forward vector based on your angles, and then check the for sign of the component.
Using some code I found online has helped me create a zoom function for a program I am attempting to make. It is to make a map that allows a user to mark points. Currently the code scales in on the map image alone but I cant get the point icons to realign to where they originally where. I cant workout the maths of it.
Code to zoom in and out
if (mev.shiftKey) {
image.scaleX = Math.max(scaleFactor*image.scaleX, minScale);
image.scaleY = Math.max(scaleFactor*image.scaleY, minScale);
}
if (mev.ctrlKey) {
image.scaleX = Math.min(1/scaleFactor*image.scaleX, maxScale);
image.scaleY = Math.min(1/scaleFactor*image.scaleY, maxScale);
mat = image.transform.matrix.clone();
MatrixTransformer.matchInternalPointWithExternal(mat,internalCenter,externalCenter);
image.transform.matrix=mat;
This allows the image to scale up with the following factors
public var scaleFactor:Number = 0.8;
public var minScale:Number = 0.25;
public var maxScale:Number = 2.0;
The problem occurs when I try to move the pointer icons that are overlaid on this image. They are not to grow or shrink at the moment but they I cant get the maths to get them to move the correct number of pixels away from the mouse location so that they are still in line. Currently I am using the following formulas
//decrease zoom
stage.getChildAt(i).x = stage.getChildAt(i).x * scaleFactor;
//increase zoom
stage.getChildAt(i2).x = stage.getChildAt(i2).x / scaleFactor;
Any thoughts ? Code I am using came from
http://www.flashandmath.com/howtos/zoom/
Quite a few elements missing from the question like the moving map underneath. Anyway now that it's sorted out ...
If you are not a math genius and can't tackle 2 math formulas at the same time then don't and tackle them one by one then combine them. Once again don't use the x,y property of point for calculation but create specific property (like in a custom class for example). I will name them here origin for convenience.
Given a point with origin property of x:100, y:200, its position on the map is (assuming map is top left coordinate, if not adapt accordingly):
point.x = map.x + point.origin.x;
point.y = map.y + point.origin.y;
the positioning is solved now you need to solve for scale which is easy:
point.x = point.origin.x * scaleFactor;
point.y = point.origin.y * scaleFactor;
Both systems are solved now you can combine the two:
point.x = map.x + (point.origin.x * scaleFactor);
point.y = map.y + (point.origin.y * scaleFactor);
i wanted to develop a game which can support all types of display sizes,
so i am using following code to multiscale.
graphics.PreferredBackBufferHeight = 768;
graphics.PreferredBackBufferWidth = 1024;
shootrect = new Rectangle( 900,650 , 100, 100);
touchrect = new Rectangle(mouse.X, mouse.Y, 0, 0);
if (mouse.LeftButton == ButtonState.Pressed && !jump && shootrect.Intersects(touchrect))
{
jump = true;
}
using this code i am trying to intersect the mouse coordinates with shootrect (which is shoot button for make player to jump) if i touch in that rect intersection is working but somewhere else in the same width and height touch is working
when i remove graphics.PreferredBackBufferHeight = 768;
graphics.PreferredBackBufferWidth = 1024; those lines from code intersection is working fine but my scaling is not proper for other size of screens
You need to scale your logic by hand (rectangles for instance) if you use those magic numbers creating them. I suggest create those relative to the screen width and height.
actually graphics.PreferredBackBufferHeight = 768;
graphics.PreferredBackBufferWidth = 1024; because of this rectangle intersection is working properly if set my screens resolution to 1024 x768 then it works well but my resoolution is 1980x1020 so its not working
I'm working on my own tile bliting engine, this one is using hexagonal tiles - but I think it doesn't differ much from regular tiles.
I have huge x,y array of tiles and they have their x,y coordinates for rendering on canvas, I iterate only the ones that should be visible on canvas in current camera position.
So I'm stuck with scaling and cant resolve this on my own.
Here is my code for drawing tiles on canvas:
public function draw():Void{
clearCanvas(); //Clear canvas (bitmapData)
var _m:Matrix;
iterateTiles(function(_tile:HexTile):Void{ // loop every tile that is visible on screen
_m = new Matrix();
_m.translate(_tile.x + cameraPoint.x,_tile.y + cameraPoint.y);//Get pre calculated tile x,y and add camera x,y
_m.scale(matrixScale, matrixScale);
drawToCanvas(_tile,_m);//Send to draw tile on canvas using Matrix
},true);
}
This works nice and fast but only problem is it scales tiles from left top corner (like regular scale would work)
Before scale
After scale
My question is how to transform tiles to always scale from center. So if tile 10:10 is in center of screen before scaling, then it should
stay there after scaling.
Sorry, I misunderstood the question, but I think I've got it now:
// Scale the distance from the original point to the center of the canvas
var xDistance:Number = ((_tile.x + cameraPoint.x) - xCenter) * matrixScale;
var yDistance:Number = ((_tile.y + cameraPoint.y) - yCenter) * matrixScale;
// Add the distances to the center of the canvas. This is where you want the tile
// to appear.
var x:Number = xCenter + xDistance;
var y:Number = yCenter + yDistance;
// Because the coordinate is going to be scaled, you need to increase it first.
x = (1 / matrixScale) * x;
y = (1 / matrixScale) * y;
_m.translate(x, y);
I have not tested this, I've just drawn it out on graph paper. Let me know if it works.
I'm trying to zoom a DisplayObject into a certain point. I figured it would be easy, but I've spent a day now trying to figure it out.
Basically, I think this should work. Emphasis on should.
//newPoint is the point being centered. There is no initial scaling, so I do not need to compensate for that (yet)
//scale is the zoom level
//container is the parent of the obj
//obj is the object being scaled/panned
var p:Point = new Point(
( this.container.width - this.obj.width * scale + newPoint.x * scale ) / 2,
( this.container.height - this.obj.height * scale + newPoint.y * scale ) / 2
);
this.obj.scaleX = this.obj.scaleY = scale;
this.obj.x = p.x;
this.obj.y = p.y;
It centers the point if scale is 1, but it gets further and further away from center as you increase the scale. I've tried dozens of different methods. This method, which I have seen on several sites, produced the same exact results. Anyone have any idea how to get this to work?
EDIT 10-1-12:
As a followup, I took the code snippet that LondonDrugs_MediaServices provided as a basis for my original issue. I needed to be able to zoom to a specific point at a specific scale relative to the unscaled image (think how Google Maps zooms to a specific location). To do this, I had to center my image on the point before running the translation code. I've posted the additional code below. For other uses (pinch to zoom, scrolling, and double click), I used the code provided by Vesper, which worked quite well.
//obj is the object being translated
//container is its parent
//x and y are the coordinates to be zoomed to, in untranslated scaling
//obj.scaleX and obj.scaleY are always identical in my class, so there is no need to account for that
//calculates current center point, with scaling
var center:Point = new Point( ( this.container.width - this.obj.width * this.obj.scaleX ) / 2, ( this.container.height - this.obj.height * this.obj.scaleX ) / 2 );
//calulcates the distance from center the point is, with scaling
var distanceFromCenter:Point = new Point( this.obj.width * this.obj.scaleX / 2 - x * this.obj.scaleX, this.obj.height * this.obj.scaleX / 2 - y * this.obj.scaleX );
//center the object on that specific point
this.obj.x = center.x + distanceFromCenter.x;
this.obj.y = center.y + distanceFromCenter.y;
var mat:Matrix=new Matrix();
mat.translate(-p.x,-p.y);
mat.scale(desiredScale,desiredScale);
mat.translate(p.x,p.y);
yourObject.transform.matrix=mat;
The core point is that scaling is done around (0,0), but you can do it with matrix that describes affine transformations. You first make an empty matrix (that is, a matrix that doesn't transform), then apply a set of transformations to it. First, place a desired point at (0,0) by translating by -1*coordinates, then scale, then translate back.
hie guys....
thank's your comments...
i found the answer...
code :
gambar.addEventListener(TransformGestureEvent.GESTURE_ZOOM , onZoom);
function onZoom(event:TransformGestureEvent):void {
var locX:Number=event.localX;
var locY:Number=event.localY;
var stX:Number=event.stageX;
var stY:Number=event.stageY;
var prevScaleX:Number=gambar.scaleX;
var prevScaleY:Number=gambar.scaleY;
var mat:Matrix;
var externalPoint=new Point(stX,stY);
var internalPoint=new Point(locX,locY);
gambar.scaleX *= event.scaleX;
gambar.scaleY *= event.scaleY;
if(event.scaleX>1 && gambar.scaleX>6){
gambar.scaleX=prevScaleX;
gambar.scaleY=prevScaleY;
}
if(event.scaleY>1 && gambar.scaleY>6){
gambar.scaleX=prevScaleX;
gambar.scaleY=prevScaleY;
}
if(event.scaleX<1 && gambar.scaleX<0.8){
gambar.scaleX=prevScaleX;
gambar.scaleY=prevScaleY;
}
if(event.scaleY<1 && gambar.scaleY<0.8){
gambar.scaleX=prevScaleX;
gambar.scaleY=prevScaleY;
}
mat=gambar.transform.matrix.clone();
MatrixTransformer.matchInternalPointWithExternal(mat,internalPoint,externalPoint);
gambar.transform.matrix=mat;
}
The matrix answer is absolutely correct, but if you happen to be a Club GreenSock member you can get some nice functionality with very simple code with the TransformAroundPointPlugin
http://www.greensock.com/as/docs/tween/com/greensock/plugins/TransformAroundPointPlugin.html
You can see an example in the plugin explorer here:
http://www.greensock.com/tweenlite/#plugins
I use this to tween all my zooms and have much better performance than when I tried to do this manually. IMO the whole library is worth it's weight in gold (and no I have no connection other than liking the library). If you need any of the other features I'd look into it. It also has the ThrowProps plugin ( http://www.greensock.com/throwprops/ )which is very important if you are going to have a bounding box on mobile that you want to have a smooth return into the boundaries.
Set obj.x to -p.x and obj.y to -p.y, set the container scaleX and scaleY to the desired value and add p.x to the container x and p.y to the container y. Done!