示例#1
0
文件: ray.cpp 项目: kaajo/ARayCasting
float Ray::intersectionWithPolygonAlt(Ray &ray, const QVector<QVector4D> polygon, QVector3D &normal, QVector3D &intersection, Ray &mirror)
{
    if(polygon.size() < 3) return std::numeric_limits<float>::max();

    normal = QVector3D::crossProduct((polygon[1] - polygon[0]).toVector3D(), (polygon[2] - polygon[1]).toVector3D());

    float distanceFromOrigin = QVector3D::dotProduct(normal, polygon[1].toVector3D() - polygon[0].toVector3D());

    QVector4D ba = ray.endPoint() - ray.startPoint();
    QVector4D pa = polygon[2] - ray.startPoint();

    float nDotA = QVector3D::dotProduct(normal, pa.toVector3D());
    float nDotBA = QVector3D::dotProduct(normal, ba.toVector3D());

    intersection = ray.startPoint().toVector3D() + (((distanceFromOrigin - nDotA)/nDotBA) * ba.toVector3D());

    QVector3D vector(QVector4D(intersection,1.0f)- ray.startPoint());

    QMatrix4x4 mat;
    mat.rotate(180, normal);

    vector = mat * vector;

    mirror = Ray(QVector4D(intersection,1.0), QVector4D(vector+intersection,1.0f));

    return calcAngleSum(intersection, polygon);
}
ShipCAD::PickRay ViewportView::convertMouseCoordToWorld(QPoint pos, int w, int h) const
{
    float x = (2.0f * pos.x()) / w - 1.0f;
    float y = 1.0f - (2.0f * pos.y()) / h;

    QVector4D from = _worldInv * QVector4D(x, y, -1.0, 1.0);
    QVector4D to = _worldInv * QVector4D(x, y, 1.0, 1.0);

    from /= from.w();
    to /= to.w();

    PickRay ray;
    ray.pt = from.toVector3D();
    ray.dir = to.toVector3D() - from.toVector3D();
    ray.dir.normalize();

#if 0
    cout << "from:" << from.x() << "," << from.y() << "," << from.z() << endl;
    cout << "to:" << to.x() << "," << to.y() << "," << to.z() << endl;

    // find the intersection with the xz plane if possible
    Plane xz(0,1,0,0);
    bool coplanar;
    QVector3D intpt;
    if (!xz.intersectLine(ray.pt, ray.dir, coplanar, intpt))
        cout << "xz intersect:" << intpt.x() << "," << intpt.y() << "," << intpt.z() << endl;
    else
        cout << "parallel to xz" << endl;
    if (coplanar)
        cout << "coplanar" << endl;
    // find the intersection with the yz plane if possible
    Plane yz(1,0,0,0);
    if (!yz.intersectLine(ray.pt, ray.dir, coplanar, intpt))
        cout << "yz intersect:" << intpt.x() << "," << intpt.y() << "," << intpt.z() << endl;
    else
        cout << "parallel to yz" << endl;
    if (coplanar)
        cout << "coplanar" << endl;
    // find the intersection with the xy plane if possible
    Plane xy(0,0,1,0);
    if (!xy.intersectLine(ray.pt, ray.dir, coplanar, intpt))
        cout << "xy intersect:" << intpt.x() << "," << intpt.y() << "," << intpt.z() << endl;
    else
        cout << "parallel to xy" << endl;
    if (coplanar)
        cout << "coplanar" << endl;
#endif

    return ray;
}
示例#3
0
QPointF GLScene::mapToScene(const QPointF &p){
//  Code below will work OK while projection is ortogonal
//  For some reason in perspective projection everything is flipped and not accurate
    QVector4D rNear = unproject(QVector3D(p.x(), p.y(), -1));
    QVector4D rFar =  unproject(QVector3D(p.x(), p.y(),  1));

    QVector<QVector3D> triangle;
    triangle << QVector3D(0, 0, 0) << QVector3D(0, 1, 0) << QVector3D(1, 0, 0);
    QVector3D normal = QVector3D::normal(triangle.at(0), triangle.at(1), triangle.at(2));

    qreal d1 = QVector3D::dotProduct(rNear.toVector3D() - triangle.at(0), normal);
    qreal d2 = QVector3D::dotProduct(rFar.toVector3D() - triangle.at(0), normal);

    QVector3D point = rNear.toVector3D() + (rFar.toVector3D() - rNear.toVector3D()) * (-d2 / (d2 - d1));
    return point.toPointF();
}
示例#4
0
void FormImageProp::colorPicked(QVector4D color){

    if(imageProp.bRoughnessColorPickingToggled){

        ui->pushButtonRoughnessPickColor->setChecked(false);
        imageProp.bRoughnessColorPickingToggled = false;
        imageProp.pickedColor                   = color.toVector3D()/255.0;
        QPalette palette = ui->labelRoughnessPickedColor->palette();
        palette.setColor(ui->labelRoughnessPickedColor->backgroundRole(), QColor(color.x(),color.y(),color.z()));
        palette.setColor(ui->labelRoughnessPickedColor->foregroundRole(), QColor(color.x(),color.y(),color.z()));
        ui->labelRoughnessPickedColor->setPalette(palette);
        update();
        emit imageChanged();
    }
}
示例#5
0
static QVector3D unproject( QVector3D v, const QMatrix4x4 &modelView, const QMatrix4x4 &projection, QRect viewport )
{
  // Reimplementation of QVector3D::unproject() - see qtbase/src/gui/math3d/qvector3d.cpp
  // The only difference is that the original implementation uses tolerance 1e-5
  // (see qFuzzyIsNull()) as a protection against division by zero. For us it is however
  // common to get lower values (e.g. as low as 1e-8 when zoomed out to the whole Earth with web mercator).

  QMatrix4x4 inverse = QMatrix4x4( projection * modelView ).inverted();

  QVector4D tmp( v, 1.0f );
  tmp.setX( ( tmp.x() - float( viewport.x() ) ) / float( viewport.width() ) );
  tmp.setY( ( tmp.y() - float( viewport.y() ) ) / float( viewport.height() ) );
  tmp = tmp * 2.0f - QVector4D( 1.0f, 1.0f, 1.0f, 1.0f );

  QVector4D obj = inverse * tmp;
  if ( qgsDoubleNear( obj.w(), 0, 1e-10 ) )
    obj.setW( 1.0f );
  obj /= obj.w();
  return obj.toVector3D();
}
void CubeMapRefractionScene::render()
{
    // Clear the buffer with the current clearing color
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    // Set up the view matrix
    QVector3D eye( 0.0f, 0.0f, 0.0f );
    QVector3D center( 0.0f, 0.0f, 1.0f );
    QVector3D up( 0.0f, 1.0f, 0.0f );
    m_viewMatrix.setToIdentity();
    m_viewMatrix.lookAt( eye, center, up );
    m_viewMatrix.rotate( m_phi, 1.0f, 0.0f, 0.0f );
    m_viewMatrix.rotate( m_theta, 0.0f, 1.0f, 0.0f );

    m_modelMatrix.setToIdentity();
    QMatrix4x4 modelViewMatrix = m_viewMatrix * m_modelMatrix;
    QMatrix4x4 mvp = m_projectionMatrix * modelViewMatrix;

    // We need a pointer to the material's shader to set uniform variables
    QOpenGLShaderProgramPtr shader = m_skyBox->material()->shader();

    // Draw the skybox
    shader->setUniformValue( "drawSkyBox", true );
    glDepthFunc(GL_LEQUAL);
    m_skyBox->render( mvp );
    glDepthFunc(GL_LESS);

    eye = QVector3D( 0.0f, 0.0f, -4.0f );
    m_viewMatrix.setToIdentity();
    m_viewMatrix.lookAt( eye, center, up );
    m_viewMatrix.rotate( m_phi, 1.0f, 0.0f, 0.0f );
    m_viewMatrix.rotate( m_theta, 0.0f, 1.0f, 0.0f );

    // Calculate the position of the camera in world coordinates
    QMatrix4x4 rot;
    rot.rotate( -m_theta, 0.0f, 1.0f, 0.0f );
    rot.rotate( -m_phi, 1.0f, 0.0f, 0.0f );
    QVector4D worldEye = rot * eye;
    QVector3D worldCamera = worldEye.toVector3D();

    // Rotate (and scale the model)
    m_modelMatrix.setToIdentity();
    static float theta = 0.0f;
    theta += 0.3f;
    m_modelMatrix.rotate( theta, 0.0f, 1.0f, 0.0f );
    m_modelMatrix.scale( 0.05f ); // Scale the toyplane mesh down to a reasonable size

    modelViewMatrix = m_viewMatrix * m_modelMatrix;
    mvp = m_projectionMatrix * modelViewMatrix;
    QMatrix3x3 normalMatrix = modelViewMatrix.normalMatrix();

    shader->setUniformValue( "worldCameraPosition", worldCamera );
    shader->setUniformValue( "modelViewMatrix", modelViewMatrix );
    shader->setUniformValue( "modelMatrix", m_modelMatrix );
    shader->setUniformValue( "normalMatrix", normalMatrix );
    shader->setUniformValue( "projectionMatrix", m_projectionMatrix );
    shader->setUniformValue( "mvp", mvp );

    // Draw the reflective mesh
    shader->setUniformValue( "drawSkyBox", false );
    shader->setUniformValue( "material.eta", 0.96f );
    shader->setUniformValue( "material.reflectionFactor", 0.0f );

    m_mesh->render();
}