devsoundextensions/effects/OrientationBase/src/OrientationBase.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:56:55 +0200
changeset 0 40261b775718
permissions -rw-r--r--
Revision: 201003 Kit: 201005

/*
* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:   Implementation of the Orientation effect base class
*
*/




// INCLUDE FILES

#ifdef _DEBUG
#include <e32svr.h>
#endif

#include <OrientationBase.h>
#include <e32math.h>
#include <math.h>



//360 degrees:
#define TWO_PI 6283
//180 degrees:
#define PI 3142
//90 degrees:
#define QUARTER_PI 1570


// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// COrientation::COrientation
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
EXPORT_C COrientation::COrientation()
    : 	iOrientationData(0,0,0,0,0,0,0,0,0),
    	iDataPckgTo(iOrientationData),
    	iDataPckgFrom(iOrientationData)
    {
    }

// Destructor
EXPORT_C COrientation::~COrientation()
    {
    }

// -----------------------------------------------------------------------------
// COrientation::Orientation
// -----------------------------------------------------------------------------
//
EXPORT_C void COrientation::Orientation(
	TInt32& aHeading, TInt32& aPitch, TInt32& aRoll )
	{
	aHeading = iOrientationData.iHeading;
	aPitch = iOrientationData.iPitch;
	aRoll = iOrientationData.iRoll;
	}

// -----------------------------------------------------------------------------
// COrientation::OrientationVectors
// -----------------------------------------------------------------------------
//
EXPORT_C void COrientation::OrientationVectors(
	TInt32& aFrontX, TInt32& aFrontY, TInt32& aFrontZ,
	TInt32& aAboveX, TInt32& aAboveY, TInt32& aAboveZ )
	{
	aFrontX = iOrientationData.iFrontX;
	aFrontY = iOrientationData.iFrontY;
	aFrontZ = iOrientationData.iFrontZ;
	aAboveX = iOrientationData.iAboveX;
	aAboveY = iOrientationData.iAboveY;
	aAboveZ = iOrientationData.iAboveZ;
	
	
	
	
	}

// -----------------------------------------------------------------------------
// COrientation::SetOrientationL
// -----------------------------------------------------------------------------
//
EXPORT_C void COrientation::SetOrientationL(
	TInt32 aHeading, TInt32 aPitch, TInt32 aRoll )
	{

    while(aPitch > PI) 
      {
	  aPitch = aPitch - TWO_PI;
      }
    if(aPitch > QUARTER_PI) 
      {
	  //pitch is here between 90 and 180degs. We swap it back to between 0 and 90degs. Heading needs swaping then too.
	  aPitch = aPitch - (aPitch-QUARTER_PI)*2;
	  aHeading = aHeading + PI;
	  aRoll = aRoll + PI; //I'm not sure if this line is needed. Remove it if you don't get correct results for roll or upVector
      }

    while(aPitch < -PI) 
      {
   	 aPitch = aPitch + TWO_PI;
      }
     
     if(aPitch < -QUARTER_PI) 
     {
	  //pitch is here between -90 and -180degs. We swap it back to between 0 and -90degs. Heading needs swaping then too.
	  aPitch = aPitch + (QUARTER_PI-aPitch)*2;
	  aHeading = aHeading + PI;
	  aRoll = aRoll + PI; //I'm not sure if this line is needed. Remove it if you don't get correct results for roll or upVector
     }

     while (aHeading < 0)
     {
	    aHeading = aHeading + TWO_PI;
	 }
     
     while (aHeading > TWO_PI)
     {
	    aHeading = aHeading - TWO_PI;
     }
     
     while (aRoll < 0)
     {
        aRoll = aRoll + TWO_PI;
     }
     while (aRoll > TWO_PI)
     {
	    aRoll = aRoll - TWO_PI;
     }

    iOrientationData.iHeading = aHeading;
	iOrientationData.iPitch = aPitch;
	iOrientationData.iRoll = aRoll;


    TReal headingSin, headingCos, pitchSin, pitchCos, rollSin, rollCos;
    
    User::LeaveIfError( Math::Sin( headingSin, (TReal)aHeading / 1000 ) );
    User::LeaveIfError( Math::Cos( headingCos, (TReal)aHeading / 1000) );
    User::LeaveIfError( Math::Sin( pitchSin, (TReal)aPitch / 1000) );
    User::LeaveIfError( Math::Cos( pitchCos, (TReal)aPitch / 1000) );
    User::LeaveIfError( Math::Sin( rollSin, (TReal)aRoll / 1000) );
    User::LeaveIfError( Math::Cos( rollCos, (TReal)aRoll / 1000) );   
        		
    iOrientationData.iFrontX = -headingSin * pitchCos * 1000;
    iOrientationData.iFrontY = pitchSin * 1000;
    iOrientationData.iFrontZ = -headingCos * pitchCos * 1000;
    iOrientationData.iAboveX = (-rollSin * headingCos + rollCos * pitchSin * headingSin) * 1000;
    iOrientationData.iAboveY = pitchCos * rollCos * 1000;
    iOrientationData.iAboveZ = (rollSin * headingSin + rollCos * headingCos * pitchSin) * 1000;
	}

