			 WAFFLING AND PACKING

				INTRO

The basic problem here is the hardware won't tile our 7x7 texture map
because it isn't a power of two.  Rather than fall back to SW we're
going to break up our primitive into tiles ourselves.  This will
require _waffling_ and _packing_.

Waffling: Breaking up line segments and triangles into smaller pieces
  that don't cross some set of gridlines.  The TRIANGLE WAFFLING
  section at the end of this document describes the details of how to
  do this for triangles.

Packing: Filling a larger "dest" image with a source image so bilinear
  with clamp evaluation of points on the edge (or outside) of dest
  produce desirable results.  See also "multi-packing"



			       PACKING

Suppose our pre-filtered texture is

ABC

In addition to its natural form we can pack it three different ways:

CABCA  Wrap (or Tile)

AABCC  Mirror (or Extend or Flip)

oABCo  Border (where o is 0x00000000)

These are all useful for different things.  Currently we have the 1st
two implemented.  With waffling they allow us to implement tiling
(with or w/o flip) "by hand" for non pow-2 textures.

Border will be useful to support viewboxes larger than the image
source, particularly in 3D.  This looks something like


|oooooABCooo|oooooABCooo|oooooABCooo|oooooABCooo|oooooABCooo|
|....+++++..|....+++++..|....+++++..|....+++++..|....+++++..|


Where the | indicate the viewport boundaries.  The pluses indicate
output pixels that came from the interior of the source texture and
the dots indicate where we used clamp.  This would be neat but IS NOT
implemented now.

What can we say about these representations?  First, EXCEPT for border
we always want waffle so that the waffle segment lies ENTIRELY within
a hardware texture map.  Within means that we need a texel border
around the waffle to make things work.  Smaller would work but is
wasteful.  For non-border non-multi-pack we waffle at the edges of the
base tile one texel in from the the hardware tile.
Let's draw the biggest picture yet.

We're going to use hw clamp because the tile doesn't work anyway.
Then what the hardware wants to draw for a line segment with
pre-filter ABC and pack CABCA is

CCCCCCCCCCCABCAAAAAAAAAAA  [FIGURE 1]

UGLY!  We're going to waffle this up into three line segments like so

ABC
+  ABC
+     ABC
---------
ABCABCABC

Better.



			  COORDINATE SYSTEMS

We have a billion coordinate sytems.  To start, let's agree that
normalized coordinates generally go from about 0 to 1 and
non-normalized generally go from about 0 to W.

Normalized viewport coordinates are what we generated from the shape
x,y and the texture transform.


ABCABCABCA
0123456789 / 3  [ Normalized viewport coordinates ] where the / 3 means divide by 3

If we use natural texture packing and hw wrapping these are all we
need.  (Thanks hw!)  Wrapping this using waffling and packing requires
two steps.

 1. We need to wrap by hand because of FIGURE 1

 2. We need to go to normalized hardware coordinates which are
    different from norm-vp coordinates because of padding:

CABCA
01234 / 5 [ Normalized hw coordinates ]

Here are the coordinates generated by these two steps.

0. Begin 012|345|678 /3
1. Wrap  012|012|012 /3
2. Remap 123|123|123 /5

These two steps are done in
CHwVertexBuffer::ViewportToPackedCoordinates.  The
CHwColorBitmapSource passes into the CHwVertexBuffer a normalized
rectangle which gives the image of the base tile in norm-hw
coordinates.




			    MULTI-PACKING

There is another case we'd like to support though.  Suppose we have a
plain old wrap but the pre-filtered texture is small and we want to
avoid making a trillion little waffle tiles.  And we're willing to
make the hw texture bigger ('cause the source is so small anyway.)  We
can "multi-pack" the source into the hw texture like this:

CABCABCABCA
01112223334

Now we'll use | to indicate the lines between waffles (which are no
longer equal to the viewport boundaries which happen 3 times as
often.)

C|ABCABCABC|ABCABCABC|ABCABCABC|ABCABCABC|A

 |012345678|9 / 3 [ Norm-vp ]

 |123456789|  / 9 [ Norm-hw ]

We can cheat here.  The CHwVertexBuffer generates the
norm-vp coordinates from x,y, based on the rgmatPointToUV matrix.  If
we append a scale by 1 / N to this matrix (where N is the multiplicity
of the multipack) then the CHwVertexBuffer will never even realize
that the multipack happened.  The CHwVertexBuffer even waffles based
on the the rgmatPointToUV and that'll work perfect too.

This needs to be worked out with a bit more precision before actually
being implemented.



			  TRIANGLE WAFFLING

"Waffling" a triangle refers to re-triangulating it so that the new
triangles do not cross the lines of a generalized uniform subdivision
of 2D.  The generalized subdivision is given by an affine matrix M
that maps cells in the subdivision to standard unit cells C_ij

C_ij = {x,y | x in [i,i+1) y in [j, j+1)}

We can waffle first one way and then the other.  If we are considering
row vectors then the two columns of the affine matrix define the two
crossing subdivisions

m00 m01

m10 m11

m20 m21

A point (x,y) is on a boundary in the first subdivision if

x m00 + y m10 + m20 = 0     (Eq 1)

and equivalently for the second matrix.

So the "slicer" function will take a column vector [a,b,c] and a
triangle T and produce a re-triangulation of T with no edges crossing
boundaries in the subdivision described by [a,b,c]

If we apply Eq 1 to the vertices of the triangle T we get a "score"
for each vertex.  This score is an integer if the vertex is on a
subdivision boundary.

We'll assume that the triangle vertices are in order from lowest to
highest score which may require flipping the order of the tri.
Suppose the entire triangle lies in cells m through m+n-1.  We can
produce a retriangulation by going through each of these cells and
producing a triangulation of the original triangle intersected with
that cell.

Call the tri vertices s,t,&v.  When producing a triangulation for a
cell m we're mostly concerned with which vertices lie before the cell
which are in the cell and which are after.  Turns out there are
exactly ten configurations (based on arranging two dividers between 3
objects.)

||123
|1|23
|12|3
|123|
1||23
1|2|3
1|23|
12|3|
12||3
123||

Given a configuration it's straightforward to figure out what
triangles to emit.



