void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out){ dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); dxTriMesh* Geom = (dxTriMesh*)g; dVector3 dv[3]; gim_trimesh_locks_work_data(&Geom->m_collision_trimesh); gim_trimesh_get_triangle_vertices(&Geom->m_collision_trimesh, Index, dv[0],dv[1],dv[2]); GetPointFromBarycentric(dv, u, v, Out); gim_trimesh_unlocks_work_data(&Geom->m_collision_trimesh); }
void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out){ dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); dxTriMesh* Geom = (dxTriMesh*)g; const dVector3& Position = *(const dVector3*)dGeomGetPosition(g); const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g); dVector3 dv[3]; FetchTriangle(Geom, Index, Position, Rotation, dv); GetPointFromBarycentric(dv, u, v, Out); }
bool CBezierPatch::intersect(const CRay &ray, CIntersactionInfo &info, CVector3DF barCoord, unsigned int iterations, bool bDebug) const { //Planes along ray CVector3DF N1 = ray.Direction().Cross(CVector3DF(-1.0f,-1.0f,-1.0f)); CVector3DF N2 = ray.Direction().Cross(N1); const float d1 = -N1.Dot(ray.StartPoint()); const float d2 = -N2.Dot(ray.StartPoint()); float fSMall = 1e-3; CVector3DF dBu, dBv; for (unsigned int i = 0; i < iterations; i++) { const double &u(barCoord.X()); const double &v(barCoord.Y()); //partial U derivative of B dBu = GetdBu(u,v); //Partial V derivative of B dBv = GetdBv(u,v); const CVector3DF B = GetPointFromBarycentric(barCoord); const CVector3DF R = CVector3DF(N1.Dot(B) + d1, N2.Dot(B) + d2, 0); if ( ( fabs(R.X()) < fSMall ) && ( fabs(R.Y()) < fSMall ) ) { break; } //Inverse Jacobian const float fN1dotdBu = N1.Dot(dBu); const float fN1dotdBv = N1.Dot(dBv); const float fN2dotdBu = N2.Dot(dBu); const float fN2dotdBv = N2.Dot(dBv); const float invConst = 1.0f / ( fN1dotdBu * fN2dotdBv - fN1dotdBv * fN2dotdBu ); Matrix inverseJacobian; inverseJacobian[0][0] = fN2dotdBv * invConst; inverseJacobian[0][1] = -fN2dotdBu * invConst; inverseJacobian[0][2] = 0; inverseJacobian[1][0] = -fN1dotdBv * invConst; inverseJacobian[1][1] = fN1dotdBu * invConst; inverseJacobian[1][2] = 0; inverseJacobian[2][0] = 0; inverseJacobian[2][1] = 0; inverseJacobian[2][2] = 1; //Newton Iteration barCoord = barCoord - R.MatrixMultiply(inverseJacobian); barCoord.SetZ(1.0 - barCoord.X() - barCoord.Y()); if (barCoord.X() > k_fMAX || barCoord.X() < k_fMIN || barCoord.Y() > k_fMAX || barCoord.Y() < k_fMIN || barCoord.Z() > k_fMAX || barCoord.Z() < k_fMIN) { return false; } } const float &u(barCoord.X()); const float &v(barCoord.Y()); const float w(1.0 - u - v); if (u < -k_fSMALL || u > 1.0f + k_fSMALL || v < -k_fSMALL || v > 1.0f + k_fSMALL || w < -k_fSMALL || w > 1.0f + k_fSMALL) { return false; } if (bDebug) { char str[100]; sprintf( str, "u: %4.2f v: %4.2f w: %4.2f", u, v, w); qDebug() << str; } //Calculating B const CVector3DF B = GetPointFromBarycentric(barCoord); if ( ( fabs(N1.Dot(B) + d1) > fSMall ) || ( fabs(N2.Dot(B) + d2) > fSMall ) ) { if (bDebug) { qDebug() << "error too big"; } return false; } // calculate the intersection float len = (B - ray.StartPoint()).Length(); if (len > info.m_fDistance) { if (bDebug) { qDebug() << "Len > Distance"; } return false; } info.m_vIntersectionPoint = B; info.m_fDistance = len; info.m_vBarCoordsLocal.SetX(u); info.m_vBarCoordsLocal.SetY(v); info.m_vBarCoordsLocal.SetZ(w); info.m_vBarCoordsGlobal = info.m_vBarCoordsLocal; if (GetSettings()->m_bNormalSmoothing) { info.m_vNormal = GetSmoothedNormal(barCoord); } else { // info.m_vNormal = GetSmoothedNormal(barCoord); info.m_vNormal = CVector3DF::Normal(dBu, dBv); } if (bDebug) { qDebug()<< "Patch Hit!"; } return true; }
const CVector3DF CBezierPatch::GetPointFromBarycentric(const QVector2D& vCoords) const { return GetPointFromBarycentric(vCoords.x(), vCoords.y()); }
const CVector3DF CBezierPatch::GetPointFromBarycentric(const CVector3DF& vCoords) const { return GetPointFromBarycentric(vCoords.X(), vCoords.Y()); }