New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Over the shoulder third person view support as part of post 1.0 featu… #1425

Open
wants to merge 8 commits into
base: master
from

Conversation

Projects
None yet
6 participants
@crussell187

crussell187 commented Aug 31, 2017

Over the shoulder third person view support as part of post 1.0 feature …#390. The setting is off by default and has a setting in the prefs tab called "Over The Shoulder Camera".

Forum topic:
https://forum.openmw.org/viewtopic.php?f=6&t=4587

Summary of effect of the changes:
It cycles by tab like vanilla when third person over shoulder is disabled. Otherwise, it will cycle first, third person vanilla, and over the shoulder third person. I decided not to enable mouse wheel distance changes with third person over shoulder since the effect moving away from the camera looked strange when the player is shifted to the left for over the shoulder.

@akortunov

This comment has been minimized.

Show comment
Hide comment
@akortunov

akortunov Aug 31, 2017

Contributor

Otherwise, it will cycle first, third person vanilla, and over the shoulder third person.

Does it make sense? Maybe just cycle first/third person. How 3d-person behaves, depends on setting value.

An another issue: a camera is not centered in a preview mode (when you hold a TAB button), if a current mode is a 3d-person over shoulder mode. A vanity mode is affected too.

Also it would be nice to show a crosshair in the "over shoulder" mode.

Contributor

akortunov commented Aug 31, 2017

Otherwise, it will cycle first, third person vanilla, and over the shoulder third person.

Does it make sense? Maybe just cycle first/third person. How 3d-person behaves, depends on setting value.

An another issue: a camera is not centered in a preview mode (when you hold a TAB button), if a current mode is a 3d-person over shoulder mode. A vanity mode is affected too.

Also it would be nice to show a crosshair in the "over shoulder" mode.

@akortunov

This comment has been minimized.

Show comment
Hide comment
@akortunov

akortunov Aug 31, 2017

Contributor

An another issue: your new mode is not persistent (if you restart a game, your mode will be swithed to the 3d-person one). This how the game stores a camera mode:
writer.writeHNT("FIRS", isFirstPerson());

So we have a two options:

  1. Implement a something like GetCameraMode and store your mode in savegame too.
  2. Modify this PR to alter 3d-person camera mode instead of adding a new one.
Contributor

akortunov commented Aug 31, 2017

An another issue: your new mode is not persistent (if you restart a game, your mode will be swithed to the 3d-person one). This how the game stores a camera mode:
writer.writeHNT("FIRS", isFirstPerson());

So we have a two options:

  1. Implement a something like GetCameraMode and store your mode in savegame too.
  2. Modify this PR to alter 3d-person camera mode instead of adding a new one.
@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Aug 31, 2017

Modify this PR to alter 3d-person camera mode instead of adding a new one.

This makes more sense, I think. Isn't switching through 3 modes a little cumbersome?

The save format shouldn't be changed for a purely visual feature.

ghost commented Aug 31, 2017

Modify this PR to alter 3d-person camera mode instead of adding a new one.

This makes more sense, I think. Isn't switching through 3 modes a little cumbersome?

The save format shouldn't be changed for a purely visual feature.

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Aug 31, 2017

Does it make sense? Maybe just cycle first/third person. How 3d-person behaves, depends on setting value.

I can remove the new cycleView function I added and revert back to toggle for all camera view modification paths. There was an opinion from Chris on the forum post that removing the setting for third person over the shoulder would be a good option with the implication that the user can manually specify their offsets in the config file. Not sure how votes are taken with all of the senior developers but just let me know what you guys think is best :).

An another issue: a camera is not centered in a preview mode (when you hold a TAB button), if a current mode is a 3d-person over shoulder mode. A vanity mode is affected too.

I will look into this when I get home. Should be an easy fix.

So we have a two options:

Implement a something like GetCameraMode and store your mode in savegame too.
Modify this PR to alter 3d-person camera mode instead of adding a new one.

I'm starting to like your idea of altering the active 3rd person if this starts affecting too many code paths (with the potential of introducing more bugs).

crussell187 commented Aug 31, 2017

Does it make sense? Maybe just cycle first/third person. How 3d-person behaves, depends on setting value.

I can remove the new cycleView function I added and revert back to toggle for all camera view modification paths. There was an opinion from Chris on the forum post that removing the setting for third person over the shoulder would be a good option with the implication that the user can manually specify their offsets in the config file. Not sure how votes are taken with all of the senior developers but just let me know what you guys think is best :).

An another issue: a camera is not centered in a preview mode (when you hold a TAB button), if a current mode is a 3d-person over shoulder mode. A vanity mode is affected too.

I will look into this when I get home. Should be an easy fix.

So we have a two options:

Implement a something like GetCameraMode and store your mode in savegame too.
Modify this PR to alter 3d-person camera mode instead of adding a new one.

I'm starting to like your idea of altering the active 3rd person if this starts affecting too many code paths (with the potential of introducing more bugs).

removed cycling of all third person views when third person over the …
…shoulder is enabled. also added settings to control x,z, and camera distance for third person over shoulder mode
@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 1, 2017

New changesets include removal of cycling code, preview mode fix for processViewChange, fix of warning for constructor ordering of member initialization list, and addition of command line settings for third person over the shoulder x,y,z offsets. Seems to be persistent over a save game now as well.

crussell187 commented Sep 1, 2017

New changesets include removal of cycling code, preview mode fix for processViewChange, fix of warning for constructor ordering of member initialization list, and addition of command line settings for third person over the shoulder x,y,z offsets. Seems to be persistent over a save game now as well.

@akortunov

This comment has been minimized.

Show comment
Hide comment
@akortunov

akortunov Sep 1, 2017

Contributor

Awesome work.
But some problems are spotted in the "over shoulder" mode:

  1. A camera in the vanity mode is not centered (review mode works fine).
  2. A mouse wheel zoom behaves weird (with "allow third person zoom = true").
  3. Maybe we should show a crosshair.
Contributor

akortunov commented Sep 1, 2017

