Skip to navigation

BBC Micro Elite

Calculating vertex coordinates

Determining whether a ship's vertex is visible or hidden from us
----------------------------------------------------------------
References: LL9 (Part 6 of 11)
  To understand the following, you'll probably want to have a look through the
  deep dive on "Back-face culling", which describes how we can work out whether
  or not a ship's face is visible.
  
  As part of the back-face cull, we projected the vector [x y z] onto the
  orientation vector space like this:
  
    [x y z] projected onto sidev = [x y z] . sidev
    [x y z] projected onto roofv = [x y z] . roofv
    [x y z] projected onto nosev = [x y z] . nosev
  
  We can express this exact same calculation in terms of matrix multiplication:
  
    [ sidev ]   [ x ]
    [ roofv ] . [ y ]
    [ nosev ]   [ z ]
  
  or, expanding it out fully:
  
                        [ sidev_x sidev_y sidev_z ]   [ x ]
    projected [x y z] = [ roofv_x roofv_y roofv_z ] . [ y ]
                        [ nosev_x nosev_y nosev_z ]   [ z ]
  
  This is just a different way of expressing the exact same equation as we used
  in part 5 of LL9, just with a matrix instead of individual dot products.
  
  Transposing the rotation matrix
  -------------------------------
  So the inverse matrix will map vectors in the orientation vector space back
  into normal ship space. The inverse of a rotation matrix is its transpose, so
  this is the calculation:
  
                        [ sidev_x roofv_x nosev_x ]   [ x ]
    projected [x y z] = [ sidev_y roofv_y nosev_y ] . [ y ]
                        [ sidev_z roofv_z nosev_z ]   [ z ]
  
  This takes a vector, which goes from the ship's centre to the vertex and is
  expressed in terms of the ship's axes (i.e. its orientation vectors), and
  instead expresses it in terms of our ship's axes (i.e. our orientation
  vectors).
  
  Given this new vector, we can add the vector from our ship to the other ship,
  to get the vector from us to the vertex, expressed in our ship's coordinates:
  
                       [ sidev_x roofv_x nosev_x ]   [ x ]   [ x ]
    vector to vertex = [ sidev_y roofv_y nosev_y ] . [ y ] + [ y ]
                       [ sidev_z roofv_z nosev_z ]   [ z ]   [ z ]
  
  The code to calculate this equation takes up parts 6 and 7 of LL9. It's in two
  parts because there are two small subroutines that have rudely inserted
  themselves just before the big reveal. These are used by part 8 and don't play
  a part in this calculation (except to make it harder to follow).