Problems using camera in OpenGL - c#

Hi, I am making an application which can make camera rotate around the model, I have successfully imported the obj format model
But I meet the problem when rotate the camera, the model will disappear as you can see
gl.Perspective(180, (double)Width / (double)Height, 100, 50000f);
The key code for rotating camera:
Calculate the center point of the model
currentX = Math.Sin(angle) * radius;
currentZ = Math.Cos(angle) * radius;
gl.LookAt(currentX,0,currentZ,
centerPoint.X, centerPoint.Y, centerPoint.Z,
0, 1, 0
);

Try modifying the near clipping plane to be much closer to the camera, and also lower the FoV angle. Try this:
gl.Perspective(90, (double)Width/(double)Height, 0.01f, 100.0f);

Check if the model is not closer than the near clipping plane. Check also the face culling: if your camera is inside the mesh, you are looking at the back faces of the polygons, which probably are not rendered.

Related

Unity: How to stop object from spinning when rotating towards object?

When I try to rotate an object towards a point, it starts spinning, but I want it to be able to freely spin, while still rotating towards that point. I can't just clamp the y rotation, because obviously it's already rotating towards a point and setting the absolute y rotation while doing so and you can't access an object's relative angles in Unity. As seen here, the blue gizmo always faces the top of the sphere (the centre of the sphere is the point I'm rotating towards). I want it to be able to move freely.
Here's my rotation code:
Quaternion dir = Quaternion.LookRotation((target - transform.position).normalized) * Quaternion.Euler(new Vector3(-90, 0, 0));
transform.rotation = Quaternion.Slerp(transform.rotation, dir, smooth);
Does anyone know how to fix this?

Draw a line from object to where camera is facing in Unity

I am starting out to create a minigolf game in Unity. I want to aim by draggin the screen with my mouse which rotates the camera around the ball. Basically I want to draw an aim line (line renderer or any other good method) from the ball to where the camera is pointing. Right now I just draw the line I want from beginning, but in the end I want it to rotate with the camera like the red line in picture below.
The code for rotating the camera is working great, where previousCameraPosition is set when I click the mouse and Rotate() is called when mouse button is being held down:
private void Rotate()
{
// Get the movement vector
Vector3 cameraMoveDirection = previousCameraPosition - mainCamera.ScreenToViewportPoint(Input.mousePosition);
// Rotate around the ball
mainCamera.transform.position = ballObject.transform.position;
// Make the rotations
mainCamera.transform.Rotate(new Vector3(1, 0, 0), cameraMoveDirection.y * 360);
mainCamera.transform.Rotate(new Vector3(0, 1, 0), -cameraMoveDirection.x * 360, Space.World);
// Set the camera a certain amount away from the ball
mainCamera.transform.Translate(new Vector3(0, 0, -ballObject.transform.position.z*2.5f));
// Update the previousCameraPosition during the movement
previousCameraPosition = mainCamera.ScreenToViewportPoint(Input.mousePosition);
}
I tried to create a helper object which was set to rotate exactly like the camera which made the line exactly like I wanted it, except it was backwards (180 degrees wrong, facing into the camera instead of away) and it was 1 unit long since it was normalized. I am stuck on this for far too long now, any help or guidance would be very appreciated.
First you can simply use the camera's forward vector without having to deal with any Quaternion rotation at all:
var forward = Camera.main.transform.forward;
Then what you actually seem to want is not exactly this direction but rather map it onto a flat XZ plane:
var actualForward = Vector3.ProjectOnPlane(forward, Vector3.up).Normalized;
then finally you can use this direction to draw your line e.g. between the points
var startPoint = ball.position;
var endpoint = startPoint + actualForward * lineLength;

How to add camera to Matrix4x4 rotation

I am trying to rotate a cube using System.Numerics.Matrix4x4 and SDL2 for graphic output. i have a hard time understanding the Matrix rotation concept.
I can do it, like so:
matrix *= Matrix4x4.CreateRotationX(deg);
matrix *= Matrix4x4.CreateRotationY(deg);
matrix *= Matrix4x4.CreateRotationZ(deg);
Then I'm using Vector3.Transform() on the points in the cube and draw lines between them. Looks... alright, it's rotating in place. But how do I get perspective? How to get a camera into the mix?
What about this method:
matrix *= Matrix4x4.CreateFromAxisAngle(new Vector3(2, 2, 2), (float)rad);
I am not sure how I'm supposed to use the vector there, or what it's supposed to do. My cube grows and stretches out weirdly... see pic of when the matrix is applied 10, 45 and 90 degrees on the cube:
https://www.dropbox.com/s/hui5jvky7cexciq/10_45_90.png?dl=0
How should I do this properly?

Texture rotating around background withut mouse in Monogame, c#

Im trying to rotate a texture in Monogame ! It schould rotate around another object like doing a circle (not routate the texture it self ), it schould do a circle rotate. It schould not rotate with the mouse but continosly rotating in that radius itself. Im new in MOnogame and a tried everything for two last days and nothing worked. Some said that i schould do somethink with Sin and Cos but i didnt get it ! Its for a project and im very lost ! I would be very very greatfull if someone could help me ! [So this logo schould routate around the background ][2]
Link to picture https://www.dropbox.com/s/gywi7teun8lqfp1/Unbenannt.png?dl=0
This is a pure math problem. From what i can understand, what you want is to make your texture orbit around a point, see this formula :
newX = centerX + ( cosX * (pointX-centerX) + sinX * (pointY -centerY))
newY = centerY + ( -sinX * (pointX-centerX) + cosX * (pointY -centerY))
With : centerX and centerY being the point around you want to orbit
cosX and sinX being respectively the cosinus of the angle and the sinus of the angle
pointX and pointY being the position you want to apply rotation from (the texture position in your case)
Note that the angle should be in radians, and not in degrees.
Answers to this question can be found here:
Have an object circle an object
There are also examples of how to use Math in MonoGames
If you want to use a matrix and let the api rotate for you you could try something like this
public Vector2 RotateAboutOrigin(Vector2 point, Vector2 origin, float rotation)
{
return Vector2.Transform(pointorigin,Matrix.CreateRotationZ(rotation))+origin;
}

Tracking Rotating Sprite

I am messing about in XNA and have run into a problem. I have a 48 * 48 sprite that I can keep track of its location in the game world by the top left corner of the sprite.
I want to be able to rotate the square and still keep track of the same point. For instance if I rotate 90degrees clockwise and the orginal X position was 200 the new X position should be 200 + 48(the size of the width of the image). Its fine for 90 degrees I am able to work that out in my head but each one in between is the problem!
I know there is probably some kind of formula to work this out.
Any help would be great! Oh the square is rotating on its center.
I'm just using spriteBatch.Draw()
spriteBatch.Draw( animations[currentAnimation].Texture,
Camera.WorldToScreen(WorldRectangle),
animations[currentAnimation].FrameRectangle,
color, rotationScale , new Vector2((float)frameHeight/2, (float)frameWidth/2), effect, TileMap.characterDepth);
If you have to keep track of a moving rotating sprite you can't use the top left corner, but its centroid. You already draw your sprite using the centroid to rotate it.
The problem is that the second parameter of your Draw call is a Rectangle, you sholud use a Vector2 position, instead.
You're building your application on top of a 3D graphics library. 3D graphics libraries are very good at solving this kind of problem! Break it down into smaller operations and let the library do the work for you.
First: it's easiest to think about these kinds of questions when you're working in model space rather than world space. In other words: you don't need to worry about where the rotating point is in absolute terms, you only need to worry about where it is relative to the untransformed model (in this case, your sprite without any rotation or translation).
So where is that? Simple:
var pt = new Vector3(-frameWidth / 2f, -frameHeight / 2f, 0f);
Your point of origin is the center of your sprite, so the center of your sprite in model space is (0, 0). This means that the top left corner of your sprite is half the width of the sprite in the negative x direction, and half the height of the sprite along the negative y direction.
Now create an object that represents the desired transformation. You can do this by creating a rotation matrix using XNA's built-in methods:
var transformation = Matrix.CreateRotationZ(MathHelper.ToRadians(90f));
Now apply the transformation to your original point:
var transformedPt = Vector3.Transform(pt, transformation);
This is still in model space, remember, so to get world coordinates you'll need to transform it into world space:
var transformedWorldX = transformedPt.X + spritePosition.X;
var transformedWorldY = transformedPt.Y + spritePosition.Y;
And there you go.

Categories