// -----------------------------------------------------------------------------
// COrientation::SetOrientationVectorsL
// -----------------------------------------------------------------------------
//
EXPORT_C void COrientation::SetOrientationVectorsL(
	TInt32 aFrontX, TInt32 aFrontY, TInt32 aFrontZ,
	TInt32 aAboveX, TInt32 aAboveY, TInt32 aAboveZ )
	{

    iOrientationData.iFrontX = aFrontX;
	iOrientationData.iFrontY = aFrontY;
	iOrientationData.iFrontZ = aFrontZ;
	iOrientationData.iAboveX = aAboveX;
	iOrientationData.iAboveY = aAboveY;
	iOrientationData.iAboveZ = aAboveZ;
	
	TInt32 previous_valid_value_of_pitch = iOrientationData.iPitch;
	
	
	if(!((aFrontX==0) && (aFrontZ==0))) 
	{
		TReal xDividedByZAtan;
        xDividedByZAtan = atan2 (-aFrontX, -aFrontZ);
        
        if(xDividedByZAtan > 0)
	      iOrientationData.iHeading = (TInt32) (xDividedByZAtan * 1000 + 0.5);
        else
 	      iOrientationData.iHeading = (TInt32) (xDividedByZAtan * 1000 - 0.5);
        
	}
  
    if(aFrontX == 0 && aFrontZ == 0) 
    {
	  if (aFrontY > 0)
	     iOrientationData.iPitch = KPi/2 * 1000 + 0.5; //verify the units!
	  else if (aFrontY == 0)
	     iOrientationData.iPitch = previous_valid_value_of_pitch;
	  else if (aFrontY < 0)
	     iOrientationData.iPitch = -KPi/2 * 1000 - 0.5; //verify the units!
    } 
    else 
    {

      TReal sqrtXZ = 0, squareFx = 0, squareFz = 0;
      Math::Pow(squareFx, aFrontX, 2);
      Math::Pow(squareFz, aFrontZ, 2);
      TReal total = squareFx + squareFz;

      Math::Sqrt (sqrtXZ, total);
      
      TReal yTotalAtan =  atan2 ((TReal)aFrontY, sqrtXZ);
      
      if (yTotalAtan > 0)
   	    iOrientationData.iPitch = (TInt32) (yTotalAtan * 1000 + 0.5);
      else
    	 iOrientationData.iPitch = (TInt32) (yTotalAtan * 1000 - 0.5);
     
     }  
		
    TReal rot_aboveX = 0;
    
    rot_aboveX = cos(-((TReal)iOrientationData.iHeading)/1000) * (((TReal)aAboveX)/1000) + sin(-((TReal)iOrientationData.iHeading)/1000) * (((TReal)aAboveZ)/1000);

    TReal rot_aboveY = 0;
    
    rot_aboveY = sin(-((TReal)iOrientationData.iHeading)/1000) * sin(-((TReal)iOrientationData.iPitch)/1000) * (((TReal)aAboveX)/1000) + cos(-((TReal)iOrientationData.iPitch)/1000) * (((TReal)aAboveY)/1000) - sin(-(TReal)iOrientationData.iPitch/1000) * cos(-((TReal)iOrientationData.iHeading)/1000)* (((TReal)aAboveZ)/1000);

    TReal roll = atan2(-rot_aboveX, rot_aboveY);
   	
   	if (roll > 0)
   	  iOrientationData.iRoll = (TInt32) (roll * 1000 + 0.5);  
	else
   	  iOrientationData.iRoll = (TInt32) (roll * 1000 - 0.5);  
	

     while (iOrientationData.iHeading < 0)
	    iOrientationData.iHeading = iOrientationData.iHeading + TWO_PI;
	    
     while (iOrientationData.iHeading > TWO_PI)
	    iOrientationData.iHeading = iOrientationData.iHeading - TWO_PI;

     while (iOrientationData.iPitch < 0)
	    iOrientationData.iPitch = iOrientationData.iPitch + TWO_PI;
	    
     while (iOrientationData.iPitch > TWO_PI)
	    iOrientationData.iPitch = iOrientationData.iPitch - TWO_PI;
	    
     while (iOrientationData.iRoll < 0)
	    iOrientationData.iRoll = iOrientationData.iRoll + TWO_PI;
     
     while (iOrientationData.iRoll > TWO_PI)
	    iOrientationData.iRoll = iOrientationData.iRoll - TWO_PI;

	}

// -----------------------------------------------------------------------------
// COrientation::DoEffectData
// -----------------------------------------------------------------------------
//
EXPORT_C const TDesC8& COrientation::DoEffectData()
	{
#ifdef _DEBUG
    RDebug::Print(_L("COrientation::DoEffectData"));
#endif
	iDataPckgTo = iOrientationData;
	return iDataPckgTo;
	}

// -----------------------------------------------------------------------------
// COrientation::SetEffectData
// -----------------------------------------------------------------------------
//
EXPORT_C void COrientation::SetEffectData(
	const TDesC8& aEffectDataBuffer )
	{
#ifdef _DEBUG
    RDebug::Print(_L("COrientation::SetEffectData"));
#endif
	TEfOrientationDataPckg dataPckg;
	dataPckg.Copy(aEffectDataBuffer);
	iOrientationData = dataPckg();
	iEnabled = iOrientationData.iEnabled;
	iEnforced = iOrientationData.iEnforced;
	iHaveUpdateRights = iOrientationData.iHaveUpdateRights;

	}

// ========================== OTHER EXPORTED FUNCTIONS =========================

// End of File