Awesome work.
But some problems are spotted in the "over shoulder" mode:

  1. A camera in the vanity mode is not centered (review mode works fine).
  2. A mouse wheel zoom behaves weird (with "allow third person zoom = true").
  3. Maybe we should show a crosshair.
@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 1, 2017

A camera in the vanity mode is not centered (review mode works fine).

Missed your comment previously about this. I'm going to set the idle value really low so I can better test this.

A mouse wheel zoom behaves weird (with "allow third person zoom = true").

I'll debug the camera distance functions. Hopefully an easy fix.

Maybe we should show a crosshair.

Agreed. Another problem I have is when you want to activate things (doors, conversation, etc.), you ideally want the activate to happen right in front of the character but I think it may be still centered even in over the shoulder mode. Does moving the activation detection when in this mode seem reasonable as well? This would affect crosshair placement as well.

crussell187 commented Sep 1, 2017

A camera in the vanity mode is not centered (review mode works fine).

Missed your comment previously about this. I'm going to set the idle value really low so I can better test this.

A mouse wheel zoom behaves weird (with "allow third person zoom = true").

I'll debug the camera distance functions. Hopefully an easy fix.

Maybe we should show a crosshair.

Agreed. Another problem I have is when you want to activate things (doors, conversation, etc.), you ideally want the activate to happen right in front of the character but I think it may be still centered even in over the shoulder mode. Does moving the activation detection when in this mode seem reasonable as well? This would affect crosshair placement as well.

@akortunov

This comment has been minimized.

Show comment
Hide comment
@akortunov

akortunov Sep 1, 2017

Contributor

Does moving the activation detection when in this mode seem reasonable as well?

I do not know for now, and suggest to add a crosshair first. Then it will be easier to experiment with activation and combat, include shooting.

Contributor

akortunov commented Sep 1, 2017

Does moving the activation detection when in this mode seem reasonable as well?

I do not know for now, and suggest to add a crosshair first. Then it will be easier to experiment with activation and combat, include shooting.

fixed alignment of vanity mode, mouse wheel zoom, and added crosshair…
… for third person over the shoulder mode
@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 1, 2017

FYI, I equipped a bow and shot and the alignment is off from the crosshair :(. Most likely the arrow trajectory is calculated to be aligned with the character and parallel to the down range axis. Either I have to move the crosshair to match or adjust the arrow path to be at an angle to meet the crosshair.

Alternatively, I could create a new mode for bow combat that would negate the normal over the shoulder for a zoomed in over the shoulder in line with the crosshair.

crussell187 commented Sep 1, 2017

FYI, I equipped a bow and shot and the alignment is off from the crosshair :(. Most likely the arrow trajectory is calculated to be aligned with the character and parallel to the down range axis. Either I have to move the crosshair to match or adjust the arrow path to be at an angle to meet the crosshair.

Alternatively, I could create a new mode for bow combat that would negate the normal over the shoulder for a zoomed in over the shoulder in line with the crosshair.

@kcat

This comment has been minimized.

Show comment
Hide comment
@kcat

kcat Sep 1, 2017

Contributor

I don't think changing anything about the activation detection or projectile trajectory is a good idea, since it would cause a change in behavior (cause difficulty activating or hitting certain things in over-the-shoulder mode compared to first-person or third-person centered, or make it possible to hit or activate things you couldn't in those modes).

Instead, try to angle the camera inward to focus on a spot that's some distance in front of the player. Or perhaps angle the camera to look at what the player's is "targetting".

Contributor

kcat commented Sep 1, 2017

I don't think changing anything about the activation detection or projectile trajectory is a good idea, since it would cause a change in behavior (cause difficulty activating or hitting certain things in over-the-shoulder mode compared to first-person or third-person centered, or make it possible to hit or activate things you couldn't in those modes).

Instead, try to angle the camera inward to focus on a spot that's some distance in front of the player. Or perhaps angle the camera to look at what the player's is "targetting".

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 1, 2017

I think i may do the tomb raider reboot style of archery which is similar to what you just described. When the player is going to shoot, zoom into behind the player such that the bow lines up with the crosshair naturally.

For general activation, adding the crosshair makes it clear where you need to be for activation but looks strange (being to the left of the door instead of in front when you choose to go through). We may want to allow an offset in activation to make this seem less strange. I'll find the code and try to do it in such a way that minimizes risk to vanilla behavior.

crussell187 commented Sep 1, 2017

I think i may do the tomb raider reboot style of archery which is similar to what you just described. When the player is going to shoot, zoom into behind the player such that the bow lines up with the crosshair naturally.

For general activation, adding the crosshair makes it clear where you need to be for activation but looks strange (being to the left of the door instead of in front when you choose to go through). We may want to allow an offset in activation to make this seem less strange. I'll find the code and try to do it in such a way that minimizes risk to vanilla behavior.

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 2, 2017

ok after both trying the offset to match activation in front of the player and reviewing online many over the shoulder games, keeping center to match vanilla makes more sense. I will focus on a change in camera view for aiming the bow now so that archery isn't broken in this mode.

crussell187 commented Sep 2, 2017

ok after both trying the offset to match activation in front of the player and reviewing online many over the shoulder games, keeping center to match vanilla makes more sense. I will focus on a change in camera view for aiming the bow now so that archery isn't broken in this mode.

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 4, 2017

So after spending a decent amount of time experimenting with a ranged third person view which orients the player character towards the target under the crosshair, I've noticed that in openmw's current state, there is no concept of camera view rotation separated from player rotation. When player rotation updates so does camera (deep within the rotate object rendering function). I'm now think about moving the camera rotation out of the rotation object function and in the general update function in character.cpp. It's been a nice 3d vector geometry refresher for me this weekend :).

Any other suggestions? I think in general this is the right way to go since it will allow other animation mechanics in third person where camera orientation is disjoint from the player. It will also allow for camera rotation updates to be event driven based on input from the player and not be constantly testing every rotating object to see if they are the object the camera is attached to:

