/*--------------------------------------------------------------------------- transf.asm: 3-D Graphics Translation, Rotation, and Scaling ----------------------------------------------------------------------------- Description: Performs the 3-D graphics transformation P' = M * P where P = 3-D point, a column vector with elements x,y,z, and w M = 4 x 4 transformation matrix (combination of translation, scaling and/or rotation) P' = Translation of point P To implement as a 4x4 by 4x1 matrix multiply would require 16 multiplies and 12 additions. In this routine, it is assumed that M is a matrix of the form | r11 r12 r13 tx | M = | r21 r22 r23 ty | | r31 r32 r33 tz | | 0 0 0 1 | i.e., a product of translation, rotational, and scaling matrices. For the true 4x4 by 4x1 multiply, see mul44x41.asm. Note that this transformation is sufficient for all combinations of translation, rotational, and scaling. The transformation can be decomposed to be P' = R * T + T, where | r11 r12 r13 | R = | r21 r22 r23 | | r31 r32 r33 | and T = | tx | | ty | | tz | reducing the operations to 9 multiplies and 9 additions. For a description of 3-D transformations and [x,y,z,w] coordinates, see Chapter 5 of Foley and VanDam's "Computer Graphics, Principles and Practice", 2nd Edition (Addison-Wesley 1990). ----------------------------------------------------------------------------- Program Characteristics: Calling Values: REGISTER FILE: r0 = number of points to transform DAG1 (Data Memory): i0 = index to point P (x,y,z,w) m0 = +1 m1 = +2 i1 = index to transformed point area i2 = index to matrix T l2 = 3 (length of T) DAG2 (Program Memory): i8 = index to matrix R l8 = 9 (length of R) m8 = +1 Registers Altered: r0-r6, r8-r10, r12-r15 Computation Time = 10N+5 cycles, where N 3-D points are transformed = 400ns per point @ 25MHz = 2.5 million points/sec @ 25MHz ----------------------------------------------------------------------------- Notes: In this implementation, the original list of points in Data Memory (pointed to by i0) contains x,y,z, and w coordinates, while the transformed points in Data Memory (pointed to by i1) only have x,y, and z coordinates. To transfer the w coordinate would require two Data Memory moves (one to read it, one to write it), and there is only a single data memory move slot left in the inner loop in this implementation. Thus preserving w in the transformed point list would cost an additional cycle. It is not necessary to physically move the w coordinates, since they are unchanged by the translate/scale/rotate operations. When the transformed points are later used, the transformed x,y,z coordinates can be accessed by one DM index register, with a modify value of +1, and the w coordinates can be accessed by another DM index register, with a modify value of +4. Specifically, when a final transformation to the canonical view volume is required, and a true 4x4 by 4x1 operation must be performed, the mul44x41.asm code shows how to index the transformed points with separate [x,y,z] and [w] indices. ----------------------------------------------------------------------------- Author: Jim Donahue, Analog Devices DSP Division Revised: 12-AUG-91 ----------------------------------------------------------------------------*/ .GLOBAL transf; .SEGMENT /pm pm_code; transf: r0 = r0-1, f1=dm(i0,m0), f4=pm(i8,m8); /* f1=px, f4=r11 */ f15=f1*f4, f2=dm(i0,m0), f4=pm(i8,m8); /* f2=py, f4=r12 */ f8=f2*f4, f3=dm(i0,m1), f4=pm(i8,m8); /* f3=pz, f4=r13 */ f8=f3*f4, f12=f8+f15, f9=dm(i2,m0), f4=pm(i8,m8); /* f9=tx, f4=r21 */ f15=f1*f4, f12=f8+f12, f4=pm(i8,m8); /* f4=r22 */ f8=f2*f4, f12=f9+f12, f4=pm(i8,m8); /* f4=r23 */ lcntr=r0, do trlp until lce; f8=f3*f4, f13=f8+f15, f10=dm(i2,m0), f4=pm(i8,m8); /*f10=ty, f4=r31*/ f15=f1*f4, f13=f8+f13, f11=dm(i2,m0), f4=pm(i8,m8); /*f11=tz, f4=r32*/ f8=f2*f4, f13=f10+f13, f4=pm(i8,m8); /* f4=r33*/ f8=f3*f4, f14=f8+f15, dm(i1,m0)=f12; f14=f8+f14, f1=dm(i0,m0), f4=pm(i8,m8); f15=f1*f4, f14=f11+f14, f2=dm(i0,m0), f4=pm(i8,m8); f8=f2*f4, f3=dm(i0,m1), f4=pm(i8,m8); f8=f3*f4, f12=f8+f15, f9=dm(i2,m0), f4=pm(i8,m8); f15=f1*f4, f12=f8+f12, dm(i1,m0)=f13, f4=pm(i8,m8); trlp: f8=f2*f4, f12=f9+f12, dm(i1,m0)=f14, f4=pm(i8,m8); f8=f3*f4, f13=f8+f15, f10=dm(i2,m0), f4=pm(i8,m8); f15=f1*f4, f13=f8+f13, f11=dm(i2,m0), f4=pm(i8,m8); f8=f2*f4, f13=f10+f13, f4=pm(i8,m8); f8=f3*f4, f14=f8+f15, dm(i1,m0)=f12; f14=f8+f14; rts(db), f14=f11+f14; dm(i1,m0)=f13; dm(i1,m0)=f14; .ENDSEG;