Skip to content

Add basic orbital camera implementation#37

Open
maaxxaam wants to merge 9 commits intoOpenAWE-Project:masterfrom
maaxxaam:orbital-cam
Open

Add basic orbital camera implementation#37
maaxxaam wants to merge 9 commits intoOpenAWE-Project:masterfrom
maaxxaam:orbital-cam

Conversation

@maaxxaam
Copy link
Contributor

@maaxxaam maaxxaam commented Jan 5, 2024

The aim of this PR is to resolve #13 by adding a mouse/gamepad controlled third person camera that orbits around player character. Camera's features include:

  • Orbiting around and following player with smoothing
  • An ability to switch shoulders
  • Aiming a "weapon" with changing FOV
  • An ability to focus camera at a specific point (that should be useful for implementing scripts later on)
  • Responding to static scenery by shortening orbit radius so character stays in camera's view

@maaxxaam
Copy link
Contributor Author

maaxxaam commented Jan 6, 2024

That's weird: player character seems to start travelling at incredible (around 20 orders of magnitude higher than normal) speeds from the start of the game which prevents me from testing the camera. I did test the code before the PR; however, I also did a rebase onto master right before pushing since my dev branch was 13 commits behind. Could the recent AI additions cause the character controller to break?

@Nostritius
Copy link
Member

Hi I tested your pr and noticed, that I made an error in the character controller leading to strange walues. It should be fixed in the last commit

@maaxxaam
Copy link
Contributor Author

maaxxaam commented Jan 6, 2024

Thank you for the fix! I've rebased the branch off the latest commit, testing should be easier now.

@maaxxaam
Copy link
Contributor Author

maaxxaam commented Jan 23, 2024

Hmm... That's odd. According to the failed build logs for commit 89fc1b2, it looks as if awe cmake target for Mac has arm64 architecture set while all of the previous targets were built for x86_64, leading to >600 lines of reference errors. I'm not sure that's supposed to happen here - after all, recent mac universal binary commits that could lead to such behavior are not included in this branch yet. 🤔
Upd.: checked out build logs for the latest master commit - apparently, it suffers from the same issue.

Copy link
Member

@Nostritius Nostritius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from the things, commented I am really thinking, that it would be better to control the camera also from the PlayerController or at least centralize the control of the player into some place, since for example, when you turn the camera around enough, Alan will also turn in that direction.

_movementRotation.y += axisEvent.delta.y;
} else if (event.action == kRotateGamepad) {
_movementRotation.x += axisEvent.absolute.x * 10.0f;
_movementRotation.y += axisEvent.absolute.y * 10.0f;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe make the rotation factor astatic constant

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That constant has appeared during a short period of time when I was able to test gamepad controls with an actual gamepad. While I do agree this should be moved into a named variable, it probably should not be a constant to allow tweaking the sensitivity during runtime (I do not remember whether original games allow this, but that seems like a useful option further down the line).

@maaxxaam
Copy link
Contributor Author

Alright, I hope I didn't go too much into commenting OrbitalCamera's behavior, but it should explain a lot more choices that were made to make the camera feel better and closer to original game's one.

Regarding the character issue: I actually have a code snippet to do that - it was intentionally left out to make this PR focused on camera only. After what happened to the event handling PR that grew double the size because I kept adding more related stuff to it, I hope that keeping changeset constrained would be the better experience for both of us (if you think otherwise - feel free to say so, I'll add that in).

Moreover, it is not completely obvious where the central place of control should be since we have at least two different ways to look at and navigate the world - through character movement and orbital camera and through free camera. I've been testing an option to make a CameraDirector class that would control storing and switching between cameras as a possible solution, but that also includes changes to event handling (namely, adding an option to remove a callback from action), which should probably be an its own PR really.

@maaxxaam maaxxaam requested a review from Nostritius March 22, 2024 15:26
Copy link
Member

@Nostritius Nostritius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from the commented things, I also thought about where to place the controls, and I see your point that it is difficult especially when considering the camera work. Nevertheless, I think, the best way would be to add the orbital cam control to the player controller due to its close relation to the other controls, we have over Alan. The freecam mode should be switchable between orbital cam and freecam, maybe with a kind of enabled flag. If you do not want to do that now, we can only add the high level orbital cam stuff.

_world->removeAction(actionInterface);
}

const CastResult PhysicsManager::raycastStatic(glm::vec3& from, glm::vec3& to) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you return CastResult by value, you can safely remove const and instead make the method itself const

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... While I can indeed do that, that seems to go against the reason that const was put there in the first place - to signal that CastResult is not supposed to be changed. As far as I understand, making the method const will not make return type const in this case, because we create it inside the function body

// src/physics/physicsman.cpp:102
return CastResult{
	true,
	rayHitPoint,
	rayHitPoint
};
// src/physics/physicsman.cpp:109
return CastResult{
	false,
	glm::zero<glm::vec3>(),
	glm::zero<glm::vec3>()
};

and not return some field of the PhysicsManager object (which would carry the const modifier of the parent object). However, it is a good idea to mark casting methods const as well since they do not change PhysicsManager.

Copy link
Member

@Nostritius Nostritius Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but you return the CastResult by value, which means the const is practically meaningless, since it can be copied. The member consts ensure it stays immutable.

};
}

const CastResult PhysicsManager::shapeCastStatic(btConvexShape* castShape, glm::mat4& from, glm::mat4& to) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you simplify the interface of this method, maybe into a sphereCastStatic, giving simply a float as radius? I just want the bullet stuff to be used exclusively in the physics part. And some comment in the header would also be nice to explain what the method is doing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing. This method was left intentionally broad for possible later use with other shapes (the same reason why raycastStatic method is still in this PR despite not being used), but I do agree that passing transformation matrices is cumbersome at the very least.

* You should have received a copy of the GNU General Public License
* along with OpenAWE. If not, see <http://www.gnu.org/licenses/>.
*/
#define GLM_ENABLE_EXPERIMANTAL
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this macro, it is already defined in the CMakeLists.txt


Physics::CharacterControllerPtr _followedObject;

btSphereShape _castSphere;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I described in another comment, bullet stuff should be exclusively located in the physics part

Copy link
Contributor Author

@maaxxaam maaxxaam Mar 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of this was to avoid frequent creation-destruction of bullet shapes for handling casts (especially because it happens every frame for the orbital camera) by storing an object used for collision inside the camera and passing it as a parameter. This could be instead mitigated by storing a sphere object in PhysicsManager (which seemed inappropriate at the time as you would have to keep changing sphere's radius for each cast) or by creating an object pool for the shapes.

maaxxaam added 9 commits July 11, 2024 19:59
Adds OrbitalCamera and ControlledOrbitalCamera classes.
Other changes:
- Add CharacterController.getUpperPosition();
- Add _fov field and getFOV() for base Camera class;
- Tweak Renderer to use camera's FOV in calculations
- Use sphere to check for camera collisions
- Accumulate and smooth user input
- Aiming moves camera closer to the character
- Shoulder gets longer with the higher pitch
- Improve default camera orientation
- Adjust defaults to match AWAN's camera better
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Player Character Orbital cam

2 participants