void RenderingManager::rotateObject(const MWWorld::Ptr &ptr, const osg::Quat& rot)
{
if(ptr == mCamera->getTrackingPtr() &&
!mCamera->isVanityOrPreviewModeEnabled()
{
mCamera->rotateCamera(-ptr.getRefData().getPosition().rot[0], -ptr.getRefData().getPosition().rot[2], false);
}

ptr.getRefData().getBaseNode()->setAttitude(rot);
}

crussell187 commented Sep 4, 2017

So after spending a decent amount of time experimenting with a ranged third person view which orients the player character towards the target under the crosshair, I've noticed that in openmw's current state, there is no concept of camera view rotation separated from player rotation. When player rotation updates so does camera (deep within the rotate object rendering function). I'm now think about moving the camera rotation out of the rotation object function and in the general update function in character.cpp. It's been a nice 3d vector geometry refresher for me this weekend :).

Any other suggestions? I think in general this is the right way to go since it will allow other animation mechanics in third person where camera orientation is disjoint from the player. It will also allow for camera rotation updates to be event driven based on input from the player and not be constantly testing every rotating object to see if they are the object the camera is attached to:

void RenderingManager::rotateObject(const MWWorld::Ptr &ptr, const osg::Quat& rot)
{
if(ptr == mCamera->getTrackingPtr() &&
!mCamera->isVanityOrPreviewModeEnabled()
{
mCamera->rotateCamera(-ptr.getRefData().getPosition().rot[0], -ptr.getRefData().getPosition().rot[2], false);
}

ptr.getRefData().getBaseNode()->setAttitude(rot);
}

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 5, 2017

So I moved the camera rotation out into character.cpp and everything seems to work. I have preliminary aim alignment working with a third person over the shoulder archery option here:

https://youtu.be/_7xBR2rQL7s

Not commit ready but feedback is welcome. What I don't like is the amount of fluctuation when lining up to the target but i may be able to minimize that with some tweaks. Another option is to stop aligning the entire player with the target under crosshair and just adjust the projectile. Technically the projectile would be bending relative to the orientation of the player for the projectile adjustment option. It might be very noticeable that the alignment from the bow shot is wrong on a close range shot. Thoughts?

crussell187 commented Sep 5, 2017

So I moved the camera rotation out into character.cpp and everything seems to work. I have preliminary aim alignment working with a third person over the shoulder archery option here:

https://youtu.be/_7xBR2rQL7s

Not commit ready but feedback is welcome. What I don't like is the amount of fluctuation when lining up to the target but i may be able to minimize that with some tweaks. Another option is to stop aligning the entire player with the target under crosshair and just adjust the projectile. Technically the projectile would be bending relative to the orientation of the player for the projectile adjustment option. It might be very noticeable that the alignment from the bow shot is wrong on a close range shot. Thoughts?

more third person over the shoulder enhancements including a third pe…
…rson ranged aim capability when pressing the G button for keyboard and the left trigger for controller to aim
@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 8, 2017

I was able to minimize the fluctuation of aligning aim with crosshair. I also decoupled the camera rotation from the general object rotation code. Now different camera modes can operate the camera rotation independent of the player while the player is moving. I currently have third person ranged aim mapped to the G key and left trigger for keyboard and controller. Let me know if you see any issues. Otherwise, it should be close to merge worthy.

crussell187 commented Sep 8, 2017

I was able to minimize the fluctuation of aligning aim with crosshair. I also decoupled the camera rotation from the general object rotation code. Now different camera modes can operate the camera rotation independent of the player while the player is moving. I currently have third person ranged aim mapped to the G key and left trigger for keyboard and controller. Let me know if you see any issues. Otherwise, it should be close to merge worthy.

@akortunov

This comment has been minimized.

Show comment
Hide comment
@akortunov

akortunov Sep 8, 2017

Contributor

I am not sure if adding a new hotkey is a good solution.

Contributor

akortunov commented Sep 8, 2017

I am not sure if adding a new hotkey is a good solution.

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 8, 2017

suggestions? it's mainly there as an aim key. Every usage is guarded with third person over the shoulder view mode so vanilla should be unaffected

crussell187 commented Sep 8, 2017

suggestions? it's mainly there as an aim key. Every usage is guarded with third person over the shoulder view mode so vanilla should be unaffected

@kcat

This comment has been minimized.

Show comment
Hide comment
@kcat

kcat Sep 8, 2017

Contributor

I wouldn't worry about aiming yet, that would be a whole separate discussion on how to properly do it. Just keep it simple, apply a horizontal and vertical offset to camera and focus on what the player is looking at.

Contributor

kcat commented Sep 8, 2017

I wouldn't worry about aiming yet, that would be a whole separate discussion on how to properly do it. Just keep it simple, apply a horizontal and vertical offset to camera and focus on what the player is looking at.

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 8, 2017

I thought about this before when you posted this option. The problem is the arrow trajectory is calculated normal to the orientation of the player ( which makes sense ). If you align the camera to the player such that the crosshair meets the player's aim you have 3 options without affecting trajectory code:

  1. Zoom completely into center again so that the camera always statically aligns with the player's trajectory
  2. Constantly shift the camera left and right by adjustments to maintain the triangulation of the target under cross hair with the player's world orientation
  3. Slightly rotate the player to adjust to the target distance when in aim while keeping the camera position/orientation static in world space. This is effectively what I have done.

1 is just what we already do for vanilla in both 3rd and 1st person. 2 seems to be what you are arguing for but I was worried it would look weird with the camera swaying back and forth. We can still keep solution 3 and I can remove the new key for aiming if that is contentious. I could instead just automatically start aiming when you equip the ranged weapon.

Note that with third person over the shoulder setting being set to false, the new key I added and the new functionality for this aiming are off and behavior is set back to vanilla.

crussell187 commented Sep 8, 2017

I thought about this before when you posted this option. The problem is the arrow trajectory is calculated normal to the orientation of the player ( which makes sense ). If you align the camera to the player such that the crosshair meets the player's aim you have 3 options without affecting trajectory code:

  1. Zoom completely into center again so that the camera always statically aligns with the player's trajectory
  2. Constantly shift the camera left and right by adjustments to maintain the triangulation of the target under cross hair with the player's world orientation
  3. Slightly rotate the player to adjust to the target distance when in aim while keeping the camera position/orientation static in world space. This is effectively what I have done.

1 is just what we already do for vanilla in both 3rd and 1st person. 2 seems to be what you are arguing for but I was worried it would look weird with the camera swaying back and forth. We can still keep solution 3 and I can remove the new key for aiming if that is contentious. I could instead just automatically start aiming when you equip the ranged weapon.

Note that with third person over the shoulder setting being set to false, the new key I added and the new functionality for this aiming are off and behavior is set back to vanilla.

@kcat

This comment has been minimized.

Show comment
Hide comment
@kcat

kcat Sep 8, 2017

Contributor

I would avoid 3, auto-rotating the player, since that adds complexity. It could cause the player to move oddly if the actor turns left and right to aim at what the camera looks at, and it creates an edge case of objects close to the camera.

Number 2 seems to be the simplest workable solution, as long as the camera transitions are done smoothly. Start simple, and more advanced/complex behaviors can be done later as needed.

The aim key may only be usable in over-the-shoulder, but it's still a whole new mechanic that should get its own discussion, and one that can give an advantage to one camera mode over the other. If aiming were to be added as a post-1.0 feature (e.g. like the Skyrim perk), it'll just create more problems to have it here first.

Contributor

kcat commented Sep 8, 2017

I would avoid 3, auto-rotating the player, since that adds complexity. It could cause the player to move oddly if the actor turns left and right to aim at what the camera looks at, and it creates an edge case of objects close to the camera.

Number 2 seems to be the simplest workable solution, as long as the camera transitions are done smoothly. Start simple, and more advanced/complex behaviors can be done later as needed.

The aim key may only be usable in over-the-shoulder, but it's still a whole new mechanic that should get its own discussion, and one that can give an advantage to one camera mode over the other. If aiming were to be added as a post-1.0 feature (e.g. like the Skyrim perk), it'll just create more problems to have it here first.

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 9, 2017

I'll try this but with this approach, you will not maintain the same target perspective entering and exiting the aim mode which means the object under crosshair before you start aiming with a bow will not be the same as the target that your third person player model will be looking at once you enter aim mode.

Also if I remove the aim key, there are only a few options to make the aim view usable:

  1. When you click left mouse to draw the bow, you transition to aim view. When you release the arrow, you exit. This will cause constant view changes for back to back shots which doesn't seem ideal.
  2. As soon as you draw your bow, you enter constant aim mode. When you sheath your bow, you exit to normal view.

The second option seems doable but you can never have your bow out during general running in combat and must go through both animations (draw and aim) to shoot.

If any of you guys are on discord to voice chat, we might be able to talk through some of these options without too many TLDR posts.

crussell187 commented Sep 9, 2017

I'll try this but with this approach, you will not maintain the same target perspective entering and exiting the aim mode which means the object under crosshair before you start aiming with a bow will not be the same as the target that your third person player model will be looking at once you enter aim mode.

Also if I remove the aim key, there are only a few options to make the aim view usable:

  1. When you click left mouse to draw the bow, you transition to aim view. When you release the arrow, you exit. This will cause constant view changes for back to back shots which doesn't seem ideal.
  2. As soon as you draw your bow, you enter constant aim mode. When you sheath your bow, you exit to normal view.

The second option seems doable but you can never have your bow out during general running in combat and must go through both animations (draw and aim) to shoot.

If any of you guys are on discord to voice chat, we might be able to talk through some of these options without too many TLDR posts.

@kcat

This comment has been minimized.

Show comment
Hide comment
@kcat

kcat Sep 9, 2017

Contributor

Don't worry about an aim view. With the camera looking at what the player is, the crosshair will be at the correct spot for shooting. Aiming can be discussed later with all camera modes in consideration.

Contributor

kcat commented Sep 9, 2017

Don't worry about an aim view. With the camera looking at what the player is, the crosshair will be at the correct spot for shooting. Aiming can be discussed later with all camera modes in consideration.

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 9, 2017

just so it's more clear what I had before and after, here's what I'm putting in the comments in beautiful ascii art:

My first algorithm which re-oriented the player:

/*
    * orientPlayerTowardsCameraCrosshair
    * Ascii art for algorithm when looking down from above:
    *
    *                      ^           |
    *                      |         -- --  <-------- Target under crosshair
    *                      |      ---  |
    *      default------>  |       / | ^
    *  3rd pers over       |      /    |
    *  shoulder orient     |     /^    |
    *                      |    / |    |
    *                      |   / new   |
    *                      |  / player |
    *                      | / orient  |
    *                  ----------      |
    *                  | Player |      |
    *                  ----------      |
    *                              -----------
    *                              | cam pos |
    *                              -----------
    */    

The algorithm you are wanting which is re-orienting the camera:

 /*
    * realignCameraTowardsPlayerCrosshair
    * Ascii art for algorithm when looking down from above:
    *
    *   target player is   |           |
    *   looking at --->  -- --       -- --  <-------- normal crosshair
    *                      | ---       |
    *      default------>  ^| \        ^
    *  3rd pers over       |   \       |
    *  shoulder orient     |    \      | <------ default 3rd pers over shoulder
    *                      |    ^\     |            camera orientation
    *                      |    | \    |
    *                      |new cam\   |
    *                      | orient \  |
    *                  ----------    \ |
    *                  | Player |     \|
    *                  ----------      |
    *                              -----------
    *                              | cam pos |
    *                              -----------
    */

crussell187 commented Sep 9, 2017

just so it's more clear what I had before and after, here's what I'm putting in the comments in beautiful ascii art:

My first algorithm which re-oriented the player:

/*
    * orientPlayerTowardsCameraCrosshair
    * Ascii art for algorithm when looking down from above:
    *
    *                      ^           |
    *                      |         -- --  <-------- Target under crosshair
    *                      |      ---  |
    *      default------>  |       / | ^
    *  3rd pers over       |      /    |
    *  shoulder orient     |     /^    |
    *                      |    / |    |
    *                      |   / new   |
    *                      |  / player |
    *                      | / orient  |
    *                  ----------      |
    *                  | Player |      |
    *                  ----------      |
    *                              -----------
    *                              | cam pos |
    *                              -----------
    */    

The algorithm you are wanting which is re-orienting the camera:

 /*
    * realignCameraTowardsPlayerCrosshair
    * Ascii art for algorithm when looking down from above:
    *
    *   target player is   |           |
    *   looking at --->  -- --       -- --  <-------- normal crosshair
    *                      | ---       |
    *      default------>  ^| \        ^
    *  3rd pers over       |   \       |
    *  shoulder orient     |    \      | <------ default 3rd pers over shoulder
    *                      |    ^\     |            camera orientation
    *                      |    | \    |
    *                      |new cam\   |
    *                      | orient \  |
    *                  ----------    \ |
    *                  | Player |     \|
    *                  ----------      |
    *                              -----------
    *                              | cam pos |
    *                              -----------
    */
@kcat

This comment has been minimized.

Show comment
Hide comment
@kcat

kcat Sep 9, 2017

Contributor

Yes, the latter is what I think it should do. The former creates an issue where the player is looking in a different direction than they're moving (i.e. they're constantly strafing). This effect would get worse the closer the object is. It also creates some edge cases where it's possible to "look at" something different in over-the-shoulder due to the camera being offset. For example:

                             |   |
                             | -- --  <-------- Target under crosshair
                             |   |
                  a wall     |   ^
                             |   |
              ---------------+   |
     default------>  ^           |
 3rd pers over       |           |
 shoulder orient     |           |
                     |           |
                 ----------      |
                 | Player |      |
                 ----------      |
                            -----------
                            | cam pos |
                            -----------

