Results 1 to 4 of 4

Thread: Trying to hook up FPSControlComponent to the accelerometer

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Lesser Wizard
    Join Date
    Nov 2010
    Location
    Los Angeles, California, United States, United States
    Posts
    126

    Default Trying to hook up FPSControlComponent to the accelerometer

    I'm trying to get the RT3DApp to use the accelerometer for camera rotation. I've gotten this far:

    In MyAppDelegate.mm (didAccelerate) I changed:
    Code:
    	
    [[UIAccelerometer sharedAccelerometer] setDelegate:self];
    [[UIAccelerometer sharedAccelerometer] setUpdateInterval:0.25f];
    in FPSControlComponent::OnAdd I added:
    Code:
    GetBaseApp()->m_sig_accel.connect(1, boost::bind(&FPSControlComponent::OnAccel, this, _1));
    Code:
    void FPSControlComponent::OnAccel(VariantList *pVList)
    {
    	CL_Vec3f v = pVList->Get(1).GetVector3();
    
    #ifdef _DEBUG
    	LogMsg("Acc: %f, %f, %f", v.x, v.y, v.z);
    #endif
    	
    // at some point, I should be able to set the rotation matrix, but I'm not sure how to do this
    	irr::scene::CCameraSceneNode *camera = (irr::scene::CCameraSceneNode*)GetIrrlichtManager()->GetScene()->getActiveCamera(); 
    	// camera->setRotation(...);
    }
    I know this is somewhat elementary matrix math, but it's been a while. How can I turn the accelerometer vector into a 3D camera rotation?

  2. #2
    Administrator Seth's Avatar
    Join Date
    Jul 2002
    Location
    Japan
    Posts
    5,376

    Default

    Hmm, very good question. I haven't done this yet... but if you can take the three values and plug them into three rotation matrixes as euler angles (x,y,z) I would guess it will sort of work, but will be jittery and you'll have to do some filtering on the input first (Kalman filter?) to make it smoother. (approximate changes over the last five frames or something like that?)

    BTW, to warn ya: I am ABOUT to get seriously into the Irrlicht part of p+ soon, in fact I did update Irrlicht to 1.7.X a few days ago and will commit it soon. Need to re-add support for loading .rttex textures from Irrlicht first.

    PS, instead of hardcoding the accel update speed in MyAppDelegate.mm, you can do this from the C++ side:

    Code:
    GetBaseApp()->SetAccelerometerUpdateHz(30); //update 30 times a second
    Seth A. Robinson
    Robinson Technologies

  3. #3
    Lesser Wizard
    Join Date
    Nov 2010
    Location
    Los Angeles, California, United States, United States
    Posts
    126

    Default

    1.7... Woot! You Rock!!!

    I've got some code that does this along with filtering. Thanks for the tips.

  4. #4
    Lesser Wizard
    Join Date
    Nov 2010
    Location
    Los Angeles, California, United States, United States
    Posts
    126

    Default

    Well, I've gotten a little further with this. You can use the accelerometer to rotate up/down and tilt to turn left/right. Next I'll be trying to move this into a separate component so displaying the controls can be optional.

    end of OnAdd():
    Code:
    	// 
    	// adding acceleromter support
    	//
    	m_nAccelSmoothing = 0.1;
    	//m_v3fAccel = CL_Vec3f(.1, .1, .1);
    		
    #ifdef _DEBUG
    		m_pAccelDisplayEnt = CreateTextLabelEntity(GetParent(), "AccelDebug", GetScreenSizeXf()/2, GetScreenSizeYf()-150, "Accel:");
    		AddFocusIfNeeded(m_pAccelDisplayEnt);
    #endif
    		
    	GetBaseApp()->m_sig_accel.connect(1, boost::bind(&FPSControlComponent::OnAccel, this, _1));
    	GetBaseApp()->SetAccelerometerUpdateHz(30); //update 30 times a second
    and our message handler:
    Code:
    void FPSControlComponent::OnAccel(VariantList *pVList)
    {
    	// get raw acceleration values
    	CL_Vec3f v = pVList->Get(1).GetVector3();
    
    	// smooth this out
    	m_v3fAccel.x = v.x * m_nAccelSmoothing + m_v3fAccel.x * (1.0 - m_nAccelSmoothing);
    	m_v3fAccel.y = v.y * m_nAccelSmoothing + m_v3fAccel.y * (1.0 - m_nAccelSmoothing);
    	m_v3fAccel.z = v.z * m_nAccelSmoothing + m_v3fAccel.z * (1.0 - m_nAccelSmoothing);
    	
    	irr::scene::CCameraSceneNode *camera = (irr::scene::CCameraSceneNode*) GetIrrlichtManager()->GetScene()->getActiveCamera(); 
    
    	if( !camera )
    		return;
    	
    	if( !m_bCalibrated )
    	{
    		// record the original camera position
    		m_v3dfCameraStart = camera->getRotation();		
    		m_bCalibrated = true;
    	}
    	
    	core::vector3df v3dfNewRot;
    	
    	// Set X Rotation
    	// TODO: this assumes landscape mode
    	
    	if( m_v3fAccel.z >=0 )
    	{
    		v3dfNewRot.X = 360 - (m_v3fAccel.z * 90);	
    	}
    	else
    	{
    		v3dfNewRot.X = (m_v3fAccel.z * -90);	
    	}
    
    	// Set Y Rotation
    	if( m_v3fAccel.y >=0 )
    	{
    		v3dfNewRot.Y = m_v3dfCameraStart.Y + (m_v3fAccel.y * 90);	
    		//v3dfNewRot.Z = 90 - (m_v3fAccel.y * 90);	
    	}
    	else
    	{
    		v3dfNewRot.Y = m_v3dfCameraStart.Y + (m_v3fAccel.y * 90);	
    		//v3dfNewRot.Z = 90 - (m_v3fAccel.y * 90);	
    	}
    	
    	//v3dfNewRot.Y = m_v3dfCameraStart.Y;
    	v3dfNewRot.Z = m_v3dfCameraStart.Z; // TODO: tilt the camera
    	
    	// set our rotation
    	camera->setRotation(v3dfNewRot);
    	
    #ifdef _DEBUG
    	char strMsg[256];
    	
    	sprintf(strMsg, "Acc: %f, %f, %f\nCam: %f, %f, %f", 
    			m_v3fAccel.x, m_v3fAccel.y, m_v3fAccel.z, 
    			v3dfNewRot.X, v3dfNewRot.Y, atan2(v3dfNewRot.X , v3dfNewRot.Y));//v3dfNewRot.Z ) ;
    
    	//LogMsg("Acc: %f, %f, %f", x, y, z);
    	
    	EntityComponent* comp = m_pAccelDisplayEnt->GetComponentByName("TextRender");
    	comp->GetVar("text")->Set(strMsg);
    #endif
    
    }

Bookmarks

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •