void SoXipDicomExaminer::adjustCamera( SoGLRenderAction* action, const SbMatrix& model ) { SbVec3f imageAxis[3]; imageAxis[0] = model[0]; imageAxis[1] = model[1]; imageAxis[1].negate(); imageAxis[2] = imageAxis[0].cross( imageAxis[1] ); float width = imageAxis[0].length(); float height = imageAxis[1].length(); SbRotation rotation = SbRotation( SbVec3f(0, 0, -1), -imageAxis[2] ); getCamera()->orientation.setValue( rotation ); SbMatrix orientationMatrix; orientationMatrix = getCamera()->orientation.getValue(); tiltCamera( SbRotation( orientationMatrix[1], imageAxis[1] ) ); getCamera()->viewAll( mImage, mViewport ); getCamera()->height = ( width > height ? width : height ) / viewAllScale.getValue(); const float d = 2.0; SbVec3f imageCenter = model[3] + imageAxis[0] / d - imageAxis[1] / d; float focalDistance = (getCamera()->position.getValue() - imageCenter).length(); SbVec3f diff = (getCamera()->position.getValue() - imageCenter) / focalDistance; getCamera()->position.setValue( imageCenter ); getCamera()->focalDistance.setValue( 0 ); getCamera()->nearDistance.setValue( -1 ); getCamera()->farDistance.setValue( 1. ); //getCamera()->nearDistance.setValue( -0.1 ); //getCamera()->farDistance.setValue( 0.1 ); }
void vpSimulator::moveInternalCamera(vpHomogeneousMatrix &cMf) { SbMatrix matrix; SbRotation rotCam; SbMatrix rotX; rotX.setRotate (SbRotation (SbVec3f(1.0f, 0.0f, 0.0f), (float)M_PI)); for(unsigned int i=0;i<4;i++) for(unsigned int j=0;j<4;j++) matrix[(int)j][(int)i]=(float)cMf[i][j]; matrix= matrix.inverse(); matrix.multLeft (rotX); rotCam.setValue(matrix); internalCamera->ref() ; internalCamera->orientation.setValue(rotCam); internalCamera->position.setValue(matrix[3][0],matrix[3][1],matrix[3][2]); internalCamera->unref() ; rotX.setRotate (SbRotation (SbVec3f(-1.0f, 0.0f, 0.0f), (float)M_PI)); matrix.multLeft (rotX); rotCam.setValue(matrix); internalCameraPosition->ref() ; internalCameraPosition->rotation.setValue(rotCam); internalCameraPosition->translation.setValue(matrix[3][0],matrix[3][1],matrix[3][2]); internalCameraPosition->unref() ; }
// Update the dragger based on the skeleton. void IvJointDragger::UpdateDragger() { ItemPtr selectedItem = GetSelectedItem(); if( !selectedItem ) { return; } KinBodyItemPtr pbody = boost::dynamic_pointer_cast<KinBodyItem>(selectedItem); if( !pbody ) { return; } vector<dReal> vjoints; pbody->GetDOFValues(vjoints); if( _jointtype == KinBody::JointSpherical ) { Vector vaxis(vjoints[_dofindex+0],vjoints[_dofindex+1],vjoints[_dofindex+2]); dReal fang = RaveSqrt(vaxis.lengthsqr3())-_jointoffset; _trackball->rotation = SbRotation(fang > 0 ? SbVec3f(vaxis.x/fang,vaxis.y/fang,vaxis.z/fang) : SbVec3f(1,0,0), fang); } else { float fang = vjoints[_dofindex]-_jointoffset; if( _jointtype == KinBody::JointSlider ) { if( _vupper[0] > _vlower[0] ) { fang = (fang-_vlower[0])/(_vupper[0]-_vlower[0]); } else { fang = 0; } } _trackball->rotation = SbRotation(SbVec3f(1,0,0), fang); } }
//////////////////////////////////////////////////////////////////////// // // Description: // Rotate the rotateDiscDragger based on mouse motion. // // Use: private // void SoRotateDiscDragger::drag() // //////////////////////////////////////////////////////////////////////// { // Set up the projector space and view. // Working space is space at end of motion matrix. planeProj->setViewVolume( getViewVolume() ); planeProj->setWorkingSpace( getLocalToWorldMatrix() ); // Get newHitPt and startHitPt in workspace. SbVec3f newHitPt = planeProj->project( getNormalizedLocaterPosition()); SbVec3f startHitPt = getLocalStartingPoint(); // Find the amount of rotation SbVec3f oldVec = startHitPt; SbVec3f newVec = newHitPt; // Remove the part of these vectors that is parallel to the normal oldVec -= SbVec3f( 0, 0, oldVec[2] ); newVec -= SbVec3f( 0, 0, newVec[2] ); // deltaRot is how much we rotated since the mouse button went down. SbRotation deltaRot = SbRotation( oldVec, newVec ); // Append this to the startMotionMatrix, which we saved at the beginning // of the drag, to find the current motion matrix. setMotionMatrix( appendRotation( getStartMotionMatrix(), deltaRot, SbVec3f(0,0,0))); }
/*! \param upVec * \param dir * \return orientation */ SbRotation kCamera::calcOrientation(const SbVec3f upVec, const SbVec3f dir) { // from comp.graphics.api.inventor ... "Setting SoCamera orientation" SbVec3f z = -dir; SbVec3f y = upVec; z.normalize(); y.normalize(); SbVec3f x = y.cross(z); // recompute y to create a valid coordinate system y = z.cross(x); // create a rotation matrix SbMatrix rot = SbMatrix::identity(); rot[0][0] = x[0]; rot[0][1] = x[1]; rot[0][2] = x[2]; rot[1][0] = y[0]; rot[1][1] = y[1]; rot[1][2] = y[2]; rot[2][0] = z[0]; rot[2][1] = z[1]; rot[2][2] = z[2]; // convert matrix into rotation return SbRotation(rot); }
void SoSFRotation::setValue(float q0, float q1, float q2, float q3) // The 4 floats // //////////////////////////////////////////////////////////////////////// { setValue(SbRotation(q0, q1, q2, q3)); }
void vpSimulator::getExternalCameraPosition(vpHomogeneousMatrix &cMf) { /* SoCamera *camera ; camera = this->externalView->getCamera() ;*/ SoSFVec3f position = externalCamera->position ; // get the rotation SoSFRotation orientation = externalCamera->orientation; SbVec3f axis ; float angle ; orientation.getValue(axis,angle) ; SbRotation rotation(axis,angle) ; // get the translation SbVec3f t ; t = position.getValue() ; SbMatrix matrix ; matrix.setRotate(rotation) ; vpHomogeneousMatrix fMc ; SbMatrix rotX; rotX.setRotate (SbRotation (SbVec3f(1.0f, 0.0f, 0.0f), (float)M_PI)); matrix.multLeft (rotX); for(unsigned int i=0;i<4;i++) for(unsigned int j=0;j<4;j++) fMc[j][i]=matrix[(int)i][(int)j]; fMc[0][3] = t[0] ; fMc[1][3] = t[1] ; fMc[2][3] = t[2] ; cMf = fMc.inverse() ; }
void SoSFRotation::setValue(const float q[4]) // Array of values // //////////////////////////////////////////////////////////////////////// { setValue(SbRotation(q)); }
// the MAIN function int main(int argc, char ** argv) { Widget mainWindow = SoXt::init(argv[0]); if (mainWindow == NULL) exit(1); SoSeparator *root; root = new SoSeparator; root->ref(); player.camera = new SoPerspectiveCamera; root->addChild(player.camera); root->addChild(createScene()) ; //player.camera->viewAll(root, myRenderArea->getViewportRegion()); player.camera->position=SbVec3f(0, 5, 20); player.camera->orientation=SbRotation(-0.1, 0, 0, 1); player.camera->nearDistance=1; player.camera->farDistance=150; player.camera->heightAngle=0.5; //view the whole scene // initialize scenemanager instance SoXtRenderArea *myRenderArea = new SoXtRenderArea(mainWindow); myRenderArea->setSceneGraph(root); myRenderArea->setTitle("Bouncing Ball"); myRenderArea->show(); SoXt::show(mainWindow); SoXt::mainLoop(); return 0; }
//////////////////////////////////////////////////////////////////////// // // Constructor // SoMotion3Event::SoMotion3Event() // //////////////////////////////////////////////////////////////////////// { translation = SbVec3f(0, 0, 0); rotation = SbRotation(SbVec3f(1, 0, 0), 0); }
void TTracker::SetEngineOutputRotation(SbRotation rotation) { SO_ENGINE_OUTPUT( outputTranslation, SoSFVec3f, setValue( SbVec3f( 0.0, 0.0, 0.0 ) ) ); SO_ENGINE_OUTPUT( outputRotation, SoSFRotation, setValue( rotation ) ); SO_ENGINE_OUTPUT( outputScaleFactor, SoSFVec3f, setValue( SbVec3f( 1.0, 1.0, 1.0 ) ) ); SO_ENGINE_OUTPUT( outputScaleOrientation, SoSFRotation, setValue( SbRotation() ) ); SO_ENGINE_OUTPUT( outputCenter, SoSFVec3f, setValue( SbVec3f( 0.0, 0.0, 0.0 ) ) ); }
void SbMatrix::setTransform(const SbVec3f &translation, const SbRotation &rotation, const SbVec3f &scaleFactor, const SbRotation &scaleOrientation, const SbVec3f ¢er) { #define TRANSLATE(vec) m.setTranslate(vec), multLeft(m) #define ROTATE(rot) rot.getValue(m), multLeft(m) SbMatrix m; makeIdentity(); if (translation != SbVec3f(0,0,0)) TRANSLATE(translation); if (center != SbVec3f(0,0,0)) TRANSLATE(center); if (rotation != SbRotation(0,0,0,1)) ROTATE(rotation); if (scaleFactor != SbVec3f(1,1,1)) { SbRotation so = scaleOrientation; if (so != SbRotation(0,0,0,1)) ROTATE(so); m.setScale(scaleFactor); multLeft(m); if (so != SbRotation(0,0,0,1)) { so.invert(); ROTATE(so); } } if (center != SbVec3f(0,0,0)) TRANSLATE(-center); #undef TRANSLATE #undef ROTATE }
bool Load_camera_settings:: init( std::string& parameters, GsTL_project* proj, Error_messages_handler* errors ) { std::vector< std::string > params = String_Op::decompose_string( parameters, Actions::separator, Actions::unique ); if( params.size() != 1 ) { errors->report( "load_camera_settings filename" ); return false; } SmartPtr<Named_interface> view_ni = Root::instance()->interface( projectViews_manager + "/main_view" ); Oinv_view* view = dynamic_cast<Oinv_view*>( view_ni.raw_ptr() ); if( !view ) { return false; } SoCamera* camera = view->get_render_area()->getCamera(); if( !camera ) return false; std::ifstream in( params[0].c_str() ); if( !in ) { std::ostringstream message; message << "Can't open file " << params[0]; errors->report( message.str() ); return false; } float x,y,z; in >> x >> y >> z; camera->position.setValue( SbVec3f(x,y,z) ); float r1,r2,r3,r4; in >> r1 >> r2 >> r3 >> r4; camera->orientation.setValue( SbRotation(r1,r2,r3,r4) ); float val; in >> val; camera->aspectRatio = val; in >> val; camera->nearDistance = val; in >> val; camera->farDistance = val; in >> val; camera->focalDistance = val; in.close(); return true; }
void TranslateRadialDragger:: orientFeedbackGeometry( const SbVec3f &localDir) { // By default, feedback geometry aligns with the x axis. // Rotate so that it points in the given direction. SbRotation rotXToDir = SbRotation(SbVec3f(1, 0, 0), localDir); // Give this rotation to the "feedbackRotate" part. SoRotation *myPart = SO_GET_ANY_PART(this, "feedbackRotate", SoRotation); myPart->rotation.setValue(rotXToDir); }
/*! Given a list of candidate grasps, \a grList , this creates a new grasp representation for each one. These representations can be seen in the grasp visualization window. */ void grasp_tester::visualizePlannedGrasps(std::list<plannedGrasp *> grList) { std::list <plannedGrasp *>::iterator gl_it; SbMatrix mat1; SbMatrix mat2; SbVec3f pos, approach, thumb; grasp_representation *gRep; for (gl_it = grList.begin(); gl_it != grList.end(); gl_it++) { pos.setValue((*gl_it)->get_graspDirection().get_point().x(), (*gl_it)->get_graspDirection().get_point().y(), (*gl_it)->get_graspDirection().get_point().z()); approach.setValue((*gl_it)->get_graspDirection().get_dir().x(), (*gl_it)->get_graspDirection().get_dir().y(), (*gl_it)->get_graspDirection().get_dir().z()); thumb.setValue((*gl_it)->get_fixedFingerDirection().x(), (*gl_it)->get_fixedFingerDirection().y(), (*gl_it)->get_fixedFingerDirection().z()); /* visualize */ mat1.setTransform(pos, SbRotation(SbVec3f(0., 1., 0.), approach), SbVec3f(1., 1., 1.)); mat2.setTransform(pos, SbRotation(SbVec3f(0., 1., 0.), thumb), SbVec3f(1., 1., 1.)); gRep = new grasp_representation(mat1, mat2, glRoot); (*gl_it)->set_graspRepresentation(gRep); } return; }
/*! \DRAGGER_CONSTRUCTOR \NODEKIT_PRE_DIAGRAM \verbatim CLASS SoRotateSphericalDragger -->"this" "callbackList" "topSeparator" "motionMatrix" "geomSeparator" --> "rotatorSwitch" --> "rotator" --> "rotatorActive" --> "feedbackSwitch" --> "feedback" --> "feedbackActive" \endverbatim \NODEKIT_POST_DIAGRAM \NODEKIT_PRE_TABLE \verbatim CLASS SoRotateSphericalDragger PVT "this", SoRotateSphericalDragger --- "callbackList", SoNodeKitListPart [ SoCallback, SoEventCallback ] PVT "topSeparator", SoSeparator --- PVT "motionMatrix", SoMatrixTransform --- PVT "geomSeparator", SoSeparator --- PVT "rotatorSwitch", SoSwitch --- "rotator", SoSeparator --- "rotatorActive", SoSeparator --- PVT "feedbackSwitch", SoSwitch --- "feedback", SoSeparator --- "feedbackActive", SoSeparator --- \endverbatim \NODEKIT_POST_TABLE */ SoRotateSphericalDragger::SoRotateSphericalDragger(void) { SO_KIT_INTERNAL_CONSTRUCTOR(SoRotateSphericalDragger); SO_KIT_ADD_CATALOG_ENTRY(rotatorSwitch, SoSwitch, TRUE, geomSeparator, feedbackSwitch, FALSE); SO_KIT_ADD_CATALOG_ENTRY(rotator, SoSeparator, TRUE, rotatorSwitch, rotatorActive, TRUE); SO_KIT_ADD_CATALOG_ENTRY(rotatorActive, SoSeparator, TRUE, rotatorSwitch, "", TRUE); SO_KIT_ADD_CATALOG_ENTRY(feedbackSwitch, SoSwitch, TRUE, geomSeparator, "", FALSE); SO_KIT_ADD_CATALOG_ENTRY(feedback, SoSeparator, TRUE, feedbackSwitch, feedbackActive, TRUE); SO_KIT_ADD_CATALOG_ENTRY(feedbackActive, SoSeparator, TRUE, feedbackSwitch, "", TRUE); if (SO_KIT_IS_FIRST_INSTANCE()) { SoInteractionKit::readDefaultParts("rotateSphericalDragger.iv", ROTATESPHERICALDRAGGER_draggergeometry, static_cast<int>(strlen(ROTATESPHERICALDRAGGER_draggergeometry))); } SO_KIT_ADD_FIELD(rotation, (SbRotation(SbVec3f(0.0f, 0.0f, 1.0f), 0.0f))); SO_KIT_INIT_INSTANCE(); // initialize default parts this->setPartAsDefault("rotator", "rotateSphericalRotator"); this->setPartAsDefault("rotatorActive", "rotateSphericalRotatorActive"); this->setPartAsDefault("feedback", "rotateSphericalFeedback"); this->setPartAsDefault("feedbackActive", "rotateSphericalFeedbackActive"); // initialize swich values SoSwitch *sw; sw = SO_GET_ANY_PART(this, "rotatorSwitch", SoSwitch); SoInteractionKit::setSwitchValue(sw, 0); sw = SO_GET_ANY_PART(this, "feedbackSwitch", SoSwitch); SoInteractionKit::setSwitchValue(sw, 0); // setup projector this->sphereProj = new SbSpherePlaneProjector(); this->userProj = FALSE; this->addStartCallback(SoRotateSphericalDragger::startCB); this->addMotionCallback(SoRotateSphericalDragger::motionCB); this->addFinishCallback(SoRotateSphericalDragger::doneCB); this->addValueChangedCallback(SoRotateSphericalDragger::valueChangedCB); this->fieldSensor = new SoFieldSensor(SoRotateSphericalDragger::fieldSensorCB, this); this->fieldSensor->setPriority(0); this->setUpConnections(TRUE, TRUE); }
void SoXipDicomExaminer::tiltCamera( const SbRotation& rot ) { SbMatrix m; m = getCamera()->orientation.getValue(); SbVec3f camy; rot.multVec( SbVec3f( m[1][0], m[1][1], m[1][2] ), camy ); m[1][0] = camy[0]; m[1][1] = camy[1]; m[1][2] = camy[2]; SbVec3f camx; rot.multVec( SbVec3f( m[0][0], m[0][1], m[0][2] ), camx ); m[0][0] = camx[0]; m[0][1] = camx[1]; m[0][2] = camx[2]; getCamera()->orientation.setValue( SbRotation(m) ); }
virtual void apply(SoNode* node) { if (!headlightRot) { SoSearchAction sa; sa.setNode(viewer->getHeadlight()); sa.apply(viewer->getSceneRoot()); SoFullPath* fullPath = (SoFullPath*) sa.getPath(); if (fullPath) { SoGroup *group = (SoGroup*) fullPath->getNodeFromTail(1); headlightRot = (SoRotation*) group->getChild(0); if (!headlightRot->isOfType(SoRotation::getClassTypeId())) headlightRot = 0; } } const SbViewportRegion vpr = getViewportRegion(); const SbVec2s & size = vpr.getViewportSizePixels(); const int width = size[0]; const int height = size[1]; const int vpsize = width / 2; SoCamera * camera = viewer->getCamera(); const SbVec3f position = camera->position.getValue(); const SbRotation orientation = camera->orientation.getValue(); const float nearplane = camera->nearDistance.getValue(); const float farplane = camera->farDistance.getValue(); camera->enableNotify(false); // Front View rotateCamera(SbRotation(SbVec3f(0,0,1), M_PI)); SbViewportRegion vp; vp.setViewportPixels(SbVec2s(0, height-width/2), SbVec2s(width, width/2) ); setViewportRegion(vp); SoGLRenderAction::apply(node); // Left View SbRotation r1(SbVec3f(0,0,1), -M_PI/2); rotateCamera(r1*SbRotation(SbVec3f(0,1,0), -M_PI/2)); vp.setViewportPixels(SbVec2s(0, height-width), SbVec2s(width/2, width) ); setViewportRegion(vp); SoGLRenderAction::apply(node); // Right View rotateCamera(SbRotation(SbVec3f(0,1,0), -M_PI)); vp.setViewportPixels(SbVec2s(width/2, height-width), SbVec2s(width/2, width) ); setViewportRegion(vp); SoGLRenderAction::apply(node); setViewportRegion(vpr); camera->position = position; camera->orientation = orientation; camera->enableNotify(true); // Restore original viewport region setViewportRegion(vpr); }
void InnerDisc::rotateTo(const SbVec3f &to) { rot->rotation = SbRotation(SbVec3f(0, 0, 1), to); }
IvJointDragger::IvJointDragger(QtCoinViewerPtr viewer, ItemPtr pItem, int iSelectedLink, float draggerScale, int iJointIndex, bool bHilitJoint) : IvDragger(viewer, pItem, draggerScale) { KinBodyItemPtr pbody = boost::dynamic_pointer_cast<KinBodyItem>(pItem); BOOST_ASSERT( !!pItem ); _trackball = NULL; _draggerRoot = NULL; if( !pbody || !pbody->GetBody() ) { return; } if((iSelectedLink < 0)||(iSelectedLink >= (int)pbody->GetBody()->GetLinks().size())) { return; } if((iJointIndex < 0)||(iJointIndex >= (int)pbody->GetBody()->GetJoints().size())) { return; } _iSelectedLink = iSelectedLink; _iJointIndex = iJointIndex; KinBody::JointConstPtr pjoint = pbody->GetBody()->GetJoints().at(iJointIndex); _jointtype = pjoint->GetType(); _dofindex = pjoint->GetDOFIndex(); _jointname = pjoint->GetName(); _jointoffset = 0; //pjoint->GetOffset(); pjoint->GetLimits(_vlower,_vupper); _pLinkNode = pbody->GetIvLink(iSelectedLink); if( _pLinkNode == NULL ) { RAVELOG_WARN("no link is selected\n"); return; } Transform tlink = pbody->GetBody()->GetLinks().at(iSelectedLink)->GetTransform(); // create a root node for the dragger nodes _draggerRoot = new SoSeparator; SoTransform* draggertrans = new SoTransform(); _pLinkNode->insertChild(_draggerRoot, 1); // insert right after transform // add a new material to change the color of the nodes being dragged _bHilitJoint = bHilitJoint; if (_bHilitJoint) { _material = new SoMaterial; _material->set("diffuseColor 0.8 0.6 0.2"); _material->setOverride(true); _pLinkNode->insertChild(_material, 1); } Vector vaxes[3]; for(int i = 0; i < pjoint->GetDOF(); ++i) { vaxes[i] = tlink.inverse().rotate(pjoint->GetAxis(i)); } // need to make sure the rotation is pointed towards the joint axis Vector vnorm = Vector(1,0,0).cross(vaxes[0]); dReal fsinang = RaveSqrt(vnorm.lengthsqr3()); if( fsinang > 0.0001f ) { vnorm /= fsinang; } else vnorm = Vector(1,0,0); Vector vtrans = tlink.inverse()*pjoint->GetAnchor(); draggertrans->translation.setValue(vtrans.x, vtrans.y, vtrans.z); draggertrans->rotation = SbRotation(SbVec3f(vnorm.x, vnorm.y, vnorm.z), atan2f(fsinang,vaxes[0].x)); _draggerRoot->addChild(draggertrans); // construct an Inventor trackball dragger float scale = _scale; _trackball = new SoTrackballDragger; AABB ab; _GetBounds(_pLinkNode, ab); _trackball->scaleFactor.setValue(ab.extents.x * scale, ab.extents.y * scale, ab.extents.z * scale); _trackball->setAnimationEnabled(false); _draggerRoot->addChild(_trackball); // get the material nodes that govern the color of the dragger and // note the dragger's normal color const char* rotators[3] = { "XRotator", "YRotator", "ZRotator" }; const char* rotatorsActive[3] = { "XRotatorActive", "YRotatorActive", "ZRotatorActive" }; // enable or disable each axis for (int i = 0; i < 3; i++) { if (i < pjoint->GetDOF()) { SoSeparator *s = (SoSeparator *)_trackball->getPart(rotators[i], false); _draggerMaterial[i] = (SoMaterial *) s->getChild(0); _normalColor = _draggerMaterial[i]->diffuseColor[0]; } else { // disable the rotator on this axis _trackball->setPart(rotators[i], NULL); _trackball->setPart(rotatorsActive[i], NULL); _draggerMaterial[i] = NULL; } } // add a motion callback handler for the dragger _trackball->addMotionCallback(_MotionHandler, this); UpdateDragger(); }
void SoXipImageAttributes::evaluate() { SoXipDataImage *imgData = image.getValue(); if (imgData) { SbXipImage *img = imgData->get(); if (img) { SO_ENGINE_OUTPUT(modelMatrix, SoSFMatrix, setValue(img->getModelMatrix())); SO_ENGINE_OUTPUT(bitsStored, SoSFShort, setValue(img->getBitsStored())); SO_ENGINE_OUTPUT(width, SoSFShort, setValue(img->getDimStored()[0])); SO_ENGINE_OUTPUT(height, SoSFShort, setValue(img->getDimStored()[1])); SO_ENGINE_OUTPUT(depth, SoSFShort, setValue(img->getDimStored()[2])); SbMatrix modelMat = img->getModelMatrix(); SbVec3f t, s; SbRotation r, so; modelMat.getTransform(t, r, s, so); modelMat.multVecMatrix(SbVec3f(0.5, 0.5, 0.5), t); // scale MPR model matrix always to max. individual dimension by default float maxScale = s[0] > s[1] ? s[0] : s[1] > s[2] ? s[1] : s[2]; // modelMat.setTransform(t, r, SbVec3f(maxScale, maxScale, maxScale), so); // when using get/setTransform, the rotation is derived from normal vector // but for gantry tilt, we need to compute normal from row and column vector SbVec3f rot[3]; rot[0] = SbVec3f(modelMat[0][0], modelMat[0][1], modelMat[0][2]); rot[1] = SbVec3f(modelMat[1][0], modelMat[1][1], modelMat[1][2]); rot[2] = rot[0].cross(rot[1]); rot[0].normalize(); rot[1].normalize(); rot[2].normalize(); rot[0] *= maxScale; rot[1] *= maxScale; rot[2] *= maxScale; modelMat = SbMatrix( rot[0][0], rot[0][1], rot[0][2], 0, rot[1][0], rot[1][1], rot[1][2], 0, rot[2][0], rot[2][1], rot[2][2], 0, t[0], t[1], t[2], 1); // update engine outputs SbMatrix tmp = SbMatrix::identity(); // flip default viewing direction tmp.setRotate(SbRotation(SbVec3f(1, 0, 0), M_PI)); SbMatrix defOrient = tmp * modelMat; // adjust so plane falls onto original plane defOrient.getTransform(t, r, s, so); SbVec3f object; modelMat = img->getModelMatrix(); modelMat.inverse().multVecMatrix(t, object); object[0] = int(object[0] * img->getDimStored()[0] + 0.5); object[1] = int(object[1] * img->getDimStored()[1] + 0.5); object[2] = int(object[2] * img->getDimStored()[2] + 0.5); object[0] /= img->getDimStored()[0]; object[1] /= img->getDimStored()[1]; object[2] /= img->getDimStored()[2]; modelMat.multVecMatrix(object, t); defOrient.setTransform(t, r, s, so); SO_ENGINE_OUTPUT(defaultOrientation, SoSFMatrix, setValue(defOrient)); SbMatrix ortho1, ortho2, ortho3; int which = XipGeomUtils::orthoOrientations(defOrient, ortho1, ortho2, ortho3); SO_ENGINE_OUTPUT(orthoScanOrientation, SoSFShort, setValue(which)); SO_ENGINE_OUTPUT(orthoOrientation1, SoSFMatrix, setValue(ortho1)); SO_ENGINE_OUTPUT(orthoOrientation2, SoSFMatrix, setValue(ortho2)); SO_ENGINE_OUTPUT(orthoOrientation3, SoSFMatrix, setValue(ortho3)); defOrient.getTransform(t, r, s, so); SO_ENGINE_OUTPUT(defaultCenter, SoSFVec3f, setValue(t)); return; } } SO_ENGINE_OUTPUT(modelMatrix, SoSFMatrix, setValue(SbMatrix::identity())); SO_ENGINE_OUTPUT(bitsStored, SoSFShort, setValue(0)); SO_ENGINE_OUTPUT(width, SoSFShort, setValue(0)); SO_ENGINE_OUTPUT(height, SoSFShort, setValue(0)); SO_ENGINE_OUTPUT(depth, SoSFShort, setValue(0)); SbMatrix rot1, rot2; SO_ENGINE_OUTPUT(defaultOrientation, SoSFMatrix, setValue(SbMatrix::identity())); SO_ENGINE_OUTPUT(orthoScanOrientation, SoSFShort, setValue(0)); SO_ENGINE_OUTPUT(orthoOrientation1, SoSFMatrix, setValue(SbMatrix::identity())); rot1.setRotate(SbRotation(SbVec3f(1, 0, 0), -M_PI / 2.f)); SO_ENGINE_OUTPUT(orthoOrientation2, SoSFMatrix, setValue(rot1)); rot2.setRotate(SbRotation(SbVec3f(0, 1, 0), M_PI / 2.f)); SO_ENGINE_OUTPUT(orthoOrientation3, SoSFMatrix, setValue(rot2 * rot1)); SO_ENGINE_OUTPUT(defaultCenter, SoSFVec3f, setValue(SbVec3f(0.5, 0.5, 0.5))); }
//////////////////////////////////////////////////////////////////////// // // Description: // Constructor // SoDragPointDragger::SoDragPointDragger() // //////////////////////////////////////////////////////////////////////// { SO_KIT_CONSTRUCTOR(SoDragPointDragger); isBuiltIn = TRUE; SO_KIT_ADD_CATALOG_ENTRY(noRotSep, SoSeparator, FALSE, topSeparator, geomSeparator,FALSE); SO_KIT_ADD_CATALOG_ENTRY(xTranslatorSwitch, SoSwitch, FALSE, noRotSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(xTranslator, SoTranslate1Dragger, TRUE, xTranslatorSwitch,\x0,TRUE); SO_KIT_ADD_CATALOG_ENTRY(xyTranslatorSwitch, SoSwitch, FALSE, noRotSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(xyTranslator, SoTranslate2Dragger, TRUE, xyTranslatorSwitch,\x0,TRUE); SO_KIT_ADD_CATALOG_ENTRY(rotXSep, SoSeparator, FALSE, topSeparator, geomSeparator,FALSE); SO_KIT_ADD_CATALOG_ENTRY(rotX, SoRotation, TRUE, rotXSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(xzTranslatorSwitch, SoSwitch, FALSE, rotXSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(xzTranslator, SoTranslate2Dragger, TRUE, xzTranslatorSwitch,\x0,TRUE); SO_KIT_ADD_CATALOG_ENTRY(rotYSep, SoSeparator, FALSE, topSeparator, geomSeparator,FALSE); SO_KIT_ADD_CATALOG_ENTRY(rotY, SoRotation, TRUE, rotYSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(zTranslatorSwitch, SoSwitch, FALSE, rotYSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(zTranslator, SoTranslate1Dragger, TRUE, zTranslatorSwitch,\x0,TRUE); SO_KIT_ADD_CATALOG_ENTRY(yzTranslatorSwitch, SoSwitch, FALSE, rotYSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(yzTranslator, SoTranslate2Dragger, TRUE, yzTranslatorSwitch,\x0,TRUE); SO_KIT_ADD_CATALOG_ENTRY(rotZSep, SoSeparator, FALSE, topSeparator, geomSeparator,FALSE); SO_KIT_ADD_CATALOG_ENTRY(rotZ, SoRotation, TRUE, rotZSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(yTranslatorSwitch, SoSwitch, FALSE, rotZSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(yTranslator, SoTranslate1Dragger, TRUE, yTranslatorSwitch,\x0,TRUE); SO_KIT_ADD_CATALOG_ENTRY(xFeedbackSwitch, SoSwitch, FALSE, topSeparator, geomSeparator,FALSE); SO_KIT_ADD_CATALOG_ENTRY(xFeedbackSep, SoSeparator, FALSE, xFeedbackSwitch,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(xFeedbackTranslation, SoTranslation, FALSE, xFeedbackSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(xFeedback, SoSeparator, TRUE, xFeedbackSep,\x0,TRUE); SO_KIT_ADD_CATALOG_ENTRY(yFeedbackSwitch, SoSwitch, FALSE, topSeparator, geomSeparator,FALSE); SO_KIT_ADD_CATALOG_ENTRY(yFeedbackSep, SoSeparator, FALSE, yFeedbackSwitch,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(yFeedbackTranslation, SoTranslation, FALSE, yFeedbackSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(yFeedback, SoSeparator, TRUE, yFeedbackSep,\x0,TRUE); SO_KIT_ADD_CATALOG_ENTRY(zFeedbackSwitch, SoSwitch, FALSE, topSeparator, geomSeparator,FALSE); SO_KIT_ADD_CATALOG_ENTRY(zFeedbackSep, SoSeparator, FALSE, zFeedbackSwitch,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(zFeedbackTranslation, SoTranslation, FALSE, zFeedbackSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(zFeedback, SoSeparator, TRUE, zFeedbackSep,\x0,TRUE); SO_KIT_ADD_CATALOG_ENTRY(planeFeedbackSep, SoSeparator, FALSE, topSeparator, geomSeparator,FALSE); SO_KIT_ADD_CATALOG_ENTRY(planeFeedbackTranslation, SoTranslation, FALSE, planeFeedbackSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(planeFeedbackSwitch, SoSwitch, FALSE, planeFeedbackSep,\x0,FALSE); SO_KIT_ADD_CATALOG_ENTRY(yzFeedback, SoSeparator, TRUE, planeFeedbackSwitch,\x0,TRUE); SO_KIT_ADD_CATALOG_ENTRY(xzFeedback, SoSeparator, TRUE, planeFeedbackSwitch,\x0,TRUE); SO_KIT_ADD_CATALOG_ENTRY(xyFeedback, SoSeparator, TRUE, planeFeedbackSwitch,\x0,TRUE); // read geometry for shared parts if (SO_KIT_IS_FIRST_INSTANCE()) readDefaultParts("dragPointDragger.iv",geomBuffer,sizeof(geomBuffer) ); // The field that reflects where the dragger has been translated to SO_KIT_ADD_FIELD(translation, (0.0, 0.0, 0.0)); SO_KIT_INIT_INSTANCE(); // Cached values to make updating the feedback geometry more efficient oldXAxisNode = NULL; oldYAxisNode = NULL; oldZAxisNode = NULL; //****************** // Set up the parts. //****************** // Set up the rotations to orient the draggers correctly. SoRotation *myRotX = new SoRotation; SoRotation *myRotY = new SoRotation; SoRotation *myRotZ = new SoRotation; myRotX->rotation = SbRotation( SbVec3f(1,0,0), 1.57079 ); myRotY->rotation = SbRotation( SbVec3f(0,1,0), 1.57079 ); myRotZ->rotation = SbRotation( SbVec3f(0,0,1), 1.57079 ); setAnyPartAsDefault("rotX", myRotX ); setAnyPartAsDefault("rotY", myRotY ); setAnyPartAsDefault("rotZ", myRotZ ); // CREATE THE CHILD DRAGGERS. // Create the translate1Draggers... SoTranslate1Dragger *myXTrans, *myYTrans, *myZTrans; myXTrans = SO_GET_ANY_PART(this,"xTranslator",SoTranslate1Dragger); myYTrans = SO_GET_ANY_PART(this,"yTranslator",SoTranslate1Dragger); myZTrans = SO_GET_ANY_PART(this,"zTranslator",SoTranslate1Dragger); // Create the translate2Draggers... SoTranslate2Dragger *myYZTrans, *myXZTrans, *myXYTrans; myYZTrans = SO_GET_ANY_PART(this,"yzTranslator",SoTranslate2Dragger); myXZTrans = SO_GET_ANY_PART(this,"xzTranslator",SoTranslate2Dragger); myXYTrans = SO_GET_ANY_PART(this,"xyTranslator",SoTranslate2Dragger); //****************** // The feedback parts jump around as the limit box changes. That is, they // stay fixed in space while the dragger moves around. // However, they jump to a new location when the dragger nears the edge. // These parts a separate translation node, since they move differently // than the dragger itself. //****************** //****************** // The feedback parts jump around as the limit box changes. That is, they // stay fixed in space while the dragger moves around. // However, they jump to a new location when the dragger nears the edge. // These parts a separate translation node, since they move differently // than the dragger itself. // // Only one plane or one axis is shown at a time, depending on which // translator has initiated the dragging. //****************** setPartAsDefault("xFeedback", "dragPointXFeedback"); setPartAsDefault("yFeedback", "dragPointYFeedback"); setPartAsDefault("zFeedback", "dragPointZFeedback"); setPartAsDefault("yzFeedback", "dragPointYZFeedback"); setPartAsDefault("xzFeedback", "dragPointXZFeedback"); setPartAsDefault("xyFeedback", "dragPointXYFeedback"); //******************** // initialize state, limitbox, gesture variables //******************** // To begin with, only the yTranslator and xzTranslators are turned on. // You can switch between pairs of line/plane draggers by hitting the // CONTROL key setSwitchValue(xTranslatorSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(yTranslatorSwitch.getValue(), 0 ); setSwitchValue(zTranslatorSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(yzTranslatorSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(xzTranslatorSwitch.getValue(), 0 ); setSwitchValue(xyTranslatorSwitch.getValue(), SO_SWITCH_NONE ); // ??? Would be cool to be able to choose a free // axis, rotate it around to whatever direction, maybe even // have it snap to things in the scene, then constrain // dragging to that line. // Start off inactive currentDragger = NULL; // The state of the modifier keys shftDown = FALSE; // Need to initialize since checkBoxLimits will look at it... startLocalHitPt.setValue(0,0,0); // The jump axes will jump when the edit point gets within // 10% of their ends jumpLimit = .1; // makes the offsetWorkLimit box limitBox.makeEmpty(); updateLimitBoxAndFeedback(); // These will be called by the child draggers after they call // their own callbacks... addStartCallback( &SoDragPointDragger::startCB ); addMotionCallback( &SoDragPointDragger::motionCB ); addFinishCallback( &SoDragPointDragger::finishCB ); // When modify keys are released, we need to turn off any constraints. addOtherEventCallback( &SoDragPointDragger::metaKeyChangeCB ); // Updates the translation field when the motionMatrix is set. addValueChangedCallback( &SoDragPointDragger::valueChangedCB ); // Updates the motionMatrix when the translation field is set. fieldSensor = new SoFieldSensor( &SoDragPointDragger::fieldSensorCB, this); fieldSensor->setPriority( 0 ); setUpConnections( TRUE, TRUE ); }
/*! \DRAGGER_CONSTRUCTOR \NODEKIT_PRE_DIAGRAM \verbatim CLASS SoCenterballDragger -->"this" "callbackList" "topSeparator" "motionMatrix" --> "translateToCenter" --> "surroundScale" --> "antiSquish" --> "lightModel" "geomSeparator" --> "XAxisSwitch" --> "XAxis" --> "YAxisSwitch" --> "YAxis" --> "ZAxisSwitch" --> "ZAxis" --> "rotator" --> "YRotator" --> "ZCenterChanger" --> "rotX90" --> "ZRotator" --> "YCenterChanger" --> "rotY90" --> "XCenterChanger" --> "rot2X90" --> "XRotator" \endverbatim \NODEKIT_POST_DIAGRAM \NODEKIT_PRE_TABLE \verbatim CLASS SoCenterballDragger PVT "this", SoCenterballDragger --- "callbackList", SoNodeKitListPart [ SoCallback, SoEventCallback ] PVT "topSeparator", SoSeparator --- PVT "motionMatrix", SoMatrixTransform --- "translateToCenter", SoMatrixTransform --- "surroundScale", SoSurroundScale --- "antiSquish", SoAntiSquish --- "lightModel", SoLightModel --- PVT "geomSeparator", SoSeparator --- "rotator", SoRotateSphericalDragger --- "YRotator", SoRotateCylindricalDragger --- "ZCenterChanger", SoTranslate2Dragger --- PVT "rotX90", SoRotation --- "ZRotator", SoRotateCylindricalDragger --- "YCenterChanger", SoTranslate2Dragger --- PVT "rotY90", SoRotation --- "XCenterChanger", SoTranslate2Dragger --- PVT "rot2X90", SoRotation --- PVT "XAxisSwitch", SoSwitch --- "XAxis", SoSeparator --- PVT "YAxisSwitch", SoSwitch --- "YAxis", SoSeparator --- PVT "ZAxisSwitch", SoSwitch --- "ZAxis", SoSeparator --- "XRotator", SoRotateCylindricalDragger --- \endverbatim \NODEKIT_POST_TABLE */ SoCenterballDragger::SoCenterballDragger(void) { SO_KIT_INTERNAL_CONSTRUCTOR(SoCenterballDragger); SO_KIT_ADD_CATALOG_ENTRY(XAxis, SoSeparator, TRUE, XAxisSwitch, "", TRUE); SO_KIT_ADD_CATALOG_ENTRY(XAxisSwitch, SoSwitch, TRUE, geomSeparator, YAxisSwitch, FALSE); SO_KIT_ADD_CATALOG_ENTRY(XCenterChanger, SoTranslate2Dragger, TRUE, topSeparator, rot2X90, TRUE); SO_KIT_ADD_CATALOG_ENTRY(XRotator, SoRotateCylindricalDragger, TRUE, topSeparator, "", TRUE); SO_KIT_ADD_CATALOG_ENTRY(YAxis, SoSeparator, TRUE, YAxisSwitch, "", TRUE); SO_KIT_ADD_CATALOG_ENTRY(YAxisSwitch, SoSwitch, TRUE, geomSeparator, ZAxisSwitch, FALSE); SO_KIT_ADD_CATALOG_ENTRY(YCenterChanger, SoTranslate2Dragger, TRUE, topSeparator, rotY90, TRUE); SO_KIT_ADD_CATALOG_ENTRY(YRotator, SoRotateCylindricalDragger, TRUE, topSeparator, ZCenterChanger, TRUE); SO_KIT_ADD_CATALOG_ENTRY(ZAxis, SoSeparator, TRUE, ZAxisSwitch, "", TRUE); SO_KIT_ADD_CATALOG_ENTRY(ZAxisSwitch, SoSwitch, TRUE, geomSeparator, "", FALSE); SO_KIT_ADD_CATALOG_ENTRY(ZCenterChanger, SoTranslate2Dragger, TRUE, topSeparator, rotX90, TRUE); SO_KIT_ADD_CATALOG_ENTRY(ZRotator, SoRotateCylindricalDragger, TRUE, topSeparator, YCenterChanger, TRUE); SO_KIT_ADD_CATALOG_ENTRY(antiSquish, SoAntiSquish, FALSE, topSeparator, lightModel, TRUE); SO_KIT_ADD_CATALOG_ENTRY(lightModel, SoLightModel, TRUE, topSeparator, geomSeparator, TRUE); SO_KIT_ADD_CATALOG_ENTRY(rot2X90, SoRotation, TRUE, topSeparator, XRotator, FALSE); SO_KIT_ADD_CATALOG_ENTRY(rotX90, SoRotation, TRUE, topSeparator, ZRotator, FALSE); SO_KIT_ADD_CATALOG_ENTRY(rotY90, SoRotation, TRUE, topSeparator, XCenterChanger, FALSE); SO_KIT_ADD_CATALOG_ENTRY(rotator, SoRotateSphericalDragger, TRUE, topSeparator, YRotator, TRUE); SO_KIT_ADD_CATALOG_ENTRY(surroundScale, SoSurroundScale, TRUE, topSeparator, antiSquish, TRUE); SO_KIT_ADD_CATALOG_ENTRY(translateToCenter, SoMatrixTransform, TRUE, topSeparator, surroundScale, TRUE); if (SO_KIT_IS_FIRST_INSTANCE()) { SoInteractionKit::readDefaultParts("centerballDragger.iv", CENTERBALLDRAGGER_draggergeometry, static_cast<int>(strlen(CENTERBALLDRAGGER_draggergeometry))); } SO_KIT_ADD_FIELD(rotation, (SbRotation(SbVec3f(0.0f, 0.0f, 1.0f), 0.0f))); SO_KIT_ADD_FIELD(center, (0.0f, 0.0f, 0.0f)); SO_KIT_INIT_INSTANCE(); // create subdraggers SO_GET_ANY_PART(this, "XCenterChanger", SoTranslate2Dragger); SO_GET_ANY_PART(this, "YCenterChanger", SoTranslate2Dragger); SO_GET_ANY_PART(this, "ZCenterChanger", SoTranslate2Dragger); SO_GET_ANY_PART(this, "XRotator", SoRotateCylindricalDragger); SO_GET_ANY_PART(this, "YRotator", SoRotateCylindricalDragger); SO_GET_ANY_PART(this, "ZRotator", SoRotateCylindricalDragger); SO_GET_ANY_PART(this, "rotator", SoRotateSphericalDragger); // create default parts this->setPartAsDefault("XAxis", "centerballXAxis"); this->setPartAsDefault("YAxis", "centerballYAxis"); this->setPartAsDefault("ZAxis", "centerballZAxis"); // initialize some nodes SoRotation *rot; rot = SO_GET_ANY_PART(this, "rot2X90", SoRotation); rot->rotation = SbRotation(SbVec3f(1.0f, 0.0f, 0.0f), (static_cast<float>(M_PI))*0.5f); rot = SO_GET_ANY_PART(this, "rotX90", SoRotation); rot->rotation = SbRotation(SbVec3f(1.0f, 0.0f, 0.0f), (static_cast<float>(M_PI))*0.5f); rot = SO_GET_ANY_PART(this, "rotY90", SoRotation); rot->rotation = SbRotation(SbVec3f(0.0f, 1.0f, 0.0f), (static_cast<float>(M_PI))*0.5f); // reset default flags for parts we set to a default value this->rot2X90.setDefault(TRUE); this->rotX90.setDefault(TRUE); this->rotY90.setDefault(TRUE); SoAntiSquish *squish = SO_GET_ANY_PART(this, "antiSquish", SoAntiSquish); squish->sizing = SoAntiSquish::LONGEST_DIAGONAL; squish->recalcAlways = FALSE; SoMatrixTransform *mt = SO_GET_ANY_PART(this, "translateToCenter", SoMatrixTransform); mt->matrix = SbMatrix::identity(); this->addValueChangedCallback(SoCenterballDragger::valueChangedCB); this->rotFieldSensor = new SoFieldSensor(SoCenterballDragger::fieldSensorCB, this); this->centerFieldSensor = new SoFieldSensor(SoCenterballDragger::fieldSensorCB, this); this->setUpConnections(TRUE, TRUE); }
int offscreenbuffersize; SbBool hadSceneCamera; SbBool hasSceneChanged; // FIXME: this will not work on all platforms/compilers static SbRotation ROT_NEG_X; static SbRotation ROT_POS_X; static SbRotation ROT_NEG_Y; static SbRotation ROT_POS_Y; static SbRotation ROT_NEG_Z; static SbRotation ROT_POS_Z; }; SbRotation SoSceneTextureCubeMapP::ROT_NEG_X = SbRotation(SbVec3f(0,1,0), (float) (M_PI/2.0f)) * SbRotation(SbVec3f(1,0,0), (float) M_PI); SbRotation SoSceneTextureCubeMapP::ROT_POS_X = SbRotation(SbVec3f(0,1,0), (float) (M_PI/-2.0f)) * SbRotation(SbVec3f(1,0,0), (float) M_PI); SbRotation SoSceneTextureCubeMapP::ROT_NEG_Y = SbRotation(SbVec3f(1,0,0), (float) (M_PI / -2.0f)); SbRotation SoSceneTextureCubeMapP::ROT_POS_Y = SbRotation(SbVec3f(1,0,0), (float) (M_PI / 2.0f)); SbRotation SoSceneTextureCubeMapP::ROT_NEG_Z = SbRotation(SbVec3f(0,1,0), 0.0f) * SbRotation(SbVec3f(0,0,1), (float) M_PI); SbRotation SoSceneTextureCubeMapP::ROT_POS_Z = SbRotation(SbVec3f(0,1,0), (float) M_PI) * SbRotation(SbVec3f(0,0,1), (float) M_PI);
void SoSFRotation::setValue(const SbVec3f &axis, // The axis float angle) // The angle (in radians) { setValue(SbRotation(axis, angle)); }
void SoBuiltinFieldConverter::doConversion(SoField *outField) // //////////////////////////////////////////////////////////////////////// { // Various variables needed by the conversion cases: int i; SbMatrix matrix; SbString string; // Combine inType/outType into one integer. switch (inType*MAXFIELDS + outType) { #define CASE(typeIn,typeOut) case typeIn*MAXFIELDS+typeOut // This macro is for converting the single/multi fields into their // corresponding multi/single value fields. // In normal code, it looks like: // Single to Multi: // SoMField->setValue(SoSField->getValue()) // Multi so Single: // if (MField->getNum() > 0) SoSField->setValue(SoMField[0]) #define CONV1(type) \ CASE(SO__CONCAT(SF,type),SO__CONCAT(MF,type)): \ ((SO__CONCAT(SoMF,type) *)outField)->setValue( \ ((SO__CONCAT(SoSF,type) *)input)->getValue()); \ break; \ CASE(SO__CONCAT(MF,type),SO__CONCAT(SF,type)): \ if (((SoMField *)input)->getNum() > 0) \ ((SO__CONCAT(SoSF,type) *)outField)->setValue( \ (*(SO__CONCAT(SoMF,type) *)input)[0]); \ break // Cases for all the field types: CONV1(BitMask); CONV1(Bool); CONV1(Color); CONV1(Enum); CONV1(Float); CONV1(Int32); CONV1(Matrix); CONV1(Name); CONV1(Node); CONV1(Path); CONV1(Plane); CONV1(Rotation); CONV1(Short); CONV1(String); CONV1(Time); CONV1(UInt32); CONV1(UShort); CONV1(Vec2f); CONV1(Vec3f); CONV1(Vec4f); #undef CONV1 // // Conversions to/from a string for all field types. The eight cases // are: // Single to/from Single string: // Single to/from Multiple string: // Multi to/from Single string: // input->get(string); outField->set(string); // Multi to/from Multi string: // for (i = 0; i < ((SoMField *)input)->getNum(); i++) { // (SoMField *)input->get1(i, string); // (SoMField *)outField->set1(i, string); // // Note: we must use the SF/MFString->setValue() routines and not just // plain set() in case there is whitespace in the string, since set() // takes file format, and in the file format strings with whitespace // must be quoted. // #define CONVSTR(type) \ CASE(SO__CONCAT(SF,type),SFString): \ CASE(SO__CONCAT(MF,type),SFString): \ input->get(string); \ ((SoSFString *)outField)->setValue(string); \ break; \ CASE(SO__CONCAT(SF,type),MFString): \ input->get(string); \ ((SoMFString *)outField)->set1Value(0,string); \ break; \ CASE(SO__CONCAT(MF,type),MFString): \ for (i = 0; i < ((SoMField *)input)->getNum(); i++) { \ ((SoMField *)input)->get1(i, string); \ ((SoMFString *)outField)->set1Value(i, string); \ } \ break; \ CASE(SFString,SO__CONCAT(SF,type)): \ CASE(MFString,SO__CONCAT(SF,type)): \ CASE(SFString,SO__CONCAT(MF,type)): \ input->get(string); \ outField->set(string.getString()); \ break; \ CASE(MFString,SO__CONCAT(MF,type)): \ for (i = 0; i < ((SoMField *)input)->getNum(); i++) { \ ((SoMField *)input)->get1(i, string); \ ((SoMField *)outField)->set1(i, string.getString()); \ } \ break // All types except string: CONVSTR(BitMask); CONVSTR(Bool); CONVSTR(Color); CONVSTR(Enum); CONVSTR(Float); CONVSTR(Int32); CONVSTR(Matrix); CONVSTR(Name); CONVSTR(Node); CONVSTR(Path); CONVSTR(Plane); CONVSTR(Rotation); CONVSTR(Short); CONVSTR(UInt32); CONVSTR(UShort); CONVSTR(Vec2f); CONVSTR(Vec3f); CONVSTR(Vec4f); #undef CONVSTR // Special case for time to string; if the time is great enough, // format as a date: CASE(SFTime,SFString): { SbTime t = ((SoSFTime *)input)->getValue(); if (t.getValue() > 3.15e7) string = t.formatDate(); else string = t.format(); ((SoSFString *)outField)->setValue(string); } break; CASE(SFTime,MFString): { SbTime t = ((SoSFTime *)input)->getValue(); if (t.getValue() > 3.15e7) string = t.formatDate(); else string = t.format(); ((SoMFString *)outField)->set1Value(0, string); } break; CASE(MFTime,SFString): { SbTime t = (*((SoMFTime *)input))[0]; if (t.getValue() > 3.15e7) string = t.formatDate(); else string = t.format(); ((SoSFString *)outField)->setValue(string); } break; CASE(MFTime,MFString): { for (i = 0; i < ((SoMField *)input)->getNum(); i++) { SbTime t = (*((SoMFTime *)input))[i]; if (t.getValue() > 3.15e7) string = t.formatDate(); else string = t.format(); ((SoMFString *)outField)->set1Value(i, string); } } break; CASE(SFString,SFTime): CASE(MFString,SFTime): CASE(SFString,MFTime): input->get(string); outField->set(string.getString()); break; CASE(MFString,MFTime): for (i = 0; i < ((SoMField *)input)->getNum(); i++) { ((SoMField *)input)->get1(i, string); ((SoMField *)outField)->set1(i, string.getString()); } break; // This macro will do most of the conversions, relying on the C++ // built-in type conversions. It does all eight combinations of // single/multi to single/multi conversions for two types that are // different. HALF_CONV does the conversions one-way, CONV does them // both ways: // Single to single: // SoSField->setValue(SoSField->getValue()); // Multi to single: // if (SoMField->getNum() > 0) SoSField->setValue(SoMField[0]) // Single to multi: // SoMField->setValue(SoSField->getValue()) // Multi to multi: // for (i = 0; i < SoMField->getNum(); i++) { // SoMField->set1Value(i, SoMfield[i]); // } // #define HALF_CONV(typeIn,typeOut,valTypeOut) \ CASE(SO__CONCAT(SF,typeIn),SO__CONCAT(SF,typeOut)): \ ((SO__CONCAT(SoSF,typeOut) *)outField)->setValue((valTypeOut) \ ((SO__CONCAT(SoSF,typeIn) *)input)->getValue()); \ break; \ CASE(SO__CONCAT(MF,typeIn),SO__CONCAT(SF,typeOut)): \ if (((SoMField *)input)->getNum() > 0) \ ((SO__CONCAT(SoSF,typeOut) *)outField)->setValue((valTypeOut) \ (*(SO__CONCAT(SoMF,typeIn) *)input)[0]); \ break; \ CASE(SO__CONCAT(SF,typeIn),SO__CONCAT(MF,typeOut)): \ ((SO__CONCAT(SoMF,typeOut) *)outField)->setValue((valTypeOut) \ ((SO__CONCAT(SoSF,typeIn) *)input)->getValue()); \ break; \ CASE(SO__CONCAT(MF,typeIn),SO__CONCAT(MF,typeOut)): \ for (i = 0; i < ((SoMField *)input)->getNum(); i++) { \ ((SO__CONCAT(SoMF,typeOut) *)outField)->set1Value(i, \ (valTypeOut) (*(SO__CONCAT(SoMF,typeIn) *)input)[i]); \ } \ break #define CONV(type1,valType1,type2,valType2) \ HALF_CONV(type1,type2,valType2); \ HALF_CONV(type2,type1,valType1) // Simple conversions for most fields: CONV(Bool,SbBool,Float,float); CONV(Bool,SbBool,Int32,int32_t); CONV(Bool,SbBool,Short,short); CONV(Bool,SbBool,UInt32,uint32_t); CONV(Bool,SbBool,UShort,unsigned short); CONV(Color,const SbColor &,Vec3f,const SbVec3f &); CONV(Float,float,Int32,int32_t); CONV(Float,float,Short,short); CONV(Float,float,UInt32,uint32_t); CONV(Float,float,UShort,unsigned short); CONV(Int32,int32_t,Short,short); CONV(Int32,int32_t,UInt32,uint32_t); CONV(Int32,int32_t,UShort,unsigned short); CONV(Short,short,UInt32,uint32_t); CONV(Short,short,UShort,unsigned short); CONV(UInt32,uint32_t,UShort,unsigned short); // Some wacky oddball conversions that we have to special-case: // Float to time can be handled by regular code because SbTime has a // constructor that takes a float, but time to float needs to be // special-cased: HALF_CONV(Float, Time, float); CASE(SFTime, SFFloat): ((SoSFFloat *)outField)->setValue( ((SoSFTime *)input)->getValue().getValue()); break; CASE(SFTime, MFFloat): ((SoMFFloat *)outField)->setValue( ((SoSFTime *)input)->getValue().getValue()); break; CASE(MFTime, SFFloat): ((SoSFFloat *)outField)->setValue( (*(SoMFTime *)input)[0].getValue()); break; CASE(MFTime, MFFloat): for (i = 0; i < ((SoMFTime *)input)->getNum(); i++) { ((SoMFFloat *)outField)->set1Value(i, (*(SoMFTime *)input)[i].getValue()); } break; CASE(SFMatrix, SFRotation): ((SoSFRotation *) outField)->setValue( SbRotation(((SoSFMatrix *) input)->getValue())); break; CASE(SFMatrix, MFRotation): ((SoMFRotation *) outField)->setValue( SbRotation(((SoSFMatrix *) input)->getValue())); break; CASE(MFMatrix, SFRotation): ((SoSFRotation *) outField)->setValue( SbRotation((* (SoMFMatrix *) input)[0])); break; CASE(MFMatrix, MFRotation): for (i = 0; i < ((SoMFMatrix *)input)->getNum(); i++) { ((SoMFRotation *)outField)->set1Value(i, SbRotation((* (SoMFMatrix *) input)[i])); } break; CASE(SFRotation, SFMatrix): matrix.setRotate(((SoSFRotation *)input)->getValue()); ((SoSFMatrix *)outField)->setValue(matrix); break; CASE(SFRotation, MFMatrix): matrix.setRotate(((SoSFRotation *)input)->getValue()); ((SoSFMatrix *)outField)->setValue(matrix); break; CASE(MFRotation, SFMatrix): matrix.setRotate((*(SoMFRotation *)input)[0]); ((SoSFMatrix *)outField)->setValue(matrix); break; CASE(MFRotation, MFMatrix): for (i = 0; i < ((SoMFRotation *)input)->getNum(); i++) { matrix.setRotate((*(SoMFRotation *)input)[i]); ((SoMFMatrix *)outField)->set1Value(i, matrix); } break; default: #ifdef DEBUG SoDebugError::post("SoBuiltinFieldConverter::doConversion", "Can't convert type %d to type %d\n", inType, outType); #endif break; } }
SoField * SoBuiltinFieldConverter::getInput(SoType type) // //////////////////////////////////////////////////////////////////////// { input = (SoField *)type.createInstance(); #define DECIDEIN(class,defaultValue) \ (type == SO__CONCAT(So,class)::getClassTypeId()) { \ inType = class; \ ((SO__CONCAT(So,class) *)input)->setValue defaultValue ; \ } if DECIDEIN(MFBitMask,(0)) else if DECIDEIN(MFBool,(FALSE)) else if DECIDEIN(MFColor,(0,0,0)) else if DECIDEIN(MFEnum,(0)) else if DECIDEIN(MFFloat,(0)) else if DECIDEIN(MFInt32,(0)) else if DECIDEIN(MFMatrix,(SbMatrix::identity())) else if DECIDEIN(MFName,("")) else if DECIDEIN(MFNode,(NULL)) else if DECIDEIN(MFPath,(NULL)) else if DECIDEIN(MFPlane,(SbPlane(SbVec3f(0,0,0),0))) else if DECIDEIN(MFRotation,(SbRotation())) else if DECIDEIN(MFShort,(0)) else if DECIDEIN(MFString,("")) else if DECIDEIN(MFTime,(SbTime::zero())) else if DECIDEIN(MFUInt32,(0)) else if DECIDEIN(MFUShort,(0)) else if DECIDEIN(MFVec2f,(0,0)) else if DECIDEIN(MFVec3f,(0,0,0)) else if DECIDEIN(MFVec4f,(0,0,0,0)) else if DECIDEIN(SFBitMask,(0)) else if DECIDEIN(SFBool,(FALSE)) else if DECIDEIN(SFColor,(0,0,0)) else if DECIDEIN(SFEnum,(0)) else if DECIDEIN(SFFloat,(0)) else if DECIDEIN(SFInt32,(0)) else if DECIDEIN(SFMatrix,(SbMatrix::identity())) else if DECIDEIN(SFName,("")) else if DECIDEIN(SFNode,(NULL)) else if DECIDEIN(SFPath,(NULL)) else if DECIDEIN(SFPlane,(SbPlane(SbVec3f(0,0,0),0))) else if DECIDEIN(SFRotation,(SbRotation())) else if DECIDEIN(SFShort,(0)) else if DECIDEIN(SFString,("")) else if DECIDEIN(SFTime,(SbTime::zero())) else if DECIDEIN(SFUInt32,(0)) else if DECIDEIN(SFUShort,(0)) else if DECIDEIN(SFVec2f,(0,0)) else if DECIDEIN(SFVec3f,(0,0,0)) else if DECIDEIN(SFVec4f,(0,0,0,0)) #undef DECIDEIN #ifdef DEBUG else { SoDebugError::post("(internal) SoBuiltinFieldConverter::getInput", "no input for type '%s'", type.getName().getString()); } #endif input->setContainer(this); myInputData->addField(this, "input", input); return input; }
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); }
void Texture3D(SoSeparator * root) { SoDB::createGlobalField("globalVerts", SoMFVec3f::getClassTypeId()); SoDB::createGlobalField("globalTVerts", SoMFVec3f::getClassTypeId()); SoDB::createGlobalField("globalnv", SoMFInt32::getClassTypeId()); SoDB::createGlobalField("planeVerts", SoMFVec3f::getClassTypeId()); SoDB::createGlobalField("planeTVerts", SoMFVec3f::getClassTypeId()); doClipping(SbVec3f(0,0,0), SbRotation()); // SoSeparator * root = new SoSeparator; // root->ref(); SoComplexity * comp = new SoComplexity; comp->textureQuality.setValue((float)0.9); root->addChild(comp); SoTexture3 * texture = new SoTexture3; texture->wrapR.setValue(SoTexture3::CLAMP); texture->wrapS.setValue(SoTexture3::CLAMP); texture->wrapT.setValue(SoTexture3::CLAMP); // SbString filenames[64]; // for (int i=0;i<64;i++) // filenames[i].sprintf("../../../data/pgmvol/slice%02d.raw.pgm",i); // texture->filenames.setValues(0,64,filenames); unsigned char * img = generateTexture(256,256,256); texture->images.setValue(SbVec3s(256,256,256), 1, img); root->addChild(texture); SoMaterial * mat = new SoMaterial; mat->emissiveColor.setValue(1,1,1); root->addChild(mat); SoTransformerDragger * dragger = new SoTransformerDragger; dragger->scaleFactor.setValue(5,5,5); dragger->addValueChangedCallback(draggerCB, NULL); root->addChild(dragger); SoCoordinate3 * clippedCoords = new SoCoordinate3; clippedCoords->point.connectFrom((SoMFVec3f *) SoDB::getGlobalField("globalVerts")); root->addChild(clippedCoords); SoTextureCoordinate3 * clippedTCoords = new SoTextureCoordinate3; clippedTCoords->point.connectFrom((SoMFVec3f *) SoDB::getGlobalField("globalTVerts")); root->addChild(clippedTCoords); SoFaceSet * clippedFS = new SoFaceSet; clippedFS->numVertices.connectFrom((SoMFInt32 *) SoDB::getGlobalField("globalnv")); root->addChild(clippedFS); SoCoordinate3 * planeCoords = new SoCoordinate3; planeCoords->point.connectFrom((SoMFVec3f *) SoDB::getGlobalField("planeVerts")); root->addChild(planeCoords); SoTextureCoordinate3 * planeTCoords = new SoTextureCoordinate3; planeTCoords->point.connectFrom((SoMFVec3f *) SoDB::getGlobalField("planeTVerts")); root->addChild(planeTCoords); SoFaceSet * planeFS = new SoFaceSet; root->addChild(planeFS); }
SbRotation SbSphereSectionProjector::getRotation(const SbVec3f &p1, const SbVec3f &p2) // //////////////////////////////////////////////////////////////////////// { SbBool tol1 = isWithinTolerance(p1); SbBool tol2 = isWithinTolerance(p2); if (tol1 && tol2) { // both points in tolerance, rotate about // sphere center return SbRotation( p1 - sphere.getCenter(), p2 - sphere.getCenter()); } else if (!tol1 && !tol2) { // both points out of tolerance, rotate about // plane point // Would like to just use this: SbRotation badRot = SbRotation(p1 - planePoint, p2 - planePoint); // but fp instablity gives back a goofy axis, so we don't get // pure roll. // So we need to snap the axis to be parallel to plane dir SbVec3f badAxis; float goodAngle; badRot.getValue(badAxis, goodAngle); SbVec3f goodAxis; if (badAxis.dot(planeDir) > 0.0) goodAxis = planeDir; else goodAxis = -planeDir; SbRotation rollRot(goodAxis, goodAngle); //Now find rotation in the direction perpendicular to this: SbVec3f diff1 = p1 - planePoint; SbVec3f diff2 = p2 - planePoint; float d = diff2.length() - diff1.length(); // Check for degenerate cases float theta = d / sphere.getRadius(); if ( fabs(theta) < 0.000001 || fabs(theta) > 1.0 ) return rollRot; diff1.normalize(); SbVec3f pullAxis = planeDir.cross( diff1 ); pullAxis.normalize(); SbRotation pullRot(pullAxis, getRadialFactor() * theta ); SbRotation totalRot = rollRot * pullRot; return totalRot; } else { // one point in, one point out, so rotate about // the center of the sphere from the point on the // sphere to the intersection of the plane and the // sphere closest to the point off the sphere SbLine planeLine; SbVec3f intersection; if (tol1) { planeLine.setValue(planePoint, p2); } else { planeLine.setValue(planePoint, p1); } if (! sphere.intersect(planeLine, intersection)) #ifdef DEBUG SoDebugError::post("SbSphereSectionProjector::getRotation", "Couldn't intersect plane line with sphere"); #else /* Do nothing */; #endif if (tol1) { // went off sphere return SbRotation( p1 - sphere.getCenter(), intersection - sphere.getCenter()); } else { // came on to sphere // "Hey cutie. You've got quite a radius..." return SbRotation( intersection - sphere.getCenter(), p2 - sphere.getCenter()); } } }