Android catcake ~ texture cube ~ Gesture interactive
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.