uiacceltk/hitchcock/coretoolkit/src/huim3gmesh.cpp
changeset 0 15bf7259bb7c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/src/huim3gmesh.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,691 @@
+/*
+* Copyright (c) 2007 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:   Definition of CHuiM3GMesh, an interface enabling usage of M3G
+ * 				 scene graphs within Hitchcock UI Toolkit user interfaces.
+ *
+*/
+
+
+
+#include <uiacceltk/huim3gmesh.h>
+#include <uiacceltk/HuiStatic.h>
+#include <uiacceltk/HuiEnv.h>
+
+// Force softfp linkage until included header has its own definitions
+#if defined(__ARMCC_VERSION)
+#pragma push
+#pragma softfp_linkage
+#endif
+#include <M3G/m3g_core.h>
+#if defined(__ARMCC_VERSION)
+#pragma pop
+#endif
+
+#include <s32file.h>
+#include <e32math.h>
+#include <cstack.h>
+
+// ======== LOCAL FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// A static function to destroy an M3G object if associated clean up item
+// is popped from the cleanup stack.
+// ---------------------------------------------------------------------------
+//
+void DestroyM3GObject(TAny* aObject)
+    {
+    m3gDeleteObject( (M3GObject)aObject );
+    }
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Default constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CHuiM3GMesh::CHuiM3GMesh()
+: CHuiMesh(EHuiMeshTypeM3G)
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// 2nd phase constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CHuiM3GMesh::ConstructL()
+    {
+    iCamRotation[0] = 0;
+    iCamRotation[1] = 0;
+    iCamRotation[2] = 0;
+    iCamRotation[3] = 0;
+    iCamTranslation[0] = 0;
+    iCamTranslation[1] = 0;
+    iCamTranslation[2] = 0;
+    iCamTranslation[3] = 0;
+    }
+
+// ---------------------------------------------------------------------------
+// Load scene from file.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CHuiM3GMesh::LoadSceneL(const TDesC& /*aFileName*/)
+    {
+    }
+
+EXPORT_C void CHuiM3GMesh::LoadSceneL(const TDesC& aFileName, M3GInterface aInterface)
+    {
+    // Release the previously loaded M3G scene graph
+    ReleaseScene();
+
+    // Load the new scene graph
+    TRAPD( err, DoLoadSceneL( aFileName, aInterface ) );
+
+    // If an error occured during the scene loading release the scene and
+    // re-leave.
+    if( err != KErrNone )
+        {
+        ReleaseScene();
+        User::Leave( err );
+        }
+    }
+
+void CHuiM3GMesh::DoLoadSceneL(const TDesC& aFileName, M3GInterface aInterface)
+    {
+    // Load M3G content from same path as images
+    TFileName fileName;
+    fileName = CHuiStatic::Env().TextureManager().ImagePath();
+    fileName += aFileName;
+
+    // Create M3G loader to load the scene from memory buffer.
+    M3GLoader loader = m3gCreateLoader(aInterface);
+    if (loader == NULL)
+        {
+        User::Leave(KErrNoMemory);
+        }
+    TCleanupItem loaderCleaner( &DestroyM3GObject, loader);
+    CleanupStack::PushL(loaderCleaner);
+
+    // Read the file contents to the memory buffer    
+    RFs fs;
+    CleanupClosePushL(fs);
+    RFileReadStream reader;
+    CleanupClosePushL(reader);
+    User::LeaveIfError(fs.Connect() );
+    TInt errorCode = reader.Open(fs, fileName, EFileRead);
+    if (errorCode != KErrNone)
+        {
+        User::Leave(errorCode);
+        }
+
+    // Read the contents of the file to a buffer.
+    TInt sceneSize = reader.Source()->SizeL();
+    TUint chunkSize = 1024;
+    TUint8 *buf = new (ELeave) TUint8[chunkSize];
+    CleanupStack::PushL(buf);
+    TInt i = 0;
+    M3Gsizei reqBytes = 1;
+    while (i < sceneSize && reqBytes > 0 ){
+    TInt j = 0;
+    for( j = 0; j < chunkSize && i < sceneSize; j++ )
+        {
+        buf[j] = reader.ReadUint8L();
+        i++;
+        }
+    reqBytes = m3gDecodeData( loader, j, buf );
+    }
+
+// Get number of loaded objects
+iNumObjects = m3gGetLoadedObjects( loader, NULL );
+
+// The input buffer from the file is not needed anymore
+CleanupStack::PopAndDestroy( buf );
+CleanupStack::PopAndDestroy( &reader );
+CleanupStack::PopAndDestroy( &fs );
+
+// Leave with KErrCorrupt if there were no M3G objects within the file (corrupted file).
+if( iNumObjects == 0 )
+    {
+    User::Leave( KErrCorrupt );
+    }
+
+// Add loaded objects to an object array.
+iObjects = new (ELeave) M3GObject[iNumObjects];
+m3gGetLoadedObjects( loader, iObjects );
+
+// Add references and find the first world object
+for( TInt ii = 0; ii < iNumObjects; ii++ )
+    {
+    m3gAddRef( iObjects[ii] );
+    if( m3gGetClass( iObjects[ii] ) == M3G_CLASS_WORLD && !iWorld )
+        {
+        iWorld = (M3GWorld)iObjects[ii];
+        break;
+        }
+    }
+
+// Fetch animation controllers from world
+PopulateAnimationControllerArrayL( (M3GObject)iWorld );
+
+iUpdateCamera = EFalse;
+iCamera = m3gGetActiveCamera(iWorld);
+if ( !iCamera )
+    {
+    // Create camera if it doesn't exist
+    // The camera is updated according to hitchcock projection and model view matrices
+    iUpdateCamera = ETrue;
+    iCamera = m3gCreateCamera(aInterface);
+    if( iCamera == NULL )
+        {
+        User::Leave( KErrNoMemory );
+        }
+    m3gAddChild( (M3GGroup)iWorld, (M3GNode)iCamera );
+    m3gSetActiveCamera( iWorld, iCamera );
+    M3GMatrix identity;
+    m3gIdentityMatrix( &identity );
+    m3gSetTransform( (M3GTransformable)iCamera, &identity );
+    m3gTranslate( (M3GTransformable)iCamera, 0.f, 0.f, 1.f );
+    m3gSetPerspective( iCamera,90.f, 1.f, 0.1f, 100.f );
+    }
+
+// Init background
+M3GBackground bg = m3gGetBackground( iWorld );
+if (!bg)
+    {
+    bg = m3gCreateBackground( aInterface );
+    if( bg == NULL )
+        {
+        User::Leave( KErrNoMemory );
+        }
+    m3gSetBackground( iWorld, bg );
+    }
+m3gSetBgEnable( bg, M3G_SETGET_COLORCLEAR, M3G_FALSE );
+m3gSetBgEnable( bg, M3G_SETGET_DEPTHCLEAR, M3G_FALSE );
+
+// Release the loader
+CleanupStack::PopAndDestroy( loader );
+}
+
+// ---------------------------------------------------------------------------
+// Object destructor.
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C CHuiM3GMesh::~CHuiM3GMesh()
+    {
+    ReleaseScene();
+    iControllers.Close();
+    }
+
+// ---------------------------------------------------------------------------
+// Set viewport rect
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CHuiM3GMesh::SetViewportRect( const THuiRealRect& aRect )
+    {
+    iViewportRect = aRect;
+    }
+
+// ---------------------------------------------------------------------------
+// Draw scene
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CHuiM3GMesh::Draw(CHuiGc& /*aGc*/, const THuiImage* /*aImage*/,
+        const THuiImage* /*aSecondaryImage*/,
+        TReal32 /*aSecondaryAlpha*/) const __SOFTFP
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// Release scene
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CHuiM3GMesh::ReleaseScene()
+    {
+    if (iObjects)
+        {
+        for (TInt i = 0; i < iNumObjects; i++)
+            {
+            m3gDeleteRef(iObjects[i]);
+            iObjects[i] = NULL;
+            }
+        delete [] iObjects;
+        iNumObjects = 0;
+        iObjects = NULL;
+        iWorld = NULL;
+        }
+    iControllers.Reset();
+    }
+
+// ---------------------------------------------------------------------------
+// Rotate world around Y axis
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CHuiM3GMesh::RotateYaw(TReal32 aAngle) __SOFTFP
+    {
+    RotateObjects(aAngle, 0.0f, 1.0f, 0.0f);
+    }
+
+// ---------------------------------------------------------------------------
+// Rotate world around X axis
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CHuiM3GMesh::RotatePitch(TReal32 aAngle) __SOFTFP
+    {
+    RotateObjects(aAngle, 1.0f, 0.0f, 0.0f);
+    }
+
+// ---------------------------------------------------------------------------
+// Find the center point of the group
+// ---------------------------------------------------------------------------
+//    
+void CHuiM3GMesh::FindObjectCenter(M3GGroup aGroup, TReal32 aTrans[4],
+        TBool aFirst)
+    {
+    TReal32 objectTrans[4];
+    TInt numChildren = m3gGetChildCount(aGroup);
+    for (TInt i = 0; i < numChildren; ++i)
+        {
+        M3GNode child = m3gGetChild((M3GGroup)aGroup, i);
+        M3GClass m3gClass = m3gGetClass((M3GObject)child);
+        M3GMesh mesh = (M3GMesh)child;
+
+        if (m3gClass == M3G_CLASS_SKINNED_MESH || m3gClass == M3G_CLASS_MESH
+                || m3gClass == M3G_CLASS_MORPHING_MESH)
+            {
+
+            // Set blending and culling
+            M3GAppearance hApp = m3gGetAppearance(mesh, 0);
+
+            /*
+             M3GCompositingMode cm = m3gGetCompositingMode(hApp);
+             m3gSetBlending(cm, M3G_REPLACE);
+             m3gSetAlphaWriteEnable(cm, 0);
+             m3gSetCompositingMode(hApp, cm);
+             m3gSetAppearance( mesh, 0, hApp );
+             */
+
+            M3GPolygonMode pm = m3gGetPolygonMode(hApp);
+            m3gSetCulling(pm, M3G_CULL_NONE);
+            m3gSetPolygonMode(hApp, pm);
+
+            m3gGetTranslation((M3GTransformable)mesh, objectTrans);
+            if (!aFirst)
+                {
+                aTrans[0] = (aTrans[0] + objectTrans[0]) / 2;
+                aTrans[1] = (aTrans[1] + objectTrans[1]) / 2;
+                aTrans[2] = (aTrans[2] + objectTrans[2]) / 2;
+                aTrans[3] = (aTrans[3] + objectTrans[3]) / 2;
+                }
+            else
+                {
+                aTrans[0] = objectTrans[0];
+                aTrans[1] = objectTrans[1];
+                aTrans[2] = objectTrans[2];
+                aTrans[3] = objectTrans[3];
+                aFirst = EFalse;
+                }
+            }
+        else
+            if (m3gClass == M3G_CLASS_GROUP || m3gClass == M3G_CLASS_WORLD)
+                {
+                m3gGetTranslation((M3GTransformable)mesh, objectTrans);
+                if (!aFirst)
+                    {
+                    aTrans[0] = (aTrans[0] + objectTrans[0]) / 2;
+                    aTrans[1] = (aTrans[1] + objectTrans[1]) / 2;
+                    aTrans[2] = (aTrans[2] + objectTrans[2]) / 2;
+                    aTrans[3] = (aTrans[3] + objectTrans[3]) / 2;
+                    }
+                else
+                    {
+                    aTrans[0] = objectTrans[0];
+                    aTrans[1] = objectTrans[1];
+                    aTrans[2] = objectTrans[2];
+                    aTrans[3] = objectTrans[3];
+                    aFirst = EFalse;
+                    }
+                FindObjectCenter((M3GGroup)child, aTrans, aFirst);
+                }
+            else
+                {
+                // For PC-lint
+                }
+        }
+
+    }
+
+// ---------------------------------------------------------------------------
+// Rotates camera around worlds objects.
+// ---------------------------------------------------------------------------
+//    
+void CHuiM3GMesh::RotateObjects(TReal32 aAngle, TReal32 aAxisX,
+        TReal32 aAxisY, TReal32 aAxisZ)
+__SOFTFP        {
+        if(iWorld != 0)
+            {
+
+            // Find the center of the objects
+            TReal32 objectTrans[4];
+            objectTrans[0] = 0;
+            objectTrans[1] = 0;
+            objectTrans[2] = 0;
+            objectTrans[3] = 0;
+            FindObjectCenter((M3GGroup)iWorld,objectTrans);
+
+            // Get camera position
+            M3GCamera cam = iCamera;
+            TReal32 trans[4];
+            m3gGetTranslation((M3GTransformable)cam, trans);
+
+            // Calculate distance of objects center point and camera
+            objectTrans[0] = objectTrans[0]-trans[0];
+            objectTrans[1] = objectTrans[1]-trans[1];
+            objectTrans[2] = objectTrans[2]-trans[2];
+            objectTrans[3] = objectTrans[3]-trans[3];
+            TReal dist;
+            Math().Sqrt(dist,(TReal)objectTrans[0]*objectTrans[0]+objectTrans[1]*objectTrans[1]+objectTrans[2]*objectTrans[2]);
+
+            // Get orientation of camera
+            TReal32 rot[4];
+            m3gGetOrientation((M3GTransformable)cam, rot);
+
+            // Create new camera vector
+            M3GVec4 camZ;
+            camZ.x = 0;
+            camZ.y = 0;
+            camZ.z = -dist;
+            camZ.w = 1;
+
+            // Create rotation matrix for camera (old position)
+            M3GMatrix rotmtx;
+            m3gIdentityMatrix(&rotmtx);
+            m3gPostRotateMatrix(&rotmtx, rot[0], rot[1], rot[2], rot[3]);
+
+            // Create rotation matrix for camera (new position)
+            M3GMatrix mtx;
+            m3gIdentityMatrix(&mtx);
+            m3gPostRotateMatrix(&mtx, aAngle, aAxisX, aAxisY, aAxisZ);
+
+            // Translate camera vector
+            m3gTransformVec4(&rotmtx,&camZ);
+
+            // Store this position
+            M3GVec4 trans2;
+            trans2.x = camZ.x;
+            trans2.y = camZ.y;
+            trans2.z = camZ.z;
+            trans2.w = camZ.w;
+
+            // create new camera vector
+            camZ.x = 0;
+            camZ.y = 0;
+            camZ.z = -dist;
+            camZ.w = 1;
+
+            // transform this vector with new position matrix
+            m3gTransformVec4(&mtx,&camZ);
+
+            // transform with old position matrix
+            m3gTransformVec4(&rotmtx,&camZ);
+
+            // move and rotate camerea based on these calculations
+            m3gPostRotate((M3GTransformable)cam,aAngle, aAxisX, aAxisY, aAxisZ);
+            m3gTranslate((M3GTransformable)cam, -camZ.x+trans2.x, -camZ.y+trans2.y, -camZ.z+trans2.z);
+
+            m3gAlignNode((M3GNode)cam,NULL);
+            }
+        }
+
+    // ---------------------------------------------------------------------------
+    // Store camera transformations
+    // ---------------------------------------------------------------------------
+    //    
+EXPORT_C void CHuiM3GMesh::StoreCamera()
+    {
+    if(iWorld != 0)
+        {
+        m3gGetOrientation((M3GTransformable)iCamera, iCamRotation);
+        m3gGetTranslation((M3GTransformable)iCamera, iCamTranslation);
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Restore camera transformations
+// ---------------------------------------------------------------------------
+//    	
+EXPORT_C void CHuiM3GMesh::RestoreCamera()
+    {
+    if(iWorld != 0)
+        {
+        m3gSetOrientation((M3GTransformable)iCamera, iCamRotation[0],iCamRotation[1],iCamRotation[2],iCamRotation[3]);
+        m3gSetTranslation((M3GTransformable)iCamera, iCamTranslation[0],iCamTranslation[1],iCamTranslation[2]);
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Fetch animation controllers from any M3G object (recursively).
+// ---------------------------------------------------------------------------
+//   
+void CHuiM3GMesh::PopulateAnimationControllerArrayL(const M3GObject aObject)
+    {
+    // Array for storing the already visited M3G object pointers.
+    RPointerArray<M3GObjectImpl> visited;
+    CleanupClosePushL(visited);
+
+    // Stack for iteratively traversing through the object reference net.
+    CStack<M3GObjectImpl, EFalse>* stack = new ( ELeave ) CStack<M3GObjectImpl, EFalse>();
+    CleanupStack::PushL(stack);
+
+    // Push the initial M3G object to the iteration stack
+    stack->PushL(aObject);
+
+    // Iterate through all objects in the iteration stack
+    while ( !stack->IsEmpty() )
+        {
+        // Pop the current M3G object
+        M3GObject current = stack->Pop();
+
+        // If animation controller, add to array
+        M3GClass m3gClass = m3gGetClass(current);
+        if (m3gClass == M3G_CLASS_ANIMATION_CONTROLLER)
+            {
+            M3GAnimationController controller =
+                    (M3GAnimationController)current;
+
+            THuiM3GMeshAnimationController newController;
+            newController.iController = controller;
+            newController.iPosition = THuiTimedValue( 0,
+                    EHuiTimedValueStyleLinear);
+            newController.iAnimating = EFalse;
+            newController.iTimeOffset = 0;
+            newController.iPreviousTime
+                    = CHuiStatic::MilliSecondsSinceStart();
+            iControllers.AppendL(newController);
+            }
+
+        // Traverse graph
+        const TInt count = m3gGetReferences(current, NULL, 0);
+        if (count)
+            {
+            visited.ReserveL(visited.Count() + count);
+            M3GObject* refs = new M3GObject[count];
+            User::LeaveIfNull(refs);
+            CleanupArrayDeletePushL(refs);
+
+            m3gGetReferences(current, refs, count);
+            for (TInt i = 0; i < count; i++)
+                {
+                TInt index = 0;
+                TInt err = visited.FindInAddressOrder(refs[i], index);
+                if (err != KErrNone)
+                    {
+                    visited.InsertL(refs[i], index);
+                    stack->PushL(refs[i]);
+                    }
+                }
+
+            CleanupStack::PopAndDestroy(refs);
+            }
+        }
+
+    CleanupStack::PopAndDestroy(stack);
+    CleanupStack::PopAndDestroy( &visited);
+    }
+
+// ---------------------------------------------------------------------------
+// Returns number of (hitchcock) animation controllers
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C TInt CHuiM3GMesh::AnimationControllerCount() const
+    {
+    TInt baseAnimations = CHuiMesh::AnimationControllerCount();
+    TInt count = iControllers.Count();
+    return baseAnimations + count;
+    }
+
+// ---------------------------------------------------------------------------
+// Set position of animation in animation controller.		
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CHuiM3GMesh::SetAnimationPosition(TInt aControllerId, TReal32 aTarget, TInt aTime) __SOFTFP
+    {
+    if(iWorld != 0)
+        {
+        // Animate every controller
+        if(aControllerId == KHuiM3GAnimateAllControllers )
+            {
+            for(int i = 0; i < iControllers.Count(); i++)
+                {
+                ((iControllers[i]).iPosition).Set(aTarget-((iControllers[i]).iTimeOffset), aTime);
+                }
+            }
+        else // Animate only aControllerId:s controller
+
+            {
+            for(int i = 0; i < iControllers.Count(); i++)
+                {
+                if(aControllerId == m3gGetUserID((M3GObject)(iControllers[i].iController)))
+                    {
+                    ((iControllers[i]).iPosition).Set(aTarget-((iControllers[i]).iTimeOffset), aTime);
+                    }
+                }
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Go through animation controllers and does animations.		
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CHuiM3GMesh::AnimateControllers()
+    {
+    if(iWorld != 0)
+        {
+        TInt currentTime = CHuiStatic::MilliSecondsSinceStart();
+        for(TInt i = 0; i < iControllers.Count(); i++)
+            {
+            M3GAnimationController controller = (iControllers[i]).iController;
+            if( ( (iControllers[i]).iPosition).Changed())
+                {
+                ((iControllers[i]).iPosition).ClearChanged();
+                }
+            else
+                {
+                if ( (iControllers[i]).iAnimating )
+                    {
+                    TInt timeChanged = currentTime-((iControllers[i]).iPreviousTime);
+                    ((iControllers[i]).iTimeOffset) += timeChanged;
+                    }
+                }
+            ((iControllers[i]).iPreviousTime) = currentTime;
+            m3gSetPosition(controller, ((iControllers[i]).iPosition).Now() + ((iControllers[i]).iTimeOffset), currentTime);
+            m3gSetActiveInterval(controller, currentTime, currentTime);
+            }
+        m3gAnimate((M3GObject)iWorld, currentTime);
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Start animation of the controller
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CHuiM3GMesh::StartAnimationController(TInt aControllerId)
+    {
+    if(iWorld != 0)
+        {
+        // Start every animation controller
+        if(aControllerId == KHuiM3GAnimateAllControllers )
+            {
+            for(int i = 0; i < iControllers.Count(); i++)
+                {
+                iControllers[i].iAnimating = ETrue;
+                TInt currentTime = CHuiStatic::MilliSecondsSinceStart();
+                m3gSetActiveInterval((iControllers[i]).iController, currentTime, currentTime);
+                }
+            }
+        else // Start only aControllerId:s controller
+
+            {
+            for(int i = 0; i < iControllers.Count(); i++)
+                {
+                if(aControllerId == m3gGetUserID((M3GObject)(iControllers[i].iController)))
+                    {
+                    iControllers[i].iAnimating = ETrue;
+                    TInt currentTime = CHuiStatic::MilliSecondsSinceStart();
+                    m3gSetActiveInterval((iControllers[i]).iController, currentTime, currentTime);
+                    }
+                }
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Stop animation of the controller
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CHuiM3GMesh::StopAnimationController(TInt aControllerId)
+    {
+    if(iWorld != 0)
+        {
+        // Stop every animation controller
+        if(aControllerId == KHuiM3GAnimateAllControllers )
+            {
+            for(int i = 0; i < iControllers.Count(); i++)
+                {
+                iControllers[i].iAnimating = EFalse;
+                TInt currentTime = CHuiStatic::MilliSecondsSinceStart();
+                m3gSetActiveInterval((iControllers[i]).iController, currentTime-2, currentTime-1);
+                }
+            }
+        else // Stop only aControllerId:s controller
+
+            {
+            for(int i = 0; i < iControllers.Count(); i++)
+                {
+                if(aControllerId == m3gGetUserID((M3GObject)(iControllers[i].iController)))
+                    {
+                    iControllers[i].iAnimating = EFalse;
+                    TInt currentTime = CHuiStatic::MilliSecondsSinceStart();
+                    m3gSetActiveInterval((iControllers[i]).iController, currentTime-2, currentTime-1);
+                    }
+                }
+            }
+        }
+    }
+
+EXPORT_C void CHuiM3GMesh::M3GMeshExtension(const TUid& /*aExtensionUid*/, TAny** aExtensionParams)
+    {
+    // If no extension with given UID was found, indicate it by returning null
+    *aExtensionParams = NULL;
+    }
+