Android catcake ~ texture cube ~ Gesture interactive

screen_shot

This sample shows how to build some texture mapping primitives with catcake, and do some interactive with the GLSurfaceView with Android Gesture recognize feature.

 

Build customized catcake primitives

    int vertexCount = 2 * 3 * 6;

    ckPrim::PrimData* cubeData = new ckPrim::PrimData[vertexCount];
    // Fill the cube data content here.    
    // Give each element: vertex position, texture uv, vertex color here
 
    // 3D primitives are placed into the “DEFAULT_3D_SCREEN_ID”ckScr
    mCubePrim.init(ckPrim::MODE_TRIANGLES, cubeData, vertexCount, 
       ckDrawMgr::DEFAULT_3D_SCREEN_ID);
    // Set the primitive texture, resource id calculated on the file name
    mCubePrim.setTextureID(ckID_("NeHe.PNG"));
    // Set the primitive local matrix
    mCubePrim.local() = mCubePrim.local().scale(100.0f, 100.0f, 100.0f);
    mCubePrim.local().trans.set(0,0,-100.0f);

The process of build customized catcake 3D primitives is very simple. Preparing the primitive data (vertex position, color and one texture uv set) first, then with init function to create a Primitive element. It seems all primitives are separated into some screen space (equal a virtual camera at some certain). Then the left render work will be for catcake it’s internal system.

 

Gestures Recognize

Here I want to use scroll left or right to rotate the cube, drag with two figures to scale it. There are a lots of implementation versions on the Internet, but here I used the one provided by the Android NDK sample, class VersionedGestureDetector.java. You could search the usage of this class in other java source files. (Searching key worlds from the develop kit source folder or sample folder is a good way to find information).

 

Rotate along the screen

With the previous Gestures Recognize method, we could get  delta x and delta y when we scroll left or right. Now we could build a 3d vector that always located on the z = 0 plane.

Scroll_Vector = ( deltaX, deltaY, 0 ) / max(deltaX, deltaY)

                     and  max(deltaX,deltaY) >= A small value (I used 0.5).

Take above vector, and cross by the z vector (point out the screen), we could calculate the rotate axis. A rotate angle also could be calculated based on the max(deltaX, deltaY).

 

Rotate cube along a axis with some angle in local space

First we need to convert a pair of axis and angle to a quat, then convert quat to matrix. Accumulate those rotate matrix into cube’s local matrix so that we could rotate it.

The following are the code that used to convert a pair of axis and angle to a standard quat.

void ckQuat::set( const ckVec& axies, r32 degrees ) 
{ 
    float _s = ckMath::sin_r32( degrees * 0.5f ); 

    x = axies.x * _s; 
    y = axies.y * _s; 
    z = axies.z * _s; 
    w = ckMath::cos_r32( degrees * 0.5f ); 
}

 

Force to use “landscape” screen

When I rotate the mobile, the cube seems not always located in the center of the screen. The reason is that switch between vertical and horizontal screen layout. To make all thing become much easier, I force the application use horizontal screen layout. To mange to that, I need to add one attribute in the AndroidManifest.xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="
http://schemas.android.com/apk/res/android"
      package="catcake_application.RotateCube"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".RotateCubeActivity"
                  android:label="@string/app_name"
                  android:screenOrientation="landscape" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>   
    <uses-sdk android:minSdkVersion="10" />
</manifest>

The red one was the added one.

 

Some Tips

1) When your eclipse connect some mobile devices, you could use “adb devices”to view those connected devices; Connect the device is the first condition that go any other further operations.

2) To uninstall application $ adb uninstall full_package_name

With this command you will remove the application also the data files under that package. You need to push data next time you install that application. (?? Could we package the external data files into the .pak file. )

 

The full source code could be found here.

posted @ 2012-10-28 08:19  opencoder  阅读(377)  评论(0编辑  收藏  举报