bool Bezier::CollideSubDivQuadSimpleNorm(const Vec3 & origin, const Vec3 & direction, Vec3 &outtri, Vec3 & normal) const { bool col = false; const int COLLISION_QUAD_DIVS = 6; const float areacut = 0.5; float t, u, v; float su = 0; float sv = 0; float umin = 0; float umax = 1; float vmin = 0; float vmax = 1; Vec3 ul = points[3][3]; Vec3 ur = points[3][0]; Vec3 br = points[0][0]; Vec3 bl = points[0][3]; for (int i = 0; i < COLLISION_QUAD_DIVS; i++) { float tu[2]; float tv[2]; //speedup for i == 0 //if (i != 0) { tu[0] = umin; if (tu[0] < 0) tu[0] = 0; tu[1] = umax; if (tu[1] > 1) tu[1] = 1; tv[0] = vmin; if (tv[0] < 0) tv[0] = 0; tv[1] = vmax; if (tv[1] > 1) tv[1] = 1; ul = SurfCoord(tu[0], tv[0]); ur = SurfCoord(tu[1], tv[0]); br = SurfCoord(tu[1], tv[1]); bl = SurfCoord(tu[0], tv[1]); } col = IntersectQuadrilateralF(origin, direction, ul, ur, br, bl, t, u, v); if (col) { //expand quad UV to surface UV //su = u * (umax - umin) + umin; //sv = v * (vmax - vmin) + vmin; su = u * (tu[1] - tu[0]) + tu[0]; sv = v * (tv[1] - tv[0]) + tv[0]; //place max and min according to area hit vmax = sv + (0.5*areacut)*(vmax - vmin); vmin = sv - (0.5*areacut)*(vmax - vmin); umax = su + (0.5*areacut)*(umax - umin); umin = su - (0.5*areacut)*(umax - umin); } else { outtri = origin; return false; } } outtri = SurfCoord(su, sv); normal = SurfNorm(su, sv); return true; }
bool BEZIER::CollideSubDivQuadSimpleNorm(const MATHVECTOR<float,3> & origin, const MATHVECTOR<float,3> & direction, MATHVECTOR<float,3> &outtri, MATHVECTOR<float,3> & normal) const { bool col = false; const int COLLISION_QUAD_DIVS = 6; const bool QUAD_DIV_FAST_DISCARD = true; float t, u, v; float su = 0; float sv = 0; float umin = 0; float umax = 1; float vmin = 0; float vmax = 1; //const float fuzziness = 0.13; MATHVECTOR<float,3> ul = points[3][3]; MATHVECTOR<float,3> ur = points[3][0]; MATHVECTOR<float,3> br = points[0][0]; MATHVECTOR<float,3> bl = points[0][3]; //int subdivnum = 0; bool loop = true; float areacut = 0.5; for (int i = 0; i < COLLISION_QUAD_DIVS && loop; i++) { float tu[2]; float tv[2]; //speedup for i == 0 //if (i != 0) { tu[0] = umin; if (tu[0] < 0) tu[0] = 0; tu[1] = umax; if (tu[1] > 1) tu[1] = 1; tv[0] = vmin; if (tv[0] < 0) tv[0] = 0; tv[1] = vmax; if (tv[1] > 1) tv[1] = 1; ul = SurfCoord(tu[0], tv[0]); ur = SurfCoord(tu[1], tv[0]); br = SurfCoord(tu[1], tv[1]); bl = SurfCoord(tu[0], tv[1]); } //u = v = 0.0; col = IntersectQuadrilateralF(origin, direction, ul, ur, br, bl, t, u, v); if (col) { //expand quad UV to surface UV //su = u * (umax - umin) + umin; //sv = v * (vmax - vmin) + vmin; su = u * (tu[1] - tu[0]) + tu[0]; sv = v * (tv[1] - tv[0]) + tv[0]; //place max and min according to area hit vmax = sv + (0.5*areacut)*(vmax-vmin); vmin = sv - (0.5*areacut)*(vmax-vmin); umax = su + (0.5*areacut)*(umax-umin); umin = su - (0.5*areacut)*(umax-umin); } else { if ((i == 0) && QUAD_DIV_FAST_DISCARD) //if (QUAD_DIV_FAST_DISCARD) { outtri = origin; return false; } else { /*if (verbose) { cout << "<" << i << ": nocol " << su << "," << sv << ">" << endl; cout << "<" << umin << "," << umax << ";" << vmin << "," << vmax << ">" << endl; ul.DebugPrint(); ur.DebugPrint(); bl.DebugPrint(); br.DebugPrint(); cout << endl; }*/ loop = false; } } } if (col)// || QUAD_DIV_FAST_DISCARD) //if (col) { /*if (!col) cout << "blip " << su << "," << sv << ": " << u << "," << v << endl;*/ outtri = SurfCoord(su, sv); normal = SurfNorm(su, sv); //if (verbose) //cout << "<" << i << ">" << endl; return true; } else { outtri = origin; return false; } }