Пример #1
0
void CubeMesh::createGeometry() {
    QGLSceneNode* geometry;
    QGLBuilder builder;
    builder.newSection(QGL::NoSmoothing);

    QGeometryData quad;
//    QVector3DArray vertices = {
//        0.0, 0.0, 0.0,
//        0.0, 0.0, 1.0
//    };
//    quad.appendVertexArray();

    geometry = builder.finalizedSceneNode();
    geometry->setParent(this);
    if (!d->sceneSet)
    {
        setScene(new CubeScene(d->topNode));
        d->sceneSet = true;
    }
}
Пример #2
0
/*!
    \internal
*/
void SphereMesh::createGeometry()
{
    // We cache a maximum of 10 levels of detail for lod animations.
    // Create a new geometry node for this level of detail if necessary.
    QGLSceneNode *geometry = d->lodGeometry.value(d->lod, 0);
    if (!geometry) {
        QGLBuilder builder;
        builder.newSection(QGL::Faceted);
        builder << QGLSphere(2.0f, d->lod);
        geometry = builder.finalizedSceneNode();
        geometry->setParent(this);
        d->lodGeometry.insert(d->lod, geometry);
    }
    Q_ASSERT_X(geometry != 0, Q_FUNC_INFO, "Could not create/find geometry!");
    if (d->currentSphere != geometry)
    {
        if (d->currentSphere)
            d->topNode->removeNode(d->currentSphere);
        d->topNode->addNode(geometry);
        d->currentSphere = geometry;
    }

    // Set the radius as a scale on the modelview transformation.
    // This way, we don't have to regenerate the geometry every
    // frame if the radius is being animated.
    if (d->radius != 1.0f)
    {
        if (!d->scale)
        {
            d->scale = new QGraphicsScale3D(d->topNode);
            d->topNode->addTransform(d->scale);
        }
        if (d->scale->scale().x() != d->radius)
        {
            d->scale->setScale(QVector3D(d->radius, d->radius, d->radius));
        }
    }
    else
    {
        // If there is already a scale set it to be the identity scale.
        // This case is optimised for in QGraphicsScale.  Removing it from
        // the transform list is too expensive, especially if the size is
        // being animated, and the next frame will recreate it.
        if (d->scale)
            d->scale->setScale(QVector3D(1, 1, 1));
    }

    // Also rotate the geometry into the correct axis orientation.
    const QVector3D Y_AXIS = QVector3D(0, 1, 0);  // for Qt::XAxis we rotate around Y
    const QVector3D X_AXIS = QVector3D(1, 0, 0);  // for Qt::YAxis we rotate around X
    if (d->axis != Qt::ZAxis && !d->rot)
    {
        d->rot = new QGraphicsRotation3D(d->topNode);
        d->topNode->addTransform(d->rot);
    }
    if (d->axis == Qt::XAxis && d->rot->axis().y() != Y_AXIS.y())
    {
        d->rot->setAxis(Y_AXIS);
        d->rot->setAngle(90.0f);
    }
    else if (d->axis == Qt::YAxis && d->rot->axis().x() != X_AXIS.x())
    {
        d->rot->setAxis(X_AXIS);
        d->rot->setAngle(-90.0f);
    }
    else if (d->axis == Qt::ZAxis && d->rot && d->rot->angle() != 0.0f)
    {
        d->rot->setAngle(0.0f);
        d->rot->setAxis(QVector3D(0, 0, 0));
    }

    if (!d->sceneSet)
    {
        setScene(new SphereScene(d->topNode));
        d->sceneSet = true;
    }
}
Пример #3
0
/*!
    \internal
*/
void CapsuleMesh::createGeometry(bool bForce)
{
    // Create a new geometry node for this level of detail if necessary.
    QGLSceneNode *geometry = 0;
    QMap<int, QGLSceneNode *>::iterator It = d->lodGeometry.find(d->lod);
    if (It != d->lodGeometry.end())
        geometry = *It;
    if (geometry && bForce) {
        if (d->currentCapsule)
            d->topNode->removeNode(d->currentCapsule);
        d->currentCapsule = 0;
        d->lodGeometry.erase(It);
        geometry->setParent(0);
        delete geometry;
        geometry = 0;
    }
    if (!geometry) {
        QGLBuilder builder;

        // For the cylinder
        int facets = 4 * (1 << d->lod);
        int layers =     (1 << d->lod) - 1;

        // For the spheres
        int divisions = d->lod;

        // Sanity check - the height of the capsule must not be less than its
        // diameter.  A minimal capsule is a sphere - where diameter == height.
        if (d->length < 2.0f * d->radius)
        {
            qWarning() << "Length of capsule must exceed its diameter"
                          << " - correcting length.";
            d->length = 2.0f * d->radius;
        }

        float diameter = d->radius+d->radius;
        float cylinderHeight = d->length - diameter;
        float offset = cylinderHeight/2.0f;

        builder << QGL::Faceted;
        QGLSceneNode *s = 0;
        s = builder.newNode();
        s->setObjectName(QLatin1String("Cylinder"));
        builder << QGLCylinder(diameter, diameter, cylinderHeight,
                               facets, layers, false, false);

        s = builder.newNode();
        s->setObjectName(QLatin1String("LeftEndCap"));
        builder << QGLDome(diameter, divisions, false);
        QMatrix4x4 translateMatrix;
        translateMatrix.setToIdentity();
        translateMatrix.rotate(180.0f, 0.0f, 1.0f, 0.0f);
        translateMatrix.translate(0.0f, 0.0f, offset);
        builder.currentNode()->setLocalTransform(translateMatrix);

        s = builder.newNode();
        s->setObjectName(QLatin1String("RightEndCap"));
        builder << QGLDome(diameter, divisions, false);
        translateMatrix.setToIdentity();
        translateMatrix.translate(0.0f, 0.0f, offset);
        builder.currentNode()->setLocalTransform(translateMatrix);

        geometry = builder.finalizedSceneNode();
        geometry->setParent(this);

        d->lodGeometry.insert(d->lod, geometry);
    }
    Q_ASSERT_X(geometry != 0, Q_FUNC_INFO, "Could not create/find geometry!");
    if (d->currentCapsule != geometry)
    {
        if (d->currentCapsule)
            d->topNode->removeNode(d->currentCapsule);
        d->topNode->addNode(geometry);
        d->currentCapsule = geometry;
    }

    if (!d->sceneSet)
    {
        setScene(new CapsuleScene(d->topNode));
        d->sceneSet = true;
    }
}