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; } }
/*! \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; } }
/*! \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; } }