home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- *
- * quartics.c
- *
- * from DKBTrace (c) 1990 David Buck
- *
- * This module implements the code for the quartic (4th order) shapes.
- *
- * This file was written by Alexander Enzmann. He wrote the code for DKB 2.11
- * QUARTICS (4th order shapes) and generously provided us these enhancements.
- *
- * This software is freely distributable. The source and/or object code may be
- * copied or uploaded to communications services so long as this notice remains
- * at the top of each file. If any changes are made to the program, you must
- * clearly indicate in the documentation and in the programs startup message
- * who it was who made the changes. The documentation should also describe what
- * those changes were. This software may not be included in whole or in
- * part into any commercial package without the express written consent of the
- * author. It may, however, be included in other public domain or freely
- * distributed software so long as the proper credit for the software is given.
- *
- * This software is provided as is without any guarantees or warranty. Although
- * the author has attempted to find and correct any bugs in the software, he
- * is not responsible for any damage caused by the use of the software. The
- * author is under no obligation to provide service, corrections, or upgrades
- * to this package.
- *
- * Despite all the legal stuff above, if you do find bugs, I would like to hear
- * about them. Also, if you have any comments or questions, you may contact me
- * at the following address:
- *
- * David Buck
- * 22C Sonnet Cres.
- * Nepean Ontario
- * Canada, K2H 8W7
- *
- * I can also be reached on the following bulleton boards:
- *
- * OMX (613) 731-3419
- * Mystic (613) 596-4249 or (613) 596-4772
- *
- * Fidonet: 1:163/109.9
- * Internet: dbuck@ccs.carleton.ca
- * The "You Can Call Me RAY" BBS (708) 358-5611
- *
- * IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
- *
- * The "You Can Call Me RAY" BBS (708) 358-5611
- * The Information Exchange BBS (708) 945-5575
- *
- *****************************************************************************/
-
- #include "frame.h"
- #include "vector.h"
- #include "dkbproto.h"
-
-
- /* Basic form of a quartic equation
- a00*x^4 + a01*x^3*y + a02*x^3*z + a03*x^3 + a04*x^2*y^2 +
- a05*x^2*y*z + a06*x^2*y + a07*x^2*z^2 + a08*x^2*z + a09*x^2 +
- a10*x*y^3 + a11*x*y^2*z + a12*x*y^2 + a13*x*y*z^2 + a14*x*y*z +
- a15*x*y + a16*x*z^3 + a17*x*z^2 + a18*x*z + a19*x + a20*y^4 +
- a21*y^3*z + a22*y^3 + a23*y^2*z^2 + a24*y^2*z + a25*y^2 + a26*y*z^3 +
- a27*y*z^2 + a28*y*z + a29*y + a30*z^4 + a31*z^3 + a32*z^2 + a33*z + a34
- */
-
- int factorials [5] = {1, 1, 2, 6, 24}; /* 0!, 1!, 2!, 3!, 4! */
- int term_counts [5] = {1, 4, 10, 20, 35};
- int terms4 [35] [4] = {
- {4, 0, 0, 0 }, {3, 1, 0, 0 }, {3, 0, 1, 0 }, {3, 0, 0, 1 }, {2, 2, 0, 0 },
- {2, 1, 1, 0 }, {2, 1, 0, 1 }, {2, 0, 2, 0 }, {2, 0, 1, 1 }, {2, 0, 0, 2 },
- {1, 3, 0, 0 }, {1, 2, 1, 0 }, {1, 2, 0, 1 }, {1, 1, 2, 0 }, {1, 1, 1, 1 },
- {1, 1, 0, 2 }, {1, 0, 3, 0 }, {1, 0, 2, 1 }, {1, 0, 1, 2 }, {1, 0, 0, 3 },
- {0, 4, 0, 0 }, {0, 3, 1, 0 }, {0, 3, 0, 1 }, {0, 2, 2, 0 }, {0, 2, 1, 1 },
- {0, 2, 0, 2 }, {0, 1, 3, 0 }, {0, 1, 2, 1 }, {0, 1, 1, 2 }, {0, 1, 0, 3 },
- {0, 0, 4, 0 }, {0, 0, 3, 1 }, {0, 0, 2, 2 }, {0, 0, 1, 3 }, {0, 0, 0, 4 },
- };
-
- int terms3 [20] [4] = {
- {3, 0, 0, 0 }, {2, 1, 0, 0 }, {2, 0, 1, 0 }, {2, 0, 0, 1 }, {1, 2, 0, 0 },
- {1, 1, 1, 0 }, {1, 1, 0, 1 }, {1, 0, 2, 0 }, {1, 0, 1, 1 }, {1, 0, 0, 2 },
- {0, 3, 0, 0 }, {0, 2, 1, 0 }, {0, 2, 0, 1 }, {0, 1, 2, 0 }, {0, 1, 1, 1 },
- {0, 1, 0, 2 }, {0, 0, 3, 0 }, {0, 0, 2, 1 }, {0, 0, 1, 2 }, {0, 0, 0, 3 },
- };
-
- int terms2 [10] [4] = {
- {2, 0, 0, 0 }, {1, 1, 0, 0 }, {1, 0, 1, 0 }, {1, 0, 0, 1 }, {0, 2, 0, 0 },
- {0, 1, 1, 0 }, {0, 1, 0, 1 }, {0, 0, 2, 0 }, {0, 0, 1, 1 }, {0, 0, 0, 2 },
- };
-
- int terms1 [4] [4] = {
- {1, 0, 0, 0 }, {0, 1, 0, 0 }, {0, 0, 1, 0 }, {0, 0, 0, 1 },
- };
-
-
- METHODS Quartic_Methods =
- { Object_Intersect, All_Quartic_Intersections,
- Inside_Quartic, Quartic_Normal, Copy_Quartic,
- Translate_Quartic, Rotate_Quartic,
- Scale_Quartic, Invert_Quartic};
-
- extern long Ray_Quartic_Tests, Ray_Quartic_Tests_Succeeded;
-
- int
- All_Quartic_Intersections(Object, Ray, Depth_Queue)
- OBJECT *Object;
- RAY *Ray;
- PRIOQ *Depth_Queue;
- {
- QUARTIC *Shape = (QUARTIC *) Object;
- DBL Depths [4];
- VECTOR Intersection_Point;
- INTERSECTION Local_Element;
- int cnt, i, j, Intersection_Found;
-
- Intersection_Found = FALSE;
- Ray_Quartic_Tests++;
- cnt = Intersect_Quartic(Ray, Shape, &Depths [0]);
- if (cnt > 0) Ray_Quartic_Tests_Succeeded++;
- for (i=0;i<cnt;i++) {
- for (j=0;j<i;j++)
- if (Depths [i] == Depths [j]) goto l0;
-
- if (Depths [i] < Small_Tolerance)
- continue;
-
- Local_Element.Depth = Depths [i];
- Local_Element.Object = Shape -> Parent_Object;
- VScale (Intersection_Point, Ray -> Direction, Depths [i]);
- VAdd (Intersection_Point, Intersection_Point, Ray -> Initial);
- Local_Element.Point = Intersection_Point;
- Local_Element.Shape = (SHAPE *)Shape;
- pq_add (Depth_Queue, &Local_Element);
- Intersection_Found = TRUE;
- l0:;
- }
- return (Intersection_Found);
- }
-
- /* Intersection of a ray and a quartic */
- int
- Intersect_Quartic(Ray, Shape, Depths)
- RAY *Ray;
- QUARTIC *Shape;
- DBL *Depths;
- {
- DBL x,y,z,x2,y2,z2,x3,y3,z3,x4,y4,z4;
- DBL xx,yy,zz,xx2,yy2,zz2,xx3,yy3,zz3,xx4,yy4,zz4;
- DBL *a, t [5];
-
- x = Ray->Initial.x;
- y = Ray->Initial.y;
- z = Ray->Initial.z;
- xx = Ray->Direction.x;
- yy = Ray->Direction.y;
- zz = Ray->Direction.z;
- x2 = x * x; y2 = y * y; z2 = z * z;
- x3 = x * x2; y3 = y * y2; z3 = z * z2;
- x4 = x * x3; y4 = y * y3; z4 = z * z3;
- xx2 = xx * xx; yy2 = yy * yy; zz2 = zz * zz;
- xx3 = xx * xx2; yy3 = yy * yy2; zz3 = zz * zz2;
- xx4 = xx * xx3; yy4 = yy * yy3; zz4 = zz * zz3;
- a = Shape->Coeffs;
-
- /*
- Determine the coefficients of t^n, where the line is represented
- as (x,y,z) + (xx,yy,zz) * t.
- */
- t [0] = a [0] * xx4 + a [1] * xx3 * yy + a [2] * xx3 * zz
- + a [4] * xx2 * yy2 + a [5] * xx2 * yy * zz + a [7] * xx2 * zz2
- + a [10] * xx * yy3 + a [11] * xx * yy2 * zz + a [13] * xx * yy * zz2
- + a [16] * xx * zz3 + a [20] * yy4 + a [21] * yy3 * zz
- + a [23] * yy2 * zz2 + a [26] * yy * zz3 + a [30] * zz4;
-
- t [1] = 4 * a [0] * x * xx3 + a [1] * (3 * x * xx2 * yy + xx3 * y)
- + a [2] * (3 * x * xx2 * zz + xx3 * z) + a [3] * xx3
- + a [4] * (2 * x * xx * yy2 + 2 * xx2 * y * yy)
- + a [5] * (xx2 * (y * zz + yy * z) + 2 * x * xx * yy * zz);
- t [1] += a [6] * xx2 * yy + a [7] * (2 * x * xx * zz2 + 2 * xx2 * z * zz)
- + a [8] * xx2 * zz + a [10] * (x * yy3 + 3 * xx * y * yy2)
- + a [11] * (xx * (2 * y * yy * zz + yy2 * z) + x * yy2 * zz)
- + a [12] * xx * yy2;
- t [1] += a [13] * (xx * (y * zz2 + 2 * yy * z * zz) + x * yy * zz2)
- + a [14] * xx * yy * zz + a [16] * (x * zz3 + 3 * xx * z * zz2)
- + a [17] * xx * zz2 + 4 * a [20] * y * yy3;
- t [1] += a [21] * (3 * y * yy2 * zz + yy3 * z)
- + a [22] * yy3 + zz * (2 * a [23] * yy * (y * zz + yy * z)
- + a [24] * yy2 + zz * (a [26] * (y * zz + 3 * yy * z)
- + a [27] * yy + zz * (4 * a [30] * z + a [31])));
-
- t [2] = 6 * a [0] * x2 * xx2 + 3 * a [1] * x * xx * (x * yy + xx * y)
- + 3 * a [2] * x * xx * (x * zz + xx * z) + 3 * a [3] * x * xx2
- + a [4] * (x2 * yy2 + 4 * x * xx * y * yy + xx2 * y2)
- + a [5] * (x2 * yy * zz + 2 * x * xx * (y * zz + yy * z)
- + xx2 * y * z) + a [6] * (2 * x * xx * yy + xx2 * y);
- t [2] += a [7] * (x2 * zz2 + 4 * x * xx * z * zz + xx2 * z2)
- + a [8] * (2 * x * xx * zz + xx2 * z) + a [9] * xx2
- + a [10] * (3 * x * y * yy2 + 3 * xx * y2 * yy)
- + a [11] * (x * yy * (2 * y * zz + yy * z)
- + xx * (y2 * zz + 2 * y * yy * z))
- + a [12] * (x * yy2 + 2 * xx * y * yy);
- t [2] += a [13] * (x * zz * (y * zz + 2 * yy * z)
- + xx * (2 * y * z * zz + yy * z2))
- + a [14] * (x * yy * zz + xx * (y * zz + yy * z)) + a [15] * xx * yy
- + a [16] * (3 * x * z * zz2 + 3 * xx * z2 * zz)
- + a [17] * (x * zz2 + 2 * xx * z * zz) + a [18] * xx * zz;
- t [2] += 6 * a [20] * y2 * yy2 + 3 * a [21] * y * yy * (y * zz + yy * z)
- + 3 * a [22] * y * yy2 + a [23] * (y2 * zz2 + 4 * y * yy * z * zz
- + yy2 * z2) + a [24] * (2 * y * yy * zz + yy2 * z) + a [25] * yy2
- + zz * (3 * a [26] * z * (y * zz + yy * z)
- + a [27] * (y * zz + 2 * yy * z) + a [28] * yy
- + 6 * a [30] * z2 * zz + 3 * a [31] * z * zz + a [32] * zz);
-
- t [3] = 4 * a [0] * x3 * xx + a [1] * x2 * (x * yy + 3 * xx * y)
- + a [2] * x2 * (x * zz + 3 * xx * z) + 3 * a [3] * x2 * xx
- + 2 * a [4] * x * y * (x * yy + xx * y)
- + a [5] * x * (x * (y * zz + yy * z) + 2 * xx * y * z)
- + a [6] * x * (x * yy + 2 * xx * y);
- t [3] += 2 * a [7] * x * z * (x * zz + xx * z)
- + a [8] * x * (x * zz + 2 * xx * z)
- + 2 * a [9] * x * xx + a [10] * (3 * x * y2 * yy-xx * y3)
- + a [11] * (x * y * (y * zz + 2 * yy * z) + xx * y2 * z)
- + a [12] * (2 * x * y * yy + xx * y2)
- + a [13] * (x * z * (2 * y * zz + yy * z) + xx * y * z2);
- t [3] += a [14] * (x * (y * zz + yy * z) + xx * y * z)
- + a [15] * (x * yy + xx * y) + a [16] * (3 * x * z2 * zz + xx * z3)
- + a [17] * (2 * x * z * zz + xx * z2) + a [18] * (x * zz + xx * z)
- + a [19] * xx + 4 * a [20] * y3 * yy
- + a [21] * y2 * (y * zz + 3 * yy * z) + 3 * a [22] * y2 * yy;
- t [3] += 2 * a [23] * y * z * (y * zz + yy * z)
- + a [24] * y * (y * zz + 2 * yy * z) + 2 * a [25] * y * yy
- + a [26] * (3 * y * z2 * zz + yy * z3)
- + a [27] * (2 * y * z * zz + yy * z2) + a [28] * (y * zz + yy * z)
- + a [29] * yy + zz * (4 * a [30] * z3 + 3 * a [31] * z2
- + 2 * a [32] * z + a [33]);
-
- t [4] = a [0] * x4 + a [1] * x3 * y + a [2] * x3 * z + a [3] * x3
- + a [4] * x2 * y2 + a [5] * x2 * y * z + a [6] * x2 * y
- + a [7] * x2 * z2 + a [8] * x2 * z + a [9] * x2 + a [10] * x * y3
- + a [11] * x * y2 * z + a [12] * x * y2 + a [13] * x * y * z2
- + a [14] * x * y * z + a [15] * x * y + a [16] * x * z3;
- t [4] += a [17] * x * z2 + a [18] * x * z + a [19] * x + a [20] * y4
- + a [21] * y3 * z + a [22] * y3 + a [23] * y2 * z2 + a [24] * y2 * z
- + a [25] * y2 + a [26] * y * z3 + a [27] * y * z2 + a [28] * y * z
- + a [29] * y + a [30] * z4 + a [31] * z3 + a [32] * z2 + a [33] * z
- + a [34];
- return solve_quartic (t, Depths);
- }
-
- int
- Inside_Quartic (point, Object)
- VECTOR *point;
- OBJECT *Object;
- {
- QUARTIC *Shape = (QUARTIC *) Object;
- DBL Result,*a,x,y,z,x2,y2,z2,x3,y3,z3,x4,y4,z4;
-
- x = point->x; y = point->y; z = point->z;
- x2 = x * x; y2 = y * y; z2 = z * z;
- x3 = x * x2; y3 = y * y2; z3 = z * z2;
- x4 = x * x3; y4 = y * y3; z4 = z * z3;
- a = Shape->Coeffs;
-
- Result = a [0]*x4 + a [1]*x3*y + a [2]*x3*z + a [3]*x3 + a [4]*x2*y2 +
- a [5]*x2*y*z + a [6]*x2*y + a [7]*x2*z2 + a [8]*x2*z + a [9]*x2 +
- a [10]*x*y3 + a [11]*x*y2*z + a [12]*x*y2 + a [13]*x*y*z2 + a [14]*x*y*z +
- a [15]*x*y + a [16]*x*z3 + a [17]*x*z2 + a [18]*x*z + a [19]*x + a [20]*y4 +
- a [21]*y3*z + a [22]*y3 + a [23]*y2*z2 + a [24]*y2*z + a [25]*y2 +
- a [26]*y*z3 + a [27]*y*z2 + a [28]*y*z + a [29]*y + a [30]*z4 + a [31]*z3 +
- a [32]*z2 + a [33]*z + a [34];
-
- if (Result < Small_Tolerance)
- return (TRUE);
- else
- return (FALSE);
- }
-
- /* Normal to a quartic */
- void
- Quartic_Normal(Result, Object, Intersection_Point)
- VECTOR *Result, *Intersection_Point;
- OBJECT *Object;
- {
- QUARTIC *Shape = (QUARTIC *) Object;
- DBL *a,x,y,z,x2,y2,z2,x3,y3,z3,Len;
-
- a = Shape->Coeffs;
- x = Intersection_Point->x;
- y = Intersection_Point->y;
- z = Intersection_Point->z;
- x2 = x * x; y2 = y * y; z2 = z * z;
- x3 = x * x2; y3 = y * y2; z3 = z * z2;
-
- Result->x = 4*a [0]*x3 + 3*x2*(a [1]*y + a [2]*z + a [3]) +
- 2*x*(a [4]*y2 + y*(a [5]*z + a [6]) + a [7]*z2 + a [8]*z + a [9]) +
- a [10]*y3 + y2*(a [11]*z + a [12]) + y*(a [13]*z2 + a [14]*z + a [15]) +
- a [16]*z3 + a [17]*z2 + a [18]*z + a [19];
-
- Result->y = a [1]*x3 + x2*(2*a [4]*y + a [5]*z + a [6]) +
- x*(3*a [10]*y2 + 2*y*(a [11]*z + a [12]) + a [13]*z2 + a [14]*z + a [15]) +
- 4*a [20]*y3 + 3*y2*(a [21]*z + a [22]) + 2*y*(a [23]*z2 + a [24]*z + a [25]) +
- a [26]*z3 + a [27]*z2 + a [28]*z + a [29];
-
- Result->z = a [2]*x3 + x2*(a [5]*y + 2*a [7]*z + a [8]) +
- x*(a [11]*y2 + y*(2*a [13]*z + a [14]) + 3*a [16]*z2 + 2*a [17]*z + a [18]) +
- a [21]*y3 + y2*(2*a [23]*z + a [24]) + y*(3*a [26]*z2 + 2*a [27]*z + a [28]) +
- 4*a [30]*z3 + 3*a [31]*z2 + 2*a [32]*z + a [33];
-
- Len = Result->x * Result->x + Result->y * Result->y + Result->z * Result->z;
- Len = sqrt(Len);
- if (Len == 0.0) {
- /* The normal is not defined at this point of the surface. Set it
- to any arbitrary direction. */
- Result->x = 1.0;
- Result->y = 0.0;
- Result->z = 0.0;
- }
- else {
- Result->x /= Len; /* normalize the normal */
- Result->y /= Len;
- Result->z /= Len;
- }
- }
-
- /* Make a copy of a quartic object */
- void *
- Copy_Quartic(Object)
- OBJECT *Object;
- {
- QUARTIC *New_Shape;
-
- New_Shape = Get_Quartic_Shape ();
- *New_Shape = *((QUARTIC *) Object);
- New_Shape -> Next_Object = NULL;
-
- if (New_Shape->Shape_Texture != NULL)
- New_Shape->Shape_Texture = Copy_Texture (New_Shape->Shape_Texture);
-
- return (New_Shape);
- }
-
- /* Move a quartic */
- void
- Translate_Quartic(Object, Vector)
- OBJECT *Object;
- VECTOR *Vector;
- {
- TRANSFORMATION Transformation;
- Get_Translation_Transformation(&Transformation, Vector);
- Transform_Quartic((QUARTIC *)Object,
- (MATRIX *)&(Transformation.inverse [0] [0]));
- Translate_Texture (&((QUARTIC *) Object)->Shape_Texture, Vector);
- }
-
- /* Rotation of a quartic */
- void
- Rotate_Quartic(Object, Vector)
- OBJECT *Object;
- VECTOR *Vector;
- {
- TRANSFORMATION Transformation;
- Get_Rotation_Transformation(&Transformation, Vector);
- Transform_Quartic((QUARTIC *)Object,
- (MATRIX *)&(Transformation.inverse [0] [0]));
- Rotate_Texture (&((QUARTIC *) Object)->Shape_Texture, Vector);
- }
-
- /* Resize a quartic */
- void
- Scale_Quartic(Object, Vector)
- OBJECT *Object;
- VECTOR *Vector;
- {
- TRANSFORMATION Transformation;
- Get_Scaling_Transformation (&Transformation, Vector);
- Transform_Quartic((QUARTIC *)Object,
- (MATRIX *)&(Transformation.inverse [0] [0]));
- Scale_Texture (&((QUARTIC *) Object)->Shape_Texture, Vector);
- }
-
- void
- Invert_Quartic(Object)
- OBJECT *Object;
- {
- QUARTIC *Shape = (QUARTIC *) Object;
- int i;
- for (i=0;i<35;i ++)
- Shape->Coeffs [i] *= -1.0;
- }
-
- /* Given a set of power values from a term in the general quartic, return
- the index of the term. */
- int
- roll_term_indices(i, j, k)
- int i, j, k;
- {
- int l, t;
- l = 4 - (i + j + k);
- if (i < 0 || i > 4 || j < 0 || j > 4 ||
- k < 0 || k > 4 || l < 0 || l > 4) {
- PRINT("Error in 'roll_term_indices': i = %d, j = %d, k = %d, l = %d\n", i, j, k, l);
- return (0);
- }
- for (t=0;t<term_counts [4];t ++)
- if (i == terms4 [t] [0] && j == terms4 [t] [1] &&
- k == terms4 [t] [2] && l == terms4 [t] [3])
- return t;
- PRINT("Term not in 'roll_term_indices': i = %d, j = %d, k = %d, l = %d\n", i, j, k, l);
- return (0);
- }
-
- /* Given the total power and the index, return the individual powers */
- void
- unroll_term_indices( power, index, i, j, k, l)
- int power, index, *i, *j, *k, *l;
- {
- if (power == 4) {
- *i = terms4 [index] [0];
- *j = terms4 [index] [1];
- *k = terms4 [index] [2];
- *l = terms4 [index] [3];
- }
- else if (power == 3) {
- *i = terms3 [index] [0];
- *j = terms3 [index] [1];
- *k = terms3 [index] [2];
- *l = terms3 [index] [3];
- }
- else if (power == 2) {
- *i = terms2 [index] [0];
- *j = terms2 [index] [1];
- *k = terms2 [index] [2];
- *l = terms2 [index] [3];
- }
- else if (power == 1) {
- *i = terms1 [index] [0];
- *j = terms1 [index] [1];
- *k = terms1 [index] [2];
- *l = terms1 [index] [3];
- }
- else {
- *i = 0;
- *j = 0;
- *k = 0;
- *l = 0;
- }
- }
-
- DBL
- do_partial_term(q, row, power, i, j, k, l)
- MATRIX *q;
- int row, power, i, j, k, l;
- {
- DBL result;
- result = ((DBL) factorials [power] /
- (factorials [i]*factorials [j]*factorials [k]*factorials [l]));
- if (i>0) result *= POW((*q) [0] [row], (DBL) i);
- if (j>0) result *= POW((*q) [1] [row], (DBL) j);
- if (k>0) result *= POW((*q) [2] [row], (DBL) k);
- if (l>0) result *= POW((*q) [3] [row], (DBL) l);
- return result;
- }
-
- /* Using the transformation matrix q, transform the general quartic equation
- given by a. */
- void
- Transform_Quartic(Shape, q)
- QUARTIC *Shape;
- MATRIX *q;
- {
- int term_index, partial_index;
- int ip, i, i0, i1, i2, i3;
- int jp, j, j0, j1, j2, j3;
- int kp, k, k0, k1, k2, k3;
- DBL b [35], partial_term;
- DBL tempx, tempy, tempz;
-
- /* Trim out any really low values from the transform. */
- for (i=0;i<4;i ++) for (j=0;j<4;j ++)
- if ((*q) [i] [j] > -EPSILON && (*q) [i] [j] < EPSILON) (*q) [i] [j] = 0.0;
-
- for (i=0;i<35;i ++) b [i] = 0.0;
-
- for (term_index=0;term_index<term_counts [4];term_index ++) {
- if (Shape->Coeffs [term_index] == 0.0) continue;
- ip = terms4 [term_index] [0]; /* Power of original x term */
- jp = terms4 [term_index] [1]; /* Power of original y term */
- kp = terms4 [term_index] [2]; /* Power of original z term */
- /* Step through terms in: (q [0] [0]*x + q [0] [1]*y + q [0] [2]*z + q [0] [3])^i */
- for (i=0;i<term_counts [ip];i ++) {
- unroll_term_indices(ip, i, &i0, &i1, &i2, &i3);
- tempx = do_partial_term(q, 0, ip, i0, i1, i2, i3);
- if (tempx == 0.0) continue;
-
- /* Step through terms in: (q [1] [0]*x + q [1] [1]*y + q [1] [2]*z + q [1] [3])^j */
- for (j=0;j<term_counts [jp];j ++) {
- unroll_term_indices(jp, j, &j0, &j1, &j2, &j3);
- tempy = do_partial_term(q, 1, jp, j0, j1, j2, j3);
- if (tempy == 0.0) continue;
-
- /* Step through terms in: (q [2] [0]*x + q [2] [1]*y + q [2] [2]*z + q [2] [3])^k */
- for (k=0;k<term_counts [kp];k ++) {
- unroll_term_indices(kp, k, &k0, &k1, &k2, &k3);
- tempz = do_partial_term(q, 2, kp, k0, k1, k2, k3);
- if (tempz == 0.0) continue;
-
- /* Figure out it's index, and add it into the result */
- partial_index = roll_term_indices(i0 + j0 + k0,i1 + j1 + k1,i2 + j2 + k2);
- partial_term = Shape->Coeffs [term_index] * tempx * tempy * tempz;
- b [partial_index] += partial_term;
- }
- }
- }
- }
- for (i=0;i<35;i ++) {
- if (b [i] > -EPSILON && b [i] < EPSILON)
- Shape->Coeffs [i] = 0.0;
- else
- Shape->Coeffs [i] = b [i];
- }
- }
-