static void sort4OptimalPivot3AnyWidth(void *base, size_t nelem, size_t width, AbstractComparator &comparator, char *pivot) { DECLARE_STACK(stack, 80); PUSH(stack, base, nelem); while(!ISEMPTY(stack)) { POP(stack, base, nelem, void); tailrecurse: switch(nelem) { case 0: case 1: continue; case 2: SORT2(0, 1); continue; case 3: SORT3OPT(0, 1, 2); continue; case 4: SORT4OPT(0, 1, 2, 3, continue); continue; default: SORT3OPT(0, nelem/2, nelem-1); PASSIGN(pivot, EPTR(nelem/2)); break; } char *pi = EPTR(1), *pj = EPTR(nelem-2); do { while(pi <= pj && comparator.cmp(pi,pivot) < 0) pi += width; while(pi <= pj && comparator.cmp(pivot,pj) < 0) pj -= width; if(pi < pj) { PSWAP(pi,pj); } if(pi <= pj) { pi += width; pj -= width; } } while(pi <= pj); const size_t i = (pi - (char*)base) / width; const size_t j = (pj - (char*)base) / width; if(j > nelem - i) { // Sort the smallest partition first, to save stackspace if(j > 0) { PUSH(stack, base, j+1); // Save start, count of elements to be sorted later. ie. Sort(base,j+1,width, comparator); } if(i < nelem-1) { // Sort(pi, nelem-i, width, comparator); base = pi; nelem -= i; goto tailrecurse; } } else { if(i < nelem-1) { // Save start,count of elements to be sorted later. ie Sort(pi,nelem-i, width, comparator); PUSH(stack, pi, nelem-i); } if(j > 0) { // Sort(base,j+1,width, comparator); nelem = j+1; goto tailrecurse; } } } }
static EndGamePosIndex encode_kkp2_ondiag_flipi5m3e(EndGameKey key, int i, int j) { UINT pi = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(i)] - 28; UINT pj = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(j)]; SORT2(pi, pj); return ADDPIT(key, ADD2EQUALALLOWEQUALLH(KKP2_ONDIAG_3MEN(key), KKP2_ONDIAG_POSCOUNT, pi, pj)) + START_RANGE_KKP2_ONDIAG_P3_BELOWDIAG - MININDEX; }
static float median_float5(float *p) { register float temp ; SORT2(p[0],p[1]) ; SORT2(p[3],p[4]) ; SORT2(p[0],p[3]) ; SORT2(p[1],p[4]) ; SORT2(p[1],p[2]) ; SORT2(p[2],p[3]) ; SORT2(p[1],p[2]) ; return(p[2]) ; }
static EndGamePosIndex encode_kkp23_ondiag_flipi6m3e(EndGameKey key, int i, int j) { const EndGamePosIndex maxAddr = KKP23_ONDIAG_POSCOUNT; UINT pi = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(i)] - 28; UINT pj = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(j)]; SORT2(pi, pj); return ADDPIT(key, ADD2EQUALALLOWEQUALLH(KKP23_ONDIAG_4MEN(key), maxAddr, pi, pj)) + START_RANGE_KKP23_ONDIAG_P4_BELOWDIAG - MININDEX; }
static EndGamePosIndex encode_kkp2_ondiag_flipij6m3e(EndGameKey key, int i, int j, int k) { const EndGamePosIndex maxAddr = KKP2_ONDIAG_POSCOUNT; UINT pi = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(i)] - 28; UINT pj = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(j)] - 28; UINT pk = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(k)]; SORT2(pi, pj); return ADDPIT(key, ADD3EQUAL(KKP2_ONDIAG_3MEN(key), maxAddr, pi, pj, pk)) + START_RANGE_KKP2_ONDIAG_P5_BELOWDIAG - MININDEX; }
static EndGamePosIndex encode_kk_ondiag_flipij5m3e(EndGameKey key, int i, int j, int k) { UINT pi = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(i)] - 28; UINT pj = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(j)] - 28; UINT pk = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(k)]; SORT2(pi, pj); // pi < pj < pk return ADDPIT(key, ADD3EQUAL(KK_ONDIAG_2MEN(key), KK_ONDIAG_POSCOUNT, pi, pj, pk)) // Use SET3OFFDIAGPOSFLIPij to decode + START_RANGE_KK_ONDIAG_P4_BELOWDIAG - MININDEX; }
inline int32 uint32_sort2(uint32 *p) { int32 key = 0; uint32 work; if (p[0] < p[1]) key += 1; SORT2(p, work); return(key); }
int PGCreateTables::DISP_EQ2 (int **matrix, int *newmat, int *row, int nr, int nc, int n_states, int opt1) { int size, i, n; int r, x, c, inc; int *base, *p, *density, *indx; ALLOC (base, nr); ALLOC (indx, nr); for (r = 0; r < nr; r++) indx [r] = r; if (opt1) { ALLOC (density, nr); for (r = 0; r < nr; r++) { indx [r] = r; p = matrix [r]; density [r] = 0; if (opt1 == 1) // Must do this order for R_matrix. (why?) for (c = 0; c < nc; c++) if (*p++ != 1) density [r]--; // Do most dense rows first. else if (opt1 == 2) for (c = 0; c < nc; c++) if (*p++ != 1) density [r]++; // Do most dense rows last. } SORT2 (density, indx, nr); FREE (density, nr); } inc = 1; size = 0; for (x = 0; x < nr; x++) { r = indx [x]; for (i = 0; i < size; i += inc) { n = size - i; if (n > nc) n = nc; if (FASTCMP (newmat+i, matrix[r], n)) break; } base [r] = i; if (i + nc > size) { size = i + nc; FASTCPY (matrix[r], newmat+i, nc); } } for (i = 0; i < n_states; i++) { row [i] = base [row [i]]; } FREE (indx, nr); FREE (base, nr); return (size); }
int PGCreateTables::DISP_ZEQ (int **matrix, int *newmat, int *row, int nr, int nc, int n_states) { int r, c, x, i, j, size; int *p, *base, *density, *indx; ALLOC (base, nr); ALLOC (indx, nr); ALLOC (density, nr); for (r = 0; r < nr; r++) { indx [r] = r; density [r] = 0; p = matrix [r]; if (optn [PG_MINIMIZE]) /* Slower. */ { for (c = 0; c < nc; c++) if (*p++) density[r]--; // Most dense rows first } else /* Faster but slightly larger. */ { for (c = 0; c < nc; c++) if (*p++) density[r]++; // Least dense rows first } } SORT2 (density, indx, nr); FREE (density, nr); size = 0; for (x = 0; x < nr; x++) { r = indx [x]; for (i = 0; i < size; i++) { for (j = 0; j < nc; j++) { if ( matrix[r][j] == 0) continue; if ((newmat+i)[j] == 0) continue; if ( matrix[r][j] != (newmat+i)[j]) goto Next; } goto Load; Next: continue; } Load: base [r] = i; for (j = 0; j < nc; j++) { (newmat+i)[j] |= matrix[r][j]; } if (i + nc > size) size = i + nc; } for (i = 0; i < n_states; i++) row [i] = base [row [i]]; FREE (indx, nr); FREE (base, nr); return (size); }
int PGCreateTables::MRG_ROWZ_N (int **matrix, int n_heads, int *row, int n_states, int opt) { int *density, *indx; int s, i, r, nr, t, x, v; if (opt) { ALLOC (indx, n_states); ALLOC (density, n_states); for (s = 0; s < n_states; s++) indx [s] = s; for (s = 0; s < n_states; s++) { t = ntt_start[s+1] - ntt_start[s]; if (opt == 1) density [s] = -t; /* Maximize Number of Columns. */ else density [s] = t; /* Minimize Number of Columns. */ } SORT2 (density, indx, n_states); FREE (density, n_states); } nr = 0; for (x = 0; x < n_states; x++) // For all states. { if (opt) s = indx[x]; else s = x; for (r = 0; r < nr; r++) // For all rows defined. { for (i = ntt_start[s]; i < ntt_start[s+1]; i++) { if (ntt_action[i] != 0) { v = *(matrix[r] + ntt_symb[i]); if (v != 0 && v != ntt_action[i]) goto Next; } } goto Old; Next: continue; } ALLOC (matrix[nr], n_heads); FASTINI (0, matrix[nr], n_heads); nr++; Old: row [s] = r; for (i = ntt_start[s]; i < ntt_start[s+1]; i++) { if (ntt_action[i] != 0) { *(matrix[r] + ntt_symb[i]) = ntt_action[i]; } } } if (opt) FREE (indx, n_states); return (nr); }
static EndGamePosIndex encode_kkp2_ondiag_flipi6m3e(EndGameKey key, UINT i, UINT j, UINT k) { const EndGamePosIndex maxAddr = KKP2_ONDIAG_POSCOUNT; UINT pi = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(i)] - 28; UINT pj = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(j)]; UINT pk = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(k)]; SORT2(pj, pk); if(pi <= pj) { return ADDPIT(key, ADD3EQUALALLOWEQUALLM(KKP2_ONDIAG_3MEN(key), maxAddr, pi, pj, pk)) + START_RANGE_KKP2_ONDIAG_P45_BELOWDIAG - MININDEX; } else { return ADDPIT(key, ADD3EQUALALLOWEQUALHM(KKP2_ONDIAG_3MEN(key), maxAddr, pj, pi, pk)) + START_RANGE_KKP2_ONDIAG_P35_BELOWDIAG - MININDEX; } }
static EndGamePosIndex encode_kk_ondiag_flipi5m3e(EndGameKey key, UINT i, UINT j, UINT k) { UINT pi = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(i)] - 28; UINT pj = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(j)]; UINT pk = EndGameKeyDefinition::s_offDiagPosToIndex[key.getPosition(k)]; SORT2(pj, pk); if(pi <= pj) { // pi <= pj < pk return ADDPIT(key, ADD3EQUALALLOWEQUALLM(KK_ONDIAG_2MEN(key), KK_ONDIAG_POSCOUNT, pi, pj, pk)) // Use SET3OFFDIAGPOSFLIPi to decode + START_RANGE_KK_ONDIAG_P34_BELOWDIAG - MININDEX; } else { // pj < pi <= pk return ADDPIT(key, ADD3EQUALALLOWEQUALHM(KK_ONDIAG_2MEN(key), KK_ONDIAG_POSCOUNT, pj, pi, pk)) // Use SET3OFFDIAGPOSFLIPj to decode + START_RANGE_KK_ONDIAG_P24_BELOWDIAG - MININDEX; } }
inline void uint32_sort234_copy(uint32 *out, uint32 *p, uint32 num) { uint32 ii; uint32 work; for (ii = 0; ii < num; ii++) { out[ii] = p[ii]; } switch (num) { case 2: SORT2(out, work); break; case 3: SORT3(out, work); break; case 4: SORT4(out, work); break; } }
static INLINE float median25f(float *p) { register float temp ; SORT2(p[0], p[1]) ; SORT2(p[3], p[4]) ; SORT2(p[2], p[4]) ; SORT2(p[2], p[3]) ; SORT2(p[6], p[7]) ; SORT2(p[5], p[7]) ; SORT2(p[5], p[6]) ; SORT2(p[9], p[10]) ; SORT2(p[8], p[10]) ; SORT2(p[8], p[9]) ; SORT2(p[12], p[13]) ; SORT2(p[11], p[13]) ; SORT2(p[11], p[12]) ; SORT2(p[15], p[16]) ; SORT2(p[14], p[16]) ; SORT2(p[14], p[15]) ; SORT2(p[18], p[19]) ; SORT2(p[17], p[19]) ; SORT2(p[17], p[18]) ; SORT2(p[21], p[22]) ; SORT2(p[20], p[22]) ; SORT2(p[20], p[21]) ; SORT2(p[23], p[24]) ; SORT2(p[2], p[5]) ; SORT2(p[3], p[6]) ; SORT2(p[0], p[6]) ; SORT2(p[0], p[3]) ; SORT2(p[4], p[7]) ; SORT2(p[1], p[7]) ; SORT2(p[1], p[4]) ; SORT2(p[11], p[14]) ; SORT2(p[8], p[14]) ; SORT2(p[8], p[11]) ; SORT2(p[12], p[15]) ; SORT2(p[9], p[15]) ; SORT2(p[9], p[12]) ; SORT2(p[13], p[16]) ; SORT2(p[10], p[16]) ; SORT2(p[10], p[13]) ; SORT2(p[20], p[23]) ; SORT2(p[17], p[23]) ; SORT2(p[17], p[20]) ; SORT2(p[21], p[24]) ; SORT2(p[18], p[24]) ; SORT2(p[18], p[21]) ; SORT2(p[19], p[22]) ; SORT2(p[8], p[17]) ; SORT2(p[9], p[18]) ; SORT2(p[0], p[18]) ; SORT2(p[0], p[9]) ; SORT2(p[10], p[19]) ; SORT2(p[1], p[19]) ; SORT2(p[1], p[10]) ; SORT2(p[11], p[20]) ; SORT2(p[2], p[20]) ; SORT2(p[2], p[11]) ; SORT2(p[12], p[21]) ; SORT2(p[3], p[21]) ; SORT2(p[3], p[12]) ; SORT2(p[13], p[22]) ; SORT2(p[4], p[22]) ; SORT2(p[4], p[13]) ; SORT2(p[14], p[23]) ; SORT2(p[5], p[23]) ; SORT2(p[5], p[14]) ; SORT2(p[15], p[24]) ; SORT2(p[6], p[24]) ; SORT2(p[6], p[15]) ; SORT2(p[7], p[16]) ; SORT2(p[7], p[19]) ; SORT2(p[13], p[21]) ; SORT2(p[15], p[23]) ; SORT2(p[7], p[13]) ; SORT2(p[7], p[15]) ; SORT2(p[1], p[9]) ; SORT2(p[3], p[11]) ; SORT2(p[5], p[17]) ; SORT2(p[11], p[17]) ; SORT2(p[9], p[17]) ; SORT2(p[4], p[10]) ; SORT2(p[6], p[12]) ; SORT2(p[7], p[14]) ; SORT2(p[4], p[6]) ; SORT2(p[4], p[7]) ; SORT2(p[12], p[14]) ; SORT2(p[10], p[14]) ; SORT2(p[6], p[7]) ; SORT2(p[10], p[12]) ; SORT2(p[6], p[10]) ; SORT2(p[6], p[17]) ; SORT2(p[12], p[17]) ; SORT2(p[7], p[17]) ; SORT2(p[7], p[10]) ; SORT2(p[12], p[18]) ; SORT2(p[7], p[12]) ; SORT2(p[10], p[18]) ; SORT2(p[12], p[20]) ; SORT2(p[10], p[20]) ; SORT2(p[10], p[12]) ; return (p[12]); }
int PGCreateTables::MRG_COLZ (int *col, int n_cols, int n_rows, int **matrix, int opt) { int *density, *indx, x, i; int c, d, k, r, new_cols, *newloc, **newmat; ALLOC (indx, n_cols); for (c = 0; c < n_cols; c++) indx [c] = c; if (opt) { ALLOC (density, n_cols); for (c = 0; c < n_cols; c++) { density [c] = 0; for (r = 0; r < n_rows; r++) { if (*(matrix[r]+c) != 0) { if (opt == 1) density [c]--; else density [c]++; } } } SORT2 (density, indx, n_cols); FREE (density, n_cols); } new_cols = n_cols; for (c = 0; c < n_cols; c++) col [c] = c; for (x = 0; x < n_cols; x++) { c = indx [x]; for (d = 0; d < n_cols; d++) { if (d != c && col [d] == d) { for (r = 0; r < n_rows; r++) { if (*(matrix[r]+c) != 0) if (*(matrix[r]+d) != 0) if (*(matrix[r]+d) != *(matrix[r]+c)) goto nope; } for (r = 0; r < n_rows; r++) { *(matrix[r]+d) |= *(matrix[r]+c); } for (k = 0; k < n_cols; k++) if (col [k] == c) col [k] = d; new_cols--; goto cont; } nope: continue; } cont: continue; } k = 0; ALLOC (newloc, n_cols); ALLOC (newmat, n_rows); for (i = 0; i < n_rows; i++) { ALLOC (newmat[i], new_cols); } for (c = 0; c < n_cols; c++) { if (col[c] == c) { for (r = 0; r < n_rows; r++) { *(newmat[r]+k) = *(matrix[r]+c); } newloc[c] = k++; } } for (c = 0; c < n_cols; c++) col [c] = newloc [col [c]]; for (r = 0; r < n_rows; r++) FASTCPY (newmat [r], matrix [r], new_cols); for (i = 0; i < n_rows; i++) FREE (newmat [i], new_cols); FREE (newmat, n_rows); FREE (indx, n_cols); FREE (newloc, n_cols); return (new_cols); }
int PGCreateTables::DISP_EQ1B (char** matrix, char* newmat, int* row, int nr, int nc, int opt1) { char* p; int* base; int* indx; int* density; int size, i, n; int r, x, c, inc; ALLOC (base, nr); if (opt1) { ALLOC (indx, nr); ALLOC (density, nr); for (r = 0; r < nr; r++) { indx[r] = r; p = matrix[r]; if (opt1 == 1) /* Decreasing order of density, slower. */ { density[r] = 0; for (c = 0; c < nc; c++) { if (*p++ != 0) density[r]--; } } else if (opt1 == 2) /* Increasing order of density, faster. */ { density[r] = 0; for (c = 0; c < nc; c++) { if (*p++ != 0) density[r]++; } } } SORT2 (density, indx, nr); FREE (density, nr); } size = 0; inc = 8; // Faster if (optn[PG_MINIMIZE]) inc = 1; // Slower if (optn[PG_BOOLMATRIX] > 1) inc = 8; // Must be 8. for (x = 0; x < nr; x++) { if (opt1) r = indx[x]; else r = x; for (i = 0; i < size; i += inc) { n = size - i; if (n > nc) n = nc; if (memcmp (matrix[r], newmat+i, n) == 0) break; } base[r] = i; if (i + nc > size) { size = i + nc; memcpy (newmat+i, matrix[r], nc); } } for (i = 0; i < n_states; i++) { row[i] = base[row[i]]; if (optn[PG_BOOLMATRIX] > 1) row[i] /= 8; } if (opt1) FREE (indx, nr); FREE (base, nr); return ((size+7)/8*8); }
int bn_tri_tri_isect_with_line(point_t V0, point_t V1, point_t V2, point_t U0, point_t U1, point_t U2, int *coplanar, point_t *isectpt1, point_t *isectpt2) { point_t E1, E2; point_t N1, N2; fastf_t d1, d2; fastf_t du0, du1, du2, dv0, dv1, dv2; fastf_t D[3]; fastf_t isect1[2] = {0, 0}; fastf_t isect2[2] = {0, 0}; point_t isectpointA1 = VINIT_ZERO; point_t isectpointA2 = VINIT_ZERO; point_t isectpointB1 = VINIT_ZERO; point_t isectpointB2 = VINIT_ZERO; fastf_t du0du1, du0du2, dv0dv1, dv0dv2; short index; fastf_t vp0, vp1, vp2; fastf_t up0, up1, up2; fastf_t b, c, max; int smallest1, smallest2; /* compute plane equation of triangle(V0, V1, V2) */ VSUB2(E1, V1, V0); VSUB2(E2, V2, V0); VCROSS(N1, E1, E2); d1=-VDOT(N1, V0); /* plane equation 1: N1.X+d1=0 */ /* put U0, U1, U2 into plane equation 1 to compute signed distances to the plane*/ du0=VDOT(N1, U0)+d1; du1=VDOT(N1, U1)+d1; du2=VDOT(N1, U2)+d1; /* coplanarity robustness check */ #if USE_EPSILON_TEST if (fabs(du0)<EPSILON) du0=0.0; if (fabs(du1)<EPSILON) du1=0.0; if (fabs(du2)<EPSILON) du2=0.0; #endif du0du1=du0*du1; du0du2=du0*du2; if (du0du1>0.0f && du0du2>0.0f) /* same sign on all of them + not equal 0 ? */ return 0; /* no intersection occurs */ /* compute plane of triangle (U0, U1, U2) */ VSUB2(E1, U1, U0); VSUB2(E2, U2, U0); VCROSS(N2, E1, E2); d2=-VDOT(N2, U0); /* plane equation 2: N2.X+d2=0 */ /* put V0, V1, V2 into plane equation 2 */ dv0=VDOT(N2, V0)+d2; dv1=VDOT(N2, V1)+d2; dv2=VDOT(N2, V2)+d2; #if USE_EPSILON_TEST if (fabs(dv0)<EPSILON) dv0=0.0; if (fabs(dv1)<EPSILON) dv1=0.0; if (fabs(dv2)<EPSILON) dv2=0.0; #endif dv0dv1=dv0*dv1; dv0dv2=dv0*dv2; if (dv0dv1>0.0f && dv0dv2>0.0f) /* same sign on all of them + not equal 0 ? */ return 0; /* no intersection occurs */ /* compute direction of intersection line */ VCROSS(D, N1, N2); /* compute and index to the largest component of D */ max=fabs(D[0]); index=0; b=fabs(D[1]); c=fabs(D[2]); if (b>max) max=b, index=1; if (c>max) index=2; /* this is the simplified projection onto L*/ vp0=V0[index]; vp1=V1[index]; vp2=V2[index]; up0=U0[index]; up1=U1[index]; up2=U2[index]; /* compute interval for triangle 1 */ *coplanar=compute_intervals_isectline(V0, V1, V2, vp0, vp1, vp2, dv0, dv1, dv2, dv0dv1, dv0dv2, &isect1[0], &isect1[1], isectpointA1, isectpointA2); if (*coplanar) return coplanar_tri_tri(N1, V0, V1, V2, U0, U1, U2); /* compute interval for triangle 2 */ compute_intervals_isectline(U0, U1, U2, up0, up1, up2, du0, du1, du2, du0du1, du0du2, &isect2[0], &isect2[1], isectpointB1, isectpointB2); SORT2(isect1[0], isect1[1], smallest1); SORT2(isect2[0], isect2[1], smallest2); if (isect1[1]<isect2[0] || isect2[1]<isect1[0]) return 0; /* at this point, we know that the triangles intersect */ if (isect2[0]<isect1[0]) { if (smallest1==0) { VMOVE(*isectpt1, isectpointA1); } else { VMOVE(*isectpt1, isectpointA2); } if (isect2[1]<isect1[1]) { if (smallest2==0) { VMOVE(*isectpt2, isectpointB2); } else { VMOVE(*isectpt2, isectpointB1); } } else { if (smallest1==0) { VMOVE(*isectpt2, isectpointA2); } else { VMOVE(*isectpt2, isectpointA1); } } } else { if (smallest2==0) { VMOVE(*isectpt1, isectpointB1); } else { VMOVE(*isectpt1, isectpointB2); } if (isect2[1]>isect1[1]) { if (smallest1==0) { VMOVE(*isectpt2, isectpointA2); } else { VMOVE(*isectpt2, isectpointA1); } } else { if (smallest2==0) { VMOVE(*isectpt2, isectpointB2); } else { VMOVE(*isectpt2, isectpointB1); } } } return 1; }
int gcv_tri_tri_intersect_with_isectline(struct soup_s *UNUSED(left), struct soup_s *UNUSED(right), struct face_s *lf, struct face_s *rf, int *coplanar, point_t *isectpt, const struct bn_tol *tol) { vect_t D, isectpointA1={0}, isectpointA2={0}, isectpointB1={0}, isectpointB2={0}; fastf_t d1, d2, du0, du1, du2, dv0, dv1, dv2, du0du1, du0du2, dv0dv1, dv0dv2, vp0, vp1, vp2, up0, up1, up2, b, c, max, isect1[2]={0, 0}, isect2[2]={0, 0}; int i, smallest1=0, smallest2=0; /* compute plane equation of triangle(lf->vert[0], lf->vert[1], lf->vert[2]) */ d1=-VDOT(lf->plane, lf->vert[0]); /* plane equation 1: lf->plane.X+d1=0 */ /* put rf->vert[0], rf->vert[1], rf->vert[2] into plane equation 1 to compute signed distances to the plane*/ du0=VDOT(lf->plane, rf->vert[0])+d1; du1=VDOT(lf->plane, rf->vert[1])+d1; du2=VDOT(lf->plane, rf->vert[2])+d1; du0du1=du0*du1; du0du2=du0*du2; if (du0du1>0.0f && du0du2>0.0f) /* same sign on all of them + not equal 0 ? */ return 0; /* no intersection occurs */ /* compute plane of triangle (rf->vert[0], rf->vert[1], rf->vert[2]) */ d2=-VDOT(rf->plane, rf->vert[0]); /* plane equation 2: rf->plane.X+d2=0 */ /* put lf->vert[0], lf->vert[1], lf->vert[2] into plane equation 2 */ dv0=VDOT(rf->plane, lf->vert[0])+d2; dv1=VDOT(rf->plane, lf->vert[1])+d2; dv2=VDOT(rf->plane, lf->vert[2])+d2; dv0dv1=dv0*dv1; dv0dv2=dv0*dv2; if (dv0dv1>0.0f && dv0dv2>0.0f) /* same sign on all of them + not equal 0 ? */ return 0; /* no intersection occurs */ /* compute direction of intersection line */ VCROSS(D, lf->plane, rf->plane); /* compute and i to the largest component of D */ max=fabs(D[0]); i=0; b=fabs(D[1]); c=fabs(D[2]); if (b>max) max=b, i=1; if (c>max) max=c, i=2; /* this is the simplified projection onto L*/ vp0=lf->vert[0][i]; vp1=lf->vert[1][i]; vp2=lf->vert[2][i]; up0=rf->vert[0][i]; up1=rf->vert[1][i]; up2=rf->vert[2][i]; /* compute interval for triangle 1 */ *coplanar=gcv_compute_intervals_isectline(lf, vp0, vp1, vp2, dv0, dv1, dv2, dv0dv1, dv0dv2, &isect1[0], &isect1[1], &isectpointA1, &isectpointA2, tol); if (*coplanar) return gcv_coplanar_tri_tri(lf->plane, lf->vert[0], lf->vert[1], lf->vert[2], rf->vert[0], rf->vert[1], rf->vert[2]); /* compute interval for triangle 2 */ gcv_compute_intervals_isectline(rf, up0, up1, up2, du0, du1, du2, du0du1, du0du2, &isect2[0], &isect2[1], &isectpointB1, &isectpointB2, tol); /* sort so that a<=b */ smallest1 = smallest2 = 0; #define SORT2(a, b, smallest) if (a>b) { fastf_t _c; _c=a; a=b; b=_c; smallest=1; } SORT2(isect1[0], isect1[1], smallest1); SORT2(isect2[0], isect2[1], smallest2); #undef SORT2 if (isect1[1]<isect2[0] || isect2[1]<isect1[0]) return 0; /* at this point, we know that the triangles intersect */ if (isect2[0] < isect1[0]) { if (smallest1 == 0) VMOVE(isectpt[0], isectpointA1); else VMOVE(isectpt[0], isectpointA2); if (isect2[1] < isect1[1]) if (smallest2 == 0) VMOVE(isectpt[1], isectpointB2); else VMOVE(isectpt[1], isectpointB1); else if (smallest1 == 0) VMOVE(isectpt[1], isectpointA2); else VMOVE(isectpt[1], isectpointA1); } else { if (smallest2 == 0) VMOVE(isectpt[0], isectpointB1); else VMOVE(isectpt[0], isectpointB2); if (isect2[1] > isect1[1]) if (smallest1 == 0) VMOVE(isectpt[1], isectpointA2); else VMOVE(isectpt[1], isectpointA1); else if (smallest2 == 0) VMOVE(isectpt[1], isectpointB2); else VMOVE(isectpt[1], isectpointB1); } return 1; }
static INLINE float median9f(float *p) { register float temp ; SORT2(p[1],p[2]) ; SORT2(p[4],p[5]) ; SORT2(p[7],p[8]) ; SORT2(p[0],p[1]) ; SORT2(p[3],p[4]) ; SORT2(p[6],p[7]) ; SORT2(p[1],p[2]) ; SORT2(p[4],p[5]) ; SORT2(p[7],p[8]) ; SORT2(p[0],p[3]) ; SORT2(p[5],p[8]) ; SORT2(p[4],p[7]) ; SORT2(p[3],p[6]) ; SORT2(p[1],p[4]) ; SORT2(p[2],p[5]) ; SORT2(p[4],p[7]) ; SORT2(p[4],p[2]) ; SORT2(p[6],p[4]) ; SORT2(p[4],p[2]) ; return(p[4]) ; }