Revs on the BBC Micro

# 3D objects: BuildCarObjects (Part 2 of 3)

```       Name: BuildCarObjects (Part 2 of 3)                           [Show more]
Type: Subroutine
Category: 3D objects
Summary: Add the racing line to the 3D coordinate of the specified car
Deep dive: Drawing a 3D car from 2D parts
Context: See this subroutine in context in the source code
References: No direct references to this subroutine in this source file

This part adds in the vector from the inside edge of the track to the car,
i.e. the second part of the above:

[ xCoord2 ]   [ xCoord2 ]   [ xTrackSegmentO ]
[ yCoord2 ] = [ yCoord2 ] + [        0       ] * carRacingLine * 4
[ zCoord2 ]   [ zCoord2 ]   [ zTrackSegmentO ]

[  0  ]
+ [ 144 ]
[  0  ]

\ We start by calculating the following:
\
\   xCoord2 =   xSegmentCoordI
\             + xTrackSegmentO * carRacingLine * 4
\
\ for the x-axis and z-axis only

LDY vectorNumber       \ Set Y to the segment vector number that we stored
\ above

LDA xTrackSegmentO,Y   \ Set VV to the 3D x-coordinate of the outer segment
STA VV                 \ vector for the car object

LDA zTrackSegmentO,Y   \ Set VV+2 to the 3D x-coordinate of the outer segment
STA VV+2               \ vector for the car object

\ Note that VV+1 still contains the y-coordinate for the
\ inner segment vector, which we can reuse as the height
\ of the track from side-to-side is always the same,
\ i.e. yTrackSegmentI = yTrackSegmentO for the same
\ vector which means the track is always level along the
\ y-axis

LDX #0                 \ We are about to work our way through the three axes,
\ so set X = 0 to use as an axis counter, working
\ through the three axes x, y, z using X = 0, 1, 2
\
\ The comments below are for the x-axis

LDA UU                 \ Set U = UU
STA U                  \       = the car's current racing line

.bcar5

LDA #0                 \ Set (V A) = 0
STA V

LDA VV,X               \ Set A to the x-coordinate of the outer segment vector

\ We now calculate (V A T) = A * U, making sure we get
\ the signs right

BPL bcar6              \ If A is positive, jump to bcar6 to multiply A and U as
\ they are

\ If we get here then A is negative, so we need to apply
\ the correct sign to the multiplication

EOR #&FF               \ Negate A (so it is now positive)
CLC

JSR Multiply8x8        \ Set (A T) = A * U

EOR #&FF               \ Negate A again (so it is now the correct sign for the
CLC                    \ multiplication)

BCS bcar7              \ If the addition just overflowed, then the result is
\ now positive, which means V is already the correct

DEC V                  \ Otherwise, decrement V to &FF so it's the correct
\ high byte for (V A T)

BCC bcar7              \ Jump to bcar7 (this BCC is effectively a JMP as we
\ just passed through a BCS)

.bcar6

JSR Multiply8x8        \ Set (A T) = A * U

.bcar7

\ By this point, we have the following, signed result:
\
\   (V A T) = A * U
\           = xTrackSegmentO * carRacingLine

ASL A                  \ Set (V A) = (V A) * 4
ROL V                  \           = xTrackSegmentO * carRacingLine * 4
ASL A
ROL V

CLC                    \ Set (xCoord2Hi xCoord2Lo) = (xCoord2Hi xCoord2Lo)
ADC xCoord2Lo,X        \                              + (V A)
STA xCoord2Lo,X        \
\ starting with the low bytes

LDA xCoord2Hi,X        \ And then the high bytes
STA xCoord2Hi,X

INX                    \ Set X = X + 2, so we skip the y-axis
INX

CPX #4                 \ Loop back to bcar5 until we have processed the x-axis
BNE bcar5              \ (for X = 0) and z-axis (for X = 2)

\ Finally, we add 144 to the y-coordinate

LDA yCoord2Lo          \ Set (yCoord2Hi yCoord2Lo) += 144
CLC                    \
ADC #144               \ starting with the low bytes
STA yCoord2Lo

BCC bcar8              \ And then the high bytes
INC yCoord2Hi
```