void OrbitCameraManipulator::computeRayPointer( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
	osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
	if (!view) return;

	m_model_screen.makeIdentity();
	// do not apply viewport here ( m_cam->getViewport()->computeWindowMatrix() ). Use normalized screen coords instead (ea.getXnormalized())
	osg::Matrixd pm( view->getCamera()->getProjectionMatrix() );
	osg::Matrixd vm( getInverseMatrix() );

	if( pm.valid() ) m_model_screen.preMult( pm );
	if( vm.valid() ) m_model_screen.preMult( vm );

	m_screen_model.invert( m_model_screen );

	m_ray_pointer_start.set( m_screen_model.preMult( osg::Vec3d( ea.getXnormalized(), ea.getYnormalized(), 0.0) ) );
	osg::Vec3d pointer_end = m_screen_model.preMult( osg::Vec3d( ea.getXnormalized(), ea.getYnormalized(), 0.1) );

	osg::Vec3d ray_direction = pointer_end - m_ray_pointer_start;
	ray_direction.normalize();
	m_ray_pointer_direction.set( ray_direction );

	double fovy, apect_ratio, zNear, zFar;
	bool perspective = pm.getPerspective( fovy, apect_ratio, zNear, zFar );
	if( perspective )
	{
		m_fovy = fovy;
	}
}
void MainAxisPCA::computeMainAxis(const std::vector<ml::vec3>& pointCloud)
{
    ML_TRACE_IN("void MainAxisPCA::computeMainAxis()");

    float** covaMatrix = matrix(1,3,1,3);
    float** jacobiMat  = matrix(1,3,1,3);
    float** invMatrix  = matrix(1,3,1,3);
    float*  eigenValues = vL_vector(1,3);
    
    const int size = static_cast<int>( pointCloud.size() );
    
    // copy positions to vertices
    float* vertices = NULL;
    ML_CHECK_NEW(vertices, float[size * 3]);

    unsigned int i=0;
    unsigned int entry = 0;

    for (i = 0; i < size; i++){

        const ml::vec3& currPos = pointCloud[i];

        vertices[entry++] = static_cast<float>(currPos[0]);
        vertices[entry++] = static_cast<float>(currPos[1]);
        vertices[entry++] = static_cast<float>(currPos[2]);
    }
    
    // Calculate center of mass
    ML_DELETE_ARR(_baryCenter);
    _baryCenter = calcBaryCenter(vertices, size);
    
    // Compute covariant matrix, so the Jacobian matrix can be computed
    getCovarianceMatrix(vertices, static_cast<long int>(size), covaMatrix, _baryCenter);
    
    // Compute the Jacobian matrix
    int nrot=0; // dummy variable
    jacobi(covaMatrix, 3, eigenValues, jacobiMat, &nrot);
    
    // Calculate main axes
    unsigned int counter=0;
    for (counter = 0; counter < 3; counter++) {
        _xAxis[counter] = jacobiMat[counter + 1][1];
        _yAxis[counter] = jacobiMat[counter + 1][2];
        _zAxis[counter] = jacobiMat[counter + 1][3];
    }
    
    // Multiply each point by the eigenvectors of the Jacobian matrix
    const float* points = vertices;
    float* newVertices  =  NULL;
    ML_CHECK_NEW(newVertices, float[size * 3]);

    unsigned int counter2 = 0;
    for (counter = 0; counter < size; counter++) {
        
        newVertices[counter2++] = dotProduct(points, _xAxis); //tempPoint.dot(_xAxis);
        newVertices[counter2++] = dotProduct(points, _yAxis); //tempPoint.dot(_yAxis);
        newVertices[counter2++] = dotProduct(points, _zAxis); //tempPoint.dot(_zAxis);
        points += 3;
    }
    
    // Get extends of the bounding box
    float minX=0, maxX=0, minY=0, maxY=0, minZ=0, maxZ=0;
    getBoundingBox(newVertices, static_cast<long int>(size), minX, maxX, minY, maxY, minZ, maxZ);
    
    // Extends of the object aligned bounding box
    _xDiameter = maxX - minX;
    _yDiameter = maxY - minY;
    _zDiameter = maxZ - minZ;
    
    // Half the extend...
    float half_x = _xDiameter / 2.0f;
    float half_y = _yDiameter / 2.0f;
    float half_z = _zDiameter / 2.0f;
    
    // Rotate all points back by multiplying them with the inverse Jacobian matrix.
    getInverseMatrix(jacobiMat, invMatrix);
    
    float* tmp = stretchVector(_xAxis, half_x);  
    for (counter = 0; counter < 3; counter++) {  
        _midPoint[counter] =  
            minX           * invMatrix[1][counter + 1] + 
           (minY + half_y) * invMatrix[2][counter + 1] + 
           (minZ + half_z) * invMatrix[3][counter + 1] + tmp[counter];
    }
    
    ML_DELETE_ARR(tmp);
    ML_DELETE_ARR(newVertices);
    ML_DELETE_ARR(vertices);
    
    free_matrix(covaMatrix, 1, 3, 1, 3);
    free_matrix(jacobiMat,  1, 3, 1, 3);
    free_matrix(invMatrix,  1, 3, 1, 3);
    free(eigenValues);
}
Example #3
0
Transform *Transform::inverse()
{
	return new Transform(getInverseMatrix());
}
Example #4
0
love::Vector2 Transform::inverseTransformPoint(love::Vector2 p)
{
	love::Vector2 result;
	getInverseMatrix().transformXY(&result, &p, 1);
	return result;
}
Example #5
0
bool FPSManipulator::calcMovement()
{
    // return if less then two events have been added.
    if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;

    float dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized();
    float dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized();

   // float distance = sqrtf(dx*dx + dy*dy);
   
    
    // return if there is no movement.
   /* if (distance==0.0f)
    {
        return false;
    }*/

  //  unsigned int buttonMask = _ga_t1->getButtonMask();
  //  if (buttonMask==osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)//pk for test, to be removed after
    {

        // rotate camera.

        float px0 = _ga_t0->getXnormalized();
        float py0 = _ga_t0->getYnormalized();
											
        float px1 = _ga_t1->getXnormalized();
        float py1 = _ga_t1->getYnormalized();
        
		//test the border to reset the position
		if(px0>0.9 || px0<-0.9 || py0>0.9 || py0<-0.9)
		{
			_gw->requestWarpPointer((_ga_t0->getXmax() - _ga_t0->getXmin())/2,(_ga_t0->getYmax() - _ga_t0->getYmin())/2);
			flushMouseEventStack(); //rest to avoid big move
		}

		double speed = _mouseScale; //default 50.0


		//horizontal rotation
		osg::Quat qh(osg::DegreesToRadians((px1-px0)*speed), osg::Z_AXIS);


		//vertical rotation
			//rotation axis //here axis is more complex

		osg::Vec3d geteye, getcenter, getup;
		getInverseMatrix().getLookAt(geteye, getcenter, getup);

		osg::Vec3d front = getcenter - geteye;
		front.normalize();
		osg::Vec3d axis = front ^ osg::Z_AXIS;
		axis.normalize();

		//test and stop the vertical rotation
		double scalar = front * osg::Z_AXIS;
		osg::Quat qv;

		qv = osg::Quat(osg::DegreesToRadians((py0-py1)*speed+computeAnimation()), axis);

		if((scalar > 0.9 && py0 > py1 ) || (scalar < -0.9 && py0 < py1 )) //going up or down near vertical axis
		{
			qv = osg::Quat(-osg::DegreesToRadians((py0-py1)*speed), axis); //inverse rotation
		}
		
		//then apply the rotations
        _rotation = _rotation*qv*qh;


        return true;

    }
  /*  else if (buttonMask==GUIEventAdapter::MIDDLE_MOUSE_BUTTON ||
        buttonMask==(GUIEventAdapter::LEFT_MOUSE_BUTTON|GUIEventAdapter::RIGHT_MOUSE_BUTTON))
    {

        // pan model.

        float scale = -0.3f*_distance;

        osg::Matrix rotation_matrix;
        rotation_matrix.makeRotate(_rotation);

        osg::Vec3 dv(dx*scale,dy*scale,0.0f);

        _center += dv*rotation_matrix;
        
        return true;

    }
    else if (buttonMask==GUIEventAdapter::RIGHT_MOUSE_BUTTON)
    {

        // zoom model.

        float fd = _distance;
        float scale = 1.0f+dy;
        if (fd*scale>_modelScale*_minimumZoomScale)
        {

            _distance *= scale;

        }
        else
        {

            // notify(DEBUG_INFO) << "Pushing forward"<<std::endl;
            // push the camera forward.
            float scale = -fd;

            osg::Matrix rotation_matrix(_rotation);

            osg::Vec3 dv = (osg::Vec3(0.0f,0.0f,-1.0f)*rotation_matrix)*(dy*scale);

            _center += dv;

        }

        return true;

    }*/

    return false;
}
Example #6
0
osg::Matrixd TopView::getMatrix() const
{
    return osg::Matrixd::inverse(getInverseMatrix());
}
Example #7
0
void MxCore::lookAtAndFit( const osg::BoundingBox& bb )
{
    // We'll get the view matrix to project the bounding box, so pre-configure it
    // to point at the box center. Eye position doesn't matter at this point (we
    // compute the eye position at the end of the function).
    osg::Vec3d newDir = bb.center() - _position;
    newDir.normalize();
    setDir( newDir );


    // Ttransform the bounding box vertices into eye space,
    // then determine their x and y extents. We'll compare the eye
    // space bb aspect ratio against the projection _aspect to
    // determine the critical axis to fit.

    osg::ref_ptr< osg::Vec3Array > corners = new osg::Vec3Array;
    corners->resize( 8 );
    ( *corners )[ 0 ].set( bb._min );
    ( *corners )[ 1 ].set( bb._max.x(), bb._min.y(), bb._min.z() );
    ( *corners )[ 2 ].set( bb._max.x(), bb._min.y(), bb._max.z() );
    ( *corners )[ 3 ].set( bb._min.x(), bb._min.y(), bb._max.z() );
    ( *corners )[ 4 ].set( bb._max );
    ( *corners )[ 5 ].set( bb._min.x(), bb._max.y(), bb._max.z() );
    ( *corners )[ 6 ].set( bb._min.x(), bb._max.y(), bb._min.z() );
    ( *corners )[ 7 ].set( bb._max.x(), bb._max.y(), bb._min.z() );

    osgwTools::transform( getInverseMatrix(), corners.get() );
    // The 'corners' array of bb verts are now in eye space.

    // Determine max and min values for eye space x and y
    osg::Vec2 minEC( FLT_MAX, FLT_MAX ), maxEC( FLT_MIN, FLT_MIN );
    unsigned int idx;
    for( idx=0; idx<8; idx++ )
    {
        const osg::Vec3& v( ( *corners )[ idx ] );
        minEC[ 0 ] = osg::minimum< float >( v.x(), minEC[ 0 ] );
        minEC[ 1 ] = osg::minimum< float >( v.y(), minEC[ 1 ] );
        maxEC[ 0 ] = osg::maximum< float >( v.x(), maxEC[ 0 ] );
        maxEC[ 1 ] = osg::maximum< float >( v.y(), maxEC[ 1 ] );
    }
    // aspect is width (x) over height (y).
    const double ecWidth( maxEC[ 0 ] - minEC[ 0 ] );
    const double ecHeight( maxEC[ 1 ] - minEC[ 1 ] );
    const double ecAspect = ecWidth / ecHeight;


    // We'll store half the extent of interest into a dummy bounding sphere's radius.
    // We'll store the analogous fov in bestFov.
    osg::BoundingSphere bs;
    double bestFov;
    if( ecAspect > _aspect )
    {
        // Fit eye space x to the view
        bs.radius() = ecWidth * .5;
        bestFov = _aspect * _fovy;
    }
    else
    {
        // Fit eye space y to the view
        bs.radius() = ecHeight * .5;
        bestFov = _fovy;
    }

    // The wrap-up code sets the eye position at the best distance from
    // the bb center. Extra distance is added in to account for the fact
    // that the input bound probably has a larger radius than the eye coord
    // bound that we're passing to computeInitialDistanceFromFOVY().
    const double extraDistance = bb.radius() - bs.radius();
    const double distance = extraDistance +
        osgwMx::computeInitialDistanceFromFOVY( bs, bestFov );
    setPosition( bs.center() - ( newDir * distance ) );
}
Example #8
0
//Comparison speed: 10.96
//Bounding Boxes: 5.89
//Ordering: 4.99
double RayGroup::intersect(Ray3D ray,RayIntersectionInfo& iInfo,double mx){
	//printf("This runs\n");
	bool ignoreMX = false;
	if (mx == -1) ignoreMX = true;
	Ray3D rayCopy = Ray3D();
	rayCopy.position = ray.position;
	rayCopy.direction = ray.direction;

	double min_t = -1;
	RayShape* min_shape = NULL;
	RayIntersectionInfo tempInfo = RayIntersectionInfo();

	double boxOut = bBox.intersect(ray);
	if (boxOut < mx || ignoreMX){
		if(boxOut > -1){

			Matrix4D matrix = getMatrix();
			ray.position = getInverseMatrix().multPosition(ray.position);
			ray.direction = getInverseMatrix().multDirection(ray.direction);
			double scaler = ray.direction.length();
			ray.direction = ray.direction.unit();

			int count = 0;
			for (int i = 0; i < sNum; i++)
			{
				RayShape* temp = shapes[i];
				double dist = temp->bBox.intersect(ray);
				if(dist < mx || ignoreMX)
				{
					if (dist > -1)
					{
						//Means we have a hit of the inner volume
						hits[count].shape = temp;
						hits[count].t = dist;
						count++;
					}					 
				}
			}
			qsort(hits,count,sizeof(RayShapeHit),RayShapeHit::Compare);
		
	
		//if (bBox.intersect(ray) > -1){
			for (int i = 0; i < count; i++)
			{
				//printf("something got hit!\n");
				//printf("i = %i\n",i);
				RayShape* temp = hits[i].shape;
		
				double t = -1;		
		
				t = temp->intersect(ray, tempInfo, mx);
				if (t > 0)
				{
					t = t / scaler;
					if (min_t == -1 || t < min_t) 
					{	
						min_t = t;
						min_shape = temp;
						iInfo.iCoordinate = tempInfo.iCoordinate;
						iInfo.normal = tempInfo.normal;
						iInfo.material = tempInfo.material;	
						break;
					}
				}
				
																																						//Checks if its a Static Ray Group with its own transform information
		
			/*StaticRayGroup* temp2 = dynamic_cast<StaticRayGroup*>(temp);
			if(temp2 != 0) 
			{  
				t = temp->intersect(rayCopy, tempInfo, mx);
				if (t > 0)
				{
					if (min_t == -1 || t < min_t) 
					{
						iInfo.iCoordinate = tempInfo.iCoordinate;
						iInfo.normal = tempInfo.normal;
						iInfo.material = tempInfo.material;
						min_t = t;
						min_shape = temp;
					}			
				}
			}
			else 
			{
				ray.position = getInverseMatrix().multPosition(rayCopy.position);
				ray.direction = getInverseMatrix().multDirection(rayCopy.direction).unit();
				t = temp->intersect(ray, tempInfo, mx);

				if (t > 0)
				{
					if (min_t == -1 || t < min_t) 
					{
						iInfo.iCoordinate = matrix.multPosition(tempInfo.iCoordinate);
						iInfo.normal = getNormalMatrix().multNormal(tempInfo.normal);
						iInfo.material = tempInfo.material;
						min_t = t;
						min_shape = temp;
					}			
				}
			}*/		
			}	
			iInfo.iCoordinate = matrix.multPosition(iInfo.iCoordinate);
			iInfo.normal = getNormalMatrix().multDirection(iInfo.normal).unit();
			//iInfo.material = iInfo.material;
		}
	}
	return min_t;

}
bool MyFirstPersonCamManipulator::handleKeyDown(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &us)
{

	switch (ea.getKey())
	{
		case osgGA::GUIEventAdapter::KEY_KP_Space:
			home(0.0);
			break;

		case 'r':
			//_rotation.makeRotate(3.1415926535/2,1.0,0.0,0.0);
		    {
		        osg::Vec3 eye;
		        osg::Vec3 dir;
		        osg::Vec3 up;
		        getInverseMatrix().getLookAt(eye,dir,up);
		        osg::Vec3 Look=dir-eye;
		        float AngleBetweenAxisAndZ;
		        float dot=osg::Vec3(0.0,0.0,1.0)*up;

		        AngleBetweenAxisAndZ=acos(dot);
		        osg::Quat restore;
		        if(Look.z()>0.0)
		             restore.makeRotate(AngleBetweenAxisAndZ,-1.0,0.0,0.0);
		        else if(Look.z()<0.0)
		             restore.makeRotate(AngleBetweenAxisAndZ,1.0,0.0,0.0);
		        else
		        {}
		        _rotation=restore*_rotation;

		        break;
		    }
		case 'w':
	        if(!move&&(currentKey=='w'))
	        {
	             _eye+=_rotation*osg::Vec3d(0.0,0.0,2.0);
	             move=true;
	            break;
	        }
	        else if(!move&&(currentKey=='s'))
	        {
	             _eye+=_rotation*osg::Vec3d(0.0,0.0,-2.0);
	             move=true;
	            //break;
	        }
	        currentKey='w';
            _eye+=_rotation*osg::Vec3d(0.0,0.0,-1.0);
            break;
		case 's':
	        if(!move&&(currentKey=='s'))
	        {
	             _eye+=_rotation*osg::Vec3d(0.0,0.0,-2.0);
	             move=true;
	            break;
	        }
	        else if(!move&&(currentKey=='w'))
	        {
	             _eye+=_rotation*osg::Vec3d(0.0,0.0,2.0);
	             move=true;
	            //break;
	        }
	        currentKey='s';
            _eye+=_rotation*osg::Vec3d(0.0,0.0,1.0);
            break;
		default:
			break;
	}
}