Skip to navigation

Maths (Geometry): GetPitchAngleDelta

Name: GetPitchAngleDelta [Show more] Type: Subroutine Category: Maths (Geometry) Summary: Calculate the pitch angle of a vector relative to an object's pitch angle
This routine calculates the following pitch angle delta: pitchDelta(Hi Lo) = angle(Hi Lo) - (objectPitchAngle 32) where angle(Hi Lo) is the angle of this triangle: object _.-+ ^ _.-´ | | vector _.-´ | y-axis (up) _.-´ | _.-´ | (A xDeltaLo) _.-´ | .-´ angle(Hi Lo) | viewer +--------------------------+ hypotenuse(Hi Lo) This triangle is typically a viewing vector from the player's eyes to a coordinate in the 3D world. The length in hypotenuse(Hi Lo) is the projection of the vector down onto the ground (i.e. y = 0), and it has already been calculated by this point from the x- and z-axis elements of the vector. In this calculation this hypotenuse length is actually the adjacent side for the pitch angle above, but I've kept the same variable name from the first part of the calculation to make it easier to follow through. So this routine takes the hypotenuse length and the y-axis element of the vector in (A xDeltaLo) and calculates the vector's pitch angle in angle(Hi Lo), and then it calculates the difference between the vector's pitch angle and the pitch angle for object #X (i.e. the viewer). In other words, this calculates the pitch angle of the viewer's gaze towards a coordinate (typically a tile), relative to the pitch angle of the viewer, so that's relative to the current viewing direction. This is used to calculate player-relative pitch angles for tiles in the current tile view, for example.
Arguments: (A xDeltaLo) A vertical delta (i.e. a y-axis element) hypotenuse(Hi Lo) The length of the hypotenuse (i.e. adjacent side) X The object number
Returns: pitchDelta(Hi Lo) The pitch angle delta (divided by 16) angle(Hi Lo) The angle of the right-angled triangle with adjacent side hypotenuse(Hi Lo) and opposite side (A xDeltaLo)
.GetPitchAngleDelta STA xDeltaHi \ Set xDelta(Hi Lo) to the vertical delta passed to the \ routine TAY \ If the high byte is positive, jump to pdel1 to skip BPL pdel1 \ the following LDA #0 \ Negate the result to make it positive, so we now have: SEC \ SBC xDeltaLo \ (A xDeltaLo) = |xDeltaHi xDeltaLo| STA xDeltaLo LDA #0 SBC xDeltaHi .pdel1 STA xDeltaAbsoluteHi \ Set xDeltaAbsoluteHi = |xDeltaHi| \ \ So we now have the absolute delta in: \ \ (xDeltaAbsoluteHi xDeltaLo) \ \ and the original high byte of the signed delta is \ still in xDeltaHi LDA hypotenuseLo \ Set (zDeltaAbsoluteHi zDeltaLo) to the length of the STA zDeltaLo \ hypotenuse hypotenuse(Hi Lo) LDA hypotenuseHi STA zDeltaAbsoluteHi LDA #0 \ Set zDeltaHi to make the sign of zDelta positive in STA zDeltaHi \ the call to GetHypotenuseAngle JSR GetHypotenuseAngle \ Calculate the angle of the hypotenuse in the triangle \ with the following non-hypotenuse sides: \ \ * xDelta(Hi Lo) \ \ * zDelta(Hi Lo) \ \ which are set as follows: \ \ * (A xDeltaLo) \ \ * hypotenuse(Hi Lo) \ \ and return the angle in angle(Hi Lo), the tangent in \ angleTangent, the length of the longer side in \ a(Hi Lo) and the length of the shorter side in \ b(Hi Lo) LDA angleLo \ Set (A pitchDeltaLo) = angle(Hi Lo) SEC \ - (objectPitchAngle 32) SBC #32 \ STA pitchDeltaLo \ starting with the low bytes LDA angleHi \ And then the high bytes SBC objectPitchAngle,X PHP \ Store the status flags from the calculation LSR A \ Set (A pitchDeltaLo) = (A pitchDeltaLo) / 16 ROR pitchDeltaLo LSR A ROR pitchDeltaLo LSR A ROR pitchDeltaLo LSR A ROR pitchDeltaLo PLP \ If result is negative, set top four bits of A BPL pdel2 ORA #%11110000 .pdel2 STA pitchDeltaHi \ Store result in pitchDelta(Hi Lo) RTS \ Return from the subroutine