The player would not only be able to "target" something around the corner (where first-person and third-person centered can't), but when shooting a projectile, it would hit the wall despite the crosshair being directly on something else.

By having the camera turn instead of the player, you avoid those issues. The worst that would happen is the camera's view gets blocked from what the player is looking at, but there are ways to fix that (move the camera back toward center until it gets line of sight). You can also leverage the fact that the engine already calculates exactly what the player is looking at for activation purposes... you can just reuse that ray test's result to figure out the needed camera orientation.

Contributor

kcat commented Sep 9, 2017

Yes, the latter is what I think it should do. The former creates an issue where the player is looking in a different direction than they're moving (i.e. they're constantly strafing). This effect would get worse the closer the object is. It also creates some edge cases where it's possible to "look at" something different in over-the-shoulder due to the camera being offset. For example:

                             |   |
                             | -- --  <-------- Target under crosshair
                             |   |
                  a wall     |   ^
                             |   |
              ---------------+   |
     default------>  ^           |
 3rd pers over       |           |
 shoulder orient     |           |
                     |           |
                 ----------      |
                 | Player |      |
                 ----------      |
                            -----------
                            | cam pos |
                            -----------

The player would not only be able to "target" something around the corner (where first-person and third-person centered can't), but when shooting a projectile, it would hit the wall despite the crosshair being directly on something else.

By having the camera turn instead of the player, you avoid those issues. The worst that would happen is the camera's view gets blocked from what the player is looking at, but there are ways to fix that (move the camera back toward center until it gets line of sight). You can also leverage the fact that the engine already calculates exactly what the player is looking at for activation purposes... you can just reuse that ray test's result to figure out the needed camera orientation.

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 9, 2017

You can also leverage the fact that the engine already calculates exactly what the player is looking at for activation purposes... you can just reuse that ray test's result to figure out the needed camera orientation.

This is currently camera centric and doesn't factor in player model position (always cast from 0.5, 0.5, cameraDistance). It's the getFacedObject routine in the activation code. This was always ok for 3rd person / 1st person centered since camera position == player position with only a distance delta to factor.

But you are right that re-using that code is the way to go :). It's how I calculated the target angle on my previous solution. Just have to plug in the players position data instead of the camera and it should just work.

Thanks for the feeback. I should have something in the next day or so.

crussell187 commented Sep 9, 2017

You can also leverage the fact that the engine already calculates exactly what the player is looking at for activation purposes... you can just reuse that ray test's result to figure out the needed camera orientation.

This is currently camera centric and doesn't factor in player model position (always cast from 0.5, 0.5, cameraDistance). It's the getFacedObject routine in the activation code. This was always ok for 3rd person / 1st person centered since camera position == player position with only a distance delta to factor.

But you are right that re-using that code is the way to go :). It's how I calculated the target angle on my previous solution. Just have to plug in the players position data instead of the camera and it should just work.

Thanks for the feeback. I should have something in the next day or so.

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 13, 2017

Small update. Tried a very basic manipulation of the getFacedObject function to calculate based off of the screen offset of the player in the third person over the shoulder instead of directly center screen.

Effectively made the below function:

MWWorld::Ptr World::getPlayerFacedObject(float maxDistance, bool ignorePlayer)
    {
        MWRender::RenderingManager::RayResult rayToObject;
        osg::Vec2f playerScreenPos = mRendering->getCamera()->getPlayerScreenPosition();
        //printf("playerScreenPos: x,y -> %f,%f\n", playerScreenPos.x(), playerScreenPos.y());
        rayToObject = mRendering->castCameraToViewportRay(playerScreenPos.x(), playerScreenPos.y(), maxDistance + mRendering->getCameraDistance(), ignorePlayer);
        return rayToObject.mHitObject;
    }

Just a tiny problem with this function is the fact that it still follows camera orientation when re-calculating the faced object so it's camera centric and not player model centric.

I do see this code used for casting a ray towards the target of a spell caster:

 osg::Vec3f origin = getActorHeadTransform(actor).getTrans();

        osg::Quat orient = osg::Quat(actor.getRefData().getPosition().rot[0], osg::Vec3f(-1,0,0))
                * osg::Quat(actor.getRefData().getPosition().rot[2], osg::Vec3f(0,0,-1));

        osg::Vec3f direction = orient * osg::Vec3f(0,1,0);
        osg::Vec3f dest = origin + direction * distance;
MWRender::RenderingManager::RayResult result2 = mRendering->castRay(origin, dest, true, true);

This should take into account the player orientation instead. Does this seem like the better option?

crussell187 commented Sep 13, 2017

Small update. Tried a very basic manipulation of the getFacedObject function to calculate based off of the screen offset of the player in the third person over the shoulder instead of directly center screen.

Effectively made the below function:

MWWorld::Ptr World::getPlayerFacedObject(float maxDistance, bool ignorePlayer)
    {
        MWRender::RenderingManager::RayResult rayToObject;
        osg::Vec2f playerScreenPos = mRendering->getCamera()->getPlayerScreenPosition();
        //printf("playerScreenPos: x,y -> %f,%f\n", playerScreenPos.x(), playerScreenPos.y());
        rayToObject = mRendering->castCameraToViewportRay(playerScreenPos.x(), playerScreenPos.y(), maxDistance + mRendering->getCameraDistance(), ignorePlayer);
        return rayToObject.mHitObject;
    }

Just a tiny problem with this function is the fact that it still follows camera orientation when re-calculating the faced object so it's camera centric and not player model centric.

I do see this code used for casting a ray towards the target of a spell caster:

 osg::Vec3f origin = getActorHeadTransform(actor).getTrans();

        osg::Quat orient = osg::Quat(actor.getRefData().getPosition().rot[0], osg::Vec3f(-1,0,0))
                * osg::Quat(actor.getRefData().getPosition().rot[2], osg::Vec3f(0,0,-1));

        osg::Vec3f direction = orient * osg::Vec3f(0,1,0);
        osg::Vec3f dest = origin + direction * distance;
MWRender::RenderingManager::RayResult result2 = mRendering->castRay(origin, dest, true, true);

This should take into account the player orientation instead. Does this seem like the better option?

added ability to orient camera towards target in front of the player …
…model for third person over the shoulder
@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Sep 14, 2017

I'll remove the aim key I added in the next commit but for now can I get some feedback from you all on the 2 options (rotate camera towards what player is looking at vs. rotate player towards what the camera crosshair is on) ?

I've experimented with both and making the camera look at the target works mostly except that the initial targeting for the player is non-intuitive. You have to look slightly to the right of the target so that the camera will rotate to look at what the player is facing.

Rotating the player seems to work better for natural targeting with the crosshair (ignoring the corner case with the building in the way that you mentioned previously).

After you pull my code, you can experiment between the 2 by modifying this code in character.cpp:

if(mPtr == getPlayer())
            MWBase::Environment::get().getWorld()->getPlayer().realignCameraTowardsPlayerCrosshair();
        /*if (mPtr == getPlayer())
            MWBase::Environment::get().getWorld()->getPlayer().orientPlayerTowardsCameraCrosshair();*/

Just comment the one you don't want active to switch between them.

Note that the code is always running (no aim key involved) and that both solutions will re-orient the camera back to match the player orientation when no target is found.

crussell187 commented Sep 14, 2017

I'll remove the aim key I added in the next commit but for now can I get some feedback from you all on the 2 options (rotate camera towards what player is looking at vs. rotate player towards what the camera crosshair is on) ?

I've experimented with both and making the camera look at the target works mostly except that the initial targeting for the player is non-intuitive. You have to look slightly to the right of the target so that the camera will rotate to look at what the player is facing.

Rotating the player seems to work better for natural targeting with the crosshair (ignoring the corner case with the building in the way that you mentioned previously).

After you pull my code, you can experiment between the 2 by modifying this code in character.cpp:

if(mPtr == getPlayer())
            MWBase::Environment::get().getWorld()->getPlayer().realignCameraTowardsPlayerCrosshair();
        /*if (mPtr == getPlayer())
            MWBase::Environment::get().getWorld()->getPlayer().orientPlayerTowardsCameraCrosshair();*/

Just comment the one you don't want active to switch between them.

Note that the code is always running (no aim key involved) and that both solutions will re-orient the camera back to match the player orientation when no target is found.

@drummyfish

This comment has been minimized.

Show comment
Hide comment
@drummyfish

drummyfish Oct 15, 2017

Contributor

This is great work, I'm gonna give it a bit of testing. Here I'll write and edit-in my notes (ignore anything that's been discussed above, I've only read a few comments):

  • When I change between over the shoulder and normal in the menu and I am in 3rd person view already, it doesn't switch the mode automatically, I have to press TAB twice (to 1st person and back again).
  • The camera sometimes goes into walls, I'm assuming you only shift the camera view but the collision is still being done against the original position? 3rd
  • I noticed this issue, but it may be unrelated to your PR (looks like when you rotate over 360 degrees to let's say 370, the value gets converted to 10 degrees to keep it in 0-360 range and makes the player rotate all the way around). If you can confirm this is not your issue, I'll put this in the bugtracker. EDIT: This doesn't happen in master, I'm pretty certain it's your wrap function in player.cpp:208.
  • Would be nice to have an option to also switch to over the left shoulder, set the offset amount etc. (can be made a separate feature later). EDIT: OK, I found there are already some settings present.
  • The cursor does some kind of autoaim on NPCs when the crosshair is near them. I guess it's related to the problem of "player character view vs camera view" and don't know if it's intentional but it feels a little weird when the camera aims on its own. It also does this in 1st person which it definitely shouldn't.
Contributor

drummyfish commented Oct 15, 2017

This is great work, I'm gonna give it a bit of testing. Here I'll write and edit-in my notes (ignore anything that's been discussed above, I've only read a few comments):

  • When I change between over the shoulder and normal in the menu and I am in 3rd person view already, it doesn't switch the mode automatically, I have to press TAB twice (to 1st person and back again).
  • The camera sometimes goes into walls, I'm assuming you only shift the camera view but the collision is still being done against the original position? 3rd
  • I noticed this issue, but it may be unrelated to your PR (looks like when you rotate over 360 degrees to let's say 370, the value gets converted to 10 degrees to keep it in 0-360 range and makes the player rotate all the way around). If you can confirm this is not your issue, I'll put this in the bugtracker. EDIT: This doesn't happen in master, I'm pretty certain it's your wrap function in player.cpp:208.
  • Would be nice to have an option to also switch to over the left shoulder, set the offset amount etc. (can be made a separate feature later). EDIT: OK, I found there are already some settings present.
  • The cursor does some kind of autoaim on NPCs when the crosshair is near them. I guess it's related to the problem of "player character view vs camera view" and don't know if it's intentional but it feels a little weird when the camera aims on its own. It also does this in 1st person which it definitely shouldn't.
@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Oct 20, 2017

Sorry for the delayed response. I didn't realize someone had stopped by to test :).

When I change between over the shoulder and normal in the menu and I am in 3rd person view already, it doesn't switch the mode automatically, I have to press TAB twice (to 1st person and back again).

This should hopefully be an easy fix. Just have to trigger the camera change immediately as a result of toggling the setting. Do we have any on setting update support?

The camera sometimes goes into walls, I'm assuming you only shift the camera view but the collision is still being done against the original position?

This is an unfortunate side effect of the focusing the camera towards what the player is looking at. The camera can rotate in such a way as to look behind a wall. That being said, it's confirmed that this doesn't happen on third person centered due to the camera being behind the player?

I noticed this issue, but it may be unrelated to your PR (looks like when you rotate over 360 degrees to let's say 370, the value gets converted to 10 degrees to keep it in 0-360 range and makes the player rotate all the way around). If you can confirm this is not your issue, I'll put this in the bugtracker. EDIT: This doesn't happen in master, I'm pretty certain it's your wrap function in player.cpp:208.

Without even thinking about the math, I blindly copied this from the logic in character.cpp for the updateHeadTracking function as the target tracking requirements are very similar. This same wrap function is also repeated in worldimp.cpp as well :). We should probably have a common utilities header file to put this in to reduce redundancy. Also might be worthwhile making sure the other algorithms that consume this expect this wrapping behavior or they may have similar issues like my code does.

The cursor does some kind of autoaim on NPCs when the crosshair is near them. I guess it's related to the problem of "player character view vs camera view" and don't know if it's intentional but it feels a little weird when the camera aims on its own. It also does this in 1st person which it definitely shouldn't.

This was my feeling as well and why I left both options in to test. Can you test the other function orientPlayerTowardsCameraCrosshair on line 1908 and 1909 of character.cpp? be sure to comment out 1906 and 1907. See if it feels more natural to have the player realign instead as it should remove the auto-aim behavior. The first person effect i'll fix. I think it's because i'm not qualifying that realign function with the current camera mode.

crussell187 commented Oct 20, 2017

Sorry for the delayed response. I didn't realize someone had stopped by to test :).

When I change between over the shoulder and normal in the menu and I am in 3rd person view already, it doesn't switch the mode automatically, I have to press TAB twice (to 1st person and back again).

This should hopefully be an easy fix. Just have to trigger the camera change immediately as a result of toggling the setting. Do we have any on setting update support?

The camera sometimes goes into walls, I'm assuming you only shift the camera view but the collision is still being done against the original position?

This is an unfortunate side effect of the focusing the camera towards what the player is looking at. The camera can rotate in such a way as to look behind a wall. That being said, it's confirmed that this doesn't happen on third person centered due to the camera being behind the player?

I noticed this issue, but it may be unrelated to your PR (looks like when you rotate over 360 degrees to let's say 370, the value gets converted to 10 degrees to keep it in 0-360 range and makes the player rotate all the way around). If you can confirm this is not your issue, I'll put this in the bugtracker. EDIT: This doesn't happen in master, I'm pretty certain it's your wrap function in player.cpp:208.

Without even thinking about the math, I blindly copied this from the logic in character.cpp for the updateHeadTracking function as the target tracking requirements are very similar. This same wrap function is also repeated in worldimp.cpp as well :). We should probably have a common utilities header file to put this in to reduce redundancy. Also might be worthwhile making sure the other algorithms that consume this expect this wrapping behavior or they may have similar issues like my code does.

The cursor does some kind of autoaim on NPCs when the crosshair is near them. I guess it's related to the problem of "player character view vs camera view" and don't know if it's intentional but it feels a little weird when the camera aims on its own. It also does this in 1st person which it definitely shouldn't.

This was my feeling as well and why I left both options in to test. Can you test the other function orientPlayerTowardsCameraCrosshair on line 1908 and 1909 of character.cpp? be sure to comment out 1906 and 1907. See if it feels more natural to have the player realign instead as it should remove the auto-aim behavior. The first person effect i'll fix. I think it's because i'm not qualifying that realign function with the current camera mode.

Unknown added some commits Oct 20, 2017

changes to not activate third person over the shoulder player/target …
…triangulation when first person or centered third person is enabled
Merge branch 'master' of git://github.com/OpenMW/openmw into third_pe…
…rson_over_shoulder

# Conflicts:
#	apps/openmw/mwinput/inputmanagerimp.cpp
#	apps/openmw/mwmechanics/actors.cpp
@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Oct 20, 2017

The first person auto-aim issue is now fixed. I have also merged with the master branch.

crussell187 commented Oct 20, 2017

The first person auto-aim issue is now fixed. I have also merged with the master branch.

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Oct 23, 2017

Posting this here because I thought it was hilarious after how much effort I spent here trying to triangulate the trajectory. It turns out that in tomb raider, they just spawn the arrow directly behind the crosshair and nobody can tell the difference :).
https://www.reddit.com/r/gaming/comments/780iyb/rottryup_thats_exactly_how_arrows_work_lara/

crussell187 commented Oct 23, 2017

Posting this here because I thought it was hilarious after how much effort I spent here trying to triangulate the trajectory. It turns out that in tomb raider, they just spawn the arrow directly behind the crosshair and nobody can tell the difference :).
https://www.reddit.com/r/gaming/comments/780iyb/rottryup_thats_exactly_how_arrows_work_lara/

