Example 2: Advanced Content

This example demonstrates how you can implement a simple AR application using some more advanced content.

It includes tracking, loading models, using animations and user interaction.

Contents

Requirements

  • Downloaded MobileSDK from www.metaio.com/software/mobile-sdk/.
  • A running development environment as described in the Getting Started Guide.
  • A device running Anroid 2.2.1 or later. You cannot use the emulator because there is no camera image available.
  • Recommended: A print-out of the MetaioMan tracking pattern. You can also display the image on your PC screen and track that.

Package Overview

MobileSDK Package

The following illustration shows a brief overview of the packages and classes used in the example application.

package_overview.png

The simple package

Here we focus on the GPSLocationBasedActivity class which you can find inside the simple package. The following graph shows a brief overview of what is inside the simple package.

simple_package_overview.png

Setting up advanced content

Advanced content may require some extra work to get started. We will have a look at a few common cases here.

Animations

Animations can be started on geometry objects. Geometry objects are instances of the IUnifeyeGeometry class. The animations need to be defined by using a 3D-editor like Blender, 3Ds Max or Maya. For more details about content creation, please refer to the corresponding content tutorials.

For using animations in the built-in renderer every animation needs to have a unique name as identifier. Using this name the respective animation can be triggered.

In this example we like to make the MetaioMan come to life by triggering his animations. He should be in a looped idle-animation on start and react to user interaction with further animations. The MeatioMan has seven animations included: idle, close_down, close_up, close_idle, shock_down, shock_up and shock_idle. The idle animation is our default one so we start it when the model gets visible.

mMetaioMan = loadGeometry("metaioman.md2");
mMetaioMan.startAnimation("idle", false);

Note the second paramter of startAnimation: It tells the MobileSDK if this animation should be looped or not. If you have only one animation, using true here is OK. Otherwise you may want to start a different animation right after the current animation is finished. That is what we want to do later so we choose false.

User interaction

User interaction means, in this context, that the 3D world shall react on touch events on the screen of the device. To realize that we simply need to overwrite the onGeometryTouched() method. The method gets automatically called when the user touches the screen and hits a geometry.

For touch events two common use cases are shown in this example:

  • Controling animations and
  • triggering movies
Controlling animations

Our goal is to animate the MetaioMan when he is touched via the screen of the device.

The model has two different animation cycles, 'close' and 'shock' (see graph below). For simplicity we let a random number decide which cycle should be started upon a touch. To do so we override the onGeometryTouched() method.

     @Override
     protected void onGeometryTouched(IUnifeyeMobileGeometry geometry) {
         /**
          * Make sure to use 'equals' here, because the pointer to the geometry coming
          * from the MobileSDK might be 
          */
         if ( !mIsAnimationRunning && geometry.equals(mMetaioMan)) {
             Logger.log("UnifeyeCallbackHandler.onGeometryTouched: " + geometry);
             if ( Math.random()< .5 )
             {
                 mMetaioMan.startAnimation("close_down", false);
             }
             else{
                 mMetaioMan.startAnimation("shock_down", false);
             }
             mIsAnimationRunning = true;
         }
         else if ( geometry.equals(mMoviePlayButtonPlane))
         {
             mMoviePlane.playMovieTexture();
             mMoviePlane.setVisible(true);
             mMoviePlayButtonPlane.setVisible(false);
         }
     }

Note the following here:

  • The equals() method must be used here instead of the ==-operator because the member mMetaioMan is not visible for the MobileSDK directly.
  • The method onGeometryTouched() overwrites the method in ARViewActivity. The ARViewActicty itself implements a callback interface of the MobileSDK and registers itself to receive callbacks.

Until now we have only started an animation. Now we like start the respective following animations when the currently running animation is finished.

animation_cycle.png

To get notifications about the end of an animation we need to implement the IUnifeyeMobileCallback class. It is an abstract class in the MobileSDK. As it is not an interface we cannot use implement with our main activity (PatternBasedTrackingActivity). But we can create a nested class that extends the abstract class:

private final class MobileSDKCallbackHandler extends IUnifeyeMobileCallback {

        public void onAnimationEnd(IUnifeyeMobileGeometry geometry,
                String animationName) {
            Logger.log("MobileSDKCallbackHandler.onAnimationEnd: "
                    + animationName);

            String nextAnimationName = "idle";
            if ( animationName == "close_down")
            {
                nextAnimationName = "close_up";
            } else if ( animationName == "close_up")
            {
                nextAnimationName = "close_idle";
            } else if ( animationName == "shock_down")
            {
                nextAnimationName = "shock_up";
            } else if ( animationName == "shock_up" )
            {
                nextAnimationName = "shock_idle";
            } else
            {
                mIsAnimationRunning = false;
            }
            geometry.startAnimation(nextAnimationName, false);
            
        }

    }

To use this class an instance of it has to be created and passed to the MobileSDK instance in the onCreate() method.

private MobileSDKCallbackHandler mMobileSDKCallbackHandler;

@Override
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mMobileSDKCallbackHandler = new MobileSDKCallbackHandler();
 }

Movie textures

If you looked carefully at the onGeometryTouched() method above you might have seen a bit of the movie-handling already.

Movie textures have to be set manually using setMovieTexture() with the according movie:

     /*
      * Create a plane. Use one of our special movie planes here. 
      */
     mMoviePlane = loadGeometry("movieplane16_9.md2");
     /*
      * Movie textures may be set explicit.
      * mMoviePlane is an instance of IUnifeyeMobileGeometry.
      */
     mMoviePlane.setMovieTexture(getAssetPath("demo_movie.3g2"), true, true);

The playback of the movie can be controlled using the following set of methods of the geometry object:

Basically you can use any geometry with movie textures. For convenience we recommend using one of our predefined planes. These are packaged with the example application. You can find them in the assets/movieplanes-folder.

Important notes

Movie textures require certain texture coordinates to be displayed correctly. This is different compared to normal textures. As you can see in this example, normal textures are scaled to fit their targets best. But for performance reasons this step is omitted for movie textures.

You can read more about this topic in our Juniao guide about Sounds, Movies and Images.

Environment mapping

Environment Mapping, also known as "Refelection Mapping" is a useful way to make models in your application more appealing.

Instead of having a simple uniform colored global illumination the model is put into a large virtual textured cube.

Example of an Environment Map
negative_x.png negative_y.png negative_z.png positive_x.png positive_y.png positive_z.png
negativ_x negativ_y negativ_z positive_x positive_y positive_z

In this example we use a environment map with a sky-look for the truck model. The map consits of six images which have to have specific names (see table above). We recommend putting those files into a subfolder of the projects assets folder. In this case we called the folder "env_map". Loading the map works now by calling loadEnvironmentMap on the MobileSDK instance:

mMobileSDK.loadEnvironmentMap( getAssetPath("env_map" ) );
_DSC3403-3.jpg

How much the environment map reflects on the model is dependet on its refelection map, which has the name <modelname>_reflective.<extension>.

For further details please refer to the EnvironmentMapping-tutorial in this Wiki.

-- SupportMetaio - 2011-11-30

Topic attachments
I Attachment Action Size Date Who Comment
pngpng animation_cycles.png manage 22.4 K 2011-12-06 - 13:43 SupportMetaio  
pngpng package_overview.png manage 77.4 K 2011-12-06 - 09:13 SupportMetaio  
Topic revision: r17 - 2011-12-08 - 13:48:49 - SupportMetaio
 
This site is powered by the TWiki collaboration platformCopyright &© by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback