Doing mouselook cap right

Hi, so I am trying to sort out a problem with mouselook cap. When moving the mouse too quickly, it can bypass the cap.
All I am doing currently is calculating the angle between the Camera and Z axis. If it is greater than a certain value and the mouse is rotating in that direction, it won’t allow it to go further. The problem lies where if it goes past 90 degrees. Anyone got a better way of doing this?

Thanks

Mouselook script (very basic):


def mouselook(cont):
    own = cont.owner
    
    mouse = cont.sensors["mouse"]
    width = render.getWindowWidth()
    height = render.getWindowHeight()
    
    own["sensitivity"] = 0.002
    own["cap"] = 170
    own["smooth"] = 0.5
    
    x = width/2 - mouse.position[0]
    y = height/2 - mouse.position[1]
    
    if not "mouse_init" in own:
        own["mouse_init"] = True
        own["prex"] = 0.0
        own["prey"] = 0.0
        x = 0
        y = 0
    
    own["prex"] = own["prex"] * own["smooth"] + x*(1-own["smooth"])
    own["prey"] = own["prey"] * own["smooth"] + y*(1-own["smooth"])
    
    x = own["prex"] * own["sensitivity"]
    y = own["prey"] * own["sensitivity"]
    
    camera_orientation = own.localOrientation
    camera_z_orientation = [camera_orientation[0][2], camera_orientation[1][2], camera_orientation[2][2]]
    angle = Vector.angle(Vector([0.0, 0.0, 1.0]), Vector(camera_z_orientation)) * (180/math.pi)
    
    if not((angle > (90 + own["cap"]/2) and y > 0) or (angle < (90 - own["cap"]/2) and y < 0)):
        own.applyRotation([y, 0.0, 0.0], True)
    own.parent.applyRotation([0.0, 0.0, x], False)
    
    if not mouse.position == [int(width/2), int(height/2)]:
        render.setMousePosition(int(width/2), int(height/2))

Can you be more explicit about the behavior that you are attempting to get?

Is your player in a turret and you want to prevent the turret to firing in just the 170 degree arc to the front of the turrent? That means being able to turn 85 degrees left/right or up/down so you cannot fire behind you.

Or this supposed to limit the camera so that it does not turn more than 170 degrees/sec?

If (mouseInput +old angle)<90:
Add angle.
If (mouseinput +old angle)>90:
Set angle to 90

It’s just simple first person mouselook. Prevent the camera from doing backflips.

That won’t work, unfortunately, because when going over 180 degrees, it goes to 179, similarly going below 0 makes it 1 (the way the vector is set up). 0 to 180, 180 to 0

get the angle from the vector is a good idea but not sufficient
the problem of the current code is that not keep in count the “magnitude” of the new rotation.
you should add it to the current angle.

ie, now is :
if currentAngle isinrange -> applyRotation

instead you should do :
if currentAngle + newRotation isinrange -> applyRotation
else: get the difference from max rotation and new rotation and maybe do rotation

there 2/3 thing different to solve :


def getAngleSigned(cam):
  v1 = Vector((0, 1))
  v2 = cam.localOrientation.col[1].yz
  return v2.angle_signed(v1)


def getNewRotation():
  return mouse_y * SENSITIVITY




currentAngle = getAngleSigned(cam)
newRotation = getNewRotation()
futureRotation = currentAngle + newRotation


if futureRotation &gt; MAXCAP:
  newRotation = MAXCAP - currentAngle
elif futureRotation &lt; MINCAP:
  newRotation = MINCAP - currentAngle
if newRotation:
  cam.applyRotation((newRotation,0,0), 1)





NB:
this line is not very clear : (ie:maybe is right right by chance)
v2 = cam.localOrientation.col[1].yz

the other should be right.

PS: parenting the camera to a empty is doable the code of BluePrintRandom(i use this way)