@kcat

This comment has been minimized.

Show comment
Hide comment
@kcat

kcat Oct 23, 2017

Contributor

Behavior like that is exactly the kind of thing to avoid. Nothing worse than "It was right in front of me, why didn't you hit?!" only to find out it's because projectiles don't spawn from "you" (the character), but the camera. And of course if they spawn from you (the character), you need to ensure the camera and character agree on where it's aiming to.

Contributor

kcat commented Oct 23, 2017

Behavior like that is exactly the kind of thing to avoid. Nothing worse than "It was right in front of me, why didn't you hit?!" only to find out it's because projectiles don't spawn from "you" (the character), but the camera. And of course if they spawn from you (the character), you need to ensure the camera and character agree on where it's aiming to.

@drummyfish

This comment has been minimized.

Show comment
Hide comment
@drummyfish

drummyfish Oct 23, 2017

Contributor

I saw this at reddit too and thought of this very PR :) The aiming really is a non-trivial issue. Maybe take a look at how this is solved in Skyrim.

Contributor

drummyfish commented Oct 23, 2017

I saw this at reddit too and thought of this very PR :) The aiming really is a non-trivial issue. Maybe take a look at how this is solved in Skyrim.

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Oct 24, 2017

Skyrim is dead center third person I thought which matches morrowind. Can anybody tell the approach used in middle earth: shadow of war / shadow of mordor? Their approach seems to be very convincing in that game although it may just be a variation on the tombraider one. Also, the tombraider bug wouldn't happen / be noticeable if collision detection for the arrow ignored objects behind the camera parallel plane ending at the tip of the drawn bow.

Btw drummyfish, I can't reproduce getting the wrap bug to occur. Any tips on making it more probable so I can test that it's fixed?

crussell187 commented Oct 24, 2017

Skyrim is dead center third person I thought which matches morrowind. Can anybody tell the approach used in middle earth: shadow of war / shadow of mordor? Their approach seems to be very convincing in that game although it may just be a variation on the tombraider one. Also, the tombraider bug wouldn't happen / be noticeable if collision detection for the arrow ignored objects behind the camera parallel plane ending at the tip of the drawn bow.

Btw drummyfish, I can't reproduce getting the wrap bug to occur. Any tips on making it more probable so I can test that it's fixed?

@mupfelofen-de

This comment has been minimized.

Show comment
Hide comment
@mupfelofen-de

mupfelofen-de Dec 5, 2017

I would really like to test this feature. But I simply don't know how to resolve the conflicts. Any help is appreciated. @crussell187 please continue this project. 👍

mupfelofen-de commented Dec 5, 2017

I would really like to test this feature. But I simply don't know how to resolve the conflicts. Any help is appreciated. @crussell187 please continue this project. 👍

@drummyfish

This comment has been minimized.

Show comment
Hide comment
@drummyfish

drummyfish Dec 5, 2017

Contributor

@mupfelofen-de you don't have to resolve the conflicts to test this, the conflicts are only for merging to the main branch. You simply fetch this pull request with git and compile, there are some tutorials on how to do that.

Contributor

drummyfish commented Dec 5, 2017

@mupfelofen-de you don't have to resolve the conflicts to test this, the conflicts are only for merging to the main branch. You simply fetch this pull request with git and compile, there are some tutorials on how to do that.

@crussell187

This comment has been minimized.

Show comment
Hide comment
@crussell187

crussell187 Dec 6, 2017

I have been leaving this alone as I still don't know which approach for third person aiming people would prefer to see. I also haven't had much time recently to work on openmw :(.

drummyfish has given his opinion on the weirdness of manipulating the camera to look at the target which the arrow is looking at. The rotate player towards target works well enough but it can sometimes look weird with the rotation happening more drastically based on the distance of the object under the crosshair. I think even though we joked about it, I might actually try the tombraider approach but with some modification to not collision detect for the arrow until it's past the edge of the bow.

Other cleanup I still need to do is for this comment from drummyfish:

The camera sometimes goes into walls, I'm assuming you only shift the camera view but the collision is still being done against the original position?

The camera could collision detect on walls so as to not pull the viewport behind the textures on buildings, rocks, trees, etc. That being said, if you get too conservative, you might trap the camera in a scene where there are tight geometry constraints.

I seem to remember that rather than prevent movement, most games tend to reduce the distance between the player and the camera when the player moves close to walls/objects while turning. This guarantees that the camera stays in front of any geometry while not giving up any player mobility.

crussell187 commented Dec 6, 2017

I have been leaving this alone as I still don't know which approach for third person aiming people would prefer to see. I also haven't had much time recently to work on openmw :(.

drummyfish has given his opinion on the weirdness of manipulating the camera to look at the target which the arrow is looking at. The rotate player towards target works well enough but it can sometimes look weird with the rotation happening more drastically based on the distance of the object under the crosshair. I think even though we joked about it, I might actually try the tombraider approach but with some modification to not collision detect for the arrow until it's past the edge of the bow.

Other cleanup I still need to do is for this comment from drummyfish:

The camera sometimes goes into walls, I'm assuming you only shift the camera view but the collision is still being done against the original position?

The camera could collision detect on walls so as to not pull the viewport behind the textures on buildings, rocks, trees, etc. That being said, if you get too conservative, you might trap the camera in a scene where there are tight geometry constraints.

I seem to remember that rather than prevent movement, most games tend to reduce the distance between the player and the camera when the player moves close to walls/objects while turning. This guarantees that the camera stays in front of any geometry while not giving up any player mobility.

@Lindomarc

Lindomarc approved these changes Jun 23, 2018 edited

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment