QVector4D Cylinder::surfaceNormal(const QVector4D &p, const Ray &ray) { QVector4D lp = m_worldToObject * p; QMatrix4x4 a = m_worldToObject.transposed(); a.setRow(3, QVector4D(0.0, 0.0, 0.0, 1.0)); if (m_hasCaps && fabs(fabs(lp.y()) - m_length * 0.5) < MathUtils::dEpsilon) { // Return cap normal QVector4D n; if (lp.y() < 0.0) n = QVector4D(0.0, -1.0, 0.0, 0.0); else n = QVector4D(0.0, 1.0, 0.0, 0.0); return (a * n).normalized(); } else { // calculate cylinder normal QVector4D o = QVector4D(0.0, lp.y(), 0.0, 1.0); QVector4D n = lp - o; n = a * n; QVector4D rd = -ray.direction(); if (QVector4D::dotProduct(n, rd) < 0) return -n.normalized(); else return n.normalized(); } }
QVector4D Cone::surfaceNormal(const QVector4D &p, const Ray &ray) { QVector4D objectP = m_worldToObject * p; QVector4D n = fabs(objectP.y()) < MathUtils::dEpsilon ? QVector4D(0.0, -1.0, 0.0, 0.0) : // We're on the base disc QVector4D(objectP.x(), 1.0 - objectP.y(), objectP.z(), 0.0); QMatrix4x4 a = m_worldToObject.transposed(); a.setRow(3, QVector4D(0.0, 0.0, 0.0, 1.0)); n = a * n; return n.normalized(); }
void Ray::set(const QVector4D &o, const QVector4D &d) { m_o = o; m_d = d.normalized(); }