Beispiel #1
0
//calcualte the screen space bounding box
void Window::calcuSSBB(const QMatrix4x4 &m, const QMatrix4x4 &v,const QMatrix4x4 &p)
{
    QVector4D res;
    QMatrix4x4 mvp = p*v*m;
    QList<float> xList;
    QList<float> yList;

    //FTR
    QVector4D ftr =QVector4D(21,21,21,1);
    res = mvp*ftr;
    xList.append((res.x()/res.z()+1)*0.5*1279);
    yList.append((1-(res.y()/res.z()+1)*0.5)*719);
    //FTL
    QVector4D ftl =QVector4D(-21,21,21,1);
    res = mvp*ftl;
    xList.append((res.x()/res.z()+1)*0.5*1279);
    yList.append((1-(res.y()/res.z()+1)*0.5)*719);
    //FBR
    QVector4D fbr =QVector4D(21,-21,21,1);
    res = mvp*fbr;
    xList.append((res.x()/res.z()+1)*0.5*1279);
    yList.append((1-(res.y()/res.z()+1)*0.5)*719);
    //FBL
    QVector4D fbl =QVector4D(-21,-21,21,1);
    res = mvp*fbl;
    xList.append((res.x()/res.z()+1)*0.5*1279);
    yList.append((1-(res.y()/res.z()+1)*0.5)*719);

    //BTR
    QVector4D btr =QVector4D(21,21,-21,1);
    res = mvp*btr;
    xList.append((res.x()/res.z()+1)*0.5*1279);
    yList.append((1-(res.y()/res.z()+1)*0.5)*719);
    //BTL
    QVector4D btl =QVector4D(-21,21,-21,1);
    res = mvp*btl;
    xList.append((res.x()/res.z()+1)*0.5*1279);
    yList.append((1-(res.y()/res.z()+1)*0.5)*719);
    //BBR
    QVector4D bbr =QVector4D(21,-21,-21,1);
    res = mvp*bbr;
    xList.append((res.x()/res.z()+1)*0.5*1279);
    yList.append((1-(res.y()/res.z()+1)*0.5)*719);
    //BBL
    QVector4D bbl =QVector4D(-21,-21,-21,1);
    res = mvp*bbl;
    xList.append((res.x()/res.z()+1)*0.5*1279);
    yList.append((1-(res.y()/res.z()+1)*0.5)*719);

    qSort(xList.begin(),xList.end());
    qSort(yList.begin(),yList.end());

    m_ssbb[0]=xList.first()/1280;
    m_ssbb[2]=xList.last()/1280;
    m_ssbb[1]=yList.first()/720;
    m_ssbb[3]=yList.last()/720;
    #define PERCENT_ENLARGE 0.20f
    #define PERCENT_BORDER  0.10f
    float width  = m_ssbb[2] - m_ssbb[0];
    float height = m_ssbb[3] - m_ssbb[1];
    float cx = m_ssbb[0] + ( width / 2.0f );
    float cy = m_ssbb[1] + ( height / 2.0f );
    width *= ( 1.0f + PERCENT_ENLARGE );
    height *= ( 1.0f + PERCENT_ENLARGE );
    m_ssbb[0] = ( cx - ( width / 2.0f ) < PERCENT_BORDER ) ? PERCENT_BORDER : cx - ( width / 2.0f );
    m_ssbb[1] = ( cy - ( height / 2.0f ) < PERCENT_BORDER ) ? PERCENT_BORDER : cy - ( height / 2.0f );
    m_ssbb[2] = ( cx + ( width / 2.0f ) > 1.0f - PERCENT_BORDER ) ? 1.0f - PERCENT_BORDER : cx + ( width / 2.0f );
    m_ssbb[3] = ( cy + ( height / 2.0f ) > 1.0f - PERCENT_BORDER ) ? 1.0f - PERCENT_BORDER : cy + ( height / 2.0f );

    qDebug() <<"x: "<< m_ssbb[0]<<" "<<  m_ssbb[2];
    qDebug() <<"y: "<< m_ssbb[1]<<" "<<  m_ssbb[3];

}
static inline int qsg_colorDiff(const QVector4D &a, const QVector4D &b)
{
    if (a.x() != b.x())
        return a.x() > b.x() ? 1 : -1;
    if (a.y() != b.y())
        return a.y() > b.y() ? 1 : -1;
    if (a.z() != b.z())
        return a.z() > b.z() ? 1 : -1;
    if (a.w() != b.w())
        return a.w() > b.w() ? 1 : -1;
    return 0;
}
Beispiel #3
0
PropertyGroup::PropertyGroup(QVector4D min, QVector4D max, QVector4D t, QString name)
{
	createBox(name);

	properties.emplace_back(new Property(min.x(), max.x(), t.x(), box));
	properties.emplace_back(new Property(min.y(), max.y(), t.y(), box));
	properties.emplace_back(new Property(min.z(), max.z(), t.z(), box));
	properties.emplace_back(new Property(min.w(), max.w(), t.w(), box));

	config();
}
QVariant PropertyMatrixModel::data(const QModelIndex &index, int role) const
{
  if (!index.isValid())
    return QVariant();

  if (role != Qt::DisplayRole && role != Qt::EditRole)
    return QVariant();

  switch (m_matrix.type()) {
    case QVariant::Matrix: {
      const QMatrix value = m_matrix.value<QMatrix>();
      switch (index.row() << 4 | index.column()) {
        case 0x00: return value.m11();
        case 0x01: return value.m12();
        case 0x10: return value.m21();
        case 0x11: return value.m22();
        case 0x20: return value.dx();
        case 0x21: return value.dy();
      }

      break;
    }

    case QVariant::Transform: {
      const QTransform value = m_matrix.value<QTransform>();
      switch (index.row() << 4 | index.column()) {
        case 0x00: return value.m11();
        case 0x01: return value.m12();
        case 0x02: return value.m13();
        case 0x10: return value.m21();
        case 0x11: return value.m22();
        case 0x12: return value.m23();
        case 0x20: return value.m31();
        case 0x21: return value.m32();
        case 0x22: return value.m33();
      }

      break;
    }

    case QVariant::Matrix4x4: {
      const QMatrix4x4 value = m_matrix.value<QMatrix4x4>();
      return value(index.row(), index.column());
    }

    case QVariant::Vector2D: {
      const QVector2D value = m_matrix.value<QVector2D>();
      switch (index.row()) {
        case 0: return value.x();
        case 1: return value.y();
      }

      break;
    }

    case QVariant::Vector3D: {
      const QVector3D value = m_matrix.value<QVector3D>();
      switch (index.row()) {
        case 0: return value.x();
        case 1: return value.y();
        case 2: return value.z();
      }

      break;
    }

    case QVariant::Vector4D: {
      const QVector4D value = m_matrix.value<QVector4D>();
      switch (index.row()) {
        case 0: return value.x();
        case 1: return value.y();
        case 2: return value.z();
        case 3: return value.w();
      }

      break;
    }

#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
    case QVariant::Quaternion: {
      float pitch, yaw, roll;

      const QQuaternion value = m_matrix.value<QQuaternion>();
      value.getEulerAngles(&pitch, &yaw, &roll);
      switch (index.row()) {
        case 0: return pitch;
        case 1: return yaw;
        case 2: return roll;
      }

      break;
    }
#endif

    default:
      break;
  }

  return QVariant();
}
bool PropertyMatrixModel::setData(const QModelIndex &index, const QVariant &data, int role)
{
  if (!index.isValid())
    return false;

  if (role != Qt::EditRole)
    return false;

  bool ok = false;
  float floatData = data.toFloat(&ok);

  if (!ok)
    return false;

  switch (m_matrix.type()) {
    case QVariant::Vector2D: {
      QVector2D value = m_matrix.value<QVector2D>();
      switch (index.row()) {
        case 0: value.setX(floatData); break;
        case 1: value.setY(floatData); break;
      }

      m_matrix = value;
      break;
    }

    case QVariant::Vector3D: {
      QVector3D value = m_matrix.value<QVector3D>();
      switch (index.row()) {
        case 0: value.setX(floatData); break;
        case 1: value.setY(floatData); break;
        case 2: value.setZ(floatData); break;
      }

      m_matrix = value;
      break;
    }

    case QVariant::Vector4D: {
      QVector4D value = m_matrix.value<QVector4D>();
      switch (index.row()) {
        case 0: value.setX(floatData); break;
        case 1: value.setY(floatData); break;
        case 2: value.setZ(floatData); break;
        case 3: value.setW(floatData); break;
      }

      m_matrix = value;
      break;
    }

#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
    case QVariant::Quaternion: {
      float pitch, yaw, roll;

      const QQuaternion value = m_matrix.value<QQuaternion>();
      value.getEulerAngles(&pitch, &yaw, &roll);
      switch (index.row()) {
        case 0: pitch = floatData; break;
        case 1: yaw = floatData; break;
        case 2: roll = floatData; break;
      }

      m_matrix = QQuaternion::fromEulerAngles(pitch, yaw, roll);
      break;
    }
#endif

    case QVariant::Matrix: {
      QMatrix value = m_matrix.value<QMatrix>();

      switch (index.row() << 4 | index.column()) {
        case 0x00: value.setMatrix(floatData, value.m12(), value.m21(), value.m22(), value.dx(), value.dy()); break;
        case 0x01: value.setMatrix(value.m11(), floatData, value.m21(), value.m22(), value.dx(), value.dy()); break;
        case 0x10: value.setMatrix(value.m11(), value.m12(), floatData, value.m22(), value.dx(), value.dy()); break;
        case 0x11: value.setMatrix(value.m11(), value.m12(), value.m21(), floatData, value.dx(), value.dy()); break;
        case 0x20: value.setMatrix(value.m11(), value.m12(), value.m21(), value.m22(), floatData, value.dy()); break;
        case 0x21: value.setMatrix(value.m11(), value.m12(), value.m21(), value.m22(), value.dx(), floatData); break;
      }

      m_matrix = value;
      break;
    }

    case QVariant::Transform: {
      QTransform value = m_matrix.value<QTransform>();

      switch (index.row() << 4 | index.column()) {
        case 0x00: value.setMatrix(floatData, value.m12(), value.m13(), value.m21(), value.m22(), value.m23(), value.m31(), value.m32(), value.m33()); break;
        case 0x01: value.setMatrix(value.m11(), floatData, value.m13(), value.m21(), value.m22(), value.m23(), value.m31(), value.m32(), value.m33()); break;
        case 0x02: value.setMatrix(value.m11(), value.m12(), floatData, value.m21(), value.m22(), value.m23(), value.m31(), value.m32(), value.m33()); break;
        case 0x10: value.setMatrix(value.m11(), value.m12(), value.m13(), floatData, value.m22(), value.m23(), value.m31(), value.m32(), value.m33()); break;
        case 0x11: value.setMatrix(value.m11(), value.m12(), value.m13(), value.m21(), floatData, value.m23(), value.m31(), value.m32(), value.m33()); break;
        case 0x12: value.setMatrix(value.m11(), value.m12(), value.m13(), value.m21(), value.m22(), floatData, value.m31(), value.m32(), value.m33()); break;
        case 0x20: value.setMatrix(value.m11(), value.m12(), value.m13(), value.m21(), value.m22(), value.m23(), floatData, value.m32(), value.m33()); break;
        case 0x21: value.setMatrix(value.m11(), value.m12(), value.m13(), value.m21(), value.m22(), value.m23(), value.m31(), floatData, value.m33()); break;
        case 0x22: value.setMatrix(value.m11(), value.m12(), value.m13(), value.m21(), value.m22(), value.m23(), value.m31(), value.m32(), floatData); break;
      }

      m_matrix = value;
      break;
    }

    case QVariant::Matrix4x4: {
      QMatrix4x4 value = m_matrix.value<QMatrix4x4>();

      value(index.row(), index.column()) = floatData;

      m_matrix = value;
      break;
    }
  }

  emit dataChanged(index, index);

  return true;
}
Beispiel #6
0
bool Qgs3DMapScene::updateCameraNearFarPlanes()
{
  // Update near and far plane from the terrain.
  // this needs to be done with great care as we have kind of circular dependency here:
  // active nodes are culled based on the current frustum (which involves near + far plane)
  // and then based on active nodes we set near and far plane.
  //
  // All of this is just heuristics assuming that all other stuff is being rendered somewhere
  // around the area where the terrain is.
  //
  // Near/far plane is setup in order to make best use of the depth buffer to avoid:
  // 1. precision errors - if the range is too great
  // 2. unwanted clipping of scene - if the range is too small

  if ( mTerrain )
  {
    Qt3DRender::QCamera *camera = cameraController()->camera();
    QMatrix4x4 viewMatrix = camera->viewMatrix();
    float fnear = 1e9;
    float ffar = 0;

    QList<QgsChunkNode *> activeNodes = mTerrain->activeNodes();

    // it could be that there are no active nodes - they could be all culled or because root node
    // is not yet loaded - we still need at least something to understand bounds of our scene
    // so lets use the root node
    if ( activeNodes.isEmpty() )
      activeNodes << mTerrain->rootNode();

    Q_FOREACH ( QgsChunkNode *node, activeNodes )
    {
      // project each corner of bbox to camera coordinates
      // and determine closest and farthest point.
      QgsAABB bbox = node->bbox();
      for ( int i = 0; i < 8; ++i )
      {
        QVector4D p( ( ( i >> 0 ) & 1 ) ? bbox.xMin : bbox.xMax,
                     ( ( i >> 1 ) & 1 ) ? bbox.yMin : bbox.yMax,
                     ( ( i >> 2 ) & 1 ) ? bbox.zMin : bbox.zMax, 1 );
        QVector4D pc = viewMatrix * p;

        float dst = -pc.z();  // in camera coordinates, x grows right, y grows down, z grows to the back
        if ( dst < fnear )
          fnear = dst;
        if ( dst > ffar )
          ffar = dst;
      }
    }
    if ( fnear < 1 )
      fnear = 1;  // does not really make sense to use negative far plane (behind camera)

    if ( fnear == 1e9 && ffar == 0 )
    {
      // the update didn't work out... this should not happen
      // well at least temprarily use some conservative starting values
      qDebug() << "oops... this should not happen! couldn't determine near/far plane. defaulting to 1...1e9";
      fnear = 1;
      ffar = 1e9;
    }

    // set near/far plane - with some tolerance in front/behind expected near/far planes
    float newFar = ffar * 2;
    float newNear = fnear / 2;
    if ( !qgsFloatNear( newFar, camera->farPlane() ) || !qgsFloatNear( newNear, camera->nearPlane() ) )
    {
      camera->setFarPlane( newFar );
      camera->setNearPlane( newNear );
      return true;
    }
  }
Ogre::Quaternion convert(const QVector4D &v)
{
	return Ogre::Quaternion(v.w(),v.x(),v.y(),v.z());
}
Beispiel #8
0
void Ray::set(const QVector4D &o, const QVector4D &d)
{
    m_o = o;
    m_d = d.normalized();
}
void BinghamRendererThread::run()
{
    const Matrix* vertices = tess::vertices( m_lod );
    int numVerts = tess::n_vertices( m_lod );

    Matrix base = ( FMath::sh_base( (*vertices), m_order ) );

    int numThreads = GLFunctions::idealThreadCount;

    double radius( 0.0 );
    QMatrix4x4 mvp = m_pMatrix * m_mvMatrix;
    if ( ( m_orient & 1 ) == 1 )
    {
        int glyphs = m_nx * m_ny;
        m_verts->reserve( numVerts * glyphs * 7 );
        QVector4D pos( 0, 0, m_z, 1.0 );
        for( int yy = m_id; yy < m_ny; yy += numThreads )
        {
            for ( int xx = 0; xx < m_nx; ++xx )
            {
                int dataPos = xx + yy * m_nx + m_zi * m_nx * m_ny;
                if ( ( fabs( m_data->at( dataPos )[8] ) > 0.0001 ) )
                {
                    float locX = xx * m_dx + m_ax;
                    float locY = yy * m_dy + m_ay;

                    pos.setX( locX );
                    pos.setY( locY );
                    QVector4D test = mvp * pos;

                    if ( fabs( test.x() / 2.0 ) < 1.0 && fabs( test.y() / 2.0 ) < 1.0 )
                    {
                        for ( int k = 0; k < 3; ++k )
                        {
                            if ( k == 0 && m_render1 )
                            {
                                for( int i = 0; i < numVerts; ++i )
                                {
                                    ColumnVector cur( 3 );
                                    cur( 1 ) = (*vertices)( i+1, 1 );
                                    cur( 2 ) = (*vertices)( i+1, 2 );
                                    cur( 3 ) = (*vertices)( i+1, 3 );

                                    ColumnVector m1( 3 );
                                    m1( 1 ) = m_data->at( dataPos )[k*9];
                                    m1( 2 ) = m_data->at( dataPos )[k*9+1];
                                    m1( 3 ) = m_data->at( dataPos )[k*9+2];

                                    ColumnVector m2( 3 );
                                    m2( 1 ) = m_data->at( dataPos )[k*9+3];
                                    m2( 2 ) = m_data->at( dataPos )[k*9+4];
                                    m2( 3 ) = m_data->at( dataPos )[k*9+5];

                                    double val_1( FMath::iprod( m1, cur ) );
                                    double val_2( FMath::iprod( m2, cur ) );


                                    double k1 = m_data->at( dataPos )[k*9+6];
                                    double k2 = m_data->at( dataPos )[k*9+7];
                                    double f0 = m_data->at( dataPos )[k*9+8];

                                    radius =  f0 * exp( -( k1 * val_1 * val_1 + k2 * val_2 * val_2 ) ) ;

                                    m_verts->push_back( (*vertices)( i+1, 1 ) );
                                    m_verts->push_back( (*vertices)( i+1, 2 ) );
                                    m_verts->push_back( (*vertices)( i+1, 3 ) );
                                    m_verts->push_back( locX );
                                    m_verts->push_back( locY );
                                    m_verts->push_back( m_z );
                                    m_verts->push_back( radius );
                                }
                            }
                            if ( k == 1 && m_render2 )
                            {
                                for( int i = 0; i < numVerts; ++i )
                                {
                                    ColumnVector cur( 3 );
                                    cur( 1 ) = (*vertices)( i+1, 1 );
                                    cur( 2 ) = (*vertices)( i+1, 2 );
                                    cur( 3 ) = (*vertices)( i+1, 3 );

                                    ColumnVector m1( 3 );
                                    m1( 1 ) = m_data->at( dataPos )[k*9];
                                    m1( 2 ) = m_data->at( dataPos )[k*9+1];
                                    m1( 3 ) = m_data->at( dataPos )[k*9+2];

                                    ColumnVector m2( 3 );
                                    m2( 1 ) = m_data->at( dataPos )[k*9+3];
                                    m2( 2 ) = m_data->at( dataPos )[k*9+4];
                                    m2( 3 ) = m_data->at( dataPos )[k*9+5];

                                    double val_1( FMath::iprod( m1, cur ) );
                                    double val_2( FMath::iprod( m2, cur ) );


                                    double k1 = m_data->at( dataPos )[k*9+6];
                                    double k2 = m_data->at( dataPos )[k*9+7];
                                    double f0 = m_data->at( dataPos )[k*9+8];

                                    radius =  f0 * exp( -( k1 * val_1 * val_1 + k2 * val_2 * val_2 ) ) ;

                                    m_verts->push_back( (*vertices)( i+1, 1 ) );
                                    m_verts->push_back( (*vertices)( i+1, 2 ) );
                                    m_verts->push_back( (*vertices)( i+1, 3 ) );
                                    m_verts->push_back( locX );
                                    m_verts->push_back( locY );
                                    m_verts->push_back( m_z );
                                    m_verts->push_back( radius );
                                }
                            }
                            if ( k == 2 && m_render3 )
                            {
                                for( int i = 0; i < numVerts; ++i )
                                {
                                    ColumnVector cur( 3 );
                                    cur( 1 ) = (*vertices)( i+1, 1 );
                                    cur( 2 ) = (*vertices)( i+1, 2 );
                                    cur( 3 ) = (*vertices)( i+1, 3 );

                                    ColumnVector m1( 3 );
                                    m1( 1 ) = m_data->at( dataPos )[k*9];
                                    m1( 2 ) = m_data->at( dataPos )[k*9+1];
                                    m1( 3 ) = m_data->at( dataPos )[k*9+2];

                                    ColumnVector m2( 3 );
                                    m2( 1 ) = m_data->at( dataPos )[k*9+3];
                                    m2( 2 ) = m_data->at( dataPos )[k*9+4];
                                    m2( 3 ) = m_data->at( dataPos )[k*9+5];

                                    double val_1( FMath::iprod( m1, cur ) );
                                    double val_2( FMath::iprod( m2, cur ) );


                                    double k1 = m_data->at( dataPos )[k*9+6];
                                    double k2 = m_data->at( dataPos )[k*9+7];
                                    double f0 = m_data->at( dataPos )[k*9+8];

                                    radius =  f0 * exp( -( k1 * val_1 * val_1 + k2 * val_2 * val_2 ) ) ;

                                    m_verts->push_back( (*vertices)( i+1, 1 ) );
                                    m_verts->push_back( (*vertices)( i+1, 2 ) );
                                    m_verts->push_back( (*vertices)( i+1, 3 ) );
                                    m_verts->push_back( locX );
                                    m_verts->push_back( locY );
                                    m_verts->push_back( m_z );
                                    m_verts->push_back( radius );
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    if ( ( m_orient & 2 ) == 2 )
    {
        int glyphs = m_nx * m_nz;
        m_verts->reserve( numVerts * glyphs * 7 );
        QVector4D pos( 0, m_y, 0, 1.0 );
        for( int zz = m_id; zz < m_nz; zz += numThreads )
        {
            for ( int xx = 0; xx < m_nx; ++xx )
            {
                int dataPos = xx + m_yi * m_nx + zz * m_nx * m_ny;
                if ( ( fabs( m_data->at( dataPos )[8] ) > 0.0001 ) )
                {
                    float locX = xx * m_dx + m_ax;
                    float locZ = zz * m_dz + m_az;

                    pos.setX( locX );
                    pos.setZ( locZ );
                    QVector4D test = mvp * pos;

                    if ( fabs( test.x() / 2.0 ) < 1.0 && fabs( test.y() / 2.0 ) < 1.0 )
                    {
                        for ( int k = 0; k < 3; ++k )
                        {
                            if ( k == 0 && m_render1 )
                            {
                                for( int i = 0; i < numVerts; ++i )
                                {
                                    ColumnVector cur( 3 );
                                    cur( 1 ) = (*vertices)( i+1, 1 );
                                    cur( 2 ) = (*vertices)( i+1, 2 );
                                    cur( 3 ) = (*vertices)( i+1, 3 );

                                    ColumnVector m1( 3 );
                                    m1( 1 ) = m_data->at( dataPos )[k*9];
                                    m1( 2 ) = m_data->at( dataPos )[k*9+1];
                                    m1( 3 ) = m_data->at( dataPos )[k*9+2];

                                    ColumnVector m2( 3 );
                                    m2( 1 ) = m_data->at( dataPos )[k*9+3];
                                    m2( 2 ) = m_data->at( dataPos )[k*9+4];
                                    m2( 3 ) = m_data->at( dataPos )[k*9+5];

                                    double val_1( FMath::iprod( m1, cur ) );
                                    double val_2( FMath::iprod( m2, cur ) );


                                    double k1 = m_data->at( dataPos )[k*9+6];
                                    double k2 = m_data->at( dataPos )[k*9+7];
                                    double f0 = m_data->at( dataPos )[k*9+8];

                                    radius =  f0 * exp( -( k1 * val_1 * val_1 + k2 * val_2 * val_2 ) ) ;

                                    m_verts->push_back( (*vertices)( i+1, 1 ) );
                                    m_verts->push_back( (*vertices)( i+1, 2 ) );
                                    m_verts->push_back( (*vertices)( i+1, 3 ) );
                                    m_verts->push_back( locX );
                                    m_verts->push_back( m_y );
                                    m_verts->push_back( locZ );
                                    m_verts->push_back( radius );
                                }
                            }
                            if ( k == 1 && m_render2 )
                            {
                                for( int i = 0; i < numVerts; ++i )
                                {
                                    ColumnVector cur( 3 );
                                    cur( 1 ) = (*vertices)( i+1, 1 );
                                    cur( 2 ) = (*vertices)( i+1, 2 );
                                    cur( 3 ) = (*vertices)( i+1, 3 );

                                    ColumnVector m1( 3 );
                                    m1( 1 ) = m_data->at( dataPos )[k*9];
                                    m1( 2 ) = m_data->at( dataPos )[k*9+1];
                                    m1( 3 ) = m_data->at( dataPos )[k*9+2];

                                    ColumnVector m2( 3 );
                                    m2( 1 ) = m_data->at( dataPos )[k*9+3];
                                    m2( 2 ) = m_data->at( dataPos )[k*9+4];
                                    m2( 3 ) = m_data->at( dataPos )[k*9+5];

                                    double val_1( FMath::iprod( m1, cur ) );
                                    double val_2( FMath::iprod( m2, cur ) );


                                    double k1 = m_data->at( dataPos )[k*9+6];
                                    double k2 = m_data->at( dataPos )[k*9+7];
                                    double f0 = m_data->at( dataPos )[k*9+8];

                                    radius =  f0 * exp( -( k1 * val_1 * val_1 + k2 * val_2 * val_2 ) ) ;

                                    m_verts->push_back( (*vertices)( i+1, 1 ) );
                                    m_verts->push_back( (*vertices)( i+1, 2 ) );
                                    m_verts->push_back( (*vertices)( i+1, 3 ) );
                                    m_verts->push_back( locX );
                                    m_verts->push_back( m_y );
                                    m_verts->push_back( locZ );
                                    m_verts->push_back( radius );
                                }
                            }
                            if ( k == 2 && m_render3 )
                            {
                                for( int i = 0; i < numVerts; ++i )
                                {
                                    ColumnVector cur( 3 );
                                    cur( 1 ) = (*vertices)( i+1, 1 );
                                    cur( 2 ) = (*vertices)( i+1, 2 );
                                    cur( 3 ) = (*vertices)( i+1, 3 );

                                    ColumnVector m1( 3 );
                                    m1( 1 ) = m_data->at( dataPos )[k*9];
                                    m1( 2 ) = m_data->at( dataPos )[k*9+1];
                                    m1( 3 ) = m_data->at( dataPos )[k*9+2];

                                    ColumnVector m2( 3 );
                                    m2( 1 ) = m_data->at( dataPos )[k*9+3];
                                    m2( 2 ) = m_data->at( dataPos )[k*9+4];
                                    m2( 3 ) = m_data->at( dataPos )[k*9+5];

                                    double val_1( FMath::iprod( m1, cur ) );
                                    double val_2( FMath::iprod( m2, cur ) );


                                    double k1 = m_data->at( dataPos )[k*9+6];
                                    double k2 = m_data->at( dataPos )[k*9+7];
                                    double f0 = m_data->at( dataPos )[k*9+8];

                                    radius =  f0 * exp( -( k1 * val_1 * val_1 + k2 * val_2 * val_2 ) ) ;

                                    m_verts->push_back( (*vertices)( i+1, 1 ) );
                                    m_verts->push_back( (*vertices)( i+1, 2 ) );
                                    m_verts->push_back( (*vertices)( i+1, 3 ) );
                                    m_verts->push_back( locX );
                                    m_verts->push_back( m_y );
                                    m_verts->push_back( locZ );
                                    m_verts->push_back( radius );
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    if ( ( m_orient & 4 )  == 4 )
    {
        int glyphs = m_ny * m_nz;
        m_verts->reserve( numVerts * glyphs * 10 );
        QVector4D pos( m_x, 0, 0, 1.0 );
        for( int yy = m_id; yy < m_ny; yy += numThreads )
        {
            for ( int zz = 0; zz < m_nz; ++zz )
            {
                int dataPos = m_xi + yy * m_nx + zz * m_nx * m_ny;
                if ( ( fabs( m_data->at( dataPos )[8] ) > 0.0001 ) )
                {
                    float locZ = zz * m_dz + m_az;
                    float locY = yy * m_dy + m_ay;

                    pos.setY( locY );
                    pos.setZ( locZ );
                    QVector4D test = mvp * pos;

                    if ( fabs( test.x() / 2.0 ) < 1.0 && fabs( test.y() / 2.0 ) < 1.0 )
                    {
                        for ( int k = 0; k < 3; ++k )
                        {
                            if ( k == 0 && m_render1 )
                            {
                                for( int i = 0; i < numVerts; ++i )
                                {
                                    ColumnVector cur( 3 );
                                    cur( 1 ) = (*vertices)( i+1, 1 );
                                    cur( 2 ) = (*vertices)( i+1, 2 );
                                    cur( 3 ) = (*vertices)( i+1, 3 );

                                    ColumnVector m1( 3 );
                                    m1( 1 ) = m_data->at( dataPos )[k*9];
                                    m1( 2 ) = m_data->at( dataPos )[k*9+1];
                                    m1( 3 ) = m_data->at( dataPos )[k*9+2];

                                    ColumnVector m2( 3 );
                                    m2( 1 ) = m_data->at( dataPos )[k*9+3];
                                    m2( 2 ) = m_data->at( dataPos )[k*9+4];
                                    m2( 3 ) = m_data->at( dataPos )[k*9+5];

                                    double val_1( FMath::iprod( m1, cur ) );
                                    double val_2( FMath::iprod( m2, cur ) );


                                    double k1 = m_data->at( dataPos )[k*9+6];
                                    double k2 = m_data->at( dataPos )[k*9+7];
                                    double f0 = m_data->at( dataPos )[k*9+8];

                                    radius =  f0 * exp( -( k1 * val_1 * val_1 + k2 * val_2 * val_2 ) ) ;

                                    m_verts->push_back( (*vertices)( i+1, 1 ) );
                                    m_verts->push_back( (*vertices)( i+1, 2 ) );
                                    m_verts->push_back( (*vertices)( i+1, 3 ) );
                                    m_verts->push_back( m_x );
                                    m_verts->push_back( locY );
                                    m_verts->push_back( locZ );
                                    m_verts->push_back( radius );
                                }
                            }
                            if ( k == 1 && m_render2 )
                            {
                                for( int i = 0; i < numVerts; ++i )
                                {
                                    ColumnVector cur( 3 );
                                    cur( 1 ) = (*vertices)( i+1, 1 );
                                    cur( 2 ) = (*vertices)( i+1, 2 );
                                    cur( 3 ) = (*vertices)( i+1, 3 );

                                    ColumnVector m1( 3 );
                                    m1( 1 ) = m_data->at( dataPos )[k*9];
                                    m1( 2 ) = m_data->at( dataPos )[k*9+1];
                                    m1( 3 ) = m_data->at( dataPos )[k*9+2];

                                    ColumnVector m2( 3 );
                                    m2( 1 ) = m_data->at( dataPos )[k*9+3];
                                    m2( 2 ) = m_data->at( dataPos )[k*9+4];
                                    m2( 3 ) = m_data->at( dataPos )[k*9+5];

                                    double val_1( FMath::iprod( m1, cur ) );
                                    double val_2( FMath::iprod( m2, cur ) );


                                    double k1 = m_data->at( dataPos )[k*9+6];
                                    double k2 = m_data->at( dataPos )[k*9+7];
                                    double f0 = m_data->at( dataPos )[k*9+8];

                                    radius =  f0 * exp( -( k1 * val_1 * val_1 + k2 * val_2 * val_2 ) ) ;

                                    m_verts->push_back( (*vertices)( i+1, 1 ) );
                                    m_verts->push_back( (*vertices)( i+1, 2 ) );
                                    m_verts->push_back( (*vertices)( i+1, 3 ) );
                                    m_verts->push_back( m_x );
                                    m_verts->push_back( locY );
                                    m_verts->push_back( locZ );
                                    m_verts->push_back( radius );
                                }
                            }
                            if ( k == 2 && m_render3 )
                            {
                                for( int i = 0; i < numVerts; ++i )
                                {
                                    ColumnVector cur( 3 );
                                    cur( 1 ) = (*vertices)( i+1, 1 );
                                    cur( 2 ) = (*vertices)( i+1, 2 );
                                    cur( 3 ) = (*vertices)( i+1, 3 );

                                    ColumnVector m1( 3 );
                                    m1( 1 ) = m_data->at( dataPos )[k*9];
                                    m1( 2 ) = m_data->at( dataPos )[k*9+1];
                                    m1( 3 ) = m_data->at( dataPos )[k*9+2];

                                    ColumnVector m2( 3 );
                                    m2( 1 ) = m_data->at( dataPos )[k*9+3];
                                    m2( 2 ) = m_data->at( dataPos )[k*9+4];
                                    m2( 3 ) = m_data->at( dataPos )[k*9+5];

                                    double val_1( FMath::iprod( m1, cur ) );
                                    double val_2( FMath::iprod( m2, cur ) );


                                    double k1 = m_data->at( dataPos )[k*9+6];
                                    double k2 = m_data->at( dataPos )[k*9+7];
                                    double f0 = m_data->at( dataPos )[k*9+8];

                                    radius =  f0 * exp( -( k1 * val_1 * val_1 + k2 * val_2 * val_2 ) ) ;

                                    m_verts->push_back( (*vertices)( i+1, 1 ) );
                                    m_verts->push_back( (*vertices)( i+1, 2 ) );
                                    m_verts->push_back( (*vertices)( i+1, 3 ) );
                                    m_verts->push_back( m_x );
                                    m_verts->push_back( locY );
                                    m_verts->push_back( locZ );
                                    m_verts->push_back( radius );
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    else
    {
        return;
    }
}
void CombinedNavRenderer::leftMouseDown( int x, int y )
{
    float xf = static_cast<float>( x );
    float yf = static_cast<float>( m_height - y );

    QVector4D test;
    test.setX( ( 2 * xf ) / m_width - 1 );
    test.setY( ( 2 * yf ) / m_height - 1 );
    test.setZ( 1 );
    test.setW( 1 );

    int xout;
    int yout;

    QVector4D out = m_mvpMatrix.inverted() * test;
    QModelIndex mi;
    if ( m_ratio > 1.5 )
    {
        xout = out.x() / m_dx;
        if ( ( (float)out.x()  / m_dx ) < m_nx )
        {
            xout = qMax( 0, qMin( xout, static_cast<int>( m_nx - 1.0 ) ) );
            yout = out.y() / m_dy;
            yout = qMax( 0, qMin( yout, static_cast<int>( m_ny - 1.0 ) ) );
            mi = model()->index( (int)Fn::Global::SAGITTAL_CORONAL, 0 );
        }
        else if ( ( (float)out.x() / m_dx ) < m_nx * 2  )
        {
            xout = xout - m_nx;
            xout = qMax( 0, qMin( xout, static_cast<int>( m_nx - 1.0 ) ) );
            yout = out.y() / m_dz;
            yout = qMax( 0, qMin( yout, static_cast<int>( m_nz - 1.0 ) ) );
            mi = model()->index( (int)Fn::Global::SAGITTAL_AXIAL, 0 );
        }
        else
        {
            xout = xout - ( 2 * m_nx );
            xout = qMax( 0, qMin( m_ny - xout - 1, static_cast<int>( m_ny - 1.0 ) ) );
            yout = out.y() / m_dz;
            yout = qMax( 0, qMin( yout, static_cast<int>( m_nz - 1.0 ) ) );
            mi = model()->index( (int)Fn::Global::CORONAL_AXIAL, 0 );
        }
    }
    else if ( m_ratio < 0.66 )
    {
        yout = out.y() / m_dz;
        if ( ( (float)out.y() / m_dz ) < m_nz )
        {
            xout = out.x() / m_dy;
            xout = qMax( 0, qMin( m_ny - xout - 1, static_cast<int>( m_ny - 1.0 ) ) );
            yout = qMax( 0, qMin( yout, static_cast<int>( m_nz - 1.0 ) ) );
            mi = model()->index( (int)Fn::Global::CORONAL_AXIAL, 0 );
        }
        else if ( ( (float)out.y() / m_dz ) < m_nz * 2  )
        {
            xout = out.x() / m_dx;
            xout = qMax( 0, qMin( xout, static_cast<int>( m_nx - 1.0 ) ) );
            yout = yout - m_nz;
            yout = qMax( 0, qMin( yout, static_cast<int>( m_nz - 1.0 ) ) );
            mi = model()->index( (int)Fn::Global::SAGITTAL_AXIAL, 0 );
        }
        else
        {
            xout = out.x() / m_dx;
            xout = qMax( 0, qMin( xout, static_cast<int>( m_nx - 1.0 ) ) );
            yout = yout - ( 2 * m_nz );
            yout = qMax( 0, qMin( yout, static_cast<int>( m_ny - 1.0 ) ) );
            mi = model()->index( (int)Fn::Global::SAGITTAL_CORONAL, 0 );
        }
    }
    else
    {
        xout = out.x() / m_dx;
        yout = out.y() / m_dy;
        if ( ( (float)out.x()  / m_dx ) < m_nx )
        {
            if ( ( (float)out.y() / m_dy ) < m_nz )
            {
                xout = qMax( 0, qMin( xout, static_cast<int>( m_nx - 1.0 ) ) );
                yout = qMax( 0, qMin( yout, static_cast<int>( m_ny - 1.0 ) ) );
                mi = model()->index( (int)Fn::Global::SAGITTAL_CORONAL, 0 );
            }
            else
            {
                xout = qMax( 0, qMin( xout, static_cast<int>( m_nx - 1.0 ) ) );
                yout = yout - m_ny;
                yout = qMax( 0, qMin( yout, static_cast<int>( m_nz - 1.0 ) ) );
                mi = model()->index( (int)Fn::Global::SAGITTAL_AXIAL, 0 );
            }
        }
        else
        {
            xout = xout - m_nx;
            xout = qMax( 0, qMin( m_ny - xout- 1, static_cast<int>( m_ny - 1.0 ) ) );
            yout = yout - m_ny;
            yout = qMax( 0, qMin( yout, static_cast<int>( m_nz - 1.0 ) ) );
            mi = model()->index( (int)Fn::Global::CORONAL_AXIAL, 0 );
        }
    }
    QPoint p( xout, yout );

    if ( mi.isValid() )
    {
        model()->setData( mi, p );
    }
}
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();
}
static MeshPtr importObject(QDataStream &stream)
{
    using namespace Ogre;

    QVector4D bbMin, bbMax;
    stream >> bbMin >> bbMax;

    float distance, distanceSquared; // Here's a bug for you: writes "double"'s instead of floats
    stream >> distanceSquared >> distance;

    MeshPtr ogreMesh = MeshManager::getSingleton().createManual("conversion",
                                                               ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

    int vertexCount, indexCount;
    stream >> vertexCount >> indexCount;

    VertexData *vertexData = new VertexData();
    ogreMesh->sharedVertexData = vertexData;

    LogManager::getSingleton().logMessage("Reading geometry...");
    VertexDeclaration* decl = vertexData->vertexDeclaration;
    VertexBufferBinding* bind = vertexData->vertexBufferBinding;
    unsigned short bufferId = 0;

    // Information for calculating bounds
    Vector3 min = Vector3::ZERO, max = Vector3::UNIT_SCALE, pos = Vector3::ZERO;
    Real maxSquaredRadius = -1;
    bool firstVertex = true;

    /*
      Create a vertex definition for our buffer
      */
    size_t offset = 0;

    const VertexElement &positionElement = decl->addElement(bufferId, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);

    const VertexElement &normalElement = decl->addElement(bufferId, offset, VET_FLOAT3, VES_NORMAL);
    offset += VertexElement::getTypeSize(VET_FLOAT3);

    // calculate how many vertexes there actually are
    vertexData->vertexCount = vertexCount;

    // Now create the vertex buffer
    HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().
            createVertexBuffer(offset, vertexData->vertexCount,
                               HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

    // Bind it
    bind->setBinding(bufferId, vbuf);

    // Lock it
    unsigned char *pVert = static_cast<unsigned char*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
    unsigned char *pVertStart = pVert;

    QVector<float> positions;
    positions.reserve(vertexCount * 3);

    // Iterate over all children (vertexbuffer entries)
    for (int i = 0; i < vertexCount; ++i) {
        float *pFloat;

        QVector4D vertex;
        stream >> vertex;
		vertex.setZ(vertex.z() * -1);

        /* Copy over the position */
        positionElement.baseVertexPointerToElement(pVert, &pFloat);
        *(pFloat++) = (float)vertex.x();
        *(pFloat++) = (float)vertex.y();
        *(pFloat++) = (float)vertex.z();

        positions.append(vertex.x());
        positions.append(vertex.y());
        positions.append(vertex.z());

        /* While we're at it, calculate the bounding sphere */
        pos.x = vertex.x();
        pos.y = vertex.y();
        pos.z = vertex.z();

        if (firstVertex) {
            min = max = pos;
            maxSquaredRadius = pos.squaredLength();
            firstVertex = false;
        } else {
            min.makeFloor(pos);
            max.makeCeil(pos);
            maxSquaredRadius = qMax(pos.squaredLength(), maxSquaredRadius);
        }

        pVert += vbuf->getVertexSize();
    }

    // Set bounds
    const AxisAlignedBox& currBox = ogreMesh->getBounds();
    Real currRadius = ogreMesh->getBoundingSphereRadius();
    if (currBox.isNull())
    {
        //do not pad the bounding box
        ogreMesh->_setBounds(AxisAlignedBox(min, max), false);
        ogreMesh->_setBoundingSphereRadius(Math::Sqrt(maxSquaredRadius));
    }
    else
    {
        AxisAlignedBox newBox(min, max);
        newBox.merge(currBox);
        //do not pad the bounding box
        ogreMesh->_setBounds(newBox, false);
        ogreMesh->_setBoundingSphereRadius(qMax(Math::Sqrt(maxSquaredRadius), currRadius));
    }

    /*
       Create faces
     */
    // All children should be submeshes
    SubMesh* sm = ogreMesh->createSubMesh();
    sm->setMaterialName("clippingMaterial");
    sm->operationType = RenderOperation::OT_TRIANGLE_LIST;
    sm->useSharedVertices = true;

    // tri list
    sm->indexData->indexCount = indexCount;

    // Allocate space
    HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
            createIndexBuffer(
                HardwareIndexBuffer::IT_16BIT,
                sm->indexData->indexCount,
                HardwareBuffer::HBU_DYNAMIC,
                false);
    sm->indexData->indexBuffer = ibuf;

    unsigned short *pShort = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_DISCARD));

    QVector<EdgeData::Triangle> triangles(indexCount / 3);

    for (int i = 0; i < indexCount / 3; ++i) {
        quint16 i1, i2, i3;

        stream >> i1 >> i2 >> i3;
        *pShort++ = i1;
        *pShort++ = i2;
        *pShort++ = i3;

        triangles[i].vertIndex[0] = i1;
        triangles[i].vertIndex[1] = i2;
        triangles[i].vertIndex[2] = i3;

    }

    /* Recalculate the vertex normals */
    Vector4 *faceNormals = (Vector4*)_aligned_malloc(sizeof(Vector4) * triangles.size(), 16);

    OptimisedUtil *util = OptimisedUtil::getImplementation();
    util->calculateFaceNormals(positions.constData(),
                               triangles.data(),
                               faceNormals,
                               indexCount / 3);

	 // Iterate over all children (vertexbuffer entries)
	pVert = pVertStart;
    for (int i = 0; i < vertexCount; ++i) {
        float *pFloat;

		Vector3 normal = Vector3::ZERO;
		
		int count = 0;

		/* Search for all faces that use this vertex */
		for (int j = 0; j < triangles.size(); ++j) {
			if (triangles[j].vertIndex[0] == i 
				|| triangles[j].vertIndex[1] == i 
				|| triangles[j].vertIndex[2] == i) {
				normal.x += faceNormals[j].x / faceNormals[j].w;
				normal.y += faceNormals[j].y / faceNormals[j].w;
				normal.z += faceNormals[j].z / faceNormals[j].w;
				count++;
			}
		}

		normal.normalise();

        /* Copy over the position */
		normalElement.baseVertexPointerToElement(pVert, &pFloat);
        *(pFloat++) = normal.x;
        *(pFloat++) = normal.y;
        *(pFloat++) = normal.z;
		
        pVert += vbuf->getVertexSize();
    }

    _aligned_free(faceNormals);

    vbuf->unlock();
    ibuf->unlock();

    return ogreMesh;
}
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;
}
Beispiel #14
0
QMatrix4x4 iPolacion::getMatrizRotacion(QVector4D q){


    QMatrix4x4 m = QMatrix4x4((1-(2*((q.y()*q.y())+(q.z()*q.z())))),
                              ((2*q.x()*q.y())-(2*q.w()*q.z())),
                              ((2*q.w()*q.y())+(2*q.x()*q.z())),
                              0
                              ,
                              ((2*q.x()*q.y())+(2*q.w()*q.z())),
                              (1-(2*((q.x()*q.x())+(q.z()*q.z())))),
                              ((-2*q.w()*q.x())+(2*q.y()*q.z())),
                              0
                              ,
                              ((-2*q.w()*q.y())+(2*q.x()*q.z())),
                              ((2*q.w()*q.x())+(2*q.y()*q.z())),
                              (1-(2*((q.x()*q.x())+(q.y()*q.y())))),
                              0
                              ,
                              0,0,0,1);
    return m;
}
Beispiel #15
0
void QgsTessellator::addPolygon( const QgsPolygon &polygon, float extrusionHeight )
{
  if ( _minimum_distance_between_coordinates( polygon ) < 0.001 )
  {
    // when the distances between coordinates of input points are very small,
    // the triangulation likes to crash on numerical errors - when the distances are ~ 1e-5
    // Assuming that the coordinates should be in a projected CRS, we should be able
    // to simplify geometries that may cause problems and avoid possible crashes
    QgsGeometry polygonSimplified = QgsGeometry( polygon.clone() ).simplify( 0.001 );
    const QgsPolygon *polygonSimplifiedData = qgsgeometry_cast<const QgsPolygon *>( polygonSimplified.constGet() );
    if ( _minimum_distance_between_coordinates( *polygonSimplifiedData ) < 0.001 )
    {
      // Failed to fix that. It could be a really tiny geometry... or maybe they gave us
      // geometry in unprojected lat/lon coordinates
      QgsMessageLog::logMessage( "geometry's coordinates are too close to each other and simplification failed - skipping", "3D" );
    }
    else
    {
      addPolygon( *polygonSimplifiedData, extrusionHeight );
    }
    return;
  }

  if ( !_check_intersecting_rings( polygon ) )
  {
    // skip the polygon - it would cause a crash inside poly2tri library
    QgsMessageLog::logMessage( "polygon rings intersect each other - skipping", "3D" );
    return;
  }

  const QgsCurve *exterior = polygon.exteriorRing();

  QList< std::vector<p2t::Point *> > polylinesToDelete;
  QHash<p2t::Point *, float> z;

  std::vector<p2t::Point *> polyline;

  const QVector3D pNormal = _calculateNormal( exterior, mOriginX, mOriginY );
  const int pCount = exterior->numPoints();

  // Polygon is a triangle
  if ( pCount == 4 )
  {
    QgsPoint pt;
    QgsVertexId::VertexType vt;
    for ( int i = 0; i < 3; i++ )
    {
      exterior->pointAt( i, pt, vt );
      mData << pt.x() - mOriginX << pt.z() << - pt.y() + mOriginY;
      if ( mAddNormals )
        mData << pNormal.x() << pNormal.z() << - pNormal.y();
    }
  }
  else
  {
    if ( !qgsDoubleNear( pNormal.length(), 1, 0.001 ) )
      return;  // this should not happen - pNormal should be normalized to unit length

    QVector3D pXVector, pYVector;
    _normalVectorToXYVectors( pNormal, pXVector, pYVector );

    // so now we have three orthogonal unit vectors defining new base
    // let's build transform matrix. We actually need just a 3x3 matrix,
    // but Qt does not have good support for it, so using 4x4 matrix instead.
    QMatrix4x4 toNewBase(
      pXVector.x(), pXVector.y(), pXVector.z(), 0,
      pYVector.x(), pYVector.y(), pYVector.z(), 0,
      pNormal.x(), pNormal.y(), pNormal.z(), 0,
      0, 0, 0, 0 );

    // our 3x3 matrix is orthogonal, so for inverse we only need to transpose it
    QMatrix4x4 toOldBase = toNewBase.transposed();

    const QgsPoint ptFirst( exterior->startPoint() );
    _ringToPoly2tri( exterior, ptFirst, toNewBase, polyline, z );
    polylinesToDelete << polyline;

    // TODO: robustness (no nearly duplicate points, invalid geometries ...)

    double x0 = ptFirst.x(), y0 = ptFirst.y(), z0 = ( std::isnan( ptFirst.z() ) ? 0 : ptFirst.z() );
    if ( polyline.size() == 3 && polygon.numInteriorRings() == 0 )
    {
      for ( std::vector<p2t::Point *>::iterator it = polyline.begin(); it != polyline.end(); it++ )
      {
        p2t::Point *p = *it;
        QVector4D ptInNewBase( p->x, p->y, z[p], 0 );
        QVector4D nPoint = toOldBase * ptInNewBase;
        const double fx = nPoint.x() - mOriginX + x0;
        const double fy = nPoint.y() - mOriginY + y0;
        const double fz = nPoint.z() + extrusionHeight + z0;
        mData << fx << fz << -fy;
        if ( mAddNormals )
          mData << pNormal.x() << pNormal.z() << - pNormal.y();
      }
    }
    else if ( polyline.size() >= 3 )
    {
      p2t::CDT *cdt = new p2t::CDT( polyline );

      // polygon holes
      for ( int i = 0; i < polygon.numInteriorRings(); ++i )
      {
        std::vector<p2t::Point *> holePolyline;
        const QgsCurve *hole = polygon.interiorRing( i );

        _ringToPoly2tri( hole, ptFirst, toNewBase, holePolyline, z );

        cdt->AddHole( holePolyline );
        polylinesToDelete << holePolyline;
      }

      try
      {
        cdt->Triangulate();

        std::vector<p2t::Triangle *> triangles = cdt->GetTriangles();

        for ( size_t i = 0; i < triangles.size(); ++i )
        {
          p2t::Triangle *t = triangles[i];
          for ( int j = 0; j < 3; ++j )
          {
            p2t::Point *p = t->GetPoint( j );
            QVector4D ptInNewBase( p->x, p->y, z[p], 0 );
            QVector4D nPoint = toOldBase * ptInNewBase;
            const double fx = nPoint.x() - mOriginX + x0;
            const double fy = nPoint.y() - mOriginY + y0;
            const double fz = nPoint.z() + extrusionHeight + z0;
            mData << fx << fz << -fy;
            if ( mAddNormals )
              mData << pNormal.x() << pNormal.z() << - pNormal.y();
          }
        }
      }
      catch ( ... )
      {
        QgsMessageLog::logMessage( "Triangulation failed. Skipping polygon...", "3D" );
      }

      delete cdt;
    }

    for ( int i = 0; i < polylinesToDelete.count(); ++i )
      qDeleteAll( polylinesToDelete[i] );
  }

  // add walls if extrusion is enabled
  if ( extrusionHeight != 0 )
  {
    _makeWalls( *exterior, false, extrusionHeight, mData, mAddNormals, mOriginX, mOriginY );

    for ( int i = 0; i < polygon.numInteriorRings(); ++i )
      _makeWalls( *polygon.interiorRing( i ), true, extrusionHeight, mData, mAddNormals, mOriginX, mOriginY );
  }
}
/*!
    Constructs a 3D vector from the specified 4D \a vector.  The w
    coordinate is dropped.

    \sa toVector4D()
*/
QVector3DD::QVector3DD(const QVector4D& vector)
{
    xp = vector.x();
    yp = vector.y();
    zp = vector.z();
}
Beispiel #17
0
void
ClipPlanes::drawViewportBorders(QGLViewer *viewer)
{
  int ow = viewer->width();
  int oh = viewer->height();
  float aspectRatio = viewer->aspectRatio();
  viewer->startScreenCoordinatesSystem();

  for (int i=0; i<m_clips.count(); i++)
    {
      QVector4D vp = m_clips[i]->viewport();
      // render only when textured plane and viewport active
      if (m_clips[i]->tfset() >= 0 &&
	  m_clips[i]->tfset() < Global::lutSize() &&
	  vp.x() >= 0.0)
	{
	  int vx, vy, vh, vw;
	  vx = vp.x()*ow;
	  vy = oh-vp.y()*oh;
	  vw = vp.z()*ow;
	  vh = vp.w()*oh;

	  vx+=1; vy+=1;
	  vw-=2; vh-=2;

	  glLineWidth(2);
	  if (m_clips[i]->viewportGrabbed())
	    {
	      glLineWidth(3);
	      glColor3f(0.0, 1.0, 0.3);
	    }
	  else
	    {
	      Vec clipColor = m_clips[i]->color();
	      glColor3dv(clipColor);
	    }
	  
	  glBegin(GL_LINE_STRIP);
	  glVertex2i(vx, vy);
	  glVertex2i(vx, vy-vh);
	  glVertex2i(vx+vw, vy-vh);
	  glVertex2i(vx+vw, vy);
	  glVertex2i(vx, vy);
	  glEnd();
	  if (m_clips[i]->viewportGrabbed())
	    {
	      glLineWidth(2);
	      glColor3f(0.8, 0.8, 0.8);
	    }
	  else
	    {
	      glLineWidth(1);
	      glColor3f(0.2, 0.2, 0.2);
	    }
	  glBegin(GL_LINE_STRIP);
	  glVertex2i(vx, vy);
	  glVertex2i(vx, vy-vh);
	  glVertex2i(vx+vw, vy-vh);
	  glVertex2i(vx+vw, vy);
	  glVertex2i(vx, vy);
	  glEnd();
	}
    }

  viewer->stopScreenCoordinatesSystem();
}
// Parse a Python object as a sequence of either QVector[234]D instances or a
// sequence of sequence of floats and return an array that can be passed to
// QGLShaderProgram::setAttributeArray().  The array is destroyed only when the
// shader is garbage collected or when replaced by another array.
const GLfloat *qpyopengl_attribute_array(PyObject *values, PyObject *shader,
        PyObject *key, int *tsize, sipErrorState *estate)
{
    // Check the key was created correctly.
    if (!key)
    {
        *estate = sipErrorFail;
        return 0;
    }

    // Get the dict that holds the converted arrays.
    PyObject *dict = ((sipSimpleWrapper *)shader)->user;

    if (!dict)
    {
        dict = PyDict_New();

        if (!dict)
        {
            Py_DECREF(key);

            *estate = sipErrorFail;
            return 0;
        }

        ((sipSimpleWrapper *)shader)->user = dict;
    }

    // Check that values is a non-empty sequence.
    values = PySequence_Fast(values, "an attribute array must be a sequence");

    if (!values)
    {
        Py_DECREF(key);

        *estate = sipErrorContinue;
        return 0;
    }

    SIP_SSIZE_T nr_items = PySequence_Fast_GET_SIZE(values);

    if (nr_items < 1)
    {
        PyErr_SetString(PyExc_TypeError,
                "an attribute array must have at least one element");

        Py_DECREF(key);
        Py_DECREF(values);

        *estate = sipErrorFail;
        return 0;
    }

    // The first element determines the type expected.
    PyObject *itm = PySequence_Fast_GET_ITEM(values, 0);

    const sipTypeDef *td;
    SIP_SSIZE_T nr_dim;

    if (sipCanConvertToType(itm, sipType_QVector2D, SIP_NOT_NONE))
    {
        td = sipType_QVector2D;
        nr_dim = 2;
    }
    else if (sipCanConvertToType(itm, sipType_QVector3D, SIP_NOT_NONE))
    {
        td = sipType_QVector3D;
        nr_dim = 3;
    }
    else if (sipCanConvertToType(itm, sipType_QVector4D, SIP_NOT_NONE))
    {
        td = sipType_QVector4D;
        nr_dim = 4;
    }
    else if (PySequence_Check(itm) && (nr_dim = PySequence_Size(itm)) >= 1)
    {
        td = 0;
    }
    else
    {
        PyErr_SetString(PyExc_TypeError,
                "an attribute array must be a sequence of QVector2D, "
                "QVector3D, QVector4D, or a sequence of sequences of floats");

        Py_DECREF(key);
        Py_DECREF(values);

        *estate = sipErrorFail;
        return 0;
    }

    // Create the array that will be returned.
    GLfloat *array = new GLfloat[nr_items * nr_dim];

    // Convert the values.
    GLfloat *ap = array;

    for (SIP_SSIZE_T i = 0; i < nr_items; ++i)
    {
        int iserr = 0;

        itm = PySequence_Fast_GET_ITEM(values, i);

        if (td)
        {
            void *cpp;

            cpp = sipForceConvertToType(itm, td, 0,
                    SIP_NOT_NONE | SIP_NO_CONVERTORS, 0, &iserr);

            if (iserr)
            {
                PyErr_Format(PyExc_TypeError,
                        "attribute array elements should all be '%s', not '%s'",
                        sipTypeAsPyTypeObject(td)->tp_name,
                        Py_TYPE(itm)->tp_name);
            }
            else if (td == sipType_QVector2D)
            {
                QVector2D *v = reinterpret_cast<QVector2D *>(cpp);

                *ap++ = v->x();
                *ap++ = v->y();
            }
            else if (td == sipType_QVector3D)
            {
                QVector3D *v = reinterpret_cast<QVector3D *>(cpp);

                *ap++ = v->x();
                *ap++ = v->y();
                *ap++ = v->z();
            }
            else if (td == sipType_QVector4D)
            {
                QVector4D *v = reinterpret_cast<QVector4D *>(cpp);

                *ap++ = v->x();
                *ap++ = v->y();
                *ap++ = v->z();
                *ap++ = v->w();
            }
        }
        else
        {
            itm = PySequence_Fast(itm,
                    "attribute array elements should all be sequences");

            if (itm)
            {
                if (PySequence_Fast_GET_SIZE(itm) != nr_dim)
                {
                    PyErr_Format(PyExc_TypeError,
                            "attribute array elements should all be sequences "
#if PY_VERSION_HEX >= 0x02050000
                            "of length %zd",
#else
                            "of length %d",
#endif
                            nr_dim);

                    Py_DECREF(itm);
                    iserr = 1;
                }
                else
                {
                    PyErr_Clear();

                    for (SIP_SSIZE_T j = 0; j < nr_dim; ++j)
                        *ap++ = PyFloat_AsDouble(
                                PySequence_Fast_GET_ITEM(itm, j));

                    if (PyErr_Occurred())
                    {
                        PyErr_SetString(PyExc_TypeError,
                                "attribute array elements should all be "
                                "sequences of floats");

                        Py_DECREF(itm);
                        iserr = 1;
                    }
                }
            }
            else
            {
                iserr = 1;
            }
        }

        if (iserr)
        {
            Py_DECREF(key);
            Py_DECREF(values);
            delete[] array;

            *estate = sipErrorFail;
            return 0;
        }
    }

    Py_DECREF(values);

    *tsize = nr_dim;

    // Wrap the array in a Python object so that it won't leak.
#if defined(SIP_USE_PYCAPSULE)
    PyObject *array_obj = PyCapsule_New(array, 0, array_dtor);
#else
    PyObject *array_obj = PyCObject_FromVoidPtr(array, array_dtor);
#endif

    if (!array_obj)
    {
        Py_DECREF(key);
        delete[] array;

        *estate = sipErrorFail;
        return 0;
    }

    int rc = PyDict_SetItem(dict, key, array_obj);

    Py_DECREF(key);
    Py_DECREF(array_obj);

    if (rc < 0)
    {
        *estate = sipErrorFail;
        return 0;
    }

    return array;
}
void KisPerspectiveTransformStrategy::Private::recalculateTransformedHandles()
{
    srcCornerPoints.clear();
    srcCornerPoints << transaction.originalTopLeft();
    srcCornerPoints << transaction.originalTopRight();
    srcCornerPoints << transaction.originalBottomLeft();
    srcCornerPoints << transaction.originalBottomRight();

    dstCornerPoints.clear();
    Q_FOREACH (const QPointF &pt, srcCornerPoints) {
        dstCornerPoints << transform.map(pt);
    }

    QMatrix4x4 realMatrix(transform);
    QVector4D v;

    v = QVector4D(1, 0, 0, 0);
    v = realMatrix * v;
    transformedHandles.xVanishingExists = !qFuzzyCompare(v.w(), 0);
    transformedHandles.xVanishing = v.toVector2DAffine().toPointF();

    v = QVector4D(0, 1, 0, 0);
    v = realMatrix * v;
    transformedHandles.yVanishingExists = !qFuzzyCompare(v.w(), 0);
    transformedHandles.yVanishing = v.toVector2DAffine().toPointF();
}

void KisPerspectiveTransformStrategy::setTransformFunction(const QPointF &mousePos, bool perspectiveModifierActive)
{
    Q_UNUSED(perspectiveModifierActive);
Beispiel #20
0
    void tvalue2json(rapidjson::Value & output, const QVariant & input, rapidjson::Value::AllocatorType & allocator)
    {
        switch(input.type())
        {
        case QVariant::Invalid:
        {
            output.SetNull();
            break;
        }
        case QVariant::Bool:
        {
            output.SetBool(input.toBool());
            break;
        }
        case QVariant::Int:
        {
            output.SetInt64(input.toInt());
            break;
        }
        case QVariant::LongLong:
        {
            output.SetInt64(input.toLongLong());
            break;
        }
        case QVariant::Double:
        {
            output.SetDouble(input.toDouble());
            break;
        }
        case QVariant::String:
        {
            QByteArray str = input.toString().toUtf8();
            output.SetString(str.data(), str.size(), allocator);
            break;
        }
        case QVariant::StringList:
        {
            QStringList list = input.toStringList();

            output.SetArray();
            output.Reserve(list.size(), allocator);

            rapidjson::Value temp;
            for(QStringList::const_iterator it = list.begin(); it != list.end(); ++it)
            {
                QByteArray str = it->toUtf8();
                temp.SetString(str.data(), str.size(), allocator);
                output.PushBack(temp, allocator);
            }
            break;
        }
        case QVariant::List:
        {
            QList<QVariant> list = input.toList();

            output.SetArray();
            output.Reserve(list.size(), allocator);

            rapidjson::Value temp;
            for(QList<QVariant>::const_iterator it = list.begin(); it != list.end(); ++it)
            {
                tvalue2json(temp, *it, allocator);
                output.PushBack(temp, allocator);
            }
            break;
        }
        case QVariant::Map:
        {
            output.SetObject();
            rapidjson::Value tempK, tempV;

            QMap<QString, QVariant> qmap = input.toMap();
            for(QMap<QString, QVariant>::const_iterator it = qmap.begin(); it != qmap.end(); ++it)
            {
                tvalue2json(tempK, it.key(), allocator);
                tvalue2json(tempV, it.value(), allocator);
                output.AddMember(tempK, tempV, allocator);
            }
            break;
        }
        case QVariant::Point:
        {
            QPoint pt = input.toPoint();

            output.SetArray();
            output.Reserve(2, allocator);

            output.PushBack(pt.x(), allocator);
            output.PushBack(pt.y(), allocator);
            break;
        }
        case QVariant::PointF:
        {
            QPointF pt = input.toPointF();

            output.SetArray();
            output.Reserve(2, allocator);

            output.PushBack(pt.x(), allocator);
            output.PushBack(pt.y(), allocator);
            break;
        }
        case QVariant::Size:
        {
            QSize pt = input.toSize();

            output.SetArray();
            output.Reserve(2, allocator);

            output.PushBack(pt.width(), allocator);
            output.PushBack(pt.height(), allocator);
            break;
        }
        case QVariant::SizeF:
        {
            QSizeF pt = input.toSizeF();

            output.SetArray();
            output.Reserve(2, allocator);

            output.PushBack(pt.width(), allocator);
            output.PushBack(pt.height(), allocator);
            break;
        }
        case QVariant::Rect:
        {
            QRect pt = input.toRect();

            output.SetArray();
            output.Reserve(4, allocator);

            output.PushBack(pt.x(), allocator);
            output.PushBack(pt.y(), allocator);
            output.PushBack(pt.width(), allocator);
            output.PushBack(pt.height(), allocator);
            break;
        }
        case QVariant::RectF:
        {
            QRectF pt = input.toRectF();

            output.SetArray();
            output.Reserve(4, allocator);

            output.PushBack(pt.x(), allocator);
            output.PushBack(pt.y(), allocator);
            output.PushBack(pt.width(), allocator);
            output.PushBack(pt.height(), allocator);
            break;
        }
        case QVariant::Vector2D:
        {
            QVector2D pt = input.value<QVector2D>();

            output.SetArray();
            output.Reserve(2, allocator);

            output.PushBack(pt.x(), allocator);
            output.PushBack(pt.y(), allocator);
            break;
        }
        case QVariant::Vector3D:
        {
            QVector3D pt = input.value<QVector3D>();

            output.SetArray();
            output.Reserve(3, allocator);

            output.PushBack(pt.x(), allocator);
            output.PushBack(pt.y(), allocator);
            output.PushBack(pt.z(), allocator);
            break;
        }
        case QVariant::Vector4D:
        {
            QVector4D pt = input.value<QVector4D>();

            output.SetArray();
            output.Reserve(4, allocator);

            output.PushBack(pt.x(), allocator);
            output.PushBack(pt.y(), allocator);
            output.PushBack(pt.z(), allocator);
            output.PushBack(pt.w(), allocator);
            break;
        }
        case QVariant::Color:
        {
            QColor pt = input.value<QColor>();

            output.SetArray();
            output.Reserve(4, allocator);

            output.PushBack(pt.red(), allocator);
            output.PushBack(pt.green(), allocator);
            output.PushBack(pt.blue(), allocator);
            output.PushBack(pt.alpha(), allocator);
            break;
        }
        default:
        {
            output.SetNull();
            assert(false && "shuldn't execute to here.");
        }
        }
    }