[BACK]Return to pfiInputXform.C CVS log [TXT][DIR] Up to [Development] / performer / src / lib / libpfui

File: [Development] / performer / src / lib / libpfui / pfiInputXform.C (download)

Revision 1.1, Tue Nov 21 21:39:35 2000 UTC (16 years, 10 months ago) by flynnt
Branch: MAIN
CVS Tags: HEAD

Initial check-in based on OpenGL Performer 2.4 tree.
-flynnt

/*
 * Copyright 1993, 1994, 1995, Silicon Graphics, Inc.
 * ALL RIGHTS RESERVED
 *
 * UNPUBLISHED -- Rights reserved under the copyright laws of the United
 * States.   Use of a copyright notice is precautionary only and does not
 * imply publication or disclosure.
 *
 * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
 * Use, duplication or disclosure by the Government is subject to restrictions
 * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
 * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
 * in similar or successor clauses in the FAR, or the DOD or NASA FAR
 * Supplement.  Contractor/manufacturer is Silicon Graphics, Inc.,
 * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
 *
 * THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
 * INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
 * DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
 * PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
 * GRAPHICS, INC.
 */


/*
 * file: pfiInputXform.C
 * ----------------------
 *
 * Libpr-based event tranform utlities for building UI components
 *
 * $Revision: 1.1 $
 * $Date: 2000/11/21 21:39:35 $
 *
 */
 
#define PF_C_API 1 // enable C API also 

#include <math.h>
#include <Performer/prmath.h>
#include <Performer/pf.h>
#include <Performer/pr/pfLinMath.h>
#include <Performer/pr/pfGeoMath.h>
#include <Performer/pr/pfMemory.h>

#define __PFI_INPUTXFORM_C__
#include <Performer/pfui.h>
#include <Performer/pfui/pfiInputXform.h>

#if 0
static void
printMat(pfMatrix& mat)
{
    pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n", 
        mat[0][0], mat[0][1], mat[0][2], mat[0][3], 
        mat[1][0], mat[1][1], mat[1][2], mat[1][3],
        mat[2][0], mat[2][1], mat[2][2], mat[2][3],
        mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
}
#endif

/******************************************************************************
 *			    pfiInputCoord Routines
 ******************************************************************************
 */


pfType *pfiInputCoord::classType = NULL;

void
pfiInputCoord::init()
{
    if (classType == NULL)
    {
	pfObject::init();
	classType = 
	    new pfType(pfObject::getClassType(), "pfiInputCoord");
    }
}

pfiInputCoord::pfiInputCoord(void) 
{
    _pfiClassInitCheck(); 
    setType(classType); 
    focus = 1; 
}

void	
pfiInputCoord::setVec(float *)
{
    pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "pfiInputCoord::setVec.");
}
void	
pfiInputCoord::setPrev(float *)
{
    pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "pfiInputCoord::setVec.");
}

void	
pfiInputCoord::getVec(float *) const
{
    pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "pfiInputCoord::getVec.");
}
void	
pfiInputCoord::getPrev(float *) const
{
    pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "pfiInputCoord::getPrev.");
}
float	
pfiInputCoord::getCoord(int) const
{
    pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "pfiInputCoord::getCoord.");
    return -2.0f;
}
float	
pfiInputCoord::getPrevCoord(int) const
{
    pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "pfiInputCoord::getPrevCoord.");
    return -2.0f;
}
float	
pfiInputCoord::getDelta(int) const
{
    pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "pfiInputCoord::getDelta.");
    return -2.0f;
}
void	
pfiInputCoord::updatePrev(void)
{
    pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "pfiInputCoord::updatePrev.");
}

pfType *pfi2DInputCoord::classType = NULL;

void
pfi2DInputCoord::init()
{
    if (classType == NULL)
    {
	pfObject::init();
	classType = 
	    new pfType(pfiInputCoord::getClassType(), "pfi2DInputCoord");
    }
}

pfi2DInputCoord::pfi2DInputCoord(void) 
{ 
    setType(classType); 
    reset(); 
}

/******************************************************************************
 *			    pfiMotionCoord Routines
 ******************************************************************************
 */



pfType *pfiMotionCoord::classType = NULL;

void
pfiMotionCoord::init()
{
    if (classType == NULL)
    {
	pfObject::init();
	classType = 
	    new pfType(pfObject::getClassType(), "pfiMotionCoord");
    }
}

 
pfiMotionCoord::pfiMotionCoord(void)
{
    _pfiClassInitCheck();
    setType(classType);
    speed				=   0.0f;
    maxSpeed				=  30.0f;	/* 30 meters/sec */
    minSpeed				=   0.0f;
    startAngVel = angularVel		=  180.0f;	/* 180 degrees/sec */
    angAccel				=  0.0f;
    startAccel = accel			=  10.0f;	/* 10 meters/sec^2 == gravity */
    maxAccel				=  100.0f;
    minAccel				=  0.0f;
    startTime = prevTime = time		= -1.0f;
    pfSetVec3(startPos.xyz, 0.0f, 0.0f, 0.0f);
    pfSetVec3(startPos.hpr, 0.0f, 0.0f, 0.0f); 	 
    reset();
}

void
pfiMotionCoord::reset(void)
{
    startTime				= -1.0f;
    prevTime				= -1.0f;
    speed				=  0.0f;
    pfSetVec3(pos.xyz, 0.0f, 0.0f, 0.0f); 
    pfSetVec3(pos.hpr, 0.0f, 0.0f, 0.0f); 
    pfSetVec3(prevPos.xyz, 0.0f, 0.0f, 0.0f); 
    pfSetVec3(prevPos.hpr, 0.0f, 0.0f, 0.0f); 
    pfMakeCoordMat(mat, &pos);
}

void
pfiMotionCoord::resetPosition(void)
{
    speed				=  0.0f;
    startTime				= -1.0f;
    prevTime				= -1.0f;
    PFCOPY_VEC3(pos.xyz, startPos.xyz);
    PFCOPY_VEC3(pos.hpr, startPos.hpr);
    PFCOPY_VEC3(prevPos.xyz, pos.xyz); 
    PFCOPY_VEC3(prevPos.hpr, pos.hpr); 
    pfMakeCoordMat(mat, &pos);
}

void
pfiMotionCoord::copyPos(pfiMotionCoord *_src)
{
    startTime				= _src->startTime;
    prevTime				= _src->prevTime;
    time				= _src->time;
    PFCOPY_VEC3(pos.xyz, _src->pos.xyz); 
    PFCOPY_VEC3(pos.hpr, _src->pos.hpr); 
    PFCOPY_VEC3(prevPos.xyz, _src->prevPos.xyz); 
    PFCOPY_VEC3(prevPos.hpr, _src->prevPos.hpr); 
    PFCOPY_MAT(mat, _src->mat);
}

void
pfiMotionCoord::copyMotion(pfiMotionCoord *_src)
{
    speed				= _src->speed;
    maxSpeed				= _src->maxSpeed;
    startSpeed				= _src->startSpeed;
    startAngVel				= _src->startAngVel;
    angularVel				= _src->angularVel;
    maxAngVel				= _src->maxAngVel;
    startAccel				= _src->startAccel;
    accel				= _src->accel;
    maxAccel				= _src->maxAccel;
}

void
pfiMotionCoord::copy(pfiMotionCoord *_src)
{
    copyPos(_src);
    copyMotion(_src);
}

void
pfiMotionCoord::makeMat(void)
{
    /* XXXX Better way to do this? */
    if (pos.hpr[2]  > 180.0f)
	pos.hpr[2] -= 360.0f;
    else if (pos.hpr[2]  < -180.0f)
	pos.hpr[2] += 360.0f;

    if (pos.hpr[1]  > 180.0f)
	pos.hpr[1] -= 360.0f;
    else if (pos.hpr[1]  < -180.0f)
	pos.hpr[1] += 360.0f;

    while (pos.hpr[0] > 180.0f)
	pos.hpr[0] -= 360.0f;
    while (pos.hpr[0] < -180.0f)
	pos.hpr[0] += 360.0f;

    /* IMPORTANT: prevent FP underflows */
    if (PF_ABSLT(pos.hpr[0], 1.0e-7f))
	pos.hpr[0] = 0.0f;
    if (PF_ABSLT(pos.hpr[1], 1.0e-7f))
	pos.hpr[1] = 0.0f;
    if (PF_ABSLT(pos.hpr[2], 1.0e-7f))
	pos.hpr[2] = 0.0f;

    pfMakeCoordMat(mat, &pos);
}

void
pfiMotionCoord::setMat(pfMatrix& _mat)
{
    pfCopyMat(mat, _mat);
    pfGetOrthoMatCoord(_mat, &pos);
    prevPos = pos;
}

void
pfiMotionCoord::setCoord(pfCoord *_coord)
{
    prevPos = pos = *_coord;
    pfMakeCoordMat(mat, &pos);
}



/******************************************************************************
 *			    pfiInput Routines
 ******************************************************************************
 */

pfType *pfiInput::classType = NULL;

void
pfiInput::init()
{
    if (classType == NULL)
    {
	pfObject::init();
	classType = 
	    new pfType(pfObject::getClassType(), "pfiInput");
    }
}


pfiInput::pfiInput(void)
{
    _pfiClassInitCheck();
    setType(classType);
    xEventMask			    = 0;
    xFocus			    = 1;
    xEventStream		    = NULL;
    xEventStreamCollector	    = NULL;
    xEventStreamProcessor	    = NULL;
}

pfiInput::~pfiInput(void)
{
}

void
pfiInput::reset(void)
{
    if (xEventStream)
	pfuResetEventStream(xEventStream);
}

void
pfiInput::setName(const char *_name)
{
    strcpy(xName, _name);
}



/******************************************************************************
 *			    pfiInputXform Routines
 ******************************************************************************
 */

float _PFI_FUDGE = -1; // XXX global scale for all controls

pfType *pfiInputXform::classType = NULL;

void
pfiInputXform::init()
{
    if (classType == NULL)
    {
	pfObject::init();
	classType = 
	    new pfType(pfObject::getClassType(), "pfiInputXform");
    }
}


pfiInputXform::pfiInputXform(void)
{
    _pfiClassInitCheck();
    setType(classType);
    xUserSetMask		    = 0x0;
    xFocus			    = 0x0;
    xInput			    = NULL;
    xInputCoord			    = NULL;
    xUpdateCB			    = NULL;
    xUpdateCBData		    = NULL;
    xStartMotionCB		    = NULL;
    xStopMotionCB		    = NULL;
    xMotionCBData		    = NULL;
    xUpdateMode			    = PFI_CB_CONT;
    pfSetVec3(xDBLimits.min, -PFI_BIGDB, -PFI_BIGDB, -PFI_BIGDB);
    pfSetVec3(xDBLimits.max,  PFI_BIGDB,  PFI_BIGDB,  PFI_BIGDB);
    xDBSphere.radius = xDBSize   = PFI_BIGDB;
    xDBSizeLg = 1.0f; // ???
    pfSetVec3(xDBSphere.center, 0.0f, 0.0f, 0.0f);
    xLimitPosMask		    = PFIX_LIMIT_POS_NONE;
    xLimitSpeedMask		    = PFIX_LIMIT_SPEED_MAX;
    xLimitAccelMask		    = PFIX_LIMIT_ACCEL_MAX;
    reset();
}

void
pfiInputXform::reset(void)
{
    xInMotion = 0;
    xMotionCoord.reset();
}

void
pfiInputXform::setName(const char *_name)
{
    strcpy(xName, _name);
}

void
pfiInputXform::resetPosition(void)
{
    xMotionCoord.resetPosition();
}

void
pfiInputXform::setMode(int _mode, int _val)
{
    switch(_mode)
    {
    case PFIX_MODE_MOTION:
	xMotionMode = _val;
	break;
    case PFIX_MODE_ACCEL:
	if (xAccelMode != _val)
	{
	    xAccelMode = _val;
		xMotionCoord.accel = 0;
	}
	break;
    case PFIXTK_MODE_AUTO:
	xAuto = _val;
	break;
    case PFIX_MODE_LIMIT_POS:
	xLimitPosMask = _val;
	break;
    case PFIX_MODE_LIMIT_SPEED:
	xLimitSpeedMask = _val;
	break;
    case PFIX_MODE_LIMIT_ACCEL:
	xLimitAccelMask = _val;
	break;
    default:
	pfNotify(PFNFY_WARN,PFNFY_USAGE,
	    "pfiInputXform:: unknown mode %d", _mode);
	break;
    }
}

int
pfiInputXform::getMode(int _mode) const
{
    switch(_mode)
    {
    case PFIX_MODE_MOTION:
	return xMotionMode;
    case PFIX_MODE_ACCEL:
	return xAccelMode;
    case PFIXTK_MODE_AUTO:
	return xAuto;
    case PFIX_MODE_LIMIT_POS:
	return xLimitPosMask;
    case PFIX_MODE_LIMIT_SPEED:
	return xLimitSpeedMask;
    case PFIX_MODE_LIMIT_ACCEL:
	return xLimitAccelMask;
    default:
	pfNotify(PFNFY_WARN,PFNFY_USAGE,
	    "pfiInputXform::getMode unknown mode %d", _mode);
	return -1;
    }
}

void
pfiInputXform::setMotionCoord(pfiMotionCoord *_xcoord)
{ 
    if (_xcoord)
	xMotionCoord.copy(_xcoord);
}

void
pfiInputXform::getMotionCoord(pfiMotionCoord *_xcoord)
{ 
    if (_xcoord)
	_xcoord->copy(&xMotionCoord);
}

void
pfiInputXform::setCenter(float _x, float _y, float _z)
{
    xDBSphere.center[0] = _x;
    xDBSphere.center[1] = _y;
    xDBSphere.center[2] = _z;
    xUserSetMask |= _PFIX_USET_BSPHERE;
}

void
pfiInputXform::setDBSize(float _size)
{
    xDBSize = _size;
    xDBSizeLg = logf(xDBSize);
    xUserSetMask |= _PFIX_USET_BSPHERE;
}


void
pfiInputXform::_setBSphere(pfSphere* _sphere)
{
    xDBSphere = *_sphere;
    xDBSize =  2.0f * xDBSphere.radius;
    xDBSizeLg = logf(xDBSize);
    if (!(xUserSetMask & _PFIX_USET_RESET_POS))
    {
	PFCOPY_VEC3(xMotionCoord.startPos.xyz, xDBSphere.center);
	xMotionCoord.startPos.xyz[PF_Y] -= xDBSize*1.5f;
	xMotionCoord.startPos.xyz[PF_Z] += xDBSphere.radius*0.5f;
	PFSET_VEC3(xMotionCoord.startPos.hpr, 0.0f, 0.0f, 0.0f);
    }
    if  (!(xUserSetMask & _PFIX_USET_MOTION_LIMITS))
    {
	xMotionCoord.startSpeed = xDBSize*0.5f;
	xMotionCoord.maxSpeed = xDBSize*2.0f;
	if (xMotionCoord.minSpeed < 0.0f)
	    xMotionCoord.minSpeed = -xMotionCoord.maxSpeed;
    }
}

void
pfiInputXform::_setDBLimits(pfBox* _dbLimits)
{
    pfSphere sphere;
    
    xDBLimits = *_dbLimits;
    
    // if user hasn't fix the sphere, keep the sphere as bound on db bounding box
    if (!(xUserSetMask & _PFIX_USET_BSPHERE))
    {
	pfSphereAroundBoxes(&sphere, (const pfBox **)&_dbLimits, 1);
	_setBSphere(&sphere);
    }
}
    
void		
pfiInputXform::setMotionLimits(float _maxSpeed, float _angularVel, float _accel)
{ 
    xMotionCoord.maxSpeed = _maxSpeed;
    if (xMotionCoord.minSpeed < 0.0f)
	    xMotionCoord.minSpeed = -xMotionCoord.maxSpeed;
    xMotionCoord.startAngVel = xMotionCoord.angularVel =  _angularVel;
    xMotionCoord.startAccel = xMotionCoord.accel = _accel; 
    if (xMotionCoord.minAccel == xMotionCoord.maxAccel)
	xMotionCoord.minAccel = -10.0f * _accel;
    xMotionCoord.maxAccel = 10.0f * _accel;
    xUserSetMask |= _PFIX_USET_MOTION_LIMITS;
}

void		
pfiInputXform::getMotionLimits(float *_maxSpeed, float *_angularVel, float *_accel) const
{ 
    *_maxSpeed = xMotionCoord.maxSpeed;
    *_angularVel = xMotionCoord.angularVel;
    *_accel = xMotionCoord.accel;
}

void
pfiInputXform::limitPos(void)
{
    if (xLimitPosMask & PFIX_LIMIT_POS_HORIZ)
    {
	if (xMotionCoord.pos.xyz[PF_X] < xDBLimits.min[PF_X])
	    xMotionCoord.pos.xyz[PF_X] = xDBLimits.min[PF_X];
	if (xMotionCoord.pos.xyz[PF_X] > xDBLimits.max[PF_X])
	    xMotionCoord.pos.xyz[PF_X] = xDBLimits.max[PF_X];
	    
	if (xMotionCoord.pos.xyz[PF_Y] < xDBLimits.min[PF_Y])
	    xMotionCoord.pos.xyz[PF_Y] = xDBLimits.min[PF_Y];
	if (xMotionCoord.pos.xyz[PF_Y] > xDBLimits.max[PF_Y])
	    xMotionCoord.pos.xyz[PF_Y] = xDBLimits.max[PF_Y];
    }
    
    if (xLimitPosMask & PFIX_LIMIT_POS_BOTTOM)
    {
	if (xMotionCoord.pos.xyz[PF_Z] < xDBLimits.min[PF_Z])
	    xMotionCoord.pos.xyz[PF_Z] = xDBLimits.min[PF_Z];
    }
    if (xLimitPosMask & PFIX_LIMIT_POS_TOP)
    {
	if (xMotionCoord.pos.xyz[PF_Z] > xDBLimits.max[PF_Z])
	    xMotionCoord.pos.xyz[PF_Z] = xDBLimits.max[PF_Z];
    }
}

void
pfiInputXform::limitSpeed(void)
{
    float s;

    /* Restrict speed if obeying max */
  
    if (xLimitSpeedMask & PFIX_LIMIT_SPEED_MAX)
    {
	if (xMotionCoord.speed > xMotionCoord.maxSpeed)
	    s = xMotionCoord.maxSpeed;
	else if (xMotionCoord.speed < xMotionCoord.minSpeed)
	    s = xMotionCoord.minSpeed;
	else
	    s = xMotionCoord.speed;
    }
    else
	s = xMotionCoord.speed;
	
    if (xLimitAccelMask & PFIX_LIMIT_ACCEL_MAX)
    {
	if (xMotionCoord.accel > xMotionCoord.maxAccel)
	    xMotionCoord.accel = xMotionCoord.maxAccel;
	if (xMotionCoord.accel < xMotionCoord.minAccel)
	    xMotionCoord.accel = xMotionCoord.minAccel;
    }
    
    /* Slow down if approaching limits of database */
    if (xLimitSpeedMask & PFIX_LIMIT_SPEED_DB)
    {
	pfBox	*box = &xDBLimits;
	if (!pfBoxContainsPt(box, xMotionCoord.pos.xyz))
	{
	    float 	dot, ch, sh;
	    pfVec2 	fromCenter;
    
	    /* XXX - Should clamp Z range in addition to X, Y */
    
	    fromCenter[0] = (xMotionCoord.pos.xyz[0] -
			     0.5f * (box->min[0] + box->max[0]));
				     
	    fromCenter[1] = (xMotionCoord.pos.xyz[1] -
			     0.5f * (box->min[1] + box->max[1]));
    
	    pfSinCos(xMotionCoord.pos.hpr[0], &sh, &ch);
				     
	    dot = fromCenter[1]*ch - fromCenter[0]*sh;
    
	    /* Slow down */
	    if (dot * s > 0.01f)
	    {
		s *= 0.96f;
	    }
	}
    }
    xMotionCoord.speed = s;     
}

