예제 #1
0
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 );
}
예제 #2
0
파일: vpSimulator.cpp 프로젝트: tswang/visp
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() ;
}
예제 #3
0
// 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);
    }
}
예제 #4
0
////////////////////////////////////////////////////////////////////////
//
// 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)));
}
예제 #5
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);
}
예제 #6
0
void
SoSFRotation::setValue(float q0, float q1, float q2, float q3)	// The 4 floats
//
////////////////////////////////////////////////////////////////////////
{
    setValue(SbRotation(q0, q1, q2, q3));
}
예제 #7
0
파일: vpSimulator.cpp 프로젝트: tswang/visp
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() ;
}
예제 #8
0
void
SoSFRotation::setValue(const float q[4])	// Array of values
//
////////////////////////////////////////////////////////////////////////
{
    setValue(SbRotation(q));
}
예제 #9
0
파일: main.cpp 프로젝트: pmitros/ball
// 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;
}
예제 #10
0
////////////////////////////////////////////////////////////////////////
//
// Constructor
//
SoMotion3Event::SoMotion3Event()
//
////////////////////////////////////////////////////////////////////////
{
    translation = SbVec3f(0, 0, 0);
    rotation    = SbRotation(SbVec3f(1, 0, 0), 0);
}
예제 #11
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 ) ) );
}
예제 #12
0
void
SbMatrix::setTransform(const SbVec3f &translation,
		 const SbRotation &rotation,
		 const SbVec3f &scaleFactor,
		 const SbRotation &scaleOrientation,
		 const SbVec3f &center)
{
#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
}
예제 #13
0
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;
}
예제 #14
0
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);
}
예제 #15
0
/*!
  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;
}
예제 #16
0
/*!
  \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);
}
예제 #17
0
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);
    }
예제 #19
0
파일: InnerDisc.cpp 프로젝트: dewf/mrLab3d
void InnerDisc::rotateTo(const SbVec3f &to)
{
	rot->rotation = SbRotation(SbVec3f(0, 0, 1), to);
}
예제 #20
0
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();
}
예제 #21
0
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)));
}
예제 #22
0
////////////////////////////////////////////////////////////////////////
//
// 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 );
}
예제 #23
0
/*!
  \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);
}
예제 #24
0
  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);
예제 #25
0
void
SoSFRotation::setValue(const SbVec3f &axis,	// The axis
		       float angle)		// The angle (in radians)
{
    setValue(SbRotation(axis, angle));
}
예제 #26
0
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;
    }
}
예제 #27
0
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;
}
예제 #28
0
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);
}
예제 #29
0
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());
	}
    }

}