XNA - Global Zoom - xna

I'm trying to allow zoom with the mouse scroll and pass a zoom value into each of my drawable objects. Each drawable object takes the zoom value and uses the scale parameter of the SpriteBatch.Draw method. Zooming each individual item though doesn't work in relation to all other objects. Is there some sort of canvas I can draw everything to, and then zoom that so everything zooms appropriately?

Use the SpriteBatch.Begin method that takes a Matrix parameter. Pass a scaling matrix:
Matrix scaleMatrix = Matrix.CreateScale(myScale);
sb.Begin(SpriteSortMode.Deferred, null, null, null, null, null, scaleMatrix);
You should use this parameter for all "global" transformations of your sprites. So you could combine (multiply) a translation and a scale matrix to move about and zoom your 2D scene.

In the camera, you have to re-create the view , changing the field of view to a smaller value:
Matrix.CreatePerspectiveFieldOfView(
MathHelper.PiOver4, // change this to, say 20°
aspectRatio,
0.0001f,
1000.0f,
out projection
);
Now this change is global since you use camera's projection in your effects

Related

Jung: prevent user from moving a vertex outside the Visualization size?

When in picking mode, I want to limit the user from dragging a vertex outside of the defined layout bounds. I've set the ISOMLayout, VisualizationModel, and the VisualizationViewer to be the same size. But if I zoom out (I'm using a CrossoverScalingControl) I can drag vertices way outside the layout/vv's bounds. This results in the scrollbars of my GraphZoomScrollPane not working as expected: there can be vertices floating out there that you can't scroll to and you have to zoom out to see them.
Surely there's a way to lock the user into a certain boundary?
Dimension preferredDimension = new Dimension(1200, 800);
Layout<CNode,CEdge> layout = new ISOMLayout<>(graph);
layout.setSize(preferredDimension);
VisualizationModel<CNode, CEdge> visualizationModel = new DefaultVisualizationModel<>(layout, preferredDimension);
vv = new VisualizationViewer<>(visualizationModel, preferredDimension);
If you want to set a boundary outside which you can't manually move a vertex, you can do that in your code (specifically, in the part that responds to you dragging a selected vertex; you can specify limits there on how far out you can drag a vertex). It's not JUNG's responsibility to prevent you from setting a vertex location to something that the Layout wouldn't use; as far as the JUNG is concerned, you can do that if you want to. :)

Get SCNMaterial's frame

I have an iPhone 3D model in my SceneKit application, it has a material which I get. It is called iScreen (the image that "is on" the screen of the iPhone):
var iScreen: SCNMaterial!
iScreen = iphone.geometry?.materialWithName("Screen")!
I decided to somehow project a webView there instead of an image.
Therefore I need the frame / position / size of the screen where iScreen "draws" to set the UIWebView's frame. Is that possible?
Note
Of course I tried position, frame, size, etc. but that all was not available :/
you will first have to know to which SCNGeometryElement the material applies (an SCNGeometry is made of one or several SCNGeometryElement).
That geometry element is essentially a list of indices to retrieve vertex data contained in the geometry's SCNGeometrySources. Here you are interested in the position source (it gives you the 3D coordinates of the vertices).
By iterating over these positions you'll be able to find the element's width and height.

Rotate an image based on reference point

I have the code that will rotate my image like a "spinner" based on its geometric center... however because the image itself is asymmetrical, i wish to rotate it about a particular reference point in terms of (x,y) coordinates of the UIImageView.
Here is my current code that rotates the image:
self.spinnerView.center=CGPointMake(self.spinnerView.center.x, self.spinnerView.center.y);
self.spinnerView.transform=CGAffineTransformMakeRotation (angle);
// why u change center of View on itself??? o_O What you want with it?
self.spinnerView.center=CGPointMake(self.spinnerView.center.x, self.spinnerView.center.y);
And read a documentation:
The origin of the transform is the value of the center property, or
the layer’s anchorPoint property if it was changed. (Use the layer
property to get the underlying Core Animation layer object.) The
default value is CGAffineTransformIdentity.
so :
self.spinnerView.layer.anchorPoint=CGPointMake(0, 0);
self.spinnerView.transform=CGAffineTransformMakeRotation(angle);
was written about anchorPoint:
You specify the value for this property using the unit coordinate
space. The default value of this property is (0.5, 0.5), which
represents the center of the layer’s bounds rectangle. All geometric
manipulations to the view occur about the specified point.

How draw only the models " front of the camera " full or partially displayed - XNA

I am developing a small game in XNA style "MinecraftGame."
As there are a lot of cubes to draw. I created a function that allows you to draw only the cubes in front of the camera! But the problem is that if a cube is not completely full in my field of vision, it will not be drawn.
As you can see on the "screenshot" below. Cubes located on the edges are not drawn.
How to draw cubes fully and partially displayed in front of the camera? and not only entirely.
Thanks a lot
Here my code to check if the Frustum contain the model:
//Initialize frustum
private void GenerateFrustum()
{
Matrix viewProjection = View * Projection;
Frustum = new BoundingFrustum(viewProjection);
}
//private void UpdateFrustum
{
Matrix viewProjection = View * Projection;
Frustum.Matrix = viewProjection;
}
//Function that will add models instantiated in the transformation matrix only if the model is in the field of view !
private udpateTransformModelInstancied()
{
for (int i = 0; i < ListInstance.Count; i++)
{
if(camera.Frustum.Contains(ListInstance[i].Transform.Translation) != ContainmentType.Disjoint)
{
instanceTransforms.Add(ListInstance[i].Transform);
}
}
.......
}
SreenShot :
You're checking the position of the cubes. This means that you're not taking the cubes' physical size into account; you're treating them as a point, and if that point is out of view, then you won't render it. What you need to do is check whether any part of the cube is visible. The two simplest ways to do this are to work out a bounding shape and use that to check, or to check whether your view contains any of the cube's corner points, rather than just its position point.
Testing for containment of bounding structures for your cubes instead of just the cube's position would work but that adds to your game's complexity by needing to manage a bunch of bounding structures plus the math of testing a bounding structure as opposed to a point. If you need the bounding structures for other stuff, then go that route. But if not, then I would simply take the cube's position, determine a point to the cube's width left or right of it and test those points. If either are 'in', then draw the cube.
Vector3 leftRightVector = Matrix.Transpose(view).Right;//calc once for each frame(or only when camera rotates)
Vestor3 testPoint1 = cubePosition + (leftRightVector * maxCubeWidth);//calc for each cube
Vestor3 testPoint2 = cubePosition + (leftRightVector * -maxCubeWidth);
if(frustum.Contains(testPoint1 || testPoint2)
{
//draw
}
As far as I can see, you are just checking the position of each cube. The most effective fix would be to make a BoundingSphere that would fully encompass one of your cubes, translate it to the cubes location and done the Frustum.Contains with that sphere instead of position :)
Also; Make the sphere just a tad bit larger than needed to account for the edges of the frustum. And remember; If you want to make a minecraft-clone, you will need to use some sort of batch-rendering technique. I reccomend using an instance buffer, as there will be less data to send to the GPU, as well as easier to implement.

How to properly apply transformations to OpenGL models

I've been trying to figure this out for six months now, and have a workable solution, but I just can't figure out how to get my model to behave exactly how I want. I'm rendering a 3D model with an arcball rotation implementation and zoom/pan functionality for the iPad, although the transformation code will be identical to that of desktop OpenGL. Currently, the user has the ability to change the center of rotation of the model by clicking on the model. The center of rotation changes, but the origin stays stationary which causes the model to move away from where the user touched the screen. What I would like it to do is allow the user to touch the model and have the model stay stationary, but have it move the origin to where the user touched. I'm not sure what transformations or the order of transformations needed to do this. The current order of transformations is:
glPushMatrix();
glTranslatef(pan.x, pan.y, 0);
glMultMatrixf(mat); //this is my rotation/scale matrix I get from my arcball class
glTranslatef(-origin.x, -origin.y, -origin.z);
//draw model
glPopMatrix();
Any idea what changes need to be made to make it so the origin moves instead of the model?
At first blush, I'd say you should shift the scene's origin to the desired rotation point before applying the rotation matrix, so that the shift happens along the global axes. then apply the rotation matrix, draw the item, and shift the origin back to the original origin for the rest of the display function (which should be taken care of in the glPopMatrix).
glPushMatrix();
glTranslatef(pan.x, pan.y, 0);
glTranslatef(-origin.x, -origin.y, -origin.z);
glMultMatrixf(mat); //this is my rotation/scale matrix I get from my arcball class
//draw model
glPopMatrix();

Resources