🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

OpenGL, Translating a Sphere

Started by
32 comments, last by Josheir 4 years, 11 months ago

I am rotating a world like a FPS and need a sphere to move opposite to the camera so that the effect is it stays put.  Here is the ball moving wrongly with the rotation:

https://www.youtube.com/watch?v=ksNt3W_p5u8 

and here is the function that changes the camera vectors with my try that didn't work:


void Camera::updateCameraVectors(void)
{
	// Calculate the new Front vector
	glm::vec3 front;
	front.x = cos(glm::radians(this->yaw)) * cos(glm::radians(this->pitch));
	front.y = sin(glm::radians(this->pitch));
	front.z = sin(glm::radians(this->yaw)) * cos(glm::radians(this->pitch));
	glm::vec3 temp = this->front;
	this->front = glm::normalize(front);
	// Also re-calculate the Right and Up vector
	this->right = glm::normalize(glm::cross(this->front, this->worldUp));  // Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
	this->up = glm::normalize(glm::cross(this->right, this->front));
	//this didn't work:
	//ball.xadj = ball.xadj + front.x;
	//ball.zadj = ball.zadj - front.z;
}

and this is for changing the world with the mouse:


void Camera::ProcessMouseMovement(GLfloat xOffset, GLfloat yOffset, GLboolean constrainPitch)
{
	xOffset *= this->mouseSensitivity;
	yOffset *= this->mouseSensitivity;
	this->yaw += xOffset;
	this->pitch += yOffset;
	// Make sure that when pitch is out of bounds, screen doesn't get flipped
	if (constrainPitch)
	{
		if (this->pitch > 89.0f)
		{
			this->pitch = 89.0f;
		}
		if (this->pitch < -89.0f)
		{
			this->pitch = -89.0f;
		}
	}
	// Update Front, Right and Up Vectors using the updated Eular angles
	this->updateCameraVectors();
}

and to get the view matrix:


glm::mat4 Camera::GetViewMatrix(void)
{
	return glm::lookAt(this->position, this->position + this->front, this->up);
}

lastly, the translate:


ball = glm::translate(ball, glm::vec3(c_mycamera.ball.xadj, 0.0f, c_mycamera.ball.zadj));

 

So,  how do I get the exactly correct amount for translating the sphere over and over again as the world rotates?

 

This has been my ongoing project for some time (thanks,)

Josheir

Advertisement

If the goal is for the sphere to remain stationary relative to the player (e.g. always directly in front, some distance from the player), then here are two typical ways you might do that:

1. Position the ball in front of the player as appropriate each update, and then allow it to be rendered like any other object.

2. Render the sphere separately, not using the camera transform, but rather using a separate set of transforms (e.g. an appropriate projection transform, and a 'model' transform to position the sphere).

What approach to take probably depends on what the sphere is supposed to represent and if/how it's supposed to interact with the environment. If, for example, it's a 'real-world' entity that the player is 'carrying' or whatever, and it can interact with the world in some way, then you might prefer option 1 above (although not necessarily). If, however, it's something like a UI element, you might prefer option 2.

Another issue would be how it's intended to interact with the environment visually. In your video it appears to be 'part of the world', but I don't know if that's what you're really after or not (sometimes UI elements, or even 'real-world' entities like the player's hands, are rendered in a way that doesn't actually interact with the world visually).

So those are some suggestions, but to be more specific it'd probably be helpful to know exactly what you're trying to do.

Ok, first let me apologize for not putting this in the graphics GPU forum.  I have really struggled with this project and I need specifics, so let me explain how I want it to work.

I have a terrain made out of triangles.  I have a large ball that is on the terrain.  When I rotate the world with the camera I want the big ball to stay put, then when the player hits the space bar I want the ball to move forward directly in front of it off in the distance.  I than want the camera to follow this ball from a set distance behind it until it stops after a set amount of movement.

I have had a hard time getting specifics for making this work and although your post is appreciated it is not exactly what I need.  I can't seem to get understandable help for this problem and the tutorials don't seem to cover this.  So, I put it on hold and come back to it later.  If anyone could help me with some very specific help I would be overjoyed.  There seem to be no tutorials on this which to me seems crazy, it would seem to be a common enough problem.  

I think I am trying to make the ball move with a model transform, and that should do it, however, I don't know how to determine this transform amount.

Thanks,

Josheir

Ok, well, it may be that I don't understand what you're wanting well enough to offer the specific help you need.

One thing that might be helpful is if you could find a video of some other game or demo that has the behavior you want, and link to it. That might clear things up. Perhaps you don't have anything like that available though.

That said, my guess (which could very well be wrong) based on what you posted is that you want an orbital camera centered on the ball, and then when you hit the space bar (or whatever), the ball moves in the direction the camera is facing (probably projected onto the ground plane), and the camera follows it. Maybe the orbital controls are disabled while the ball is moving (?), but presumably once the ball comes to a stop, the orbital control is restored.

Here:

https://www.youtube.com/watch?v=aZpW2wQPSD0