void
pfiInputXform::update(void)
{
    xMotionCoord.prevTime	    = xMotionCoord.time;
    xMotionCoord.time		    = pfGetTime();
    if (xMotionCoord.startTime < 0.0f)
    {
	xMotionCoord.prevTime = xMotionCoord.startTime = xMotionCoord.time;
    }
    xMotionCoord.prevPos = xMotionCoord.pos;
    if (xUpdateCB)
	xUpdateMode = xUpdateCB(this, xInputCoord, xUpdateCBData);
    else
	xUpdateMode=PFI_CB_CONT;
}

void
pfiInputXform::setMat(pfMatrix& _mat)
{
    xMotionCoord.setMat(_mat);
}

void
pfiInputXform::setCoord(pfCoord *_coord)
{
    xMotionCoord.setCoord(_coord);
}

void
pfiInputXform::stop(void)
{
    xInMotion			= 0; 
    xMotionCoord.speed		= 0.0f;
}

/******************************************************************************
 *		Travel Xformer Routines
 ******************************************************************************
 */
 
 

pfType *pfiInputXformTravel::classType = NULL;

void
pfiInputXformTravel::init()
{
    if (classType == NULL)
    {
	pfiInputXform::init();
	classType = 
	    new pfType(pfiInputXform::getClassType(), "pfiInputXformTravel");
    }
}

pfiInputXformTravel::pfiInputXformTravel(void)
{
    setType(classType);
    xAuto			= 0;
    xMotionCoord.startSpeed	= 12.0f;
    xMotionCoord.minSpeed	= 0.0f;
    xMotionCoord.maxSpeed	= 40.0f;
    xMotionCoord.angularVel	= 90.0f;
    xMotionCoord.startAccel = xMotionCoord.accel = 1.25f;
    xMotionCoord.maxAccel	= 10.0f;
    xMotionCoord.minAccel	= 0.0f;
    reset();
}

void
pfiInputXformTravel::reset(void)
{
    pfiInputXform::reset();
    xMotionMode			= PFIXTR_MOTION_STOP;
    xMotionMod			= 0x0;
    xAccelMode			= PFIXTR_ACCEL_NONE;
    xAccelRate			= 0.0f;
}

void
pfiInputXformTravel::stop(void)
{ 
    pfiInputXform::stop();
    xAccelMode			= PFIXTR_ACCEL_NONE;
    xMotionMode			= PFIXTR_MOTION_STOP;
    xMotionMod			= 0x0;
}

void
pfiInputXformTravel::setMode(int _mode, int _val)
{
    switch(_mode)
    {
    case PFIXTR_MODE_MOTION:
	if (xMotionMode == _val)
	    return;
	if (!xInMotion)
	    xMotionCoord.speed = xMotionCoord.startSpeed;
	xMotionMode = _val;
	break;
    case PFIXTR_MODE_MOTION_MOD:
	xMotionMod = _val;
	break;
    case PFIXTR_MODE_ACCEL:
	if (xAccelMode != _val)
	{
	    xAccelMode = _val;
		xMotionCoord.accel = 0;
	}
	break;
    case PFIXTR_MODE_AUTO:
	xAuto = _val;
	break;
    default:
	pfNotify(PFNFY_WARN,PFNFY_USAGE,
	    "pfiInputXformTravel::setMode() - unknown mode %d", _mode);
	break;
    }
}

int
pfiInputXformTravel::getMode(int _mode) const
{
    switch(_mode)
    {
    case PFIXTR_MODE_MOTION:
	return xMotionMode;
    case PFIXTR_MODE_MOTION_MOD:
	return xMotionMod;
    case PFIXTR_MODE_ACCEL:
	return xAccelMode;
    case PFIXTR_MODE_AUTO:
	return xAuto;
    default:
	pfNotify(PFNFY_WARN,PFNFY_USAGE,
	    "pfiInputXformTravel::getMode() - unknown mode %d", _mode);
	return -1;
    }
}