SoGesturePinchEvent::SoGesturePinchEvent(QPinchGesture* qpinch, QWidget *widget) { int h = widget->height(); QPointF widgetCorner = QPointF(widget->mapToGlobal(QPoint(0,0))); qreal scaleToWidget = (widget->mapFromGlobal(QPoint(800,800))-widget->mapFromGlobal(QPoint(0,0))).x()/800.0; QPointF pnt;//temporary pnt = qpinch->startCenterPoint(); pnt = (pnt-widgetCorner)*scaleToWidget;//translate screen coord. into widget coord. startCenter = SbVec2f(pnt.x(), h - pnt.y()); pnt = qpinch->centerPoint(); pnt = (pnt-widgetCorner)*scaleToWidget; curCenter = SbVec2f(pnt.x(), h - pnt.y()); pnt = qpinch->lastCenterPoint(); pnt = (pnt-widgetCorner)*scaleToWidget; deltaCenter = curCenter - SbVec2f(pnt.x(), h - pnt.y()); deltaZoom = qpinch->scaleFactor(); totalZoom = qpinch->totalScaleFactor(); deltaAngle = qpinch->rotationAngle(); totalAngle = qpinch->totalRotationAngle(); state = SbGestureState(qpinch->state()); this->setPosition(SbVec2s(curCenter)); Qt::KeyboardModifiers mods = QApplication::keyboardModifiers(); this->setAltDown(mods.testFlag(Qt::AltModifier)); this->setCtrlDown(mods.testFlag(Qt::ControlModifier)); this->setShiftDown(mods.testFlag(Qt::ShiftModifier)); this->setTime(SbTime::getTimeOfDay()); }
SbVec3f SoXipPlot2Ruler::projectScreenOffsetToWorld( const SbVec2s& pixelOffset ) { SbVec2f normOffset = SbVec2f( pixelOffset[0] / (float) mViewportRegion.getViewportSizePixels()[0], pixelOffset[1] / (float) mViewportRegion.getViewportSizePixels()[1] ); return mPlaneProj.project( normOffset ) - mPlaneProj.project( SbVec2f( 0, 0 ) ); }
SoGesturePanEvent::SoGesturePanEvent(QPanGesture* qpan, QWidget *widget) { totalOffset = SbVec2f(qpan->offset().x(), -qpan->offset().y()); deltaOffset = SbVec2f(qpan->delta().x(), -qpan->delta().y()); state = SbGestureState(qpan->state()); Qt::KeyboardModifiers mods = QApplication::keyboardModifiers(); this->setAltDown(mods.testFlag(Qt::AltModifier)); this->setCtrlDown(mods.testFlag(Qt::ControlModifier)); this->setShiftDown(mods.testFlag(Qt::ShiftModifier)); this->setTime(SbTime::getTimeOfDay()); }
// Pixels-pr-mm. SbVec2f SoOffscreenCGData::getResolution(void) { #ifdef COIN_MACOS_10_3 CGDirectDisplayID display = CGMainDisplayID(); CGSize size = CGDisplayScreenSize(display); return SbVec2f(CGDisplayPixelsWide(display)/size.width, CGDisplayPixelsHigh(display)/size.height)l #else return SbVec2f(72.0f / 25.4f, 72.0f / 25.4f); // fall back to 72dpi #endif }
SoCallbackAction::Response SoToVRMLActionP::post_primitives_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node) { SoToVRMLActionP * thisp = THISP(closure); int n; SoGroup * tail = thisp->get_current_tail(); SoCoordinate3 * coord = new SoCoordinate3; coord->point.setValues(0, thisp->bsptree->numPoints(), thisp->bsptree->getPointsArrayPtr()); tail->addChild(coord); SoIndexedFaceSet * ifs = NEW_NODE(SoIndexedFaceSet, node); SoNormal * normal = new SoNormal; normal->vector.setValues(0, thisp->bsptreenormal->numPoints(), thisp->bsptreenormal->getPointsArrayPtr()); tail->addChild(normal); ifs->coordIndex.setValues(0, thisp->coordidx->getLength(), thisp->coordidx->getArrayPtr()); ifs->normalIndex.setValues(0, thisp->normalidx->getLength(), thisp->normalidx->getArrayPtr()); if (thisp->texidx) { SoTextureCoordinate2 * tex = new SoTextureCoordinate2; ifs->textureCoordIndex.setValues(0, thisp->texidx->getLength(), thisp->texidx->getArrayPtr()); tail->addChild(tex); n = thisp->bsptreetex->numPoints(); tex->point.setNum(n); SbVec2f * ptr = tex->point.startEditing(); for (int i = 0; i < n; i++) { SbVec3f p = thisp->bsptreetex->getPoint(i); ptr[i] = SbVec2f(p[0], p[1]); } tex->point.finishEditing(); } if (thisp->coloridx) { SoMaterialBinding * bind = new SoMaterialBinding; bind->value = SoMaterialBinding::PER_VERTEX_INDEXED; tail->addChild(bind); ifs->materialIndex.setValues(0, thisp->coloridx->getLength(), thisp->coloridx->getArrayPtr()); } tail->addChild(ifs); delete thisp->bsptree; thisp->bsptree = NULL; delete thisp->bsptreetex; thisp->bsptreetex = NULL; delete thisp->bsptreenormal; thisp->bsptreenormal = NULL; delete thisp->coordidx; thisp->coordidx = NULL; delete thisp->normalidx; thisp->normalidx = NULL; delete thisp->texidx; thisp->texidx = NULL; delete thisp->coloridx; thisp->coloridx = NULL; return SoCallbackAction::CONTINUE; }
/*! Set \a num vector array elements from \a xy, starting at index \a start. */ void SoMFVec2f::setValues(int start, int numarg, const float xy[][2]) { if (start+numarg > this->maxNum) this->allocValues(start+numarg); else if (start+numarg > this->num) this->num = start+numarg; for(int i=0; i < numarg; i++) this->values[start+i] = SbVec2f(xy[i]); this->valueChanged(); }
SoGuiSceneTexture2::SoGuiSceneTexture2(void) { this->internals = new SceneTexture2; PRIVATE(this)->api = this; SO_NODE_CONSTRUCTOR(SoGuiSceneTexture2); SO_NODE_ADD_FIELD(size, (SbVec2f(256.0f, 256.0f))); SO_NODE_ADD_FIELD(scene, (NULL)); PRIVATE(this)->size_sensor = new SoFieldSensor(SceneTexture2::size_updated_cb, PRIVATE(this)); PRIVATE(this)->size_sensor->attach(&(this->size)); PRIVATE(this)->render_sensor = new SoOneShotSensor(SceneTexture2::render_cb, PRIVATE(this)); }
void getScreenPixelVectors(SoGLRenderAction *action, const SbVec3f position, SbVec3f &xPixelVec, SbVec3f &yPixelVec) { // To compute correct offset in world space we project width of text onto a plane parallel // to the near plane of the camera that goes through the current translation of the model matrix. SoState *state = action->getState(); SbPlaneProjector planeProj(FALSE); SbViewVolume viewVolume = SoViewVolumeElement::get(state); SbViewportRegion viewport = SoViewportRegionElement::get(state); planeProj.setViewVolume(viewVolume); planeProj.setPlane(SbPlane(viewVolume.getPlane(0.f).getNormal(), position)); float pixelWidth = 1.f / (float) viewport.getViewportSizePixels()[0]; float pixelHeight = 1.f / (float) viewport.getViewportSizePixels()[1]; SbVec3f p1 = planeProj.project(SbVec2f(0, 0)); SbVec3f p2 = planeProj.project(SbVec2f(pixelWidth, 0)); xPixelVec = (p2 - p1); p2 = planeProj.project(SbVec2f(0, pixelHeight)); yPixelVec = (p2 - p1); }
int SoXipOverlayTransformBoxManip::pickControlPoint( SoHandleEventAction* action ) { if( mControlPointsSwitch->whichChild.getValue() != -1 ) { SbVec2f mousePt = action->getEvent()->getNormalizedPosition( action->getViewportRegion() ); SbVec3f screenPt; const SbVec3f* point = mControlPointsCoords->point.getValues(0); int numPoints = mControlPointsCoords->point.getNum(); for( int i = 0; i < numPoints; ++ i ) { mViewVolume.projectToScreen( point[i], screenPt ); SbVec2f d = SbVec2f( screenPt[0], screenPt[1] ) - mousePt; if( d.length() < 0.01 ) return i; } } return -1; }
void SmTextureText2::buildStringQuad(SoAction * action, int idx, SbVec3f & p0, SbVec3f & p1, SbVec3f & p2, SbVec3f & p3) { //FIXME: Support multiple strings at one position (multiline text) SoState * state = action->getState(); const SbString * strings; const int numstrings = this->getStrings(state, strings); const SbVec3f * positions; const int numpositions = this->getPositions(state, positions); const float * rotations; const int numrotations = this->getRotations(state, rotations); const SbVec3f & offset = this->offset.getValue(); Justification halign = static_cast<Justification>(this->justification.getValue()); VerticalJustification valign = static_cast<VerticalJustification>(this->verticalJustification.getValue()); const SbViewVolume & vv = SoViewVolumeElement::get(state); const SbViewportRegion & vpr = SoViewportRegionElement::get(state); SbMatrix modelmatrix = SoModelMatrixElement::get(state); const SmTextureFont::FontImage * font = SmTextureFontElement::get(state); SbVec2s vpsize = vpr.getViewportSizePixels(); float px = vpsize[0]; float py = vpsize[1]; SbVec3f world, screen; modelmatrix.multVecMatrix(positions[idx] + offset, world); vv.projectToScreen(world, screen); float up, down, left, right; float width = static_cast<float>(font->stringWidth(strings[idx])); switch (halign){ case LEFT: right = width; left = 0; break; case CENTER: right = width / 2; left = -right; break; case RIGHT: right = 0.4f; left = -(width - 0.4f); break; } left /= px; right /= px; float ascent = static_cast<float>(font->getAscent()); float descent = static_cast<float>(font->getDescent()); float height = ascent + descent + 1; switch(valign){ case TOP: up = 0; down = -height; break; case VCENTER: up = height / 2; down = -up; break; case BOTTOM://actually BASELINE up = ascent; down = -descent; break; } up /= py; down /= py; SbMatrix rotation = SbMatrix::identity(); rotation.setRotate(SbRotation(SbVec3f(0, 0, 1), rotations[numrotations > 1 ? idx : 0])); SbMatrix translation = SbMatrix::identity(); translation.setTranslate(SbVec3f(screen[0], screen[1], 0)); //need to account for viewport aspect ratio as we are working in normalized screen coords: float aspectx = px >= py ? 1 : py / px; float aspecty = py >= px ? 1 : px / py; SbMatrix scale = SbMatrix::identity(); scale.setScale(SbVec3f(aspectx, aspecty, 1)); SbMatrix invScale = scale.inverse(); //screen coords (offsets from text "anchor" point): SbVec3f offsets[4]; offsets[0] = SbVec3f(left, down, 0); offsets[1] = SbVec3f(right, down, 0); offsets[2] = SbVec3f(right, up, 0); offsets[3] = SbVec3f(left, up, 0); SbVec2f screenPos[4]; for (int i = 0; i < 4; i++){ SbVec3f & offset = offsets[i]; invScale.multVecMatrix(offset, offset); rotation.multVecMatrix(offset, offset); scale.multVecMatrix(offset, offset); translation.multVecMatrix(offset, offset); screenPos[i] = SbVec2f(offset[0], offset[1]); } float dist = -vv.getPlane(0.0f).getDistance(world); // find the four screen points in the plane p0 = vv.getPlanePoint(dist, screenPos[0]); p1 = vv.getPlanePoint(dist, screenPos[1]); p2 = vv.getPlanePoint(dist, screenPos[2]); p3 = vv.getPlanePoint(dist, screenPos[3]); // transform back to object space SbMatrix inv = modelmatrix.inverse(); inv.multVecMatrix(p0, p0); inv.multVecMatrix(p1, p1); inv.multVecMatrix(p2, p2); inv.multVecMatrix(p3, p3); }
// // the 12 triangles in the cube // static int sogenerate_cube_vindices[] = { 0, 1, 3, 2, 5, 4, 6, 7, 1, 5, 7, 3, 4, 0, 2, 6, 4, 5, 1, 0, 2, 3, 7, 6 }; static const SbVec2f sogenerate_cube_texcoords[] = { SbVec2f(1.0f, 1.0f), SbVec2f(0.0f, 1.0f), SbVec2f(0.0f, 0.0f), SbVec2f(1.0f, 0.0f) }; // // a cube needs 6 normals // static const SbVec3f sogenerate_cube_normals[] = { SbVec3f(0.0f, 0.0f, 1.0f), SbVec3f(0.0f, 0.0f, -1.0f), SbVec3f(-1.0f, 0.0f, 0.0f), SbVec3f(1.0f, 0.0f, 0.0f), SbVec3f(0.0f, 1.0f, 0.0f),
void SoXipCPUMprRender::GLRender(SoGLRenderAction * action) { SoState *state = action->getState(); SbViewportRegion vpRegion = SoViewportRegionElement::get(state); SbVec2s vpSize = vpRegion.getViewportSizePixels(); // Don't do anything if 0 size if (!vpSize[0] || !vpSize[1]) return; // Bind texture to available texture stage if (!mMPRTexId) glGenTextures(1, &mMPRTexId); int texUnit = SoXipMultiTextureElement::getFreeUnit(state); SoXipMultiTextureElement::setUnit(state, texUnit); SoXipMultiTextureElement::bindTexture(state, GL_TEXTURE_2D, mMPRTexId); // Check the size against min/max SbVec2s minmax = minMaxSize.getValue(); int which = (vpSize[0] > vpSize[1]) ? 0 : 1; float ratio = (float) vpSize[which] / (float) vpSize[1 - which]; // If smallest dim is < min if (vpSize[1 - which] < minmax[0]) { // Clamp to min and change biggest dim according to aspect ratio vpSize[1 - which] = minmax[0]; vpSize[which] = (short) (ratio * vpSize[1 - which]); } // If biggest dim is > max if (vpSize[which] > minmax[1]) { // Clamp to max and change smallest dim according to aspect ratio vpSize[which] = minmax[1]; vpSize[1 - which] = (short) (vpSize[which] / ratio); } // Ready the buffers readyBuffers(state); if (vpSize[0] == 0 || vpSize[1] == 0) return; // Check if mpr texture must be resized if (mMPRSize != vpSize) { resizeBuffers(vpSize); mUpdateFlag |= UPDATE_MPRCACHE; } // Exit if unsupported image type if (mTexInternalFormat == 0 || mTexType == 0) return; // Check if orientation has changed SbVec3f corners[4]; SbViewVolume viewVolume = SoViewVolumeElement::get(state); float dist = viewVolume.getNearDist() + viewVolume.getDepth() * 0.5f; corners[0] = viewVolume.getPlanePoint(dist, SbVec2f(0, 1)); corners[1] = viewVolume.getPlanePoint(dist, SbVec2f(1, 1)); corners[2] = viewVolume.getPlanePoint(dist, SbVec2f(1, 0)); corners[3] = viewVolume.getPlanePoint(dist, SbVec2f(0, 0)); if (corners[0] != mCorners[0] || corners[1] != mCorners[1] || corners[2] != mCorners[2] || corners[3] != mCorners[3]) { mCorners[0] = corners[0]; mCorners[1] = corners[1]; mCorners[2] = corners[2]; mCorners[3] = corners[3]; mUpdateFlag |= UPDATE_MPRCACHE; } // if (mUpdateFlag & UPDATE_MPRCACHE) { // Compute new cache table and mpr switch (mVolDataType) { case SbXipImage::UNSIGNED_BYTE: mLutBuf ? computeMPRCacheLUT(this, (unsigned char*)mVolBuf, state) : computeMPRCache(this, (unsigned char*)mVolBuf, state); break; case SbXipImage::BYTE: mLutBuf ? computeMPRCacheLUT(this, (char*)mVolBuf, state) : computeMPRCache(this, (char*)mVolBuf, state); break; case SbXipImage::UNSIGNED_SHORT: mLutBuf ? computeMPRCacheLUT(this, (unsigned short*)mVolBuf, state) : computeMPRCache(this, (unsigned short*)mVolBuf, state); break; case SbXipImage::SHORT: mLutBuf ? computeMPRCacheLUT(this, (short*)mVolBuf, state) : computeMPRCache(this, (short*)mVolBuf, state); break; case SbXipImage::UNSIGNED_INT: mLutBuf ? computeMPRCacheLUT(this, (unsigned int*)mVolBuf, state) : computeMPRCache(this, (unsigned int*)mVolBuf, state); break; case SbXipImage::INT: mLutBuf ? computeMPRCacheLUT(this, (int*)mVolBuf, state) : computeMPRCache(this, (int*)mVolBuf, state); break; case SbXipImage::FLOAT: mLutBuf ? computeMPRCacheLUT(this, (float*)mVolBuf, state) : computeMPRCache(this, (float*)mVolBuf, state); break; case SbXipImage::DOUBLE: mLutBuf ? computeMPRCacheLUT(this, (double*)mVolBuf, state) : computeMPRCache(this, (double*)mVolBuf, state); break; default: // will never come here cause we already checked for it in resize break; } // Update mpr texture updateTexture(); } else if (mUpdateFlag & UPDATE_MPR) { // Compute new mpr switch (mVolDataType) { case SbXipImage::UNSIGNED_BYTE: mLutBuf ? computeMPRLUT(this, (unsigned char*)mVolBuf) : computeMPR(this, (unsigned char*)mVolBuf); break; case SbXipImage::BYTE: mLutBuf ? computeMPRLUT(this, (char*)mVolBuf) : computeMPR(this, (char*)mVolBuf); break; case SbXipImage::UNSIGNED_SHORT: mLutBuf ? computeMPRLUT(this, (unsigned short*)mVolBuf) : computeMPR(this, (unsigned short*)mVolBuf); break; case SbXipImage::SHORT: mLutBuf ? computeMPRLUT(this, (short*)mVolBuf) : computeMPR(this, (short*)mVolBuf); break; case SbXipImage::UNSIGNED_INT: mLutBuf ? computeMPRLUT(this, (unsigned int*)mVolBuf) : computeMPR(this, (unsigned int*)mVolBuf); break; case SbXipImage::INT: mLutBuf ? computeMPRLUT(this, (int*)mVolBuf) : computeMPR(this, (int*)mVolBuf); break; case SbXipImage::FLOAT: mLutBuf ? computeMPRLUT(this, (float*)mVolBuf) : computeMPR(this, (float*)mVolBuf); break; case SbXipImage::DOUBLE: mLutBuf ? computeMPRLUT(this, (double*)mVolBuf) : computeMPR(this, (double*)mVolBuf); break; default: // will never come here cause we already checked for it in resize break; } // Update mpr texture updateTexture(); } // Render mpr to a quad renderMPR(texUnit); // Reset update flag mUpdateFlag = 0; }
SoShaderParameterArray2f::SoShaderParameterArray2f(void) { SO_NODE_CONSTRUCTOR(SoShaderParameterArray2f); SO_NODE_ADD_FIELD(value, (SbVec2f(0,0))); }
SbVec3f( 2, 0.25, 0 ) }; static const int s_faceIndices[32] = { 0, 4, 3, -1, 1, 4, 0, -1, 1, 5, 4, -1, 2, 5, 1, -1, 3, 7, 6, -1, 4, 7, 3, -1, 4, 8, 7, -1, 5, 8, 4, -1 }; static const SbVec2f s_iconTextCoords[4] = { SbVec2f(0,0), SbVec2f(1,0), SbVec2f(1,1), SbVec2f(0,1) }; static const SbVec3f s_iconCoords[4] = { SbVec3f( 0, 0, 0), SbVec3f(0.2, 0, 0), SbVec3f(0.2, 0.2, 0), SbVec3f( 0, 0.2, 0) }; static const unsigned int s_defaultColors[9] = { 0xccccccff, 0xccccccff, 0xccccccff,
static void generate_cylinder(const float radius, const float height, const int numslices, const unsigned int flags, SoShape * const shape, SoAction * const action) { int i; int slices = numslices; if (slices > 128) slices = 128; if (slices < 4) slices = 4; float h2 = height * 0.5f; SbVec3f coords[129]; SbVec3f normals[130]; SbVec2f texcoords[129]; sogenerate_generate_3d_circle(coords, slices, radius, -h2); coords[slices] = coords[0]; sogenerate_generate_3d_circle(normals, slices, 1.0f, 0.0f); normals[slices] = normals[0]; normals[slices+1] = normals[1]; int matnr = 0; SoPrimitiveVertex vertex; SoCylinderDetail sideDetail; SoCylinderDetail bottomDetail; SoCylinderDetail topDetail; sideDetail.setPart(SoCylinder::SIDES); bottomDetail.setPart(SoCylinder::BOTTOM); topDetail.setPart(SoCylinder::TOP); if (flags & SOGEN_GENERATE_SIDE) { shape->beginShape(action, SoShape::QUAD_STRIP); vertex.setDetail(&sideDetail); vertex.setMaterialIndex(matnr); i = 0; float t = 0.0; float inc = 1.0f / slices; while (i <= slices) { vertex.setTextureCoords(SbVec2f(t, 1.0f)); vertex.setNormal(normals[i]); SbVec3f c = coords[i]; vertex.setPoint(SbVec3f(c[0], h2, c[2])); shape->shapeVertex(&vertex); vertex.setTextureCoords(SbVec2f(t, 0.0f)); vertex.setPoint(c); shape->shapeVertex(&vertex); i++; t += inc; } if (flags & SOGEN_MATERIAL_PER_PART) matnr++; shape->endShape(); } if (flags & (SOGEN_GENERATE_BOTTOM | SOGEN_GENERATE_TOP)) { sogenerate_generate_2d_circle(texcoords, slices, 0.5f); texcoords[slices] = texcoords[0]; } if (flags & SOGEN_GENERATE_TOP) { vertex.setMaterialIndex(matnr); vertex.setDetail(&topDetail); vertex.setNormal(SbVec3f(0.0f, 1.0f, 0.0f)); shape->beginShape(action, SoShape::TRIANGLE_FAN); for (i = 0; i < slices; i++) { vertex.setTextureCoords(SbVec2f(texcoords[i][0] + 0.5f, 1.0f - texcoords[i][1] - 0.5f)); const SbVec3f &c = coords[i]; vertex.setPoint(SbVec3f(c[0], h2, c[2])); shape->shapeVertex(&vertex); } shape->endShape(); if (flags & SOGEN_MATERIAL_PER_PART) matnr++; } if (flags & SOGEN_GENERATE_BOTTOM) { vertex.setMaterialIndex(matnr); vertex.setDetail(&bottomDetail); shape->beginShape(action, SoShape::TRIANGLE_FAN); vertex.setNormal(SbVec3f(0.0f, -1.0f, 0.0f)); for (i = slices-1; i >= 0; i--) { vertex.setTextureCoords(texcoords[i] + SbVec2f(0.5f, 0.5f)); vertex.setPoint(coords[i]); shape->shapeVertex(&vertex); } shape->endShape(); } }
void MFVec2::setValue(float x, float y) { this->setValue(SbVec2f(x, y)); }
void MFVec2::set1Value(int idx, const float xy[2]) { this->set1Value(idx, SbVec2f(xy)); }
//====================================================================== // // Description: // projection of telepointer // // // Use: private //====================================================================== void TPHandler::projectTelePointer(TelePointer *, const SbVec3f pos, float aspectRatio, SbVec3f &intersection, InvExaminerViewer *viewer) { const int xOffset = 61; const int yOffset = 33; float xs, ys, zs; // normalized screen coordinates SbVec3f screen; SbVec2s size = viewer->getSize(); if (viewer->isDecoration()) { // !! Attention: SoXtRenderArea with offset size[0] = size[0] - xOffset; size[1] = size[1] - yOffset; } float aspRat = size[0] / (float)size[1]; // set aspect ratio explicitely tp_camera->aspectRatio.setValue(aspRat); // default setting tp_camera->height.setValue(2.0); // scale height tp_camera->scaleHeight(1 / aspRat); /* float h = tp_camera->height.getValue(); fprintf(stderr, "Height Camera: %.6f\n", h); */ // get the view volume -> rectangular box SbViewVolume viewVolume = tp_camera->getViewVolume(); // determine mouse position viewVolume.projectToScreen(pos, screen); screen.getValue(xs, ys, zs); /* cerr << "xs: " << xs << endl; cerr << "ys: " << ys << endl; */ // project the mouse point to a line SbVec3f p0, p1; viewVolume.projectPointToLine(SbVec2f(xs, ys), p0, p1); // take the midpoint of the line as telepointer position intersection = (p0 + p1) / 2.0f; // adapt telepointer position to the aspect ratio if (aspectRatio > 1.0) { intersection[0] = intersection[0] * aspectRatio / aspRat; intersection[1] = intersection[1] * aspectRatio / aspRat; } if (aspectRatio < 1.0) { // in this case the aspect ratio submitted to the function // and belonging to the delivered position leads to wrong projection point // => local correction for x-, y-value intersection[0] = intersection[0] / aspRat; intersection[1] = intersection[1] / aspRat; } /* float fx,fy,fz; intersection.getValue(fx,fy,fz); cerr << "TP: (" << fx << "," << fy << "," << fz << ")" << endl; */ }
static void generate_cone(const float radius, const float height, const int numslices, const unsigned int flags, SoShape * const shape, SoAction * const action) { int i; int slices = numslices; if (slices > 128) slices = 128; if (slices < 4) slices = 4; float h2 = height * 0.5f; // put coordinates on the stack SbVec3f coords[129]; SbVec3f normals[130]; SbVec2f texcoords[129]; sogenerate_generate_3d_circle(coords, slices, radius, -h2); coords[slices] = coords[0]; double a = atan(height/radius); sogenerate_generate_3d_circle(normals, slices, (float) sin(a), (float) cos(a)); normals[slices] = normals[0]; normals[slices+1] = normals[1]; int matnr = 0; SoPrimitiveVertex vertex; SoConeDetail sideDetail; SoConeDetail bottomDetail; sideDetail.setPart(SoCone::SIDES); bottomDetail.setPart(SoCone::BOTTOM); // FIXME: the texture coordinate generation for cone sides is of // sub-par quality. The textures comes out looking "skewed" and // "compressed". 20010926 mortene. if (flags & SOGEN_GENERATE_SIDE) { vertex.setDetail(&sideDetail); vertex.setMaterialIndex(matnr); shape->beginShape(action, SoShape::TRIANGLES); i = 0; float t = 1.0; float delta = 1.0f / slices; while (i < slices) { vertex.setTextureCoords(SbVec2f(t - delta*0.5f, 1.0f)); vertex.setNormal((normals[i] + normals[i+1])*0.5f); vertex.setPoint(SbVec3f(0.0f, h2, 0.0f)); shape->shapeVertex(&vertex); vertex.setTextureCoords(SbVec2f(t, 0.0f)); vertex.setNormal(normals[i]); vertex.setPoint(coords[i]); shape->shapeVertex(&vertex); vertex.setTextureCoords(SbVec2f(t-delta, 0.0f)); vertex.setNormal(normals[i+1]); vertex.setPoint(coords[i+1]); shape->shapeVertex(&vertex); i++; t -= delta; } if (flags & SOGEN_MATERIAL_PER_PART) matnr++; shape->endShape(); } if (flags & SOGEN_GENERATE_BOTTOM) { vertex.setDetail(&bottomDetail); vertex.setMaterialIndex(matnr); sogenerate_generate_2d_circle(texcoords, slices, 0.5f); texcoords[slices] = texcoords[0]; shape->beginShape(action, SoShape::TRIANGLE_FAN); vertex.setNormal(SbVec3f(0.0f, -1.0f, 0.0f)); for (i = slices-1; i >= 0; i--) { vertex.setTextureCoords(texcoords[i]+SbVec2f(0.5f, 0.5f)); vertex.setPoint(coords[i]); shape->shapeVertex(&vertex); } shape->endShape(); } }
// //////////////////////////////////////////////////////////////////////// { } /* ** Source for the builtin field type interpolaters */ SO_INTERPOLATE_SOURCE(SoInterpolateFloat, SoMFFloat, float, (0), (1), ((1-a)*v0)+(a*v1)); SO_INTERPOLATE_SOURCE(SoInterpolateRotation, SoMFRotation, SbRotation, (SbRotation::identity()), (SbRotation::identity()), SbRotation::slerp(v0,v1,a)); SO_INTERPOLATE_SOURCE(SoInterpolateVec2f, SoMFVec2f, SbVec2f, (SbVec2f(0,0)), (SbVec2f(0,0)), ((1-a)*v0)+(a*v1)); SO_INTERPOLATE_SOURCE(SoInterpolateVec3f, SoMFVec3f, SbVec3f, (SbVec3f(0,0,0)), (SbVec3f(0,0,0)), ((1-a)*v0)+(a*v1)); SO_INTERPOLATE_SOURCE(SoInterpolateVec4f, SoMFVec4f, SbVec4f, (SbVec4f(0,0,0,0)), (SbVec4f(0,0,0,0)), ((1-a)*v0)+(a*v1));
void MFVec2::setValue(const float xy[2]) { if (xy == NULL) this->setNum(0); else this->setValue(SbVec2f(xy)); }
void MFVec2::set1Value(int idx, float x, float y) { this->set1Value(idx, SbVec2f(x, y)); }
static void generate_sphere(const float radius, const int numstacks, const int numslices, SoShape * const shape, SoAction * const action) { int stacks = numstacks; int slices = numslices; if (stacks < 3) stacks = 3; if (slices < 4) slices = 4; if (slices > 128) slices = 128; // used to cache last stack's data SbVec3f coords[129]; SbVec3f normals[129]; float S[129]; int i, j; float rho; float drho; float theta; float dtheta; float tc, ts; SbVec3f tmp; drho = float(M_PI) / (float) (stacks-1); dtheta = 2.0f * float(M_PI) / (float) slices; float currs = 0.0f; float incs = 1.0f / (float)slices; rho = drho; theta = 0.0f; tc = (float) cos(rho); ts = - (float) sin(rho); tmp.setValue(0.0f, tc, ts); normals[0] = tmp; tmp *= radius; coords[0] = tmp; S[0] = currs; float dT = 1.0f / (float) (stacks-1); float T = 1.0f - dT; SoPrimitiveVertex vertex; shape->beginShape(action, SoShape::TRIANGLES); for (j = 1; j <= slices; j++) { vertex.setNormal(SbVec3f(0.0f, 1.0f, 0.0f)); vertex.setTextureCoords(SbVec2f(currs + 0.5f * incs, 1.0f)); vertex.setPoint(SbVec3f(0.0f, radius, 0.0f)); shape->shapeVertex(&vertex); vertex.setNormal(normals[j-1]); vertex.setTextureCoords(SbVec2f(currs, T)); vertex.setPoint(coords[j-1]); shape->shapeVertex(&vertex); currs += incs; theta += dtheta; S[j] = currs; tmp.setValue(float(sin(theta))*ts, tc, float(cos(theta))*ts); normals[j] = tmp; tmp *= radius; coords[j] = tmp; vertex.setNormal(normals[j]); vertex.setTextureCoords(SbVec2f(currs, T)); vertex.setPoint(coords[j]); shape->shapeVertex(&vertex); } shape->endShape(); rho += drho; for (i = 2; i < stacks-1; i++) { tc = (float)cos(rho); ts = - (float) sin(rho); shape->beginShape(action, SoShape::QUAD_STRIP); theta = 0.0f; for (j = 0; j <= slices; j++) { vertex.setTextureCoords(SbVec2f(S[j], T)); vertex.setNormal(normals[j]); vertex.setPoint(coords[j]); shape->shapeVertex(&vertex); vertex.setTextureCoords(SbVec2f(S[j], T-dT)); tmp.setValue(float(sin(theta))*ts, tc, float(cos(theta))*ts); normals[j] = tmp; vertex.setNormal(tmp); tmp *= radius; coords[j] = tmp; theta += dtheta; vertex.setPoint(tmp); shape->shapeVertex(&vertex); } shape->endShape(); rho += drho; T -= dT; } shape->beginShape(action, SoShape::TRIANGLES); for (j = 0; j < slices; j++) { vertex.setTextureCoords(SbVec2f(S[j], T)); vertex.setNormal(normals[j]); vertex.setPoint(coords[j]); shape->shapeVertex(&vertex); vertex.setTextureCoords(SbVec2f(S[j]+incs*0.5f, 0.0f)); vertex.setNormal(SbVec3f(0.0f, -1.0f, 0.0f)); vertex.setPoint(SbVec3f(0.0f, -radius, 0.0f)); shape->shapeVertex(&vertex); vertex.setTextureCoords(SbVec2f(S[j+1], T)); vertex.setNormal(normals[j+1]); vertex.setPoint(coords[j+1]); shape->shapeVertex(&vertex); } shape->endShape(); }