Is a video of an orbital camera that I think I linked to in another post recently as well. It may not look right to you visually because there's no ground/terrain, and because the camera goes under the target object at times, but it demonstrates the basic idea of an orbital camera. Perhaps this is what you want (for the rotation part at least), but with a different pitch range (to prohibit going under the terrain), or perhaps with no pitch variance at all (just a fixed pitch/elevation).

1 hour ago, Zakwayda said:

 

That said, my guess (which could very well be wrong) based on what you posted is that you want an orbital camera centered on the ball, and then when you hit the space bar (or whatever), the ball moves in the direction the camera is facing (probably projected onto the ground plane), and the camera follows it. Maybe the orbital controls are disabled while the ball is moving (?), but presumably once the ball comes to a stop, the orbital control is restored. 

 

This all sounds right and if you watched the video from my link this seems to be an orbital camera too, however the camera is not centered on the ball yet.

Yes, while the ball moves the orbital camera is disabled and it doesn't need to restore yet.

EDIT: It's a golf game if this helps!

51 minutes ago, Josheir said:

This all sounds right and if you watched the video from my link this seems to be an orbital camera too, however the camera is not centered on the ball yet.

I'd say the camera in your video isn't an orbital camera, because 'orbiting' around a target point is what makes an orbital camera orbital (at least that's my understanding of the term). Your video just looks like a standard first-person camera to me.

Quote

It's a golf game if this helps!

It does ? Together with your description, that gives a pretty good idea of what you're after, I think.

I'd recommend searching for 'orbital camera' and see if you can find some clear examples or tutorials. That doesn't entirely cover the second part of the problem (moving the ball and following it with the camera), but dealing with the orbital part first seems reasonable.

If you run into problems, someone here could probably provide some hints on how to implement it, as an orbital camera in its simplest form is fairly straightforward. In that case it'd be useful to know if you want the camera elevation to be variable (e.g. controllable with the mouse), or fixed.

Some general tips:

- First I would move the camera to the sphere instead of the other way around because you probably want it to follow your ball right? Anyway the steps below apply to both cases.

- If you want need the camera to be in the same location as the sphere you need the inverse matrix.

- Because with a sphere, rotation does not matter it is sufficient to take the sphere position which is in the 4th column of your sphere's matrix or in your camera's view matrix (inverted = *-1).

- However if your camera position and your sphere's position are exactly the same you wont see much (at least with backface culling on) because you are inside the sphere, which is probably not what you want. You can move in the direction of you camera by getting it's view dir (3rd column of your view matrix) which can be scaled by the distance you want to keep to your sphere

- For more information on what columns in a view matrix represent: http://www.songho.ca/opengl/gl_transform.html#modelview

- With that you can do an orbit camera

Referring to the code example from the op (which looks more like a first person cam), imo one thing you'd have to change is the lookat-matrix. In your example, it is the matrix for a first person camera (position, position + direction, up). If you change the direction vector to the target (centre of the ball), the camera will follow the ball when its position changes.

Additionally change the following:

- camera position = distance to target * trigonometry to calculate position. So your cam stays on a spherical shell around the target.

- camera front vector = target - position.

- set the view matrix as above. Edit: i mean (position, target, up).

In your mouse movement method:

- eventually, if your intuition dictates, invert pitch and/or yaw between first person and orbital mode

- as with first person, restrict pitch to +/- 89° to avoid flipping.

In your scroll method or where ever you want to control that:

- set distance between camera and target = length(target - position)

Additional restrictions where they apply.

Hope that helps on a theoretical basis on your orbital camera search ? My camera object has 12 kB of code and remarks and still it's buggy ...

The original source code had the following:


// Processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis

    void ProcessMouseScroll( GLfloat yOffset )

    {

        if ( this->zoom >= 1.0f && this->zoom <= 45.0f )

        {

            this->zoom -= yOffset;

        }

        

        if ( this->zoom <= 1.0f )

        {

            this->zoom = 1.0f;

        }

        

        if ( this->zoom >= 45.0f )

        {

            this->zoom = 45.0f;

        }

    }

This I think made it an orbital camera.  However, a FPS camera would be fine and what I would really like is to see some code to keep the ball centered so that it can move straight into the screen.

 

Josheir

3 minutes ago, Josheir said:

However, a FPS camera would be find and what I would really like is to see some code to keep the ball centered.

Assuming you mean 'fine', I think there may be some confusion of terminology here. Keeping a target position centered is a typical feature of an orbital camera, not a (so-called) FPS camera, so unless you're looking for something different than you seem to be looking for, I don't think an FPS camera is what you want, even with modifications.

Quote

This I think made it an orbital camera.

That code doesn't distinguish between camera types, because it controls zoom and any camera type (or at least both FPS and orbital cameras) can support zoom.

In any case, I'll again suggest linking to a video that shows the behavior you want, if you can find one, and searching for resources on orbital cameras. (And of course there have been some suggestions made in this thread as well.) If you get stuck or the suggestions so far aren't sufficient, I or someone else can probably take another run at it. There's not that much to an orbital camera in its simplest form, so the basics can probably be explained in a forum post. But, I think it would be helpful to first clarify exactly what behavior you're looking for (e.g. via video), as there still seems to be some confusion about that.

This topic is closed to new replies.

Advertisement